Compare commits

...

2 Commits

Author SHA1 Message Date
Matt Bruce
8e2141f749 test trials
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-02-22 15:46:19 -06:00
Matt Bruce
673cf69e20 first cut for fixing issue with codable for complex enums
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2024-02-22 12:13:36 -06:00

View File

@ -25,8 +25,6 @@ extension VDS.Tabs.Overflow: Codable {}
extension VDS.Tabs.Size: Codable {}
extension VDS.TextLink.Size: Codable {}
extension VDS.TextLinkCaret.IconPosition: Codable {}
extension VDS.TileContainer.BackgroundColor: Codable {}
extension VDS.TileContainer.Padding: Codable {}
extension VDS.TileContainer.AspectRatio: Codable {}
extension VDS.Tooltip.FillColor: Codable {}
extension VDS.Tooltip.Size: Codable {}
@ -61,3 +59,267 @@ extension DecodableDefault {
public typealias BlackColor = Wrapper<Sources.BlackColor>
public typealias Surface = Wrapper<Sources.Surface>
}
//extension VDS.TileContainer.BackgroundColor: Codable {
// public func encode(to encoder: Encoder) throws {
// var container = encoder.singleValueContainer()
// switch self {
// case .custom(let value):
// try container.encode(value)
// default:
// try container.encode(String(reflecting: self))
// }
// }
//
// // Init from decoder to handle the decoding based on the type
// public init(from decoder: Decoder) throws {
// let container = try decoder.singleValueContainer()
// let type = try container.decode(String.self)
// switch type {
// case "primary":
// self = .primary
// case "secondary":
// self = .secondary
// case "white":
// self = .white
// case "black":
// self = .black
// default:
// self = .custom(type)
// }
// }
//}
//extension VDS.TileContainer.Padding: Codable {
// enum PaddingError: Error {
// case valueNotFound(type: String)
// }
// public func encode(to encoder: Encoder) throws {
// var container = encoder.singleValueContainer()
// switch self {
// case .custom(let value):
// try container.encode(value)
// default:
// try container.encode(String(reflecting: self))
// }
// }
//
// // Init from decoder to handle the decoding based on the type
// public init(from decoder: Decoder) throws {
// let container = try decoder.singleValueContainer()
// do {
// let type = try container.decode(String.self)
// switch type {
// case "padding2X":
// self = .padding2X
// case "padding4X":
// self = .padding4X
// case "padding6X":
// self = .padding6X
// case "padding8X":
// self = .padding8X
// case "padding12X":
// self = .padding12X
// default:
// throw PaddingError.valueNotFound(type: type)
// }
// } catch PaddingError.valueNotFound(let type) {
// throw PaddingError.valueNotFound(type: type)
// } catch {
// let type = try container.decode(CGFloat.self)
// self = .custom(type)
// }
// }
//}
public protocol CustomEnumCodable: Codable {
associatedtype CustomValueType: Codable
init(custom value: CustomValueType)
var customValue: CustomValueType? { get }
var stringValue: String { get }
init?(stringValue: String)
}
extension CustomEnumCodable {
public var stringValue: String {
let mirror = Mirror(reflecting: self)
if mirror.children.isEmpty {
return String(describing: self)
} else {
for child in mirror.children {
if let label = child.label, label == "custom" {
return label
}
}
return "custom"
}
}
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let customValueType = try? container.decode(CustomValueType.self) {
self.init(custom: customValueType)
} else {
let stringValue = try container.decode(String.self)
if let instance = Self(stringValue: stringValue) {
self = instance
} else {
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Unknown value")
}
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
if let customValue {
try container.encode(customValue)
} else {
try container.encode(self.stringValue)
}
}
}
//extension VDS.TileContainer.Padding: CustomEnumCodable {
//
// public var customValue: CGFloat? {
// if case .custom(let value) = self { value } else { nil }
// }
//
// public init(custom value: CGFloat) {
// self = .custom(value)
// }
//
// public init?(stringValue: String) {
// switch stringValue {
// case "padding2X":
// self = .padding2X
// case "padding4X":
// self = .padding4X
// case "padding6X":
// self = .padding6X
// case "padding8X":
// self = .padding8X
// case "padding12X":
// self = .padding12X
// default:
// return nil
// }
// }
//}
//
//extension VDS.TileContainer.BackgroundColor: CustomEnumCodable {
// public var customValue: String? {
// if case .custom(let value) = self { value } else { nil }
// }
//
// public init(custom value: String) {
// self = .custom(value)
// }
//
// public init?(stringValue: String) {
// switch stringValue {
// case "primary":
// self = .primary
// case "secondary":
// self = .secondary
// case "white":
// self = .white
// case "black":
// self = .black
// default:
// return nil
// }
// }
//}
public protocol EnumCodable: Codable {
associatedtype AssociatedValueType: Codable
var typeName: String { get }
var associatedValue: AssociatedValueType? { get }
init?(typeName: String, associatedValue: AssociatedValueType?)
}
extension EnumCodable {
public var typeName: String {
let mirror = Mirror(reflecting: self)
if mirror.children.isEmpty {
return String(describing: self)
} else {
return mirror.children.first?.label ?? "custom"
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: EnumCodableCodingKeys.self)
try container.encode(typeName, forKey: .type)
if let value = associatedValue {
try container.encode(value, forKey: .value)
}
}
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: EnumCodableCodingKeys.self)
let typeName = try container.decode(String.self, forKey: .type)
let value = try container.decodeIfPresent(AssociatedValueType.self, forKey: .value)
if let instance = Self(typeName: typeName, associatedValue: value) {
self = instance
} else {
throw DecodingError.dataCorruptedError(forKey: .type, in: container, debugDescription: "Cannot initialize \(Self.self) from typeName \(typeName)")
}
}
}
enum EnumCodableCodingKeys: String, CodingKey {
case type
case value
}
extension VDS.TileContainer.Padding: EnumCodable {
public var associatedValue: CGFloat? {
if case .custom(let value) = self { value } else { nil }
}
public init?(typeName: String, associatedValue: CGFloat?) {
switch typeName {
case "padding2X":
self = .padding2X
case "padding4X":
self = .padding4X
case "padding6X":
self = .padding6X
case "padding8X":
self = .padding8X
case "padding12X":
self = .padding12X
case "custom":
guard let associatedValue else { return nil }
self = .custom(associatedValue)
default: return nil
}
}
}
extension VDS.TileContainer.BackgroundColor: EnumCodable {
public var associatedValue: String? {
if case .custom(let value) = self { value } else { nil }
}
public init?(typeName: String, associatedValue: String?) {
switch typeName {
case "primary":
self = .primary
case "secondary":
self = .secondary
case "white":
self = .white
case "black":
self = .black
case "custom":
guard let associatedValue else { return nil }
self = .custom(associatedValue)
default: return nil
}
}
}