-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Add ResilientDecodingErrorReporter #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- ThirdPartyLicenses/ResilientDecoding/LICENSE 파일 추가 - README.md에 ResilientDecoding acknowledgement 추가
- Add ErrorReporting.swift for error tracking and reporting - Add ResilientDecodingOutcome enum for decoding results - Add ArrayDecodingError for array-specific error handling - Add DictionaryDecodingError for dictionary-specific error handling
- Add ResilientProjectedValue base implementation - Add ResilientArrayProjectedValue for array property wrappers - Add ResilientDictionaryProjectedValue for dictionary property wrappers
- Add PolymorphicProjectedValue base implementation - Add PolymorphicLossyArrayProjectedValue for lossy array operations
- Move PolymorphicEnumCodableTests.swift to Enum/ directory - Move PolymorphicEnumDecodableTests.swift to Enum/ directory - Move PolymorphicValueTests.swift to Value/ directory
…bleTests Improve test safety by using #require instead of force unwrapping
- Add outcome tracking to DefaultCodable property wrapper - Implement projected value for error reporting - Handle nil values and decoding errors gracefully - Add comprehensive tests for resilient behavior
- Add outcome tracking to DataValue property wrapper - Implement projected value for error reporting - Handle decoding errors with proper error tracking - Add comprehensive tests for resilient behavior
- Add outcome tracking to DateValue and OptionalDateValue - Implement projected value for error reporting - Handle decoding errors with proper error tracking - Add comprehensive tests for resilient behavior
- Add outcome tracking to LosslessValue and LosslessArray - Implement projected value for error reporting - Handle decoding errors with proper error tracking - Add comprehensive tests for resilient behavior
- Add outcome tracking to LossyArray and LossyDictionary - Implement projected value for error reporting - Track element-level decoding results - Add comprehensive tests for resilient behavior
- Add outcome tracking to PolymorphicValue and PolymorphicArrayValue - Implement projected value for error reporting - Handle decoding errors with proper error tracking - Add comprehensive tests for resilient behavior
- Add outcome tracking to OptionalPolymorphicValue - Update KeyedDecodingContainer extension - Implement projected value for error reporting - Add comprehensive tests for resilient behavior
- Add outcome tracking to LossyOptionalPolymorphicValue - Update KeyedDecodingContainer extension - Implement projected value for error reporting - Add comprehensive tests for resilient behavior
- Add outcome tracking to OptionalPolymorphicArrayValue - Update KeyedDecodingContainer extension with error handling - Implement projected value for error reporting - Add comprehensive tests for resilient behavior
…alue - Add outcome tracking to DefaultEmptyPolymorphicArrayValue - Update KeyedDecodingContainer extension with error handling - Implement projected value for error reporting - Move test file to ArrayValue directory
- Add outcome tracking to PolymorphicLossyArrayValue - Update KeyedDecodingContainer extension with error handling - Implement projected value with element results - Move test file to ArrayValue directory
…ing implementation
📝 WalkthroughWalkthroughThis update introduces a comprehensive resilient decoding system to the KarrotCodableKit framework. It adds new property wrapper features for error tracking, projected value types for debugging, and a robust error reporting mechanism. Numerous test suites are added to validate resilient decoding behavior, error recovery, and error reporting across various property wrappers and polymorphic types. The changes also include code cleanups, comment formatting, and minor syntactic improvements. Changes
Sequence Diagram(s)sequenceDiagram
participant Decoder
participant PropertyWrapper
participant ErrorReporter
participant Client
Decoder->>PropertyWrapper: decode(value)
alt Decoding succeeds
PropertyWrapper->>PropertyWrapper: set outcome = decodedSuccessfully
else Decoding fails
PropertyWrapper->>ErrorReporter: reportError(error)
PropertyWrapper->>PropertyWrapper: set outcome = recoveredFrom(error, wasReported: true)
end
PropertyWrapper->>Client: expose projectedValue (outcome, error)
Client->>ErrorReporter: flushReportedErrors()
Estimated code review effort🎯 5 (Critical) | ⏱️ ~90+ minutes This is a large, high-complexity update with new core types, significant property wrapper refactors, new error reporting infrastructure, many new test suites, and broad API changes. Reviewers should plan for a deep, multi-pass review including API surface, error handling, and test coverage. Possibly related PRs
Suggested labels
Suggested reviewers
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. ✨ Finishing Touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 22
🔭 Outside diff range comments (3)
Sources/KarrotCodableKit/BetterCodable/DateValue/OptionalDateValue.swift (1)
89-108: KeyedDecodingContainer extensions may need outcome tracking [MEDIUM]The
decodeIfPresentmethods create new instances without proper outcome tracking. Consider updating these to use the internal initializer with appropriate outcomes.public func decodeIfPresent<T>( _ type: OptionalDateValue<T>.Type, forKey key: Self.Key ) throws -> OptionalDateValue<T> where T.RawValue == String { let stringOptionalValue = try decodeIfPresent(String.self, forKey: key) guard let stringValue = stringOptionalValue else { - return .init(wrappedValue: nil) + return .init(wrappedValue: nil, outcome: .keyNotFound) } let dateValue = try T.decode(stringValue) - return .init(wrappedValue: dateValue) + return .init(wrappedValue: dateValue, outcome: .decodedSuccessfully) }Sources/KarrotCodableKit/PolymorphicCodable/PolymorphicArrayValue.swift (1)
50-62: Missing error reporting integration [HIGH]Unlike
DefaultEmptyPolymorphicArrayValue, this wrapper doesn't integrate with the error reporting system when decoding fails. This creates inconsistency in error handling across similar wrappers.Consider adding error reporting similar to
DefaultEmptyPolymorphicArrayValue:public init(from decoder: Decoder) throws { - var container = try decoder.unkeyedContainer() - - var elements = [PolymorphicType.ExpectedType]() - while !container.isAtEnd { - let value = try container.decode(PolymorphicValue<PolymorphicType>.self).wrappedValue - elements.append(value) - } - - self.wrappedValue = elements - self.outcome = .decodedSuccessfully + do { + var container = try decoder.unkeyedContainer() + var elements = [PolymorphicType.ExpectedType]() + + while !container.isAtEnd { + let value = try container.decode(PolymorphicValue<PolymorphicType>.self).wrappedValue + elements.append(value) + } + + self.wrappedValue = elements + self.outcome = .decodedSuccessfully + } catch { + decoder.reportError(error) + throw error + }Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyDictionary.swift (1)
236-250: Potential issue with key extraction when counts don't matchThe
zipoperation will silently truncate if the key counts don't match. Consider adding validation:private static func extractKeys( from decoder: Decoder, container: KeyedDecodingContainer<DictionaryCodingKey> ) throws -> [ExtractedKey] { // Decode a dictionary ignoring the values to decode the original keys // without using the `JSONDecoder.KeyDecodingStrategy`. let keys = try decoder.singleValueContainer().decode([String: AnyDecodableValue].self).keys + + let containerKeys = container.allKeys + guard keys.count == containerKeys.count else { + throw DecodingError.dataCorrupted( + DecodingError.Context( + codingPath: decoder.codingPath, + debugDescription: "Key count mismatch: \(keys.count) vs \(containerKeys.count)" + ) + ) + } return zip( - container.allKeys.sorted(by: { $0.stringValue < $1.stringValue }), + containerKeys.sorted(by: { $0.stringValue < $1.stringValue }), keys.sorted() ) .map { ExtractedKey(codingKey: $0, originalKey: $1) } }
📜 Review details
Configuration used: .coderabbit.yml
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
ThirdPartyLicenses/ResilientDecoding/LICENSEis excluded by!**/ThirdPartyLicenses/**
📒 Files selected for processing (46)
README.md(1 hunks)Sources/KarrotCodableKit/BetterCodable/DataValue/DataValue.swift(2 hunks)Sources/KarrotCodableKit/BetterCodable/DateValue/DateValue.swift(2 hunks)Sources/KarrotCodableKit/BetterCodable/DateValue/OptionalDateValue.swift(2 hunks)Sources/KarrotCodableKit/BetterCodable/Defaults/DefaultCodable.swift(6 hunks)Sources/KarrotCodableKit/BetterCodable/Extenstoins/Result+Extension.swift(1 hunks)Sources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessArray.swift(3 hunks)Sources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessValue.swift(2 hunks)Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyArray.swift(2 hunks)Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyDictionary.swift(4 hunks)Sources/KarrotCodableKit/BetterCodable/ResilientProjectedValue.swift(1 hunks)Sources/KarrotCodableKit/PolymorphicCodable/DefaultEmptyPolymorphicArrayValue.swift(2 hunks)Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+DefaultEmptyPolymorphicArrayValue.swift(1 hunks)Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+LossyOptionalPolymorphicValue.swift(1 hunks)Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+OptionalPolymorphicArrayValue.swift(2 hunks)Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+OptionalPolymorphicValue.swift(1 hunks)Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+PolymorphicLossyArrayValue.swift(1 hunks)Sources/KarrotCodableKit/PolymorphicCodable/LossyOptionalPolymorphicValue.swift(2 hunks)Sources/KarrotCodableKit/PolymorphicCodable/OptionalPolymorphicArrayValue.swift(2 hunks)Sources/KarrotCodableKit/PolymorphicCodable/OptionalPolymorphicValue.swift(2 hunks)Sources/KarrotCodableKit/PolymorphicCodable/PolymorphicArrayValue.swift(3 hunks)Sources/KarrotCodableKit/PolymorphicCodable/PolymorphicLossyArrayValue.swift(4 hunks)Sources/KarrotCodableKit/PolymorphicCodable/PolymorphicProjectedValue.swift(1 hunks)Sources/KarrotCodableKit/PolymorphicCodable/PolymorphicValue.swift(2 hunks)Sources/KarrotCodableKit/Resilient/ArrayDecodingError.swift(1 hunks)Sources/KarrotCodableKit/Resilient/DictionaryDecodingError.swift(1 hunks)Sources/KarrotCodableKit/Resilient/ErrorReporting.swift(1 hunks)Sources/KarrotCodableKit/Resilient/ResilientDecodingOutcome.swift(1 hunks)Tests/KarrotCodableKitTests/BetterCodable/DataValue/DataValueResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/BetterCodable/DateValue/DateValueResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultCodableResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessArrayResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessValueResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyArrayResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyDictionaryResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/DefaultEmptyPolymorphicArrayValueResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/DefaultEmptyPolymorphicArrayValueTests.swift(3 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/PolymorphicArrayValueResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/PolymorphicLossyArrayValueResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/PolymorphicLossyArrayValueTests.swift(1 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalPolymorphicArrayValueResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalValue/LossyOptionalPolymorphicValueResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalValue/LossyOptionalPolymorphicValueTests.swift(1 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalValue/OptionalPolymorphicValueResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/UnnestedPolymorphicTests/UnnestedPolymorphicDecodableTests.swift(5 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/Value/PolymorphicValueResilientTests.swift(1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
Tests/KarrotCodableKitTests/**
⚙️ CodeRabbit Configuration File
Tests/KarrotCodableKitTests/**: You are a senior Swift/iOS engineer reviewing runtime functionality tests for KarrotCodableKit's Codable extensions.1. Runtime Behavior Testing [HIGH]
- Verify JSON encoding/decoding scenarios cover real-world use cases
- Check polymorphic type resolution testing across different strategies
- Assess property wrapper testing (@DATEvalue, @DefaultFalse, etc.)
- Validate error handling and edge case coverage
2. Test Data Quality [HIGH]
- Review test JSON structures for realistic complexity
- Check that TestDoubles provide comprehensive mock scenarios
- Verify test data covers various data types and edge cases
- Assess polymorphic test data represents actual usage patterns
3. Integration Testing [MEDIUM]
- Check integration between macro-generated code and runtime functionality
- Verify end-to-end scenarios combining multiple KarrotCodableKit features
- Assess performance testing for large data structures
- Review memory usage testing for complex polymorphic scenarios
Review Focus
- Prioritize real-world usage scenario coverage
- Focus on Codable correctness and performance implications
- Mark comments with priority: [HIGH], [MEDIUM], or [LOW]
Files:
Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalValue/LossyOptionalPolymorphicValueTests.swiftTests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/PolymorphicLossyArrayValueTests.swiftTests/KarrotCodableKitTests/PolymorphicCodable/UnnestedPolymorphicTests/UnnestedPolymorphicDecodableTests.swiftTests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/DefaultEmptyPolymorphicArrayValueTests.swiftTests/KarrotCodableKitTests/BetterCodable/DataValue/DataValueResilientTests.swiftTests/KarrotCodableKitTests/PolymorphicCodable/OptionalValue/OptionalPolymorphicValueResilientTests.swiftTests/KarrotCodableKitTests/PolymorphicCodable/Value/PolymorphicValueResilientTests.swiftTests/KarrotCodableKitTests/PolymorphicCodable/OptionalPolymorphicArrayValueResilientTests.swiftTests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyDictionaryResilientTests.swiftTests/KarrotCodableKitTests/PolymorphicCodable/OptionalValue/LossyOptionalPolymorphicValueResilientTests.swiftTests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessArrayResilientTests.swiftTests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessValueResilientTests.swiftTests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyArrayResilientTests.swiftTests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/PolymorphicArrayValueResilientTests.swiftTests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/DefaultEmptyPolymorphicArrayValueResilientTests.swiftTests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/PolymorphicLossyArrayValueResilientTests.swiftTests/KarrotCodableKitTests/BetterCodable/DateValue/DateValueResilientTests.swiftTests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultCodableResilientTests.swift
*
⚙️ CodeRabbit Configuration File
*: You are a senior Swift/iOS engineer with 15+ years of experience reviewing KarrotCodableKit code changes.Review Priorities [HIGH]
- Code quality: memory leaks, error handling, readability (100 chars/line)
- Architecture: SOLID principles, design patterns, DRY/KISS
- Swift best practices: modern features, memory management, performance
Communication
- Mark priority: [HIGH], [MEDIUM], [LOW]
- Provide specific code examples
- Focus on high-impact improvements over style
Files:
README.md
**/*.md
⚙️ CodeRabbit Configuration File
**/*.md: You are a senior technical writer reviewing documentation for KarrotCodableKit, a Swift Codable extension library.1. Technical Accuracy [HIGH]
- Verify code examples compile and work correctly
- Check that API documentation matches actual implementation
- Validate macro usage examples demonstrate proper syntax
- Assess JSON examples are well-formed and realistic
2. Documentation Completeness [HIGH]
- Review coverage of all major features (CustomCodable, PolymorphicCodable, AnyCodable, BetterCodable)
- Check that complex concepts like polymorphic type resolution are well explained
- Verify installation and setup instructions are current
- Assess troubleshooting and error handling guidance
3. User Experience [MEDIUM]
- Evaluate documentation structure and navigation clarity
- Check that examples progress from simple to complex appropriately
- Verify code snippets include necessary imports and context
- Assess whether documentation answers common user questions
Review Focus
- Prioritize accuracy and completeness over style
- Focus on developer experience and practical usage scenarios
- Mark comments with priority: [HIGH], [MEDIUM], or [LOW]
Files:
README.md
Sources/KarrotCodableKit/**
⚙️ CodeRabbit Configuration File
Sources/KarrotCodableKit/**: You are a senior Swift/iOS engineer reviewing runtime library code for KarrotCodableKit, a comprehensive Codable extension framework.1. Codable Performance [HIGH]
- Check encoding/decoding efficiency and memory usage
- Verify proper handling of large JSON structures
- Assess polymorphic type resolution performance
- Review property wrapper overhead and optimization
2. Type Safety & Polymorphism [HIGH]
- Validate PolymorphicCodable identifier-based type resolution
- Check AnyCodable type erasure implementation for edge cases
- Verify UnnestedPolymorphic macro integration with runtime components
- Assess error handling in polymorphic decoding scenarios
3. API Design [HIGH]
- Evaluate public interface consistency across modules
- Check property wrapper ergonomics (@DefaultFalse, @DATEvalue, etc.)
- Verify protocol design follows Swift API guidelines
- Assess extensibility for new Codable patterns
4. BetterCodable Integration [MEDIUM]
- Review property wrapper implementations for common patterns
- Check date strategy implementations (ISO8601, RFC3339, etc.)
- Verify default value and lossy conversion handling
- Assess data encoding strategies (Base64, etc.)
5. Error Handling [MEDIUM]
- Verify comprehensive DecodingError and EncodingError usage
- Check PolymorphicCodableError provides sufficient context
- Assess graceful fallback handling in polymorphic scenarios
Review Focus
- Prioritize runtime correctness and performance over style
- Focus on real-world JSON processing scenarios
- Mark comments with priority: [HIGH], [MEDIUM], or [LOW]
Files:
Sources/KarrotCodableKit/BetterCodable/Extenstoins/Result+Extension.swiftSources/KarrotCodableKit/PolymorphicCodable/OptionalPolymorphicValue.swiftSources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessArray.swiftSources/KarrotCodableKit/PolymorphicCodable/LossyOptionalPolymorphicValue.swiftSources/KarrotCodableKit/BetterCodable/DateValue/DateValue.swiftSources/KarrotCodableKit/PolymorphicCodable/PolymorphicArrayValue.swiftSources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+OptionalPolymorphicArrayValue.swiftSources/KarrotCodableKit/BetterCodable/DateValue/OptionalDateValue.swiftSources/KarrotCodableKit/PolymorphicCodable/PolymorphicProjectedValue.swiftSources/KarrotCodableKit/Resilient/ResilientDecodingOutcome.swiftSources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessValue.swiftSources/KarrotCodableKit/BetterCodable/DataValue/DataValue.swiftSources/KarrotCodableKit/PolymorphicCodable/DefaultEmptyPolymorphicArrayValue.swiftSources/KarrotCodableKit/Resilient/ArrayDecodingError.swiftSources/KarrotCodableKit/BetterCodable/LossyValue/LossyArray.swiftSources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+OptionalPolymorphicValue.swiftSources/KarrotCodableKit/PolymorphicCodable/PolymorphicLossyArrayValue.swiftSources/KarrotCodableKit/BetterCodable/ResilientProjectedValue.swiftSources/KarrotCodableKit/PolymorphicCodable/OptionalPolymorphicArrayValue.swiftSources/KarrotCodableKit/PolymorphicCodable/PolymorphicValue.swiftSources/KarrotCodableKit/Resilient/DictionaryDecodingError.swiftSources/KarrotCodableKit/BetterCodable/Defaults/DefaultCodable.swiftSources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+PolymorphicLossyArrayValue.swiftSources/KarrotCodableKit/Resilient/ErrorReporting.swiftSources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+DefaultEmptyPolymorphicArrayValue.swiftSources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+LossyOptionalPolymorphicValue.swiftSources/KarrotCodableKit/BetterCodable/LossyValue/LossyDictionary.swift
🧬 Code Graph Analysis (12)
Tests/KarrotCodableKitTests/BetterCodable/DataValue/DataValueResilientTests.swift (2)
Sources/KarrotCodableKit/Resilient/ErrorReporting.swift (5)
decode(56-71)enableResilientDecodingErrorReporting(23-27)enableResilientDecodingErrorReporting(52-54)flushReportedErrors(84-89)errors(109-117)Tests/KarrotCodableKitTests/BetterCodable/DataValue/DataValueTests.swift (1)
DataValueTests(12-47)
Sources/KarrotCodableKit/PolymorphicCodable/OptionalPolymorphicValue.swift (1)
Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+OptionalPolymorphicValue.swift (1)
decode(12-21)
Sources/KarrotCodableKit/BetterCodable/DateValue/DateValue.swift (8)
Sources/KarrotCodableKit/BetterCodable/DateValue/OptionalDateValue.swift (2)
decode(89-94)lhs(75-77)Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyDictionary.swift (2)
decode(269-279)lhs(259-261)Sources/KarrotCodableKit/BetterCodable/Defaults/DefaultCodable.swift (4)
decode(120-149)decode(157-208)decode(215-272)lhs(99-101)Sources/KarrotCodableKit/Resilient/ErrorReporting.swift (1)
reportError(154-166)Sources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessArray.swift (1)
lhs(88-90)Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyArray.swift (1)
lhs(107-109)Sources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessValue.swift (1)
lhs(91-93)Sources/KarrotCodableKit/BetterCodable/DataValue/DataValue.swift (1)
lhs(70-72)
Sources/KarrotCodableKit/PolymorphicCodable/PolymorphicArrayValue.swift (2)
Sources/KarrotCodableKit/PolymorphicCodable/DefaultEmptyPolymorphicArrayValue.swift (2)
lhs(92-94)hash(98-100)Sources/KarrotCodableKit/PolymorphicCodable/PolymorphicValue.swift (2)
lhs(64-66)hash(70-72)
Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+OptionalPolymorphicArrayValue.swift (1)
Sources/KarrotCodableKit/Resilient/ErrorReporting.swift (1)
reportError(154-166)
Sources/KarrotCodableKit/PolymorphicCodable/PolymorphicProjectedValue.swift (1)
Sources/KarrotCodableKit/Resilient/ResilientDecodingOutcome.swift (1)
recoveredFrom(46-46)
Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalPolymorphicArrayValueResilientTests.swift (3)
Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+OptionalPolymorphicArrayValue.swift (1)
decode(12-25)Sources/KarrotCodableKit/Resilient/ErrorReporting.swift (1)
flushReportedErrors(84-89)Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalPolymorphicArrayValueTests.swift (1)
OptionalPolymorphicArrayValueTests(13-214)
Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyArray.swift (3)
Sources/KarrotCodableKit/Resilient/ErrorReporting.swift (1)
reportError(154-166)Sources/KarrotCodableKit/Resilient/ResilientDecodingOutcome.swift (1)
recoveredFrom(46-46)Sources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessArray.swift (2)
lhs(88-90)hash(94-96)
Sources/KarrotCodableKit/BetterCodable/ResilientProjectedValue.swift (3)
Sources/KarrotCodableKit/Resilient/ResilientDecodingOutcome.swift (1)
recoveredFrom(46-46)Sources/KarrotCodableKit/Resilient/ArrayDecodingError.swift (1)
arrayDecodingError(24-40)Sources/KarrotCodableKit/Resilient/DictionaryDecodingError.swift (1)
dictionaryDecodingError(23-38)
Sources/KarrotCodableKit/Resilient/DictionaryDecodingError.swift (2)
Sources/KarrotCodableKit/Resilient/ErrorReporting.swift (1)
errors(109-117)Sources/KarrotCodableKit/Resilient/ResilientDecodingOutcome.swift (1)
recoveredFrom(46-46)
Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+PolymorphicLossyArrayValue.swift (2)
Sources/KarrotCodableKit/Resilient/ResilientDecodingOutcome.swift (1)
recoveredFrom(46-46)Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+DefaultEmptyPolymorphicArrayValue.swift (1)
decodeIfPresent(31-48)
Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+DefaultEmptyPolymorphicArrayValue.swift (1)
Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+PolymorphicLossyArrayValue.swift (1)
decodeIfPresent(48-69)
🪛 SwiftLint (0.57.0)
Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalPolymorphicArrayValueResilientTests.swift
[Warning] 16-16: Type name 'ResilientOptionalPolymorphicArrayDummyResponse' should be between 3 and 40 characters long
(type_name)
[Warning] 30-30: Type name 'OptionalPolymorphicArrayValueResilientTests' should be between 3 and 40 characters long
(type_name)
Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalValue/LossyOptionalPolymorphicValueResilientTests.swift
[Warning] 6-6: Type name 'LossyOptionalPolymorphicValueResilientTests' should be between 3 and 40 characters long
(type_name)
Tests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/DefaultEmptyPolymorphicArrayValueResilientTests.swift
[Warning] 6-6: Type name 'DefaultEmptyPolymorphicArrayValueResilientTests' should be between 3 and 40 characters long
(type_name)
🔇 Additional comments (100)
Tests/KarrotCodableKitTests/PolymorphicCodable/UnnestedPolymorphicTests/UnnestedPolymorphicDecodableTests.swift (3)
58-61: Excellent safety improvement with consistent error handling! [HIGH]The change from forced unwrapping to
try #require(json.data(using: .utf8))significantly improves test safety by preventing potential runtime crashes if string-to-data conversion fails. This pattern provides clear test failure messages when data conversion issues occur.
84-87: Consistent safety pattern applied across all test methods. [HIGH]The uniform application of
try #require(json.data(using: .utf8))across all test methods demonstrates excellent consistency. This approach ensures that:
- Test reliability: Prevents crashes from malformed JSON strings during development
- Clear failure reporting: The
#requiremacro provides descriptive failure messages- Maintainability: Consistent error handling pattern across the test suite
The test scenarios cover comprehensive edge cases including missing keys, partial data, missing required properties, and wrong data types - excellent coverage for polymorphic decoding validation.
Also applies to: 108-111, 127-130, 147-150
47-156: Comprehensive test coverage with realistic scenarios. [HIGH]The test suite excellently covers the full spectrum of polymorphic decoding scenarios:
- Successful decoding: Basic polymorphic item decoding with proper validation
- Edge cases: Missing optional properties, partial data, required property failures
- Error scenarios: Missing data keys, wrong data types with appropriate
DecodingErrorexpectations- Data quality: Realistic JSON structures that mirror production use cases
The test data represents actual usage patterns with meaningful property names (
id,title,count,url) and realistic values. This aligns perfectly with the coding guidelines emphasis on real-world usage scenario coverage.README.md (1)
280-280: LGTM! Proper attribution added for ResilientDecodingOutcome.The acknowledgement correctly credits the airbnb/ResilientDecoding library as the source of inspiration for the new resilient decoding functionality, maintaining consistency with other third-party acknowledgements in the section.
Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalValue/LossyOptionalPolymorphicValueTests.swift (1)
120-120: Good catch on the grammar correction.Fixing "thens" to "then" improves the readability of the test comment.
Tests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/PolymorphicLossyArrayValueTests.swift (1)
164-164: Another good grammar fix.Consistent improvement in test comment readability by correcting "thens" to "then".
Tests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/DefaultEmptyPolymorphicArrayValueTests.swift (1)
116-116: Clean up of test comment formatting looks good.The more concise comment style (removing colons and extra explanatory text) improves readability while maintaining the clear given/when/then structure of the tests.
Also applies to: 133-133, 136-136, 163-163
Sources/KarrotCodableKit/BetterCodable/Extenstoins/Result+Extension.swift (1)
10-34: Well-designed Result extension with useful convenience properties.The implementation provides clean, non-throwing access to Result values:
isSuccess/isFailure: Efficient boolean checks using pattern matchingsuccess: Safe value extraction usingtry? get()failure: Consistent pattern matching for error extraction- Package access level is appropriate for internal utilities
This extension will be valuable for the resilient decoding infrastructure introduced in this PR.
Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalValue/OptionalPolymorphicValueResilientTests.swift (4)
11-30: LGTM! Well-structured test for nil value handlingThe test properly validates that null JSON values are handled correctly with appropriate outcome tracking.
32-49: Good coverage of missing key scenarioThe test effectively validates the keyNotFound outcome when the expected key is absent from the JSON.
51-80: Comprehensive test for successful polymorphic decodingThe test properly validates successful decoding with realistic JSON data structure and thorough assertions on the decoded object properties.
101-115: Test adequately covers invalid JSON scenarioThe test validates error handling for type mismatches in the JSON structure.
Sources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessArray.swift (3)
21-38: Well-designed outcome tracking and projected value implementationThe addition of outcome tracking with debug-only projected value follows best practices for exposing diagnostic information without impacting release builds.
87-97: Standard conformance implementationsThe Equatable and Hashable implementations correctly delegate to the wrapped value, maintaining consistency with other property wrappers.
69-74: Critical: Incorrect condition for determining decoding success [HIGH]The condition
elements.count == results.countis incorrect for lossy array decoding. When elements fail to decode, they are skipped (not added toelements), makingelements.countless thanresults.count. This means the condition will be false even when all decodable elements were successfully decoded, incorrectly setting the outcome torecoveredFrom.- if elements.count == results.count { + if results.allSatisfy({ if case .success = $0 { true } else { false } }) { self.init(wrappedValue: elements, outcome: .decodedSuccessfully) } else { let error = ResilientDecodingOutcome.ArrayDecodingError(results: results) self.init(wrappedValue: elements, outcome: .recoveredFrom(error, wasReported: false)) }Likely an incorrect or invalid review comment.
Tests/KarrotCodableKitTests/BetterCodable/DateValue/DateValueResilientTests.swift (3)
47-69: Good coverage of invalid date format scenariosThe test effectively validates error handling with diverse invalid formats for each date strategy.
71-93: Proper validation of null value handlingThe test correctly verifies that null values cause decoding failures for non-optional Date properties.
95-124: Excellent integration test for error reporting [HIGH]The test thoroughly validates the integration with JSONDecoder's resilient error reporting mechanism using appropriate type mismatch scenarios.
Sources/KarrotCodableKit/BetterCodable/DateValue/DateValue.swift (3)
27-42: Clean implementation of outcome trackingThe outcome property and projected value implementation follows the established pattern across the codebase.
65-69: Good consistency improvementUsing
Selfin the equality operator signature improves consistency with other property wrappers in the codebase.
46-55: Critical: Incomplete property initialization on error path [HIGH]When decoding fails, the error is rethrown without initializing the
outcomeproperty, which violates Swift's initialization requirements. All stored properties must be initialized before throwing from an initializer.public init(from decoder: Decoder) throws { do { let value = try Formatter.RawValue(from: decoder) self.wrappedValue = try Formatter.decode(value) self.outcome = .decodedSuccessfully } catch { decoder.reportError(error) + self.wrappedValue = Date() // or another appropriate default + self.outcome = .recoveredFrom(error, wasReported: true) throw error } }Alternatively, if a default date is not appropriate, this property wrapper might not be suitable for non-optional date values when resilient decoding is needed.
Likely an incorrect or invalid review comment.
Tests/KarrotCodableKitTests/BetterCodable/DataValue/DataValueResilientTests.swift (4)
19-41: Well-structured test with clear validationsThe test effectively validates successful base64 decoding with readable test data and appropriate outcome assertions.
43-64: Comprehensive invalid format testingThe test uses diverse invalid base64 patterns to ensure robust error handling.
66-87: Correct null value handling validationThe test properly verifies that null values cause decoding failures for non-optional Data properties.
89-117: Solid error reporting integration test [HIGH]The test effectively validates error capture with diverse type mismatch scenarios and appropriately flexible error count assertion.
Tests/KarrotCodableKitTests/PolymorphicCodable/Value/PolymorphicValueResilientTests.swift (1)
18-45: LGTM! Well-structured test for successful decoding scenarioThe test properly validates both the successful decoding behavior and the projected value access in debug builds. Good use of conditional compilation for debug-only features.
Sources/KarrotCodableKit/Resilient/ResilientDecodingOutcome.swift (1)
8-49: Excellent design for debug/release optimizationThe conditional compilation approach provides rich debugging information in development while minimizing runtime overhead in production. The Equatable implementation pragmatically compares outcome types and reporting status without comparing error instances.
Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+OptionalPolymorphicArrayValue.swift (2)
12-25: LGTM! Clean delegation patternThe method properly delegates to
decodeIfPresentand handles the nil case with appropriate outcome tracking.
61-66: Good error reporting patternThe error handling correctly reports the error through the decoder before rethrowing, enabling resilient error collection while maintaining the expected throwing behavior.
Sources/KarrotCodableKit/PolymorphicCodable/OptionalPolymorphicValue.swift (1)
42-53: Well-designed projected value with appropriate safeguardsThe conditional compilation ensures debug-only access to diagnostic information while preventing accidental usage in production builds with a clear error message.
Sources/KarrotCodableKit/PolymorphicCodable/LossyOptionalPolymorphicValue.swift (2)
67-80: LGTM! Proper error recovery implementationThe error handling correctly reports errors for diagnostics while providing the expected lossy behavior of returning nil on failure. The outcome tracking accurately reflects the recovery state.
82-93: Consistent Equatable and Hashable implementationsThe implementations correctly focus on the wrapped value for equality and hashing, ignoring the decoding outcome which is appropriate for these protocols.
Tests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyDictionaryResilientTests.swift (3)
14-23: Good test fixture design!The fixture covers a variety of dictionary types (String/Int keys, primitive/object values) which provides comprehensive test coverage for the
@LossyDictionarywrapper.
80-105: Well-structured error reporting test! [MEDIUM]The test properly validates integration with the decoder's error reporting mechanism and uses flexible assertions that don't overly constrain the implementation.
107-154: Comprehensive edge case coverage! [HIGH]Both tests properly validate important scenarios:
- Complete decoding failure results in empty dictionaries with appropriate error states
- Missing keys correctly produce empty dictionaries without errors
- The distinction between null (not an error) and wrong type (error) is well-handled
Sources/KarrotCodableKit/Resilient/ArrayDecodingError.swift (2)
13-22: Clean error aggregation design! [HIGH]The
ArrayDecodingErrorstruct effectively uses Swift'sResulttype to track per-element decoding outcomes and provides convenient error extraction.
24-40: Thoughtful error transformation logic! [HIGH]The method correctly handles all outcome cases with appropriate transformations. The assertion preventing double-reporting of
ArrayDecodingErrorand the usability-focused design of wrapping top-level errors are particularly well-considered.Sources/KarrotCodableKit/PolymorphicCodable/PolymorphicProjectedValue.swift (2)
13-28: Well-designed protocol with smart defaults! [HIGH]The
PolymorphicProjectedValueProtocolprovides a minimal interface with a useful default implementation for error extraction that correctly handles all outcome cases.
43-58: Excellent specialization for array diagnostics! [HIGH]The
PolymorphicLossyArrayProjectedValueeffectively extends the base projected value with element-level result tracking, enabling detailed debugging of array decoding failures.Sources/KarrotCodableKit/PolymorphicCodable/PolymorphicValue.swift (3)
27-42: Consistent resilient decoding implementation! [HIGH]The addition of outcome tracking and projected value follows the established pattern across the framework, maintaining backward compatibility while enabling error diagnostics.
52-61: Proper error reporting integration! [HIGH]The decoding implementation correctly integrates with the error reporting system while maintaining backward compatibility by rethrowing errors.
63-73: Correct equality semantics! [HIGH]The Equatable and Hashable implementations correctly focus on the wrapped value, ensuring that decoding outcomes don't affect value equality - which is the appropriate semantic for these property wrappers.
Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+OptionalPolymorphicValue.swift (1)
23-46: Well-structured optional decoding with detailed outcome tracking! [HIGH]The implementation correctly distinguishes between:
- Missing keys (returns nil)
- Null values (returns wrapper with
.valueWasNil)- Successful decoding (returns wrapper with
.decodedSuccessfully)- Decoding errors (throws without recovery)
The use of
superDecoderfor nested decoding is appropriate.Sources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessValue.swift (5)
34-34: Good addition of outcome tracking for resilient decoding [HIGH]The
outcomeproperty properly tracks decoding results, enabling error inspection in debug builds. This aligns well with the broader resilient decoding pattern.
42-50: Internal initializer provides necessary flexibility [MEDIUM]The internal initializer allows precise control over outcome assignment, which is essential for the resilient decoding infrastructure.
52-56: DEBUG-only projected value is appropriately scoped [MEDIUM]Limiting the projected value to DEBUG builds prevents production overhead while providing valuable debugging information during development.
63-75: Verify error reporting behavior in fallback decoding [HIGH]The fallback decoding logic reports errors correctly, but there's a potential issue: when fallback succeeds,
outcomeis set to.decodedSuccessfullyeven though the primary decoding failed. Consider using a different outcome like.recoveredFrom(error)to distinguish successful primary decoding from successful fallback.// Current logic may be misleading: self.outcome = .decodedSuccessfully // This suggests primary decoding succeeded // Consider: self.outcome = .recoveredFrom(error) // This indicates fallback was used
91-91: Simplified equality implementation is cleaner [LOW]Using
Selfinstead of the full generic type name improves readability and maintainability.Sources/KarrotCodableKit/BetterCodable/DataValue/DataValue.swift (3)
28-28: Outcome tracking follows established pattern [MEDIUM]Consistent with other property wrappers in the resilient decoding framework.
35-38: Internal initializer enables outcome control [MEDIUM]The internal initializer provides necessary flexibility for the resilient decoding infrastructure.
69-79: Explicit conformances improve clarity [LOW]Adding explicit
EquatableandHashableconformances makes the behavior more transparent and consistent with other wrappers.Tests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyArrayResilientTests.swift (4)
14-23: Well-structured test fixture with comprehensive types [HIGH]The fixture covers different data types (integers, strings, nested objects) which provides good coverage for the LossyArray resilient decoding behavior.
25-72: Thorough validation of projected value functionality [HIGH]The test comprehensively validates:
- Filtering behavior (invalid elements removed, valid ones retained)
- Error count tracking
- Individual element success/failure status
- Cross-type validation
This provides excellent coverage of the resilient decoding features.
74-95: Good integration testing with error reporter [HIGH]Tests the end-to-end error reporting flow, ensuring the JSONDecoder extension works correctly with the resilient decoding infrastructure.
122-147: Edge case testing for complete failure scenarios [HIGH]Testing behavior when entire array decoding fails (wrong type, null values) ensures robust fallback handling. The distinction between error cases and null handling is well validated.
Sources/KarrotCodableKit/BetterCodable/DateValue/OptionalDateValue.swift (3)
29-29: Outcome tracking consistent with framework pattern [MEDIUM]Proper integration with the resilient decoding infrastructure.
36-39: Internal initializer enables outcome control [MEDIUM]Necessary for the resilient decoding framework's internal operations.
50-63: Excellent handling of optional-specific decoding cases [HIGH]The implementation correctly distinguishes between:
- Successful decoding (
.decodedSuccessfully)- Explicit nil values (
.valueWasNil)- Other decoding errors (reported and rethrown)
This provides precise outcome tracking for optional date scenarios.
Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+DefaultEmptyPolymorphicArrayValue.swift (3)
16-29: Excellent explicit handling of decoding scenarios [HIGH]The implementation correctly handles three distinct cases:
- Missing key →
.keyNotFoundoutcome- Null value →
.valueWasNiloutcome- Present value → delegate to property wrapper's decoder
This provides clear outcome tracking and follows the established pattern from
PolymorphicLossyArrayValue.
34-48: Consistent decodeIfPresent implementation [HIGH]The
decodeIfPresentmethod correctly returnsnilfor missing keys and handles null values consistently with thedecodemethod. UsingsuperDecoderensures proper decoding context.
27-28: ✅ superDecoder(forKey:) usage verifiedI’ve reviewed the
DefaultEmptyPolymorphicArrayValueimplementation and confirmed that:
- The property wrapper’s
init(from:)correctly reads an unkeyed container from the passed-in decoder.- Error handling (catching and reporting) behaves as intended.
- Delegating to
superDecoder(forKey:)is the proper way to provide the wrapper with its own decoding context.No changes are needed here.
Sources/KarrotCodableKit/PolymorphicCodable/DefaultEmptyPolymorphicArrayValue.swift (4)
34-45: Well-designed resilient decoding integration! [HIGH]The outcome tracking implementation follows a consistent pattern with the internal initializer properly supporting dependency injection for testing scenarios.
47-57: Smart conditional compilation for projected values [HIGH]The debug-only projected value approach prevents production overhead while enabling development-time error inspection. The fatal error in non-debug builds provides clear developer feedback.
63-78: Excellent error handling improvements [HIGH]The migration from
decoder.reportError(error)significantly improves the debugging experience by integrating with the centralized error reporting system.
91-101: Proper Equatable/Hashable implementation [MEDIUM]The explicit conformances based on
wrappedValueare correctly implemented and consistent with similar property wrappers in the codebase.Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalValue/LossyOptionalPolymorphicValueResilientTests.swift (3)
5-9: Comprehensive test fixture design [HIGH]The test fixture properly uses the polymorphic property wrapper and provides good coverage for resilient decoding scenarios.
26-29: Excellent projected value testing pattern [HIGH]The conditional compilation ensures projected value tests only run in debug builds, aligning with the property wrapper implementation. The outcome verification is thorough and accurate.
Also applies to: 46-48, 77-79
136-162: Robust error reporting integration test [HIGH]This test effectively validates the end-to-end error reporting flow, ensuring errors are properly captured and accessible through the error reporter.
Tests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessValueResilientTests.swift (4)
14-19: Well-structured multi-type test fixture [HIGH]The fixture effectively tests multiple primitive types in a single test, providing comprehensive coverage of LosslessValue behavior across different data types.
42-48: Thorough projected value verification [HIGH]The debug-conditional testing of projected values ensures the resilient decoding outcomes are properly tracked for successful conversions.
65-73: Effective async failure testing [HIGH]The use of
confirmation(expectedCount: 1)provides clear verification that exceptions are thrown as expected for unconvertible values.Also applies to: 90-98
127-132: Solid error reporting validation [HIGH]The test properly verifies that the error reporting system captures decoding failures, even when the main decoding operation throws.
Sources/KarrotCodableKit/Resilient/DictionaryDecodingError.swift (4)
12-21: Clean generic error structure design [HIGH]The
DictionaryDecodingErrorprovides a well-structured way to capture per-key decoding results with a convenienterrorscomputed property for accessing failures.
15-16: Efficient error filtering implementation [MEDIUM]Using
compactMapValues(\.failure)is an elegant and performant way to extract only the failed results from the dictionary.
29-32: Good assertion for error reporting validation [MEDIUM]The assertion that
DictionaryDecodingErrorshould not be reported helps catch incorrect usage patterns during development.
34-36: Thoughtful design decision for top-level errors [MEDIUM]The comment explaining why top-level errors aren't included in dictionary results shows careful consideration of the API design - there's no natural key to associate with container-level failures.
Sources/KarrotCodableKit/PolymorphicCodable/PolymorphicArrayValue.swift (3)
23-35: Consistent resilient decoding pattern [HIGH]The outcome tracking implementation follows the established pattern across property wrappers, providing good consistency in the API.
37-47: Proper projected value implementation [HIGH]The debug-only projected value with fatal error in production builds maintains the same pattern as other wrappers in the codebase.
74-84: Consistent Equatable/Hashable implementation [MEDIUM]The conformances follow the same pattern as other polymorphic wrappers, correctly using
wrappedValuefor equality and hashing.Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyArray.swift (3)
16-34: Good design with debug-only projected value [MEDIUM]The implementation correctly exposes detailed decoding information only in DEBUG builds, avoiding runtime overhead in production. The dual initializer pattern (public with default outcome, internal with custom outcome) is well-structured for the resilient decoding use case.
106-116: Correct equality and hashing implementation [LOW]The Equatable and Hashable conformances correctly focus on the wrapped value only, ignoring the decoding outcome metadata. This ensures consistent behavior when comparing decoded values.
79-86: Incorrect success condition logic [HIGH]The condition
elements.count == results.countwill never be true when there are decoding failures, sinceelementsonly contains successfully decoded values whileresultscontains both successes and failures.The logic should check if all results are successful:
#if DEBUG -if elements.count == results.count { +if results.allSatisfy({ if case .success = $0 { return true } else { return false } }) { self.init(wrappedValue: elements, outcome: .decodedSuccessfully) } else { let error = ResilientDecodingOutcome.ArrayDecodingError(results: results) self.init(wrappedValue: elements, outcome: .recoveredFrom(error, wasReported: false)) }Likely an incorrect or invalid review comment.
Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+LossyOptionalPolymorphicValue.swift (1)
12-21: Clean delegation pattern [LOW]Good use of the delegation pattern to
decodeIfPresent, avoiding code duplication while properly handling the required field case with appropriate outcome tracking.Tests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/PolymorphicArrayValueResilientTests.swift (1)
6-161: Comprehensive polymorphic array testing [LOW]Excellent test coverage for polymorphic array decoding scenarios. The tests properly validate both successful decoding and various failure modes, including partial failures and error reporting integration.
The use of the DummyNotice test doubles provides good type variety for testing polymorphic behavior.
Tests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/DefaultEmptyPolymorphicArrayValueResilientTests.swift (1)
69-103: Good error recovery testing [LOW]Excellent test for the default empty behavior when encountering invalid elements. The pattern matching on the outcome enum in DEBUG mode is a clean way to validate the expected recovery state.
Sources/KarrotCodableKit/PolymorphicCodable/OptionalPolymorphicArrayValue.swift (1)
65-102: Well-implemented decoding with proper error handling [HIGH]The decoding implementation correctly handles nil values, tracks outcomes, and reports errors before rethrowing. The separation between nil checking and array decoding is clean and follows Swift best practices.
Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalPolymorphicArrayValueResilientTests.swift (1)
1-287: Comprehensive test coverage for resilient decoding [HIGH]Excellent test suite covering all major scenarios including successful decoding, error cases, and edge conditions. The tests properly validate both the decoded values and the resilient decoding outcomes in DEBUG builds.
The static analysis warnings about type name length can be safely ignored as the descriptive names improve test readability.
Tests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/PolymorphicLossyArrayValueResilientTests.swift (1)
1-204: Well-structured tests validating lossy array behavior [HIGH]Excellent test coverage for the lossy array wrapper, including:
- Validation that valid elements are preserved while invalid ones are skipped
- Proper testing of error reporting integration
- Edge case handling for missing keys and invalid types
The tests effectively demonstrate the resilient decoding behavior and outcome tracking.
Sources/KarrotCodableKit/BetterCodable/ResilientProjectedValue.swift (3)
12-27: Well-designed protocol with sensible default implementationThe protocol design is clean and the default error extraction implementation correctly handles all outcome cases. Good use of protocol extensions to provide shared functionality.
29-39: Simple and effective base implementationThe base projected value type correctly implements the protocol with minimal overhead. Good documentation explaining its purpose.
65-77: Consistent implementation with array counterpartThe dictionary projected value follows the same pattern as the array version, maintaining good API consistency. The same validation suggestion applies here.
Tests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultCodableResilientTests.swift (2)
14-63: Excellent test coverage for error reporting functionalityThe test effectively validates both the resilient behavior (falling back to defaults) and the error reporting mechanism. Good use of #if DEBUG to test debug-only features.
156-213: Comprehensive test coverage for all decoding scenariosThe test suite thoroughly covers:
- Error reporting integration with JSONDecoder
- LossyOptional behavior
- All outcome types (keyNotFound, valueWasNil, recoveredFrom)
Excellent attention to edge cases and debug-specific behavior.
[HIGH]
Sources/KarrotCodableKit/BetterCodable/Defaults/DefaultCodable.swift (3)
19-29: Well-designed protocol enhancement with backward compatibilityThe addition of
isFrozenwith a default implementation ensures backward compatibility while providing flexible error reporting control. Clear documentation explains the behavior difference.
63-89: Robust decoding implementation with proper error handlingThe implementation correctly:
- Handles nil values as a separate case from errors
- Reports all errors to the decoder
- Tracks outcomes only in debug builds for zero production overhead
Good separation of concerns and performance consideration.
[HIGH]
274-286: Clean error creation logicThe helper method provides a clear separation between the two error types and includes appropriate context information in the DecodingError case.
Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyDictionary.swift (2)
64-75: Well-structured state management for complex decodingThe
DecodingStatestruct effectively separates production data (elements) from debug information (results). Good use of conditional compilation to avoid overhead in release builds.
135-183: Robust single key-value decoding with proper error handlingBoth methods correctly:
- Use safe casting with early return on failure
- Report errors to the decoder
- Track results in debug builds
- Handle decoding failures gracefully
Good defensive programming approach.
[HIGH]
Sources/KarrotCodableKit/Resilient/ErrorReporting.swift (2)
23-45: Good defensive programming for multiple reporter scenarioThe implementation correctly:
- Uses assertion to catch development errors
- Gracefully handles the edge case in production
- Marks the digest to indicate potential missing errors
Well-thought-out error handling approach.
171-219: Excellent debug visualization featuresThe debug printing implementation provides:
- Clear hierarchical error visualization
- Concise error descriptions without redundant paths
- Special handling for UnknownNovelValueError visibility
This will significantly improve the debugging experience.
[HIGH]
Sources/KarrotCodableKit/BetterCodable/Extenstoins/Result+Extension.swift
Show resolved
Hide resolved
...KitTests/PolymorphicCodable/ArrayValue/DefaultEmptyPolymorphicArrayValueResilientTests.swift
Show resolved
Hide resolved
...eKitTests/PolymorphicCodable/OptionalValue/LossyOptionalPolymorphicValueResilientTests.swift
Show resolved
Hide resolved
...odableKitTests/PolymorphicCodable/OptionalValue/OptionalPolymorphicValueResilientTests.swift
Show resolved
Hide resolved
Tests/KarrotCodableKitTests/PolymorphicCodable/Value/PolymorphicValueResilientTests.swift
Outdated
Show resolved
Hide resolved
Tests/KarrotCodableKitTests/PolymorphicCodable/Value/PolymorphicValueResilientTests.swift
Show resolved
Hide resolved
5be056c to
7e150de
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 8
🔭 Outside diff range comments (5)
Tests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicEncodableMacroTests.swift (1)
72-86: Consider adding whitespace-only identifier case for fuller negative-path coverageRight now the failure path checks an empty string (
""). A common real-world mistake is passing a string that looks non-empty but is all whitespace (" "or"\t"). Adding a companion test would ensure the macro emits the same diagnostic for that scenario and strengthens guardrail coverage.+ func testPolymorphicEncodableMacroIdentifierWhitespaceError() { + #if canImport(KarrotCodableKitMacros) + assertMacroExpansion( + """ + @PolymorphicEncodable( + identifier: " ", + codingKeyStyle: .default + ) + struct Dummy: Notice {} + """, + expandedSource: "struct Dummy: Notice {}", + diagnostics: [ + DiagnosticSpec( + message: "Invalid polymorphic identifier: expected a non-empty string.", + line: 1, + column: 1 + ), + ], + macros: testMacros, + indentationWidth: .spaces(2) + ) + #else + throw XCTSkip("macros are only supported when running tests for the host platform") + #endif + }[HIGH]
Tests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicDeodableMacroTests.swift (1)
1-7: Filename typo (‘Deodable’) may hinder discoveryThe file is named
PolymorphicDeodableMacroTests.swift, missing the “c” in “Decodable”. Renaming toPolymorphicDecodableMacroTests.swiftwill keep naming consistent with the macro and class, improving searchability and avoiding confusion in future maintenance.Tests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicCodableStrategyProvidingMacroTests.swift (2)
27-45: Consider an additional test with a non-defaultidentifierCodingKey
Right now both “happy-path” tests keep the key as"type". A quick follow-up test where the key is, say,"kind"would verify that:
- The generated
PolymorphicMetaCodingKeyenum containscase kindpolymorphicMetaCodingKeyreturns.kind- The
decodehelper is called with.kindThat guards against a future regression in the default-parameter logic.
154-168: Edge-case diagnostic coverage could be tighter
This negative test intentionally attaches the macro to astructand expects a single diagnostic.
BecausematchingTypesis also empty, the macro implementation may (or should) emit an additional “matchingTypes cannot be empty” error when attached to a protocol. You might want a dedicated test for that scenario so both validation branches stay protected.Tests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicCodableMacroTests.swift (1)
27-112: Consider expanding test coverageWhile the current tests cover basic macro expansion and identifier validation, consider adding test cases for:
- Different
codingKeyStyleoptions beyond.snakeCase- Edge cases with complex struct hierarchies
- Integration with inheritance scenarios
This would bring the coverage in line with the comprehensive testing seen in the enum macro tests.
♻️ Duplicate comments (14)
Tests/KarrotCodableKitTests/BetterCodable/DateValue/DateValueResilientTests.swift (1)
26-26: Document timestamp for better readability [LOW]The hardcoded timestamp lacks context about what date it represents.
- "timestampDate": 1735728000 + "timestampDate": 1735728000 // 2025-01-01T12:00:00ZTests/KarrotCodableKitTests/PolymorphicCodable/OptionalValue/OptionalPolymorphicValueResilientTests.swift (1)
82-99: Consider validating specific error type [MEDIUM]While the test correctly validates that an error is thrown, checking for the specific error type would improve test precision.
Tests/KarrotCodableKitTests/PolymorphicCodable/Value/PolymorphicValueResilientTests.swift (2)
90-99: Consider adding a more specific error assertion [MEDIUM]While the test correctly verifies that null values cause decoding to fail, it would be more robust to assert the specific error type or message to ensure the failure is for the expected reason.
await confirmation(expectedCount: 1) { confirmation in do { _ = try decoder.decode(Fixture.self, from: data) Issue.record("Should have thrown") } catch { - // Verify specific error type if possible - // e.g., check for DecodingError.valueNotFound or similar + // Verify specific error type + if let decodingError = error as? DecodingError, + case .valueNotFound = decodingError { + confirmation() + } else { + Issue.record("Expected DecodingError.valueNotFound but got: \(error)") + } confirmation() } }
133-139: Add more specific error digest validation [MEDIUM]The test verifies that errors are reported, but it would be more thorough to validate the specific error content to ensure the correct error was captured.
// Check if error was reported let digest = try #require(errorDigest) #expect(digest.errors.count >= 1) + +// Verify the error contains expected information +if let firstError = digest.errors.first { + // Check for type mismatch error on "key" field + #expect(firstError.path.contains("key")) + // Additional assertions about error details if available +}Tests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyDictionaryResilientTests.swift (1)
71-73: Move comment closer to its associated validation.The comment describing the intDict validation should be placed directly above the assertion for better readability.
Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyArray.swift (1)
63-77: Performance consideration for large arrays remains unaddressed. [HIGH]The implementation still uses
superDecoder()for each element, which was previously flagged as a potential performance concern for large arrays. Consider the suggestions from the previous review about benchmarking and potentially implementing a threshold-based approach.Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+LossyOptionalPolymorphicValue.swift (1)
37-47: Potential issue with error reporter decoder creation [MEDIUM]Creating a new
superDecoderafter a decoding failure (line 44) might fail or not accurately represent the decoder state where the error occurred. The error should be reported using the decoder instance where it happened.Consider capturing and using the original decoder:
// Try to decode the polymorphic value +let decoder = try superDecoder(forKey: key) do { - let decoder = try superDecoder(forKey: key) let value = try T.decode(from: decoder) return LossyOptionalPolymorphicValue(wrappedValue: value, outcome: .decodedSuccessfully) } catch { // Report error to resilient decoding error reporter - let decoder = try? superDecoder(forKey: key) - decoder?.reportError(error) + decoder.reportError(error) return LossyOptionalPolymorphicValue(wrappedValue: nil, outcome: .recoveredFrom(error, wasReported: true)) }Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+PolymorphicLossyArrayValue.swift (2)
35-49: Report errors before recovering to empty array [HIGH]When decoding fails, the error should be reported to the decoder before recovering. This ensures the error is captured by the resilient decoding error reporter.
do { let decoder = try superDecoder(forKey: key) return try PolymorphicLossyArrayValue(from: decoder) } catch { + // Report the error before recovering + if let resilientDecoder = decoder as? Decoder { + resilientDecoder.reportError(error) + } // If decoding fails (e.g., not an array), return empty array #if DEBUG - return PolymorphicLossyArrayValue(wrappedValue: [], outcome: .recoveredFrom(error, wasReported: false), results: []) + return PolymorphicLossyArrayValue(wrappedValue: [], outcome: .recoveredFrom(error, wasReported: true), results: []) #else - return PolymorphicLossyArrayValue(wrappedValue: [], outcome: .recoveredFrom(error, wasReported: false)) + return PolymorphicLossyArrayValue(wrappedValue: [], outcome: .recoveredFrom(error, wasReported: true)) #endif }
62-68: Fix inconsistent outcome parameter handling in non-DEBUG builds [MEDIUM]In the
decodeIfPresentmethod, when handling null values in non-DEBUG builds (line 66), thePolymorphicLossyArrayValueis created without theoutcomeparameter, unlike thedecodemethod which always provides it. This inconsistency could lead to issues if the initializer expects the outcome parameter.#if DEBUG return PolymorphicLossyArrayValue(wrappedValue: [], outcome: .valueWasNil, results: []) #else -return PolymorphicLossyArrayValue(wrappedValue: []) +return PolymorphicLossyArrayValue(wrappedValue: [], outcome: .valueWasNil) #endifTests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessArrayResilientTests.swift (1)
14-142: Well-designed test fixture and comprehensive coverage [HIGH]The test suite effectively validates lossless array decoding behavior:
- Clear fixture design with explicit non-convertible type (NestedObject)
- Thorough verification of element-level success/failure tracking
- Proper error reporting integration testing
- Good coverage of edge cases (complete failure, missing keys)
Tests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultCodableResilientTests.swift (1)
287-291: Pattern matching implementation looks good!The error validation correctly uses pattern matching to check for
UnknownNovelValueErrorand verify the novel value, which is cleaner than nested if-let statements.Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyDictionary.swift (1)
236-249: Consider performance optimization for large dictionariesThe current implementation decodes the dictionary structure twice - once in
extractKeysto get original keys without key decoding strategy interference, and again to decode actual values. While this approach correctly preserves original keys, it could impact performance for very large dictionaries.[MEDIUM]
Sources/KarrotCodableKit/Resilient/ErrorReporting.swift (2)
76-101: Thread safety documentation neededThe
ResilientDecodingErrorReporterclass maintains mutable state without synchronization. WhileJSONDecoderitself is typically not thread-safe, this should be explicitly documented to prevent misuse in concurrent contexts.[HIGH]
Consider either:
- Adding thread-safety mechanisms (dispatch queue or locks)
- Clearly documenting that instances must not be shared across threads
#!/bin/bash # Check if JSONDecoder or similar decoders are documented as thread-safe rg -A 5 -B 5 "thread.?safe|concurrent|synchroniz" --type swift
138-140: Consider lazy evaluation for error aggregationThe
errorscomputed property recreates the array on each access by concatenating errors from all children. For scenarios with many errors, consider caching or using a more efficient traversal approach.[LOW]
📜 Review details
Configuration used: .coderabbit.yml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (54)
Sources/KarrotCodableKit/BetterCodable/DataValue/DataValue.swift(2 hunks)Sources/KarrotCodableKit/BetterCodable/DateValue/DateValue.swift(2 hunks)Sources/KarrotCodableKit/BetterCodable/DateValue/OptionalDateValue.swift(2 hunks)Sources/KarrotCodableKit/BetterCodable/Defaults/DefaultCodable.swift(5 hunks)Sources/KarrotCodableKit/BetterCodable/Extensions/Result+Extension.swift(1 hunks)Sources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessArray.swift(3 hunks)Sources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessValue.swift(2 hunks)Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyArray.swift(2 hunks)Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyDictionary.swift(4 hunks)Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyOptional.swift(0 hunks)Sources/KarrotCodableKit/BetterCodable/ResilientProjectedValue.swift(1 hunks)Sources/KarrotCodableKit/Encodable+ToDictionary.swift(1 hunks)Sources/KarrotCodableKit/PolymorphicCodable/DefaultEmptyPolymorphicArrayValue.swift(2 hunks)Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+DefaultEmptyPolymorphicArrayValue.swift(1 hunks)Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+LossyOptionalPolymorphicValue.swift(1 hunks)Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+OptionalPolymorphicArrayValue.swift(2 hunks)Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+OptionalPolymorphicValue.swift(1 hunks)Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+PolymorphicLossyArrayValue.swift(1 hunks)Sources/KarrotCodableKit/PolymorphicCodable/OptionalPolymorphicArrayValue.swift(2 hunks)Sources/KarrotCodableKit/PolymorphicCodable/PolymorphicArrayValue.swift(3 hunks)Sources/KarrotCodableKit/PolymorphicCodable/PolymorphicProjectedValue.swift(1 hunks)Sources/KarrotCodableKit/Resilient/ArrayDecodingError.swift(1 hunks)Sources/KarrotCodableKit/Resilient/DictionaryDecodingError.swift(1 hunks)Sources/KarrotCodableKit/Resilient/ErrorReporting.swift(1 hunks)Tests/KarrotCodableKitTests/BetterCodable/DataValue/DataValueResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/BetterCodable/DateValue/DateValueResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultCodableResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultCodableTests.swift(1 hunks)Tests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultEmptyArrayTests.swift(0 hunks)Tests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessArrayResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessArrayTests.swift(0 hunks)Tests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessValueResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyArrayResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyArrayTests.swift(0 hunks)Tests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyDictionaryResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/PolymorphicArrayValueResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/PolymorphicLossyArrayValueResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/Enum/PolymorphicEnumDecodableTests.swift(0 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalPolymorphicArrayValueResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalPolymorphicArrayValueTests.swift(8 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalValue/OptionalPolymorphicValueResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/TestDoubles/UnnestedPolymorphicCodableDummy.swift(0 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/Value/PolymorphicValueResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/Value/PolymorphicValueTests.swift(0 hunks)Tests/KarrotCodableMacrosTests/CustomCodableMacros/CustomCodableMacroTests.swift(1 hunks)Tests/KarrotCodableMacrosTests/CustomCodableMacros/CustomDecodableMacroTests.swift(1 hunks)Tests/KarrotCodableMacrosTests/CustomCodableMacros/CustomEncodableMacroTests.swift(1 hunks)Tests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicCodableMacroTests.swift(1 hunks)Tests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicCodableStrategyProvidingMacroTests.swift(1 hunks)Tests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicDeodableMacroTests.swift(1 hunks)Tests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicEncodableMacroTests.swift(1 hunks)Tests/KarrotCodableMacrosTests/PolymorphicEnumCodableMacroTests/PolymorphicEnumCodableMacroTests.swift(6 hunks)Tests/KarrotCodableMacrosTests/PolymorphicEnumCodableMacroTests/PolymorphicEnumDecodableMacroTests.swift(6 hunks)Tests/KarrotCodableMacrosTests/PolymorphicEnumCodableMacroTests/PolymorphicEnumEncodableMacroTests.swift(4 hunks)
💤 Files with no reviewable changes (7)
- Tests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessArrayTests.swift
- Tests/KarrotCodableKitTests/PolymorphicCodable/Value/PolymorphicValueTests.swift
- Tests/KarrotCodableKitTests/PolymorphicCodable/Enum/PolymorphicEnumDecodableTests.swift
- Tests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultEmptyArrayTests.swift
- Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyOptional.swift
- Tests/KarrotCodableKitTests/PolymorphicCodable/TestDoubles/UnnestedPolymorphicCodableDummy.swift
- Tests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyArrayTests.swift
🧰 Additional context used
📓 Path-based instructions (3)
Tests/KarrotCodableMacrosTests/**
⚙️ CodeRabbit Configuration File
Tests/KarrotCodableMacrosTests/**: You are a senior Swift/iOS engineer reviewing macro expansion tests for KarrotCodableKit's Swift macro implementations.1. Macro Expansion Testing [HIGH]
- Verify SwiftSyntaxMacrosTestSupport usage is comprehensive
- Check that all macro expansion scenarios are covered
- Assess edge case testing for invalid macro arguments
- Validate diagnostic message testing matches actual validation logic
2. Test Code Quality [HIGH]
- Review test case organization and naming clarity
- Check that test data represents realistic usage scenarios
- Verify test assertions are specific and meaningful
- Assess test maintainability and readability
3. Coverage Assessment [MEDIUM]
- Ensure all macro variants (Codable, Decodable, Encodable) are tested
- Check polymorphic macro test coverage for different identifier strategies
- Verify error conditions and validation failures are tested
- Assess macro registration and plugin functionality testing
Review Focus
- Prioritize test correctness and comprehensive coverage
- Focus on macro-specific testing patterns and SwiftSyntax integration
- Mark comments with priority: [HIGH], [MEDIUM], or [LOW]
Files:
Tests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicEncodableMacroTests.swiftTests/KarrotCodableMacrosTests/CustomCodableMacros/CustomCodableMacroTests.swiftTests/KarrotCodableMacrosTests/CustomCodableMacros/CustomDecodableMacroTests.swiftTests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicCodableMacroTests.swiftTests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicCodableStrategyProvidingMacroTests.swiftTests/KarrotCodableMacrosTests/PolymorphicEnumCodableMacroTests/PolymorphicEnumEncodableMacroTests.swiftTests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicDeodableMacroTests.swiftTests/KarrotCodableMacrosTests/CustomCodableMacros/CustomEncodableMacroTests.swiftTests/KarrotCodableMacrosTests/PolymorphicEnumCodableMacroTests/PolymorphicEnumCodableMacroTests.swiftTests/KarrotCodableMacrosTests/PolymorphicEnumCodableMacroTests/PolymorphicEnumDecodableMacroTests.swift
Sources/KarrotCodableKit/**
⚙️ CodeRabbit Configuration File
Sources/KarrotCodableKit/**: You are a senior Swift/iOS engineer reviewing runtime library code for KarrotCodableKit, a comprehensive Codable extension framework.1. Codable Performance [HIGH]
- Check encoding/decoding efficiency and memory usage
- Verify proper handling of large JSON structures
- Assess polymorphic type resolution performance
- Review property wrapper overhead and optimization
2. Type Safety & Polymorphism [HIGH]
- Validate PolymorphicCodable identifier-based type resolution
- Check AnyCodable type erasure implementation for edge cases
- Verify UnnestedPolymorphic macro integration with runtime components
- Assess error handling in polymorphic decoding scenarios
3. API Design [HIGH]
- Evaluate public interface consistency across modules
- Check property wrapper ergonomics (@DefaultFalse, @DATEvalue, etc.)
- Verify protocol design follows Swift API guidelines
- Assess extensibility for new Codable patterns
4. BetterCodable Integration [MEDIUM]
- Review property wrapper implementations for common patterns
- Check date strategy implementations (ISO8601, RFC3339, etc.)
- Verify default value and lossy conversion handling
- Assess data encoding strategies (Base64, etc.)
5. Error Handling [MEDIUM]
- Verify comprehensive DecodingError and EncodingError usage
- Check PolymorphicCodableError provides sufficient context
- Assess graceful fallback handling in polymorphic scenarios
Review Focus
- Prioritize runtime correctness and performance over style
- Focus on real-world JSON processing scenarios
- Mark comments with priority: [HIGH], [MEDIUM], or [LOW]
Files:
Sources/KarrotCodableKit/Encodable+ToDictionary.swiftSources/KarrotCodableKit/BetterCodable/Extensions/Result+Extension.swiftSources/KarrotCodableKit/PolymorphicCodable/PolymorphicProjectedValue.swiftSources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+OptionalPolymorphicArrayValue.swiftSources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+DefaultEmptyPolymorphicArrayValue.swiftSources/KarrotCodableKit/PolymorphicCodable/DefaultEmptyPolymorphicArrayValue.swiftSources/KarrotCodableKit/Resilient/ArrayDecodingError.swiftSources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+OptionalPolymorphicValue.swiftSources/KarrotCodableKit/BetterCodable/DateValue/DateValue.swiftSources/KarrotCodableKit/BetterCodable/LossyValue/LossyArray.swiftSources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+LossyOptionalPolymorphicValue.swiftSources/KarrotCodableKit/Resilient/DictionaryDecodingError.swiftSources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessArray.swiftSources/KarrotCodableKit/BetterCodable/DataValue/DataValue.swiftSources/KarrotCodableKit/BetterCodable/DateValue/OptionalDateValue.swiftSources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+PolymorphicLossyArrayValue.swiftSources/KarrotCodableKit/PolymorphicCodable/OptionalPolymorphicArrayValue.swiftSources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessValue.swiftSources/KarrotCodableKit/BetterCodable/ResilientProjectedValue.swiftSources/KarrotCodableKit/BetterCodable/Defaults/DefaultCodable.swiftSources/KarrotCodableKit/BetterCodable/LossyValue/LossyDictionary.swiftSources/KarrotCodableKit/PolymorphicCodable/PolymorphicArrayValue.swiftSources/KarrotCodableKit/Resilient/ErrorReporting.swift
Tests/KarrotCodableKitTests/**
⚙️ CodeRabbit Configuration File
Tests/KarrotCodableKitTests/**: You are a senior Swift/iOS engineer reviewing runtime functionality tests for KarrotCodableKit's Codable extensions.1. Runtime Behavior Testing [HIGH]
- Verify JSON encoding/decoding scenarios cover real-world use cases
- Check polymorphic type resolution testing across different strategies
- Assess property wrapper testing (@DATEvalue, @DefaultFalse, etc.)
- Validate error handling and edge case coverage
2. Test Data Quality [HIGH]
- Review test JSON structures for realistic complexity
- Check that TestDoubles provide comprehensive mock scenarios
- Verify test data covers various data types and edge cases
- Assess polymorphic test data represents actual usage patterns
3. Integration Testing [MEDIUM]
- Check integration between macro-generated code and runtime functionality
- Verify end-to-end scenarios combining multiple KarrotCodableKit features
- Assess performance testing for large data structures
- Review memory usage testing for complex polymorphic scenarios
Review Focus
- Prioritize real-world usage scenario coverage
- Focus on Codable correctness and performance implications
- Mark comments with priority: [HIGH], [MEDIUM], or [LOW]
Files:
Tests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultCodableTests.swiftTests/KarrotCodableKitTests/BetterCodable/DateValue/DateValueResilientTests.swiftTests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyDictionaryResilientTests.swiftTests/KarrotCodableKitTests/BetterCodable/DataValue/DataValueResilientTests.swiftTests/KarrotCodableKitTests/PolymorphicCodable/OptionalValue/OptionalPolymorphicValueResilientTests.swiftTests/KarrotCodableKitTests/PolymorphicCodable/Value/PolymorphicValueResilientTests.swiftTests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessValueResilientTests.swiftTests/KarrotCodableKitTests/PolymorphicCodable/OptionalPolymorphicArrayValueTests.swiftTests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessArrayResilientTests.swiftTests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyArrayResilientTests.swiftTests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/PolymorphicLossyArrayValueResilientTests.swiftTests/KarrotCodableKitTests/PolymorphicCodable/OptionalPolymorphicArrayValueResilientTests.swiftTests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/PolymorphicArrayValueResilientTests.swiftTests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultCodableResilientTests.swift
🧬 Code Graph Analysis (10)
Sources/KarrotCodableKit/PolymorphicCodable/PolymorphicProjectedValue.swift (1)
Sources/KarrotCodableKit/Resilient/ResilientDecodingOutcome.swift (1)
recoveredFrom(46-46)
Sources/KarrotCodableKit/Resilient/ArrayDecodingError.swift (1)
Sources/KarrotCodableKit/Resilient/ResilientDecodingOutcome.swift (1)
recoveredFrom(46-46)
Sources/KarrotCodableKit/BetterCodable/DateValue/DateValue.swift (1)
Sources/KarrotCodableKit/Resilient/ErrorReporting.swift (1)
reportError(154-166)
Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+LossyOptionalPolymorphicValue.swift (3)
Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+OptionalPolymorphicValue.swift (2)
decodeIfPresent(23-46)decode(12-21)Sources/KarrotCodableKit/Resilient/ErrorReporting.swift (2)
decode(56-71)reportError(154-166)Sources/KarrotCodableKit/Resilient/ResilientDecodingOutcome.swift (1)
recoveredFrom(46-46)
Sources/KarrotCodableKit/Resilient/DictionaryDecodingError.swift (1)
Sources/KarrotCodableKit/Resilient/ResilientDecodingOutcome.swift (1)
recoveredFrom(46-46)
Sources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessArray.swift (9)
Sources/KarrotCodableKit/Resilient/ErrorReporting.swift (1)
reportError(154-166)Sources/KarrotCodableKit/Resilient/ResilientDecodingOutcome.swift (1)
recoveredFrom(46-46)Sources/KarrotCodableKit/BetterCodable/DataValue/DataValue.swift (2)
lhs(65-67)hash(71-73)Sources/KarrotCodableKit/BetterCodable/DateValue/DateValue.swift (2)
lhs(66-68)hash(72-74)Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyArray.swift (2)
lhs(107-109)hash(113-115)Sources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessValue.swift (2)
lhs(91-93)hash(97-99)Sources/KarrotCodableKit/PolymorphicCodable/DefaultEmptyPolymorphicArrayValue.swift (2)
lhs(92-94)hash(98-100)Sources/KarrotCodableKit/PolymorphicCodable/OptionalPolymorphicArrayValue.swift (2)
lhs(122-124)hash(128-130)Sources/KarrotCodableKit/PolymorphicCodable/PolymorphicArrayValue.swift (2)
lhs(75-77)hash(81-83)
Sources/KarrotCodableKit/BetterCodable/DateValue/OptionalDateValue.swift (4)
Sources/KarrotCodableKit/BetterCodable/Defaults/DefaultCodable.swift (4)
decode(120-149)decode(157-214)decode(221-278)lhs(99-101)Sources/KarrotCodableKit/BetterCodable/DateValue/Strategy/ISO8601Strategy.swift (2)
decode(19-29)decode(37-40)Sources/KarrotCodableKit/BetterCodable/DateValue/Strategy/TimestampStrategy.swift (2)
decode(18-20)decode(28-31)Sources/KarrotCodableKit/Resilient/ErrorReporting.swift (1)
reportError(154-166)
Sources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessValue.swift (11)
Sources/KarrotCodableKit/Resilient/ErrorReporting.swift (1)
reportError(154-166)Sources/KarrotCodableKit/BetterCodable/DataValue/DataValue.swift (1)
lhs(65-67)Sources/KarrotCodableKit/BetterCodable/DateValue/DateValue.swift (1)
lhs(66-68)Sources/KarrotCodableKit/BetterCodable/DateValue/OptionalDateValue.swift (1)
lhs(75-77)Sources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessArray.swift (1)
lhs(87-89)Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyArray.swift (1)
lhs(107-109)Sources/KarrotCodableKit/BetterCodable/Defaults/DefaultCodable.swift (1)
lhs(99-101)Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyDictionary.swift (1)
lhs(259-261)Sources/KarrotCodableKit/PolymorphicCodable/DefaultEmptyPolymorphicArrayValue.swift (1)
lhs(92-94)Sources/KarrotCodableKit/PolymorphicCodable/OptionalPolymorphicArrayValue.swift (1)
lhs(122-124)Sources/KarrotCodableKit/PolymorphicCodable/PolymorphicArrayValue.swift (1)
lhs(75-77)
Sources/KarrotCodableKit/BetterCodable/ResilientProjectedValue.swift (3)
Sources/KarrotCodableKit/Resilient/ResilientDecodingOutcome.swift (1)
recoveredFrom(46-46)Sources/KarrotCodableKit/Resilient/ArrayDecodingError.swift (1)
arrayDecodingError(24-40)Sources/KarrotCodableKit/Resilient/DictionaryDecodingError.swift (1)
dictionaryDecodingError(23-38)
Sources/KarrotCodableKit/PolymorphicCodable/PolymorphicArrayValue.swift (11)
Sources/KarrotCodableKit/BetterCodable/DataValue/DataValue.swift (2)
lhs(65-67)hash(71-73)Sources/KarrotCodableKit/BetterCodable/DateValue/DateValue.swift (2)
lhs(66-68)hash(72-74)Sources/KarrotCodableKit/BetterCodable/DateValue/OptionalDateValue.swift (2)
lhs(75-77)hash(81-83)Sources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessArray.swift (2)
lhs(87-89)hash(93-95)Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyArray.swift (2)
lhs(107-109)hash(113-115)Sources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessValue.swift (2)
lhs(91-93)hash(97-99)Sources/KarrotCodableKit/BetterCodable/Defaults/DefaultCodable.swift (2)
lhs(99-101)hash(105-107)Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyDictionary.swift (1)
lhs(259-261)Sources/KarrotCodableKit/PolymorphicCodable/DefaultEmptyPolymorphicArrayValue.swift (2)
lhs(92-94)hash(98-100)Sources/KarrotCodableKit/PolymorphicCodable/OptionalPolymorphicArrayValue.swift (2)
lhs(122-124)hash(128-130)Sources/KarrotCodableKit/PolymorphicCodable/PolymorphicValue.swift (2)
lhs(64-66)hash(70-72)
🪛 SwiftLint (0.57.0)
Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalPolymorphicArrayValueResilientTests.swift
[Warning] 16-16: Type name 'ResilientOptionalPolymorphicArrayDummyResponse' should be between 3 and 40 characters long
(type_name)
[Warning] 30-30: Type name 'OptionalPolymorphicArrayValueResilientTests' should be between 3 and 40 characters long
(type_name)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Build and Test (16.1, release)
- GitHub Check: Check Macro Compatibility
🔇 Additional comments (73)
Tests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicEncodableMacroTests.swift (1)
102-108: Comma fix unblocks diagnostics parsing – nice catchThe added trailing comma restores valid Swift array syntax, preventing the diagnostics list from being parsed as a single-tuple expression. No further action needed.
Tests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicDeodableMacroTests.swift (1)
102-109: Trailing comma addition fixes compile-time failure—nice catchThe extra comma after the
DiagnosticSpecentry eliminates the previous syntax error and aligns the style with the rest of the test suite. Looks good.Tests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicCodableStrategyProvidingMacroTests.swift (1)
133-136: Whitespace cleanup looks good
The stray blank line before the struct’s closing brace is gone; no functional impact.Tests/KarrotCodableMacrosTests/CustomCodableMacros/CustomDecodableMacroTests.swift (1)
305-306: Trailing comma => cleaner future diffs
The extra comma after the lastDiagnosticSpeckeeps the diagnostics array diff-friendly when more specs are appended later. Looks good.Tests/KarrotCodableMacrosTests/CustomCodableMacros/CustomCodableMacroTests.swift (1)
305-306: Consistent diagnostics style
Same trailing-comma tweak here; maintains a uniform style across the macro test suite. 👍Tests/KarrotCodableMacrosTests/CustomCodableMacros/CustomEncodableMacroTests.swift (1)
305-306: No-op formatting change acknowledged
The added comma mirrors the pattern used elsewhere—no functional impact, but it aids maintainability.Tests/KarrotCodableMacrosTests/PolymorphicEnumCodableMacroTests/PolymorphicEnumCodableMacroTests.swift (1)
164-169: Uniform comma fixes across all diagnostics
All diagnostics arrays now terminate with commas, preventing awkward diffs when new specs are introduced. Change is purely cosmetic—LGTM.Also applies to: 197-202, 230-235, 262-268, 366-371, 398-404
Tests/KarrotCodableMacrosTests/PolymorphicEnumCodableMacroTests/PolymorphicEnumEncodableMacroTests.swift (1)
124-129: Formatting sync
Trailing-comma additions keep the style consistent with the rest of the test suite. Ready to merge.Also applies to: 157-162, 190-195, 222-228
Tests/KarrotCodableMacrosTests/PolymorphicEnumCodableMacroTests/PolymorphicEnumDecodableMacroTests.swift (2)
146-146: LGTM: Consistent formatting improvementThe trailing comma additions improve code consistency across all diagnostic test cases. This is a good practice for array literals in Swift.
Also applies to: 179-179, 212-212, 245-245, 335-335, 368-368
25-376: Excellent macro test coverageThis test suite provides comprehensive coverage of the PolymorphicEnumDecodable macro validation scenarios:
- ✅ Basic macro expansion with custom and default parameters
- ✅ Type validation (enum-only restriction)
- ✅ Identifier validation (non-empty strings)
- ✅ Associated value validation (single value requirement)
- ✅ Fallback case handling and validation
The test structure follows SwiftSyntaxMacrosTestSupport best practices with clear input/output validation and specific diagnostic assertions.
Sources/KarrotCodableKit/Encodable+ToDictionary.swift (2)
22-26: Clean formatting improvementThe multiline guard statement formatting enhances readability while maintaining the same robust error handling logic.
20-31: Solid implementation with proper error handlingThe
toDictionary()method provides a clean API for converting Encodable types to dictionaries with appropriate error propagation. The use of.fragmentsAllowedoption is appropriate for handling various JSON structures.Tests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicCodableMacroTests.swift (1)
104-104: Consistent formatting improvementThe parenthesis alignment matches the formatting pattern used across other macro test files.
Tests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultCodableTests.swift (2)
180-180: Clean formatting improvementRemoving the extraneous blank line improves code consistency in the encode method.
44-209: Comprehensive DefaultCodable test coverageThis test suite excellently covers diverse DefaultCodable scenarios:
- ✅ Date decoding strategies with custom formatters
- ✅ Nested property wrapper combinations (@DefaultCodable + @DATEvalue)
- ✅ Complex container types (arrays, dictionaries)
- ✅ Custom enum types with associated values and manual Codable implementation
The test data represents realistic usage patterns and the assertions validate both decoding and encoding roundtrips effectively.
Sources/KarrotCodableKit/BetterCodable/Extensions/Result+Extension.swift (1)
10-34: Well-designed Result convenience extensionsThese computed properties provide clean, non-throwing access to Result state and values, which aligns perfectly with the resilient decoding infrastructure. The implementations are efficient and follow Swift best practices:
isSuccess/isFailure: Clean boolean state checkssuccess: Safe optional access to success valuefailure: Pattern matching for error extractionThe package-level visibility is appropriate for internal framework usage.
Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+OptionalPolymorphicArrayValue.swift (2)
12-25: Clean implementation of optional decoding with outcome tracking [MEDIUM]The decode method properly leverages
decodeIfPresentfor the actual decoding logic and handles missing keys appropriately. The conditional compilation for DEBUG mode is well-structured to provide additional debugging information without affecting release performance.
62-66: superDecoder is necessary for error reportingKeyedDecodingContainer (and SingleValueDecodingContainer) don’t expose their underlying Decoder, so the only way to obtain a Decoder instance with the correct codingPath is via
superDecoder(forKey:)(orsuperDecoder()). CallingreportErroron that nested decoder ensures errors are reported at the right location. This pattern is intentionally used across both PolymorphicCodable and BetterCodable (e.g. PolymorphicValue.swift:57, OptionalPolymorphicArrayValue.swift:64, LossyOptionalPolymorphicValue.swift:45, DefaultEmptyPolymorphicArrayValue.swift:75). The overhead is negligible and the approach is sound.Likely an incorrect or invalid review comment.
Sources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessArray.swift (1)
86-96: Equatable and Hashable implementations look good [LOW]The implementations correctly delegate to the wrapped array's conformances, following the established pattern across the codebase.
Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+DefaultEmptyPolymorphicArrayValue.swift (2)
12-29: Well-structured decode implementation with proper edge case handling [MEDIUM]The method correctly handles missing keys and null values before attempting decoding. Using superDecoder ensures proper context for the property wrapper's decoder.
31-48: Consistent implementation with decode method [MEDIUM]The decodeIfPresent method maintains consistency with the decode method's logic while appropriately returning nil for missing keys.
Tests/KarrotCodableKitTests/BetterCodable/DateValue/DateValueResilientTests.swift (1)
95-124: Comprehensive error reporting test [MEDIUM]The error reporting test effectively validates the integration with JSONDecoder's resilient decoding error reporter. Good coverage of different invalid type scenarios.
Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalValue/OptionalPolymorphicValueResilientTests.swift (1)
11-80: Well-structured test cases for resilient decoding outcomes [MEDIUM]The tests effectively validate different decoding outcomes (nil, missing key, successful) and properly verify the debug-only projected values. Good separation of test scenarios.
Tests/KarrotCodableKitTests/BetterCodable/DataValue/DataValueResilientTests.swift (3)
43-64: Test verification could be more specific [MEDIUM]The test correctly verifies that invalid Base64 strings cause decoding failure, but could be more specific about the expected error type to ensure the failure is for the expected reason.
await confirmation(expectedCount: 1) { confirmation in do { _ = try decoder.decode(Fixture.self, from: data) Issue.record("Should have thrown") - } catch { - // Invalid Base64 format causes decoding failure + } catch let error as DecodingError { + // Verify it's a data corruption error for invalid Base64 + if case .dataCorrupted = error { + confirmation() + } else { + Issue.record("Expected dataCorrupted error but got: \(error)") + } + } catch { + Issue.record("Unexpected error type: \(error)") confirmation() } }
78-87: Add specific error type verification for null handling [MEDIUM]The test should verify the specific error type to ensure null values are handled as expected.
await confirmation(expectedCount: 1) { confirmation in do { _ = try decoder.decode(Fixture.self, from: data) Issue.record("Should have thrown") - } catch { - // null values cannot be converted to Data + } catch let error as DecodingError { + // Verify it's a valueNotFound error for null + if case .valueNotFound = error { + confirmation() + } else { + Issue.record("Expected valueNotFound error but got: \(error)") + } + } catch { + Issue.record("Unexpected error type: \(error)") confirmation() } }
113-117: Enhance error digest validation [MEDIUM]Consider validating the specific error details to ensure the correct errors are being reported.
let digest = try #require(errorDigest) #expect(digest.errors.count >= 1) + +// Verify specific error details +if let firstError = digest.errors.first { + // Check that the error relates to type mismatch + #expect(firstError.path.contains("base64Data") || firstError.path.contains("anotherData")) +}Sources/KarrotCodableKit/BetterCodable/DataValue/DataValue.swift (1)
47-55: Solid implementation of resilient decoding [HIGH]The error handling and outcome tracking implementation is well-structured. The single do-catch block appropriately handles both string decoding and data decoding failures while reporting errors before rethrowing.
Sources/KarrotCodableKit/BetterCodable/DateValue/DateValue.swift (2)
47-55: Well-implemented resilient decoding pattern [HIGH]The error handling implementation correctly reports errors before rethrowing and tracks the decoding outcome. This maintains consistency with the resilient decoding pattern across other property wrappers.
66-68: Clean use of Self in Equatable conformance [LOW]The use of
Selfinstead of the explicit generic type improves readability and follows the consistent pattern used across other property wrappers in the codebase.Sources/KarrotCodableKit/Resilient/ArrayDecodingError.swift (2)
14-17: Efficient error extraction implementation [HIGH]The use of
compactMap(\.failure)to extract errors from results is clean and efficient. The structure appropriately preserves both successful and failed results for debugging purposes.
30-33: Good defensive programming with assertion [MEDIUM]The assertion correctly ensures that
ArrayDecodingErrorinstances are not reported through the standard error reporting mechanism, preventing double-reporting. This is an appropriate use of assertions for catching programming errors during development.Tests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyDictionaryResilientTests.swift (3)
14-24: Well-structured test fixture with comprehensive type coverage.The fixture effectively covers different dictionary key-value type combinations including primitive types and nested objects, which ensures thorough testing of the resilient decoding functionality.
81-106: Excellent error reporting integration test.This test effectively validates that decoding errors are properly captured by the resilient error reporting system, ensuring that partial failures are tracked without failing the entire decoding process.
108-133: Good coverage of complete failure scenarios.The test properly verifies that when dictionary decoding completely fails (wrong types), the wrapper gracefully falls back to empty dictionaries and tracks the errors appropriately. The distinction between actual errors and null values (line 131) is particularly well-tested.
Sources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessValue.swift (3)
34-50: Well-implemented outcome tracking following the established pattern.The addition of the
outcomeproperty and the new internal initializer aligns perfectly with the resilient decoding infrastructure. The default outcome of.decodedSuccessfullyis appropriate for the public initializer.
52-56: Clean projected value implementation for debug builds.The debug-only projected value provides appropriate access to decoding outcomes for diagnostic purposes without affecting production builds.
90-94: Good simplification of the equality operator.Using
Selfinstead of explicit type parameters improves readability and maintains consistency with other property wrappers in the codebase.Sources/KarrotCodableKit/PolymorphicCodable/PolymorphicProjectedValue.swift (3)
11-28: Well-designed protocol with effective default implementation.The
PolymorphicProjectedValueProtocolprovides a clean abstraction for polymorphic projected values, and the default error extraction implementation correctly handles all outcome cases while reducing code duplication.
30-41: Clean and focused base implementation.The
PolymorphicProjectedValuestruct provides a simple, reusable implementation for standard polymorphic property wrapper projected values.
43-58: Excellent specialized implementation for lossy arrays.The
PolymorphicLossyArrayProjectedValueeffectively extends the base pattern to include element-level result tracking, which is essential for debugging lossy array decoding operations.Sources/KarrotCodableKit/BetterCodable/DateValue/OptionalDateValue.swift (3)
29-39: Consistent outcome tracking implementation.The outcome property and initializers follow the established pattern across the codebase, providing proper tracking of decoding results.
46-64: Robust decoding implementation with proper error handling.The nested error handling correctly distinguishes between nil values (
.valueWasNil) and actual decoding errors, while ensuring all errors are reported through the resilient decoding system.
41-43: Standard projected value implementation.The debug-only projected value follows the established pattern for exposing decoding outcomes.
Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+OptionalPolymorphicValue.swift (2)
12-21: Clean implementation of required key decoding.The method effectively handles missing required keys by returning an
OptionalPolymorphicValuewith the appropriate.keyNotFoundoutcome, maintaining consistency with the resilient decoding pattern.
23-46: Well-structured optional decoding with clear outcome tracking.The method effectively distinguishes between missing keys, null values, and actual values, setting appropriate outcomes for each case. The explicit comment about error propagation (line 43) helps clarify the intentional design decision.
Tests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyArrayResilientTests.swift (2)
25-72: Well-structured test for projected value error tracking. [HIGH]The test comprehensively validates resilient decoding behavior with mixed valid/invalid elements. Good coverage of different failure types (type mismatches, nulls, invalid nested fields) and proper separation of DEBUG-only assertions.
122-147: Good coverage of complete decoding failure scenarios. [HIGH]The test properly validates fallback behavior when array decoding completely fails. The distinction between null values (not an error) and type mismatches (errors) is well-captured.
Sources/KarrotCodableKit/PolymorphicCodable/DefaultEmptyPolymorphicArrayValue.swift (4)
34-45: Proper implementation of resilient decoding outcome tracking. [HIGH]The outcome property and initializers follow the established pattern across the codebase. Good separation between public API (defaulting to success) and internal API (allowing specific outcomes).
47-57: Well-designed DEBUG-only projected value access. [HIGH]The conditional compilation ensures projected values are only accessible during development, preventing production overhead. The fatal error message clearly indicates the restriction.
61-79: Correct integration of error reporting in decoding logic. [HIGH]The decoding implementation properly reports errors and tracks outcomes without altering the existing fallback behavior. The error is correctly reported before recovery.
91-101: Correct Equatable/Hashable implementations. [HIGH]The implementations properly focus on the wrapped value only, maintaining backward compatibility and expected behavior. The outcome is correctly excluded from equality/hashing.
Tests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessValueResilientTests.swift (2)
21-49: Good test coverage for successful type conversions. [HIGH]The test validates that @LosslessValue properly converts between compatible types and tracks successful outcomes. All common conversion scenarios are covered.
51-74: Proper validation of null value handling. [HIGH]The test correctly verifies that @LosslessValue throws on null values, which is the expected behavior. Good use of the confirmation pattern for exception testing.
Sources/KarrotCodableKit/Resilient/DictionaryDecodingError.swift (2)
12-21: Clean implementation of dictionary error tracking. [HIGH]The struct design is well-thought-out, storing complete results while providing convenient access to just the errors. Good use of
compactMapValueswith keypath syntax for concise error extraction.
23-38: Thoughtful handling of different outcome cases. [HIGH]The method correctly handles all outcome types. The assertion preventing double-reporting of
DictionaryDecodingErroris important. The design decision to exclude top-level errors for dictionaries is well-reasoned and documented.Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyArray.swift (4)
19-33: Consistent implementation of outcome tracking. [HIGH]The property and initializer changes follow the established pattern across the codebase. Good separation between public and internal APIs.
40-53: Good null value detection logic. [HIGH]The implementation properly distinguishes between null values and other decoding scenarios. The try-catch pattern ensures array decoding proceeds if single value container fails.
106-116: Correct Equatable/Hashable implementations. [HIGH]The implementations properly compare only the wrapped values, maintaining backward compatibility.
79-88: Fix incorrect success detection logic. [HIGH]The condition
elements.count == results.countwill always be true since both arrays are built in parallel. This means errors will never be properly tracked in the outcome. The logic should check if any decoding failures occurred.#if DEBUG -if elements.count == results.count { +if results.allSatisfy({ $0.isSuccess }) { self.init(wrappedValue: elements, outcome: .decodedSuccessfully) } else { let error = ResilientDecodingOutcome.ArrayDecodingError(results: results) self.init(wrappedValue: elements, outcome: .recoveredFrom(error, wasReported: false)) } #elseAlternatively, you could check if
elements.count < results.countto detect if any elements were filtered out.Likely an incorrect or invalid review comment.
Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+LossyOptionalPolymorphicValue.swift (1)
12-21: LGTM! Clean delegation patternThe
decodemethod correctly delegates todecodeIfPresentand provides appropriate outcome tracking for missing keys. This implementation is consistent with other polymorphic value decoders.Sources/KarrotCodableKit/PolymorphicCodable/PolymorphicArrayValue.swift (3)
23-36: Well-designed outcome tracking implementationThe dual initializer pattern properly separates public API (defaulting to successful decoding) from internal framework usage (allowing specific outcome values). This design maintains backward compatibility while enabling resilient decoding features.
37-48: Excellent DEBUG-only projected value patternThe conditional compilation ensures debugging features are available during development but completely removed from production builds. The fatal error message clearly indicates this is a programmer error, preventing silent failures.
74-84: Correct Equatable and Hashable implementationsThe conditional conformances properly delegate to the wrapped array's implementations. Correctly excludes the
outcomeproperty from equality and hashing as it represents decoding metadata, not the actual value.Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalPolymorphicArrayValueTests.swift (1)
16-16: Good adoption of Swift Testing naming conventionsRemoving the
testprefix from method names follows Swift Testing best practices where the@Testattribute clearly identifies test methods. This makes test names more concise and readable.Also applies to: 57-57, 95-95, 114-114, 141-141, 166-166, 185-185
Tests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/PolymorphicArrayValueResilientTests.swift (2)
1-162: Comprehensive resilient decoding test coverage [HIGH]Excellent test suite that thoroughly validates the resilient decoding behavior:
- Covers all major scenarios: success, empty arrays, invalid elements, missing keys
- Properly tests DEBUG-only features with conditional compilation
- Validates integration with error reporting system
- Uses realistic polymorphic type test data
The structured approach with descriptive test names makes the test intent clear.
132-161: Good validation of error reporting integrationThe test properly verifies that decoding errors are captured by the resilient error reporter. Using
flushReportedErrors()to validate error collection ensures the integration works as designed.Sources/KarrotCodableKit/PolymorphicCodable/OptionalPolymorphicArrayValue.swift (2)
65-103: Well-structured decoding implementation [HIGH]The decoding logic correctly handles the optional nature of the array with explicit nil checking before attempting array decoding. The error reporting integration and conditional compilation for debug/release builds are properly implemented.
121-133: Correct protocol conformance implementationsThe explicit implementations for Equatable, Hashable, and Sendable are appropriate. Comparing only
wrappedValuefor equality and hashing is the correct semantic choice.Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalPolymorphicArrayValueResilientTests.swift (1)
34-310: Comprehensive test coverage [HIGH]Excellent test suite covering all resilient decoding scenarios:
- Valid array decoding with heterogeneous types
- Empty arrays, null values, and missing keys
- Error reporting for invalid elements
- Debug-only projected value verification
- Multiple properties interaction
The tests properly verify both the happy path and error conditions.
Tests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/PolymorphicLossyArrayValueResilientTests.swift (1)
5-203: Excellent test coverage for lossy array behavior [HIGH]The test suite thoroughly validates polymorphic lossy array decoding:
- Correctly verifies that invalid elements are skipped while valid ones are decoded
- Per-element result tracking with detailed success/failure verification
- Proper outcome states for different scenarios (success, keyNotFound, recoveredFrom)
- Error reporting integration confirms partial errors are captured
Sources/KarrotCodableKit/BetterCodable/ResilientProjectedValue.swift (2)
11-39: Well-designed protocol and base implementationThe
ResilientProjectedValueProtocolprovides a clean, consistent interface for all projected values with appropriate default error extraction logic. The debug-only compilation ensures no runtime overhead in release builds.
45-77: Safe dynamic member lookup implementationThe dynamic member lookup for both array and dictionary projected values is implemented safely. The underlying
arrayDecodingError()anddictionaryDecodingError()methods handle all outcome cases gracefully, returning empty collections for non-error cases. No additional runtime validation is needed.Sources/KarrotCodableKit/BetterCodable/Defaults/DefaultCodable.swift (1)
280-292: Well-structured error creation for unknown raw valuesThe
createUnknownRawValueErrorhelper method provides a clean separation of error creation logic based on theisFrozenflag. This approach maintains consistency with the resilient decoding philosophy while providing flexibility for different error handling strategies.
Sources/KarrotCodableKit/BetterCodable/Extensions/Result+Extension.swift
Outdated
Show resolved
Hide resolved
Sources/KarrotCodableKit/BetterCodable/Extensions/Result+Extension.swift
Show resolved
Hide resolved
Sources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessArray.swift
Show resolved
Hide resolved
Sources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessValue.swift
Show resolved
Hide resolved
...Kit/PolymorphicCodable/Extensions/KeyedDecodingContainer+OptionalPolymorphicArrayValue.swift
Show resolved
Hide resolved
Sources/KarrotCodableKit/PolymorphicCodable/OptionalPolymorphicArrayValue.swift
Show resolved
Hide resolved
Tests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyArrayResilientTests.swift
Show resolved
Hide resolved
...s/KarrotCodableKitTests/PolymorphicCodable/OptionalPolymorphicArrayValueResilientTests.swift
Show resolved
Hide resolved
7e150de to
3449843
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 8
🔭 Outside diff range comments (1)
Tests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicDeodableMacroTests.swift (1)
1-1: Fix filename typo [MEDIUM]The filename contains a typo:
PolymorphicDeodableMacroTests.swiftshould bePolymorphicDecodableMacroTests.swift. This inconsistency could cause confusion when navigating the test suite.Consider renaming the file to match the correct spelling:
-Tests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicDeodableMacroTests.swift +Tests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicDecodableMacroTests.swift
♻️ Duplicate comments (21)
Sources/KarrotCodableKit/BetterCodable/Extensions/Result+Extension.swift (2)
2-2: Filename header comment is now correct.The filename comment correctly shows "Result+Extension.swift" matching the actual filename. The previous typo has been resolved.
22-24: Consider adding documentation for error-swallowing behavior.The
successproperty usestry? get()which intentionally discards any failure errors. While this provides a clean non-throwing API, a brief comment would help future maintainers understand this is intentional.package var success: Success? { + // Returns the success value, discarding any failure try? get() }Sources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessArray.swift (1)
68-73: Fix incorrect outcome determination logic [HIGH]The condition
elements.count == results.countwill always evaluate to true since both arrays are populated in parallel. This prevents proper error detection.#if DEBUG - if elements.count == results.count { + let hasErrors = results.contains { if case .failure = $0 { return true } else { return false } } + if !hasErrors { self.init(wrappedValue: elements, outcome: .decodedSuccessfully) } else { let error = ResilientDecodingOutcome.ArrayDecodingError(results: results) self.init(wrappedValue: elements, outcome: .recoveredFrom(error, wasReported: false)) }Tests/KarrotCodableKitTests/BetterCodable/DateValue/DateValueResilientTests.swift (1)
26-26: Document the hardcoded timestamp for clarity [LOW]The timestamp
1735728000represents a specific date but lacks context for future maintainers."isoDate": "2025-01-01T12:00:00Z", "rfcDate": "2025-01-01T12:00:00+00:00", - "timestampDate": 1735728000 + "timestampDate": 1735728000 // 2025-01-01T12:00:00ZTests/KarrotCodableKitTests/PolymorphicCodable/OptionalValue/OptionalPolymorphicValueResilientTests.swift (1)
82-99: Validate specific error type for better test precision [MEDIUM]The test should verify the specific polymorphic decoding error rather than any generic error.
Consider capturing and validating the specific error type to ensure it's a polymorphic decoding error:
#expect(throws: Error.self) { _ = try JSONDecoder().decode(Fixture.self, from: data) } + // Add specific error type validation if needed for precisionSources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+OptionalPolymorphicArrayValue.swift (1)
45-45: Remove redundant comment [LOW]The comment is self-explanatory from the code context.
- // Try to decode the array do {Tests/KarrotCodableKitTests/PolymorphicCodable/Value/PolymorphicValueResilientTests.swift (2)
77-99: Consider adding a more specific error assertion [MEDIUM]
102-139: Add more specific error digest validation [MEDIUM]Sources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessValue.swift (1)
64-75: Track recovery in the outcome for better diagnostics.When fallback decoding succeeds after the primary decoding fails, the outcome should reflect that recovery occurred. This preserves valuable diagnostic information about the decoding path taken.
Apply this fix to properly track the recovery:
self.wrappedValue = value self.type = Swift.type(of: rawValue) - self.outcome = .decodedSuccessfully + self.outcome = .recoveredFrom(error, wasReported: true)Tests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyArrayResilientTests.swift (1)
74-95: Consider more specific error assertions. [MEDIUM]The test only checks that at least one error was reported. Since the test data has exactly one invalid element ("two" in the integers array), consider asserting the exact error count and potentially the error details.
Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyArray.swift (1)
63-77: Performance consideration for large arrays [HIGH]Using
superDecoder()for each array element enables proper error reporting but creates additional decoder instances per element. For large arrays, this could impact performance compared to direct element decoding.Consider benchmarking this approach against direct decoding for typical array sizes in your use cases. If performance becomes an issue, you might want to add a threshold-based approach or make the detailed error tracking configurable.
Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+LossyOptionalPolymorphicValue.swift (1)
38-47: Critical issue with error reporter decoder creation [HIGH]Creating a new
superDecoderafter a decoding failure might fail or not accurately represent the decoder state where the error occurred. The error should be reported using the decoder instance where it happened.Apply this fix to capture and use the original decoder:
// Try to decode the polymorphic value +let decoder = try superDecoder(forKey: key) do { - let decoder = try superDecoder(forKey: key) let value = try T.decode(from: decoder) return LossyOptionalPolymorphicValue(wrappedValue: value, outcome: .decodedSuccessfully) } catch { // Report error to resilient decoding error reporter - let decoder = try? superDecoder(forKey: key) - decoder?.reportError(error) + decoder.reportError(error) return LossyOptionalPolymorphicValue(wrappedValue: nil, outcome: .recoveredFrom(error, wasReported: true)) }Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+PolymorphicLossyArrayValue.swift (2)
35-49: Report errors before recovering to empty array [HIGH]When decoding fails, the error should be reported to the decoder before recovering. This ensures the error is captured by the resilient decoding error reporter.
do { let decoder = try superDecoder(forKey: key) return try PolymorphicLossyArrayValue(from: decoder) } catch { + // Report the error before recovering + let errorDecoder = try? superDecoder(forKey: key) + errorDecoder?.reportError(error) // If decoding fails (e.g., not an array), return empty array #if DEBUG return PolymorphicLossyArrayValue( wrappedValue: [], - outcome: .recoveredFrom(error, wasReported: false), + outcome: .recoveredFrom(error, wasReported: true), results: [] ) #else - return PolymorphicLossyArrayValue(wrappedValue: [], outcome: .recoveredFrom(error, wasReported: false)) + return PolymorphicLossyArrayValue(wrappedValue: [], outcome: .recoveredFrom(error, wasReported: true)) #endif }
62-68: Fix inconsistent outcome parameter handling in non-DEBUG builds [MEDIUM]In the
decodeIfPresentmethod, when handling null values in non-DEBUG builds, thePolymorphicLossyArrayValueis created without theoutcomeparameter, unlike thedecodemethod which always provides it.#if DEBUG return PolymorphicLossyArrayValue(wrappedValue: [], outcome: .valueWasNil, results: []) #else -return PolymorphicLossyArrayValue(wrappedValue: []) +return PolymorphicLossyArrayValue(wrappedValue: [], outcome: .valueWasNil) #endifTests/KarrotCodableKitTests/PolymorphicCodable/OptionalPolymorphicArrayValueResilientTests.swift (1)
16-16: Consider shorter type name [LOW]The type name exceeds SwiftLint's 40 character limit. Consider shortening while maintaining clarity.
-struct ResilientOptionalPolymorphicArrayDummyResponse { +struct OptionalPolymorphicArrayResponse {Sources/KarrotCodableKit/PolymorphicCodable/OptionalPolymorphicArrayValue.swift (1)
41-43: Consider makingoutcomeproperty internal [MEDIUM]The
outcomeproperty is currently public, but it's primarily used for debug-only projected values. Making it internal would better encapsulate implementation details while still allowing access through the debug-only projected value.- /// The outcome of the decoding process - public let outcome: ResilientDecodingOutcome + /// The outcome of the decoding process + internal let outcome: ResilientDecodingOutcomeTests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessArrayResilientTests.swift (1)
14-32: Well-structured test fixture [LOW]The fixture design effectively tests different scenarios with various types. The explicit
init?returning nil forNestedObjectclearly demonstrates non-convertible types.Consider adding a test case for very large arrays to validate the performance characteristics of the resilient decoding approach.
Sources/KarrotCodableKit/BetterCodable/ResilientProjectedValue.swift (1)
45-58: Consider adding runtime validation for outcome typeThe dynamic member lookup implementation is clever, but it assumes the outcome contains array-related errors. Consider adding a debug assertion to validate this assumption:
public subscript<U>( dynamicMember keyPath: KeyPath<ResilientDecodingOutcome.ArrayDecodingError<Element>, U> ) -> U { + #if DEBUG + // Validate that the outcome can produce an array decoding error + switch outcome { + case .recoveredFrom(let error, _) where error is ResilientDecodingOutcome.ArrayDecodingError<Element>: + break + case .decodedSuccessfully, .keyNotFound, .valueWasNil: + break + case .recoveredFrom: + assertionFailure("Unexpected error type for array projected value") + } + #endif outcome.arrayDecodingError()[keyPath: keyPath] }Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyDictionary.swift (1)
198-234: Well-structured decoding implementation with proper error handlingThe refactored decoding logic with early nil detection and type-specific dispatching is clean and maintainable. The error reporting integration ensures failures are tracked without breaking the decoding process.
Sources/KarrotCodableKit/Resilient/ErrorReporting.swift (2)
76-101: Thread safety concern needs to be addressedThe error reporter maintains mutable state without synchronization, which could lead to data races in concurrent decoding scenarios.
125-141: Performance optimization opportunity for error collectionThe current implementation recreates the error array on each access, which could impact performance with many errors.
📜 Review details
Configuration used: .coderabbit.yml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (54)
Sources/KarrotCodableKit/BetterCodable/DataValue/DataValue.swift(2 hunks)Sources/KarrotCodableKit/BetterCodable/DateValue/DateValue.swift(2 hunks)Sources/KarrotCodableKit/BetterCodable/DateValue/OptionalDateValue.swift(2 hunks)Sources/KarrotCodableKit/BetterCodable/Defaults/DefaultCodable.swift(5 hunks)Sources/KarrotCodableKit/BetterCodable/Extensions/Result+Extension.swift(1 hunks)Sources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessArray.swift(3 hunks)Sources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessValue.swift(2 hunks)Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyArray.swift(2 hunks)Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyDictionary.swift(4 hunks)Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyOptional.swift(0 hunks)Sources/KarrotCodableKit/BetterCodable/ResilientProjectedValue.swift(1 hunks)Sources/KarrotCodableKit/Encodable+ToDictionary.swift(1 hunks)Sources/KarrotCodableKit/PolymorphicCodable/DefaultEmptyPolymorphicArrayValue.swift(2 hunks)Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+DefaultEmptyPolymorphicArrayValue.swift(1 hunks)Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+LossyOptionalPolymorphicValue.swift(1 hunks)Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+OptionalPolymorphicArrayValue.swift(2 hunks)Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+OptionalPolymorphicValue.swift(1 hunks)Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+PolymorphicLossyArrayValue.swift(1 hunks)Sources/KarrotCodableKit/PolymorphicCodable/OptionalPolymorphicArrayValue.swift(2 hunks)Sources/KarrotCodableKit/PolymorphicCodable/PolymorphicArrayValue.swift(3 hunks)Sources/KarrotCodableKit/PolymorphicCodable/PolymorphicProjectedValue.swift(1 hunks)Sources/KarrotCodableKit/Resilient/ArrayDecodingError.swift(1 hunks)Sources/KarrotCodableKit/Resilient/DictionaryDecodingError.swift(1 hunks)Sources/KarrotCodableKit/Resilient/ErrorReporting.swift(1 hunks)Tests/KarrotCodableKitTests/BetterCodable/DataValue/DataValueResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/BetterCodable/DateValue/DateValueResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultCodableResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultCodableTests.swift(1 hunks)Tests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultEmptyArrayTests.swift(0 hunks)Tests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessArrayResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessArrayTests.swift(0 hunks)Tests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessValueResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyArrayResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyArrayTests.swift(0 hunks)Tests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyDictionaryResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/PolymorphicArrayValueResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/PolymorphicLossyArrayValueResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/Enum/PolymorphicEnumDecodableTests.swift(0 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalPolymorphicArrayValueResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalPolymorphicArrayValueTests.swift(8 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalValue/OptionalPolymorphicValueResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/TestDoubles/UnnestedPolymorphicCodableDummy.swift(0 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/Value/PolymorphicValueResilientTests.swift(1 hunks)Tests/KarrotCodableKitTests/PolymorphicCodable/Value/PolymorphicValueTests.swift(0 hunks)Tests/KarrotCodableMacrosTests/CustomCodableMacros/CustomCodableMacroTests.swift(1 hunks)Tests/KarrotCodableMacrosTests/CustomCodableMacros/CustomDecodableMacroTests.swift(1 hunks)Tests/KarrotCodableMacrosTests/CustomCodableMacros/CustomEncodableMacroTests.swift(1 hunks)Tests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicCodableMacroTests.swift(1 hunks)Tests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicCodableStrategyProvidingMacroTests.swift(1 hunks)Tests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicDeodableMacroTests.swift(1 hunks)Tests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicEncodableMacroTests.swift(1 hunks)Tests/KarrotCodableMacrosTests/PolymorphicEnumCodableMacroTests/PolymorphicEnumCodableMacroTests.swift(6 hunks)Tests/KarrotCodableMacrosTests/PolymorphicEnumCodableMacroTests/PolymorphicEnumDecodableMacroTests.swift(6 hunks)Tests/KarrotCodableMacrosTests/PolymorphicEnumCodableMacroTests/PolymorphicEnumEncodableMacroTests.swift(4 hunks)
💤 Files with no reviewable changes (7)
- Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyOptional.swift
- Tests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultEmptyArrayTests.swift
- Tests/KarrotCodableKitTests/PolymorphicCodable/Value/PolymorphicValueTests.swift
- Tests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessArrayTests.swift
- Tests/KarrotCodableKitTests/PolymorphicCodable/Enum/PolymorphicEnumDecodableTests.swift
- Tests/KarrotCodableKitTests/PolymorphicCodable/TestDoubles/UnnestedPolymorphicCodableDummy.swift
- Tests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyArrayTests.swift
🧰 Additional context used
📓 Path-based instructions (3)
Sources/KarrotCodableKit/**
⚙️ CodeRabbit Configuration File
Sources/KarrotCodableKit/**: You are a senior Swift/iOS engineer reviewing runtime library code for KarrotCodableKit, a comprehensive Codable extension framework.1. Codable Performance [HIGH]
- Check encoding/decoding efficiency and memory usage
- Verify proper handling of large JSON structures
- Assess polymorphic type resolution performance
- Review property wrapper overhead and optimization
2. Type Safety & Polymorphism [HIGH]
- Validate PolymorphicCodable identifier-based type resolution
- Check AnyCodable type erasure implementation for edge cases
- Verify UnnestedPolymorphic macro integration with runtime components
- Assess error handling in polymorphic decoding scenarios
3. API Design [HIGH]
- Evaluate public interface consistency across modules
- Check property wrapper ergonomics (@DefaultFalse, @DATEvalue, etc.)
- Verify protocol design follows Swift API guidelines
- Assess extensibility for new Codable patterns
4. BetterCodable Integration [MEDIUM]
- Review property wrapper implementations for common patterns
- Check date strategy implementations (ISO8601, RFC3339, etc.)
- Verify default value and lossy conversion handling
- Assess data encoding strategies (Base64, etc.)
5. Error Handling [MEDIUM]
- Verify comprehensive DecodingError and EncodingError usage
- Check PolymorphicCodableError provides sufficient context
- Assess graceful fallback handling in polymorphic scenarios
Review Focus
- Prioritize runtime correctness and performance over style
- Focus on real-world JSON processing scenarios
- Mark comments with priority: [HIGH], [MEDIUM], or [LOW]
Files:
Sources/KarrotCodableKit/Encodable+ToDictionary.swiftSources/KarrotCodableKit/BetterCodable/Extensions/Result+Extension.swiftSources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+OptionalPolymorphicArrayValue.swiftSources/KarrotCodableKit/Resilient/DictionaryDecodingError.swiftSources/KarrotCodableKit/BetterCodable/LossyValue/LossyArray.swiftSources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+LossyOptionalPolymorphicValue.swiftSources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessArray.swiftSources/KarrotCodableKit/PolymorphicCodable/DefaultEmptyPolymorphicArrayValue.swiftSources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+DefaultEmptyPolymorphicArrayValue.swiftSources/KarrotCodableKit/BetterCodable/DateValue/DateValue.swiftSources/KarrotCodableKit/BetterCodable/DateValue/OptionalDateValue.swiftSources/KarrotCodableKit/BetterCodable/LosslessValue/LosslessValue.swiftSources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+PolymorphicLossyArrayValue.swiftSources/KarrotCodableKit/BetterCodable/ResilientProjectedValue.swiftSources/KarrotCodableKit/PolymorphicCodable/PolymorphicProjectedValue.swiftSources/KarrotCodableKit/Resilient/ArrayDecodingError.swiftSources/KarrotCodableKit/BetterCodable/DataValue/DataValue.swiftSources/KarrotCodableKit/Resilient/ErrorReporting.swiftSources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+OptionalPolymorphicValue.swiftSources/KarrotCodableKit/PolymorphicCodable/PolymorphicArrayValue.swiftSources/KarrotCodableKit/PolymorphicCodable/OptionalPolymorphicArrayValue.swiftSources/KarrotCodableKit/BetterCodable/LossyValue/LossyDictionary.swiftSources/KarrotCodableKit/BetterCodable/Defaults/DefaultCodable.swift
Tests/KarrotCodableMacrosTests/**
⚙️ CodeRabbit Configuration File
Tests/KarrotCodableMacrosTests/**: You are a senior Swift/iOS engineer reviewing macro expansion tests for KarrotCodableKit's Swift macro implementations.1. Macro Expansion Testing [HIGH]
- Verify SwiftSyntaxMacrosTestSupport usage is comprehensive
- Check that all macro expansion scenarios are covered
- Assess edge case testing for invalid macro arguments
- Validate diagnostic message testing matches actual validation logic
2. Test Code Quality [HIGH]
- Review test case organization and naming clarity
- Check that test data represents realistic usage scenarios
- Verify test assertions are specific and meaningful
- Assess test maintainability and readability
3. Coverage Assessment [MEDIUM]
- Ensure all macro variants (Codable, Decodable, Encodable) are tested
- Check polymorphic macro test coverage for different identifier strategies
- Verify error conditions and validation failures are tested
- Assess macro registration and plugin functionality testing
Review Focus
- Prioritize test correctness and comprehensive coverage
- Focus on macro-specific testing patterns and SwiftSyntax integration
- Mark comments with priority: [HIGH], [MEDIUM], or [LOW]
Files:
Tests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicDeodableMacroTests.swiftTests/KarrotCodableMacrosTests/CustomCodableMacros/CustomDecodableMacroTests.swiftTests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicCodableMacroTests.swiftTests/KarrotCodableMacrosTests/PolymorphicEnumCodableMacroTests/PolymorphicEnumEncodableMacroTests.swiftTests/KarrotCodableMacrosTests/PolymorphicEnumCodableMacroTests/PolymorphicEnumDecodableMacroTests.swiftTests/KarrotCodableMacrosTests/CustomCodableMacros/CustomCodableMacroTests.swiftTests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicCodableStrategyProvidingMacroTests.swiftTests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicEncodableMacroTests.swiftTests/KarrotCodableMacrosTests/CustomCodableMacros/CustomEncodableMacroTests.swiftTests/KarrotCodableMacrosTests/PolymorphicEnumCodableMacroTests/PolymorphicEnumCodableMacroTests.swift
Tests/KarrotCodableKitTests/**
⚙️ CodeRabbit Configuration File
Tests/KarrotCodableKitTests/**: You are a senior Swift/iOS engineer reviewing runtime functionality tests for KarrotCodableKit's Codable extensions.1. Runtime Behavior Testing [HIGH]
- Verify JSON encoding/decoding scenarios cover real-world use cases
- Check polymorphic type resolution testing across different strategies
- Assess property wrapper testing (@DATEvalue, @DefaultFalse, etc.)
- Validate error handling and edge case coverage
2. Test Data Quality [HIGH]
- Review test JSON structures for realistic complexity
- Check that TestDoubles provide comprehensive mock scenarios
- Verify test data covers various data types and edge cases
- Assess polymorphic test data represents actual usage patterns
3. Integration Testing [MEDIUM]
- Check integration between macro-generated code and runtime functionality
- Verify end-to-end scenarios combining multiple KarrotCodableKit features
- Assess performance testing for large data structures
- Review memory usage testing for complex polymorphic scenarios
Review Focus
- Prioritize real-world usage scenario coverage
- Focus on Codable correctness and performance implications
- Mark comments with priority: [HIGH], [MEDIUM], or [LOW]
Files:
Tests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultCodableTests.swiftTests/KarrotCodableKitTests/BetterCodable/DateValue/DateValueResilientTests.swiftTests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessValueResilientTests.swiftTests/KarrotCodableKitTests/PolymorphicCodable/OptionalPolymorphicArrayValueTests.swiftTests/KarrotCodableKitTests/PolymorphicCodable/Value/PolymorphicValueResilientTests.swiftTests/KarrotCodableKitTests/BetterCodable/DataValue/DataValueResilientTests.swiftTests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/PolymorphicLossyArrayValueResilientTests.swiftTests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/PolymorphicArrayValueResilientTests.swiftTests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyDictionaryResilientTests.swiftTests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessArrayResilientTests.swiftTests/KarrotCodableKitTests/PolymorphicCodable/OptionalValue/OptionalPolymorphicValueResilientTests.swiftTests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultCodableResilientTests.swiftTests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyArrayResilientTests.swiftTests/KarrotCodableKitTests/PolymorphicCodable/OptionalPolymorphicArrayValueResilientTests.swift
🧬 Code Graph Analysis (5)
Tests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessValueResilientTests.swift (2)
Tests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessValueTests.swift (1)
LosslessValueTests(12-121)Tests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessArrayTests.swift (1)
LosslessArrayTests(12-58)
Tests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/PolymorphicLossyArrayValueResilientTests.swift (1)
Tests/KarrotCodableKitTests/PolymorphicCodable/PolymorphicLossyArrayValueTests.swift (1)
PolymorphicLossyArrayValueTests(13-112)
Tests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/PolymorphicArrayValueResilientTests.swift (1)
Tests/KarrotCodableKitTests/PolymorphicCodable/PolymorphicLossyArrayValueTests.swift (1)
PolymorphicLossyArrayValueTests(13-112)
Tests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyDictionaryResilientTests.swift (1)
Tests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyDictionaryTests.swift (4)
LossyDictionaryTests(12-109)testEncodingDecodedLossyDictionaryIgnoresFailableElements(39-64)Fixture(13-16)testDecodingLossyDictionaryIgnoresFailableElements(18-37)
Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalValue/OptionalPolymorphicValueResilientTests.swift (1)
Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalPolymorphicValueTests.swift (1)
OptionalPolymorphicValueTests(13-71)
🪛 SwiftLint (0.57.0)
Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalPolymorphicArrayValueResilientTests.swift
[Warning] 16-16: Type name 'ResilientOptionalPolymorphicArrayDummyResponse' should be between 3 and 40 characters long
(type_name)
[Warning] 30-30: Type name 'OptionalPolymorphicArrayValueResilientTests' should be between 3 and 40 characters long
(type_name)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Build and Test (16.1, release)
- GitHub Check: Check Macro Compatibility
🔇 Additional comments (65)
Sources/KarrotCodableKit/Encodable+ToDictionary.swift (1)
22-26: Good formatting improvement for multiline guard statement.The reformatting enhances readability by breaking the complex guard condition across multiple lines. This follows Swift style conventions for complex conditions.
Tests/KarrotCodableMacrosTests/CustomCodableMacros/CustomDecodableMacroTests.swift (1)
303-306: Trailing comma improves maintainability – LGTM
Adding the trailing comma after the lastDiagnosticSpeckeeps the style consistent with Swift array formatting conventions and makes future diffs cleaner. No further action needed.Tests/KarrotCodableMacrosTests/CustomCodableMacros/CustomCodableMacroTests.swift (1)
295-306: Trailing-comma addition looks goodAdding the trailing comma after the last
DiagnosticSpeckeeps the diagnostics array diff-friendly and consistent with Swift style conventions—no functional impact on the test.Tests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicEncodableMacroTests.swift (2)
107-107: Good formatting improvement! [HIGH]Adding the trailing comma improves consistency with Swift style guidelines and makes future additions to the diagnostics array cleaner.
19-115: Excellent macro test coverage! [HIGH]The test suite demonstrates solid macro testing practices:
- Comprehensive positive case testing with realistic macro usage
- Error diagnostic testing for invalid identifier values
- Proper use of SwiftSyntaxMacrosTestSupport patterns
- Clear test organization and naming
The macro expansion validation covers both the generated CodingKeys enum and the PolymorphicEncodableType extension, ensuring complete functionality verification.
Tests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicDeodableMacroTests.swift (1)
107-107: Good formatting consistency! [HIGH]The trailing comma addition aligns with the formatting improvements across the macro test suite.
Tests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicCodableMacroTests.swift (2)
104-104: Consistent formatting improvement! [HIGH]The trailing comma addition maintains consistency across the macro test suite formatting standards.
27-112: Well-structured macro tests! [HIGH]The test cases effectively validate:
- Complete macro expansion with CodingKeys generation and PolymorphicCodableType extension
- Error handling for invalid identifier values
- Proper diagnostic message validation
The test structure follows SwiftSyntax macro testing best practices with clear separation of input, expected output, and error diagnostics.
Tests/KarrotCodableMacrosTests/CustomCodableMacros/CustomEncodableMacroTests.swift (2)
305-305: Formatting consistency maintained! [HIGH]The trailing comma addition keeps this file aligned with the broader formatting standardization across macro tests.
18-314: Exceptional macro test coverage! [HIGH]This test suite demonstrates excellent macro testing practices:
Comprehensive Scenarios:
- Basic macro expansion with different coding key styles
- Nested struct handling (both inline and extension-based)
- CodableKey macro integration testing
- Error case validation for unsupported types
Test Organization:
- Clear MARK sections for different test categories
- Descriptive test method names
- Proper separation of concerns
Edge Case Coverage:
- Tests enum application errors with multiple diagnostic specs
- Validates computed property handling
- Covers various coding key transformation scenarios
The test structure provides confidence in the macro's robustness across different usage patterns.
Tests/KarrotCodableMacrosTests/PolymorphicEnumCodableMacroTests/PolymorphicEnumCodableMacroTests.swift (2)
168-168: Consistent formatting across all diagnostics! [HIGH]The trailing comma additions across all diagnostic arrays maintain excellent formatting consistency throughout this comprehensive test suite.
Also applies to: 201-201, 234-234, 267-267, 370-370, 403-403
25-411: Outstanding comprehensive macro testing! [HIGH]This test suite represents exemplary macro testing with exceptional coverage:
Core Functionality Testing:
- Complete macro expansion validation with proper Codable implementation
- Default parameter handling verification
- Complex enum case patterns with associated values
Comprehensive Error Scenarios:
- Type validation (enum-only application)
- Empty identifier validation
- Associated value count restrictions
- Missing associated value detection
- Fallback case validation and naming
Advanced Features:
- Fallback case functionality with proper default handling
- Complex associated value patterns (named vs unnamed)
- Integration with polymorphic identifier system
Test Organization Excellence:
- Clear MARK sections separating test categories
- Descriptive test names indicating specific validation scenarios
- Proper diagnostic message validation with line/column specificity
This level of test coverage ensures robust macro behavior across all supported use cases and provides excellent protection against regressions.
Tests/KarrotCodableMacrosTests/PolymorphicEnumCodableMacroTests/PolymorphicEnumEncodableMacroTests.swift (1)
128-128: LGTM! Good formatting consistency improvements.Adding trailing commas after
DiagnosticSpecinstances improves code consistency and makes future array modifications cleaner with smaller diffs.Also applies to: 161-161, 194-194, 227-227
Tests/KarrotCodableMacrosTests/PolymorphicEnumCodableMacroTests/PolymorphicEnumDecodableMacroTests.swift (1)
146-146: LGTM! Consistent formatting improvements.These trailing comma additions align well with the formatting improvements in the companion
PolymorphicEnumEncodableMacroTests.swiftfile, maintaining consistency across the macro test suite.Also applies to: 179-179, 212-212, 245-245, 335-335, 368-368
Tests/KarrotCodableMacrosTests/PolymorphicCodableMacrosTests/PolymorphicCodableStrategyProvidingMacroTests.swift (1)
135-135: LGTM! Minor whitespace cleanup.Removing the trailing whitespace improves the precision of the macro expansion test output formatting.
Tests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultCodableTests.swift (1)
180-180: LGTM! Good readability improvement.Adding a blank line between the switch cases improves the readability of the
encode(to:)method.Sources/KarrotCodableKit/BetterCodable/Extensions/Result+Extension.swift (1)
11-24: LGTM! Clean and useful Result extensions.These convenience properties provide a nice API for working with Result types. The implementations are correct and follow Swift conventions well.
Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+DefaultEmptyPolymorphicArrayValue.swift (2)
12-29: Well-implemented resilient decoding with proper edge case handling [HIGH]The
decodemethod correctly handles all scenarios: missing keys, null values, and actual decoding. The use ofsuperDecoderensures proper polymorphic decoding through the property wrapper's decoder.
31-49: Consistent optional decoding semantics [MEDIUM]The
decodeIfPresentmethod properly returnsnilfor missing keys while maintaining the same resilient decoding pattern for null values and decoding errors.Tests/KarrotCodableKitTests/BetterCodable/DateValue/DateValueResilientTests.swift (1)
12-125: Comprehensive test coverage for resilient decoding [HIGH]Excellent test suite covering all key scenarios: successful decoding, invalid formats, null values, and error reporting integration. The use of
confirmationfor async testing and proper error assertions ensures robust validation.Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalValue/OptionalPolymorphicValueResilientTests.swift (1)
5-117: Well-structured test suite for optional polymorphic values [HIGH]The test suite effectively validates all key scenarios for optional polymorphic value decoding, including proper outcome tracking in debug mode. Good use of the Testing framework's features.
Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+OptionalPolymorphicArrayValue.swift (1)
27-68: Robust polymorphic array decoding with proper error handling [HIGH]The
decodeIfPresentimplementation correctly handles all edge cases and properly decodes polymorphic arrays element by element. The error reporting throughsuperDecoderensures errors are captured before rethrowing.Tests/KarrotCodableKitTests/BetterCodable/DataValue/DataValueResilientTests.swift (1)
19-41: LGTM! Well-structured test for successful decoding [HIGH]The test properly validates both the decoded values and the resilient decoding outcomes in debug builds.
Sources/KarrotCodableKit/BetterCodable/DateValue/DateValue.swift (2)
45-56: Well-implemented resilient decoding pattern [HIGH]The error reporting integration is clean and follows best practices. The do-catch block properly reports errors before rethrowing.
28-42: Good separation of public and internal APIs [HIGH]The dual initializer pattern provides a clean public API while allowing internal flexibility for testing and error states.
Sources/KarrotCodableKit/BetterCodable/DataValue/DataValue.swift (2)
45-56: Clean error handling implementation [HIGH]The single do-catch block properly handles both string decoding and strategy decoding failures, reporting errors appropriately.
64-75: Proper conditional conformance implementation [HIGH]Good improvement from empty extensions to explicit implementations with appropriate type constraints.
Tests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyDictionaryResilientTests.swift (2)
26-79: Excellent test coverage for dictionary resilience [HIGH]The test thoroughly validates partial decoding failures with detailed assertions on both successful and failed key-value pairs. Great use of projected values to verify error details.
108-158: Thorough edge case testing [HIGH]Excellent coverage of edge cases with clear distinction between different failure modes (wrong type vs null vs missing). The outcome tracking provides valuable debugging information.
Sources/KarrotCodableKit/Resilient/ArrayDecodingError.swift (1)
10-42: Well-designed resilient error reporting structure! 👍The implementation provides a clean abstraction for array decoding errors with proper debug-only compilation. The design choice to wrap top-level errors in a single-element array (lines 36-38) is pragmatic and well-documented.
Sources/KarrotCodableKit/PolymorphicCodable/PolymorphicProjectedValue.swift (1)
11-58: Excellent protocol-oriented design for projected values!The separation between the protocol and concrete implementations provides good extensibility. The specialized
PolymorphicLossyArrayProjectedValueappropriately extends the base functionality with element-level granularity.Sources/KarrotCodableKit/Resilient/DictionaryDecodingError.swift (1)
10-40: Smart design decision for dictionary error handling!The choice to return an empty dictionary for top-level errors (line 35) rather than attempting to assign an arbitrary key is well-reasoned and clearly documented. This appropriately differs from the array approach where index positioning is natural.
Sources/KarrotCodableKit/PolymorphicCodable/Extensions/KeyedDecodingContainer+OptionalPolymorphicValue.swift (1)
23-46: Excellent explicit handling of all decoding scenarios!The implementation correctly distinguishes between missing keys, null values, and actual decoding errors. The deliberate choice to throw errors without recovery for
OptionalPolymorphicValueis well-documented and appropriate for optional types.Sources/KarrotCodableKit/PolymorphicCodable/DefaultEmptyPolymorphicArrayValue.swift (4)
34-45: LGTM! Well-structured outcome tracking implementation.The addition of the
outcomeproperty and dual initializer pattern correctly implements resilient decoding outcome tracking. The public initializer appropriately defaults to.decodedSuccessfullyfor programmatic initialization, while the internal initializer enables the decoder to set specific outcomes.
47-58: Excellent debug-only projected value implementation.The conditional compilation approach ensures zero runtime overhead in production builds while providing valuable debugging capabilities during development. The fatal error message clearly identifies the property wrapper type, which will help developers quickly identify misuse.
61-80: Proper error reporting integration.The decoding implementation correctly integrates with the resilient error reporting system. The transition from
decoder.reportError(error)enables centralized error collection, and the outcome tracking accurately reflects both successful decoding and error recovery states.
91-101: Standard conformance implementations look good.The explicit
EquatableandHashableimplementations correctly use only thewrappedValuefor comparison and hashing, treating theoutcomeas metadata. This aligns with expected semantics where two instances with the same data but different decoding paths are considered equal.Tests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyArrayResilientTests.swift (3)
25-72: Comprehensive projected value testing.Excellent test coverage for the projected value functionality. The test thoroughly validates:
- Correct filtering of invalid elements (type mismatches, nulls)
- Detailed result tracking per element
- Error count accuracy for each array type
The element-by-element verification provides confidence in the implementation's correctness.
97-120: Good coverage of convenience API.The test effectively validates the
decode(_:from:reportResilientDecodingErrors:)convenience method, verifying both the decoded result and error collection in a single call.
122-147: Thorough edge case testing.Excellent coverage of complete failure scenarios. The test correctly validates that:
- Non-array values result in empty arrays
- Error information is properly tracked in debug builds
nullis correctly treated as a valid empty value rather than an errorSources/KarrotCodableKit/BetterCodable/DateValue/OptionalDateValue.swift (3)
29-43: Consistent resilient decoding implementation.The outcome tracking and projected value implementation follows the established pattern across the codebase. The inline projected value syntax is appropriate for this simple wrapper.
47-64: Well-structured error handling with proper outcome tracking.The nested error handling correctly distinguishes between:
- Successful decoding (
.decodedSuccessfully)- Nil/missing values (
.valueWasNil)- Formatter errors (reported and rethrown)
- Other decoding errors (reported and rethrown)
All error paths properly integrate with the error reporter while maintaining the original error propagation behavior.
74-78: Good use of Self type alias.The simplified signature using
Selfis more idiomatic and cleaner than the generic parameter approach.Tests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessValueResilientTests.swift (3)
21-49: Good positive test coverage.The test effectively validates successful lossless conversions across different type combinations (number→string, string→number, string→bool, string→double). The debug assertions confirm that all conversions are tracked as successful.
51-74: Proper null value handling test.The test correctly validates that
@LosslessValuecannot handle null values and throws an error as expected. Good use of the confirmation pattern to ensure the expected failure occurs.
76-99: Thorough edge case testing.The test effectively validates that complex JSON types (objects and arrays) cannot be converted to primitive types, ensuring the wrapper's type safety boundaries are properly enforced.
Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyArray.swift (3)
19-34: Consistent outcome tracking implementation.The implementation correctly uses
ResilientArrayProjectedValuefor array-specific error details, maintaining consistency with the established pattern while providing array-appropriate functionality.
40-54: Good null value detection logic.The explicit null check before array decoding properly distinguishes between null values (valid empty array) and actual decoding failures. The empty catch block is appropriately documented and serves its purpose.
79-86: Logic issue in outcome determination. [HIGH]The condition
elements.count == results.counton line 80 will always be true because both arrays are built in parallel. The intended check should compare the number of successful elements against the total attempts.#if DEBUG -if elements.count == results.count { +let successCount = results.filter({ $0.isSuccess }).count +if successCount == results.count { self.init(wrappedValue: elements, outcome: .decodedSuccessfully) } else { let error = ResilientDecodingOutcome.ArrayDecodingError(results: results) self.init(wrappedValue: elements, outcome: .recoveredFrom(error, wasReported: false)) } #elseLikely an incorrect or invalid review comment.
Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalPolymorphicArrayValueTests.swift (1)
16-16: Test naming convention update looks good!The removal of the
testprefix from all test methods aligns with Swift Testing framework conventions where the@Testattribute is used instead. This makes the test names more concise and readable.Also applies to: 57-57, 95-95, 114-114, 141-141, 166-166, 185-185
Sources/KarrotCodableKit/PolymorphicCodable/PolymorphicArrayValue.swift (2)
23-48: Resilient decoding implementation looks solid! [HIGH]The addition of
outcometracking and debug-onlyprojectedValuefollows the established pattern across the codebase. The fatal error for non-DEBUG builds appropriately prevents misuse in production.
74-84: Proper Equatable and Hashable implementationsThe conformances correctly compare and hash only the
wrappedValue, which is the appropriate behavior for a property wrapper.Tests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/PolymorphicArrayValueResilientTests.swift (1)
1-161: Excellent test coverage for resilient decoding! [HIGH]The test suite comprehensively covers all decoding scenarios including success cases, various failure modes, and error reporting integration. The use of conditional compilation for DEBUG-only features is appropriate.
Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalPolymorphicArrayValueResilientTests.swift (1)
34-311: Excellent test coverage for resilient decoding scenarios [HIGH]The test suite provides comprehensive coverage of OptionalPolymorphicArrayValue behavior including:
- Valid heterogeneous arrays with proper type resolution
- Edge cases (empty arrays, null values, missing keys)
- Error reporting integration
- Debug-only projected value validation
- Multiple property interactions
The tests effectively validate real-world JSON decoding scenarios with proper assertions on both values and outcomes.
Sources/KarrotCodableKit/PolymorphicCodable/OptionalPolymorphicArrayValue.swift (1)
64-103: Well-structured resilient decoding implementation [HIGH]The decoding logic properly handles all scenarios:
- Explicit nil detection with
.valueWasNiloutcome- Array decoding with element-wise polymorphic resolution
- Error reporting before rethrowing for debugging
This implementation aligns well with the resilient decoding pattern across the codebase.
Tests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessArrayResilientTests.swift (1)
35-142: Comprehensive resilient decoding test coverage [HIGH]The test suite effectively validates:
- Lossless conversion behavior with mixed valid/invalid elements
- Detailed error tracking through projected values
- Integration with resilient decoding error reporter
- Edge cases (complete failure, missing keys)
The assertions properly verify both the filtered results and the error information, providing confidence in the resilient decoding implementation.
Tests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/PolymorphicLossyArrayValueResilientTests.swift (1)
5-203: Excellent polymorphic lossy array test coverage [HIGH]The test suite provides thorough validation of PolymorphicLossyArrayValue behavior:
- Proper handling of heterogeneous polymorphic arrays
- Lossy behavior correctly skips invalid elements while preserving valid ones
- Detailed outcome tracking with per-element success/failure status
- Integration with error reporting system
The tests effectively cover real-world scenarios where arrays may contain invalid or unexpected elements.
Sources/KarrotCodableKit/BetterCodable/ResilientProjectedValue.swift (1)
10-78: Well-designed resilient projected value infrastructure [HIGH]The implementation provides an elegant solution for DEBUG-only error tracking:
- Clean protocol abstraction with sensible defaults
- Type-specific implementations for arrays and dictionaries
- Dynamic member lookup provides intuitive access to error details
- Zero production overhead with DEBUG compilation
This design effectively supports the resilient decoding feature across all property wrappers.
Sources/KarrotCodableKit/BetterCodable/LossyValue/LossyDictionary.swift (4)
19-35: Good implementation of resilient decoding outcome trackingThe addition of the
outcomeproperty and updated initializers properly integrates with the resilient decoding system. The debug-only projected value is a nice touch for development-time debugging.
64-106: Excellent refactoring into focused helper methodsThe decomposition into
ExtractedKey,DecodingState, and specialized decoding methods significantly improves code clarity and maintainability. The separation of debug-only state tracking is well implemented.
135-183: Robust error handling in key-value decodingThe implementation properly handles type mismatches with safe casting and integrates error reporting without failing the entire decoding process. The pattern of consuming failed values as
AnyDecodableValueis a clever way to prevent decoder state corruption.
266-285: Useful KeyedDecodingContainer extensionThe extension properly handles missing keys and maintains consistency with the resilient decoding pattern by returning empty dictionaries with appropriate outcomes.
Sources/KarrotCodableKit/Resilient/ErrorReporting.swift (3)
12-45: Well-designed error reporting enablement APIThe implementation provides a clean API for enabling error reporting with appropriate safeguards against misuse. The assertion and
mayBeMissingReportedErrorsflag ensure developers are aware of incorrect usage patterns.
148-167: Clean integration with Decoder protocolThe extension provides a natural API for reporting errors during decoding with appropriate safety checks and path tracking.
227-238: Thoughtful handling of unknown enum casesThe
UnknownNovelValueErrortype elegantly handles API evolution scenarios where new enum values shouldn't trigger error reports. This is particularly useful for maintaining backward compatibility.
Tests/KarrotCodableKitTests/BetterCodable/DataValue/DataValueResilientTests.swift
Show resolved
Hide resolved
Tests/KarrotCodableKitTests/BetterCodable/DataValue/DataValueResilientTests.swift
Show resolved
Hide resolved
Tests/KarrotCodableKitTests/BetterCodable/DataValue/DataValueResilientTests.swift
Show resolved
Hide resolved
Tests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultCodableResilientTests.swift
Show resolved
Hide resolved
Tests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessValueResilientTests.swift
Show resolved
Hide resolved
Tests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyDictionaryResilientTests.swift
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🔭 Outside diff range comments (1)
README.md (1)
280-281: Consistency: terminate acknowledgement sentence with a period [LOW]All previous bullet items end with a period; add one here for consistency:
- ResilientDecodingErrorReporter was adapted from [airbnb/ResilientDecoding](https://github.com/airbnb/ResilientDecoding) + ResilientDecodingErrorReporter was adapted from [airbnb/ResilientDecoding](https://github.com/airbnb/ResilientDecoding).
📜 Review details
Configuration used: .coderabbit.yml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
README.md(2 hunks)Sources/KarrotCodableKit/PolymorphicCodable/Interface/PolymorphicCodableStrategyProviding.swift(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
Sources/KarrotCodableKit/**
⚙️ CodeRabbit Configuration File
Sources/KarrotCodableKit/**: You are a senior Swift/iOS engineer reviewing runtime library code for KarrotCodableKit, a comprehensive Codable extension framework.1. Codable Performance [HIGH]
- Check encoding/decoding efficiency and memory usage
- Verify proper handling of large JSON structures
- Assess polymorphic type resolution performance
- Review property wrapper overhead and optimization
2. Type Safety & Polymorphism [HIGH]
- Validate PolymorphicCodable identifier-based type resolution
- Check AnyCodable type erasure implementation for edge cases
- Verify UnnestedPolymorphic macro integration with runtime components
- Assess error handling in polymorphic decoding scenarios
3. API Design [HIGH]
- Evaluate public interface consistency across modules
- Check property wrapper ergonomics (@DefaultFalse, @DATEvalue, etc.)
- Verify protocol design follows Swift API guidelines
- Assess extensibility for new Codable patterns
4. BetterCodable Integration [MEDIUM]
- Review property wrapper implementations for common patterns
- Check date strategy implementations (ISO8601, RFC3339, etc.)
- Verify default value and lossy conversion handling
- Assess data encoding strategies (Base64, etc.)
5. Error Handling [MEDIUM]
- Verify comprehensive DecodingError and EncodingError usage
- Check PolymorphicCodableError provides sufficient context
- Assess graceful fallback handling in polymorphic scenarios
Review Focus
- Prioritize runtime correctness and performance over style
- Focus on real-world JSON processing scenarios
- Mark comments with priority: [HIGH], [MEDIUM], or [LOW]
Files:
Sources/KarrotCodableKit/PolymorphicCodable/Interface/PolymorphicCodableStrategyProviding.swift
*
⚙️ CodeRabbit Configuration File
*: You are a senior Swift/iOS engineer with 15+ years of experience reviewing KarrotCodableKit code changes.Review Priorities [HIGH]
- Code quality: memory leaks, error handling, readability (100 chars/line)
- Architecture: SOLID principles, design patterns, DRY/KISS
- Swift best practices: modern features, memory management, performance
Communication
- Mark priority: [HIGH], [MEDIUM], [LOW]
- Provide specific code examples
- Focus on high-impact improvements over style
Files:
README.md
**/*.md
⚙️ CodeRabbit Configuration File
**/*.md: You are a senior technical writer reviewing documentation for KarrotCodableKit, a Swift Codable extension library.1. Technical Accuracy [HIGH]
- Verify code examples compile and work correctly
- Check that API documentation matches actual implementation
- Validate macro usage examples demonstrate proper syntax
- Assess JSON examples are well-formed and realistic
2. Documentation Completeness [HIGH]
- Review coverage of all major features (CustomCodable, PolymorphicCodable, AnyCodable, BetterCodable)
- Check that complex concepts like polymorphic type resolution are well explained
- Verify installation and setup instructions are current
- Assess troubleshooting and error handling guidance
3. User Experience [MEDIUM]
- Evaluate documentation structure and navigation clarity
- Check that examples progress from simple to complex appropriately
- Verify code snippets include necessary imports and context
- Assess whether documentation answers common user questions
Review Focus
- Prioritize accuracy and completeness over style
- Focus on developer experience and practical usage scenarios
- Mark comments with priority: [HIGH], [MEDIUM], or [LOW]
Files:
README.md
🪛 LanguageTool
README.md
[grammar] ~123-~123: Use correct spacing
Context: ...PolymorphicCodable PolymorphicCodable provides functionality to easily decode polymorp...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~123-~123: Use correct spacing
Context: ...ty wrappers like PolymorphicValue and PolymorphicArrayValue. Parameters: - identifierCodingKey: S...
(QB_NEW_EN_OTHER_ERROR_IDS_5)
[grammar] ~126-~126: Use articles correctly
Context: ... to the discriminator.propertyName in OpenAPI Specification's oneOf definition. Defau...
(QB_NEW_EN_OTHER_ERROR_IDS_11)
🪛 markdownlint-cli2 (0.17.2)
README.md
126-126: Lists should be surrounded by blank lines
(MD032, blanks-around-lists)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Build and Test (16.1, release)
- GitHub Check: Build and Test (16.1, debug)
- GitHub Check: Check Macro Compatibility
Sources/KarrotCodableKit/PolymorphicCodable/Interface/PolymorphicCodableStrategyProviding.swift
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: .coderabbit.yml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
.github/workflows/ci.yml(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Build and Test (16.4, debug)
- GitHub Check: Build and Test (16.4, release)
- GitHub Check: Check Macro Compatibility
ppth0608
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍 👍
테스트 코드 위주로 확인했어요.
Background (Required)
silently ignored, making it difficult to debug issues in production
allowing developers to monitor and debug decoding issues without breaking the application
Changes
Testing Methods
behavior
Review Notes
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
oneOfpattern support and discriminator usage.Tests
Style
Chores