SwiftyLab / MetaCodable

Supercharge Swift's Codable implementations with macros meta-programming.
https://swiftpackageindex.com/SwiftyLab/MetaCodable/main/documentation/metacodable
MIT License
629 stars 23 forks source link

[Feature Request] Support convert JSON fields to the types of my Swift objects automatically, without me having to manually add @CodedBy. #93

Open zy19890102 opened 4 months ago

zy19890102 commented 4 months ago

I want to replace the previous tool with it. However, I am facing an issue now. My Swift object data comes from many different APIs, and the same field from different APIs may have different data types. The previous tool automatically converted them to the desired data types for me. I don't know which fields need to be marked with @CodedBy because there are too many such fields, and it's difficult to identify them manually. Can you provide a feature to automatically convert the data types to the desired types?

Moreover, many APIs have not been maintained for a long time, making it difficult to determine the specific data types.

soumyamahunt commented 1 month ago

Same as discussed #51 while I am not in favour of the approach suggested in #51.

I think such feature could be implemented in a more generic way, i.e. a new parameter commonStrategies could be introduced in @Codable macro which accepts such strategies which can be applied to all the properties. The API definitions

in MetaCodable:

...
public macro Codable(commonStrategies: [CodableCommonStrategy] = []) = ...

public struct CodableCommonStrategy {
    package init() {} // package access level to only allow strategies handled by MetaCodable
}

in HelperCoders:

extension CodableCommonStrategy {
    public static func codedBy(_ helperCoderStrategy: HelperCoderStrategy) -> Self {
        return .init()
    }

    // additional strategies can be added in future

    public enum HelperCoderStrategy {
        case valueCoder(_ additionalTypes: [any ValueCodingStrategy] = []) // additionalTypes can be used to pass custom ValueCodingStrategy implementations, by default only library provided ValueCodingStrategy implementation will be used
        // additional helpercoder cases can be added in future
    }
}

The current macro usage:

@Codable
fileprivate struct Model {
    @CodedBy(ValueCoder<Bool>())
    let bool: Bool
    @CodedBy(ValueCoder<Int>())
    let int: Int
    @CodedBy(ValueCoder<Double>())
    let double: Double
    @CodedBy(ValueCoder<String>())
    let string: String
}

converts to this:

@Codable(commonStrategies: [.codedBy(.valueCoder())])
fileprivate struct Model {
    let bool: Bool
    let int: Int
    let double: Double
    let string: String
}

@wzio @zy19890102 let me know your thoughts on this approach.