Simplify `YAMLEncoder`
- Rename `ScalarRepresentableCustomizedForCodable` to `YAMLEncodable` - Replace methods required by protocol with generic methods
This commit is contained in:
parent
3041d16db2
commit
18e173301d
|
@ -81,17 +81,6 @@ private class _Encoder: Swift.Encoder {
|
|||
set { node.sequence = newValue }
|
||||
}
|
||||
|
||||
/// Encode `ScalarRepresentable` to `node`
|
||||
func represent<T: ScalarRepresentable>(_ value: T) throws {
|
||||
assertCanEncodeNewValue()
|
||||
node = try box(value)
|
||||
}
|
||||
|
||||
func represent<T: ScalarRepresentableCustomizedForCodable>(_ value: T) throws {
|
||||
assertCanEncodeNewValue()
|
||||
node = value.representedForCodable()
|
||||
}
|
||||
|
||||
/// create a new `_ReferencingEncoder` instance as `key` inheriting `userInfo`
|
||||
func encoder(for key: CodingKey) -> _ReferencingEncoder {
|
||||
return .init(referencing: self, key: key)
|
||||
|
@ -102,19 +91,6 @@ private class _Encoder: Swift.Encoder {
|
|||
return .init(referencing: self, at: index)
|
||||
}
|
||||
|
||||
/// Create `Node` from `ScalarRepresentable`.
|
||||
/// Errors throwed by `ScalarRepresentable` will be boxed into `EncodingError`
|
||||
private func box(_ representable: ScalarRepresentable) throws -> Node {
|
||||
do {
|
||||
return try representable.represented()
|
||||
} catch {
|
||||
let context = EncodingError.Context(codingPath: codingPath,
|
||||
debugDescription: "Unable to encode the given value to YAML.",
|
||||
underlyingError: error)
|
||||
throw EncodingError.invalidValue(representable, context)
|
||||
}
|
||||
}
|
||||
|
||||
private var canEncodeNewValue: Bool { return node == .unused }
|
||||
}
|
||||
|
||||
|
@ -157,22 +133,9 @@ private struct _KeyedEncodingContainer<Key: CodingKey> : KeyedEncodingContainerP
|
|||
// MARK: - Swift.KeyedEncodingContainerProtocol Methods
|
||||
|
||||
var codingPath: [CodingKey] { return encoder.codingPath }
|
||||
func encodeNil(forKey key: Key) throws { encoder.mapping[key.stringValue] = .null }
|
||||
func encode(_ value: Bool, forKey key: Key) throws { try encoder(for: key).represent(value) }
|
||||
func encode(_ value: Int, forKey key: Key) throws { try encoder(for: key).represent(value) }
|
||||
func encode(_ value: Int8, forKey key: Key) throws { try encoder(for: key).represent(value) }
|
||||
func encode(_ value: Int16, forKey key: Key) throws { try encoder(for: key).represent(value) }
|
||||
func encode(_ value: Int32, forKey key: Key) throws { try encoder(for: key).represent(value) }
|
||||
func encode(_ value: Int64, forKey key: Key) throws { try encoder(for: key).represent(value) }
|
||||
func encode(_ value: UInt, forKey key: Key) throws { try encoder(for: key).represent(value) }
|
||||
func encode(_ value: UInt8, forKey key: Key) throws { try encoder(for: key).represent(value) }
|
||||
func encode(_ value: UInt16, forKey key: Key) throws { try encoder(for: key).represent(value) }
|
||||
func encode(_ value: UInt32, forKey key: Key) throws { try encoder(for: key).represent(value) }
|
||||
func encode(_ value: UInt64, forKey key: Key) throws { try encoder(for: key).represent(value) }
|
||||
func encode(_ value: Float, forKey key: Key) throws { try encoder(for: key).represent(value) }
|
||||
func encode(_ value: Double, forKey key: Key) throws { try encoder(for: key).represent(value) }
|
||||
func encode(_ value: String, forKey key: Key) throws { encoder.mapping[key.stringValue] = Node(value) }
|
||||
func encode<T>(_ value: T, forKey key: Key) throws where T: Encodable { try encoder(for: key).encode(value) }
|
||||
func encodeNil(forKey key: Key) throws { encoder.mapping[key.stringValue] = .null }
|
||||
func encode<T>(_ value: T, forKey key: Key) throws where T: YAMLEncodable { try encoder(for: key).encode(value) }
|
||||
func encode<T>(_ value: T, forKey key: Key) throws where T: Encodable { try encoder(for: key).encode(value) }
|
||||
|
||||
func nestedContainer<NestedKey>(keyedBy type: NestedKey.Type,
|
||||
forKey key: Key) -> KeyedEncodingContainer<NestedKey> {
|
||||
|
@ -202,22 +165,9 @@ private struct _UnkeyedEncodingContainer: UnkeyedEncodingContainer {
|
|||
|
||||
var codingPath: [CodingKey] { return encoder.codingPath }
|
||||
var count: Int { return encoder.sequence.count }
|
||||
func encodeNil() throws { encoder.sequence.append(.null) }
|
||||
func encode(_ value: Bool) throws { try currentEncoder.represent(value) }
|
||||
func encode(_ value: Int) throws { try currentEncoder.represent(value) }
|
||||
func encode(_ value: Int8) throws { try currentEncoder.represent(value) }
|
||||
func encode(_ value: Int16) throws { try currentEncoder.represent(value) }
|
||||
func encode(_ value: Int32) throws { try currentEncoder.represent(value) }
|
||||
func encode(_ value: Int64) throws { try currentEncoder.represent(value) }
|
||||
func encode(_ value: UInt) throws { try currentEncoder.represent(value) }
|
||||
func encode(_ value: UInt8) throws { try currentEncoder.represent(value) }
|
||||
func encode(_ value: UInt16) throws { try currentEncoder.represent(value) }
|
||||
func encode(_ value: UInt32) throws { try currentEncoder.represent(value) }
|
||||
func encode(_ value: UInt64) throws { try currentEncoder.represent(value) }
|
||||
func encode(_ value: Float) throws { try currentEncoder.represent(value) }
|
||||
func encode(_ value: Double) throws { try currentEncoder.represent(value) }
|
||||
func encode(_ value: String) throws { encoder.sequence.append(Node(value)) }
|
||||
func encode<T>(_ value: T) throws where T: Encodable { try currentEncoder.encode(value) }
|
||||
func encodeNil() throws { encoder.sequence.append(.null) }
|
||||
func encode<T>(_ value: T) throws where T: YAMLEncodable { try currentEncoder.encode(value) }
|
||||
func encode<T>(_ value: T) throws where T: Encodable { try currentEncoder.encode(value) }
|
||||
|
||||
func nestedContainer<NestedKey>(keyedBy type: NestedKey.Type) -> KeyedEncodingContainer<NestedKey> {
|
||||
return currentEncoder.container(keyedBy: type)
|
||||
|
@ -243,31 +193,15 @@ extension _Encoder: SingleValueEncodingContainer {
|
|||
node = .null
|
||||
}
|
||||
|
||||
func encode(_ value: Bool) throws { try represent(value) }
|
||||
func encode(_ value: Int) throws { try represent(value) }
|
||||
func encode(_ value: Int8) throws { try represent(value) }
|
||||
func encode(_ value: Int16) throws { try represent(value) }
|
||||
func encode(_ value: Int32) throws { try represent(value) }
|
||||
func encode(_ value: Int64) throws { try represent(value) }
|
||||
func encode(_ value: UInt) throws { try represent(value) }
|
||||
func encode(_ value: UInt8) throws { try represent(value) }
|
||||
func encode(_ value: UInt16) throws { try represent(value) }
|
||||
func encode(_ value: UInt32) throws { try represent(value) }
|
||||
func encode(_ value: UInt64) throws { try represent(value) }
|
||||
func encode(_ value: Float) throws { try represent(value) }
|
||||
func encode(_ value: Double) throws { try represent(value) }
|
||||
|
||||
func encode(_ value: String) throws {
|
||||
func encode<T>(_ value: T) throws where T: YAMLEncodable {
|
||||
assertCanEncodeNewValue()
|
||||
node = Node(value)
|
||||
node = value.box()
|
||||
}
|
||||
|
||||
func encode<T>(_ value: T) throws where T: Encodable {
|
||||
assertCanEncodeNewValue()
|
||||
if let customized = value as? ScalarRepresentableCustomizedForCodable {
|
||||
node = customized.representedForCodable()
|
||||
} else if let representable = value as? ScalarRepresentable {
|
||||
node = try box(representable)
|
||||
if let encodable = value as? YAMLEncodable {
|
||||
node = encodable.box()
|
||||
} else {
|
||||
try value.encode(to: self)
|
||||
}
|
||||
|
|
|
@ -219,25 +219,52 @@ extension String: ScalarRepresentable {
|
|||
|
||||
/// MARK: - ScalarRepresentableCustomizedForCodable
|
||||
|
||||
public protocol ScalarRepresentableCustomizedForCodable: ScalarRepresentable {
|
||||
func representedForCodable() -> Node
|
||||
public protocol YAMLEncodable: Encodable {
|
||||
func box() -> Node
|
||||
}
|
||||
|
||||
extension Date: ScalarRepresentableCustomizedForCodable {
|
||||
public func representedForCodable() -> Node {
|
||||
extension YAMLEncodable where Self: ScalarRepresentable {
|
||||
public func box() -> Node {
|
||||
return .scalar(represented())
|
||||
}
|
||||
}
|
||||
|
||||
extension Bool: YAMLEncodable {}
|
||||
extension Data: YAMLEncodable {}
|
||||
extension Decimal: YAMLEncodable {}
|
||||
extension Int: YAMLEncodable {}
|
||||
extension Int8: YAMLEncodable {}
|
||||
extension Int16: YAMLEncodable {}
|
||||
extension Int32: YAMLEncodable {}
|
||||
extension Int64: YAMLEncodable {}
|
||||
extension UInt: YAMLEncodable {}
|
||||
extension UInt8: YAMLEncodable {}
|
||||
extension UInt16: YAMLEncodable {}
|
||||
extension UInt32: YAMLEncodable {}
|
||||
extension UInt64: YAMLEncodable {}
|
||||
extension URL: YAMLEncodable {}
|
||||
extension String: YAMLEncodable {}
|
||||
|
||||
extension Date: YAMLEncodable {
|
||||
public func box() -> Node {
|
||||
return Node(iso8601StringWithFullNanosecond, Tag(.timestamp))
|
||||
}
|
||||
}
|
||||
|
||||
extension Double: ScalarRepresentableCustomizedForCodable {}
|
||||
extension Float: ScalarRepresentableCustomizedForCodable {}
|
||||
|
||||
extension FloatingPoint where Self: CVarArg {
|
||||
public func representedForCodable() -> Node {
|
||||
extension Double: YAMLEncodable {
|
||||
public func box() -> Node {
|
||||
return Node(formattedStringForCodable, Tag(.float))
|
||||
}
|
||||
}
|
||||
|
||||
private var formattedStringForCodable: String {
|
||||
extension Float: YAMLEncodable {
|
||||
public func box() -> Node {
|
||||
return Node(formattedStringForCodable, Tag(.float))
|
||||
}
|
||||
}
|
||||
|
||||
private extension FloatingPoint where Self: CVarArg {
|
||||
var formattedStringForCodable: String {
|
||||
// Since `NumberFormatter` creates a string with insufficient precision for Decode,
|
||||
// it uses with `String(format:...)`
|
||||
#if os(Linux)
|
||||
|
@ -252,3 +279,11 @@ extension FloatingPoint where Self: CVarArg {
|
|||
return string
|
||||
}
|
||||
}
|
||||
|
||||
@available(*, unavailable, renamed: "YAMLEncodable")
|
||||
typealias ScalarRepresentableCustomizedForCodable = YAMLEncodable
|
||||
|
||||
extension YAMLEncodable {
|
||||
@available(*, unavailable, renamed: "box()")
|
||||
func representedForCodable() -> Node { fatalError("unreachable") }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue