Last active
January 26, 2023 18:32
-
-
Save krzyzanowskim/7f2c07a090f762c97be2780c2fea813c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
struct EmojiUnkeyedEncodingContainer : UnkeyedEncodingContainer { | |
// MARK: Properties | |
private(set) public var codingPath: [CodingKey] | |
private var encoder: EmojiEncoder; | |
/// The number of elements encoded into the container. | |
public var count: Int { | |
return 0 | |
} | |
// MARK: - Initialization | |
init(referencing encoder: EmojiEncoder) { | |
codingPath = [] | |
self.encoder = encoder | |
} | |
// MARK: - UnkeyedEncodingContainer Methods | |
public mutating func encodeNil() throws { } | |
public mutating func encode(_ value: Bool) throws { } | |
public mutating func encode(_ value: Int) throws { } | |
public mutating func encode(_ value: Int8) throws { } | |
public mutating func encode(_ value: Int16) throws { } | |
public mutating func encode(_ value: Int32) throws { } | |
public mutating func encode(_ value: Int64) throws { } | |
public mutating func encode(_ value: UInt) throws { } | |
public mutating func encode(_ value: UInt8) throws { } | |
public mutating func encode(_ value: UInt16) throws { } | |
public mutating func encode(_ value: UInt32) throws { } | |
public mutating func encode(_ value: UInt64) throws { } | |
public mutating func encode(_ value: String) throws { | |
encoder.storage += Array(value.utf8) | |
} | |
public mutating func encode(_ value: Float) throws { | |
} | |
public mutating func encode(_ value: Double) throws { | |
} | |
public mutating func encode<T : Encodable>(_ value: T) throws { | |
try value.encode(to: superEncoder()) | |
} | |
public mutating func nestedContainer<NestedKey>(keyedBy keyType: NestedKey.Type) -> KeyedEncodingContainer<NestedKey> { | |
let container = EmojiEncodingContainer<NestedKey>(referencing: self.encoder) | |
return KeyedEncodingContainer(container) | |
} | |
public mutating func nestedUnkeyedContainer() -> UnkeyedEncodingContainer { | |
return EmojiUnkeyedEncodingContainer(referencing: self.encoder) | |
} | |
public mutating func superEncoder() -> Encoder { | |
return EmojiEncoder() | |
} | |
} | |
struct EmojiEncodingContainer<K : CodingKey> : KeyedEncodingContainerProtocol { | |
typealias Key = K | |
private(set) public var codingPath: [CodingKey] | |
private var encoder: EmojiEncoder; | |
init(referencing encoder: EmojiEncoder) { | |
codingPath = [] | |
self.encoder = encoder | |
} | |
// MARK: - KeyedEncodingContainerProtocol Methods | |
public mutating func encodeNil(forKey key: Key) throws { } | |
public mutating func encode(_ value: Bool, forKey key: Key) throws { } | |
public mutating func encode(_ value: Int, forKey key: Key) throws { } | |
public mutating func encode(_ value: Int8, forKey key: Key) throws { } | |
public mutating func encode(_ value: Int16, forKey key: Key) throws { } | |
public mutating func encode(_ value: Int32, forKey key: Key) throws { } | |
public mutating func encode(_ value: Int64, forKey key: Key) throws { } | |
public mutating func encode(_ value: UInt, forKey key: Key) throws { } | |
public mutating func encode(_ value: UInt8, forKey key: Key) throws { } | |
public mutating func encode(_ value: UInt16, forKey key: Key) throws { } | |
public mutating func encode(_ value: UInt32, forKey key: Key) throws { } | |
public mutating func encode(_ value: UInt64, forKey key: Key) throws { } | |
public mutating func encode(_ value: String, forKey key: Key) throws { | |
encoder.storage += Array(value.utf8) | |
} | |
public mutating func encode(_ value: Float, forKey key: Key) throws { | |
} | |
public mutating func encode(_ value: Double, forKey key: Key) throws { | |
} | |
public mutating func encode<T : Encodable>(_ value: T, forKey key: Key) throws { | |
try value.encode(to: superEncoder()) | |
} | |
public mutating func nestedContainer<NestedKey>(keyedBy keyType: NestedKey.Type, forKey key: Key) -> KeyedEncodingContainer<NestedKey> { | |
let container = EmojiEncodingContainer<NestedKey>(referencing: self.encoder) | |
return KeyedEncodingContainer(container) | |
} | |
public mutating func nestedUnkeyedContainer(forKey key: Key) -> UnkeyedEncodingContainer { | |
return EmojiUnkeyedEncodingContainer(referencing: self.encoder) | |
} | |
public mutating func superEncoder() -> Encoder { | |
return EmojiEncoder() | |
} | |
public mutating func superEncoder(forKey key: Key) -> Encoder { | |
return EmojiEncoder() | |
} | |
} | |
public class EmojiEncoder: Encoder { | |
public var codingPath: [CodingKey] | |
public var userInfo: [CodingUserInfoKey : Any] | |
fileprivate(set) var storage: [UInt8] | |
public init() { | |
codingPath = [] | |
userInfo = [:] | |
storage = [UInt8]() | |
} | |
public func container<Key>(keyedBy: Key.Type) -> KeyedEncodingContainer<Key> { | |
let container = EmojiEncodingContainer<Key>(referencing: self) | |
return KeyedEncodingContainer(container) | |
} | |
public func singleValueContainer() -> SingleValueEncodingContainer { | |
return self | |
} | |
public func unkeyedContainer() -> UnkeyedEncodingContainer { | |
return EmojiUnkeyedEncodingContainer(referencing: self) | |
} | |
// | |
public func data() -> Data { | |
return Data(self.storage) | |
} | |
} | |
extension EmojiEncoder : SingleValueEncodingContainer { | |
public func encodeNil() throws { | |
} | |
public func encode(_ value: Bool) throws { | |
} | |
public func encode(_ value: Int) throws { | |
} | |
public func encode(_ value: Int8) throws { | |
} | |
public func encode(_ value: Int16) throws { | |
} | |
public func encode(_ value: Int32) throws { | |
} | |
public func encode(_ value: Int64) throws { | |
} | |
public func encode(_ value: UInt) throws { | |
} | |
public func encode(_ value: UInt8) throws { | |
} | |
public func encode(_ value: UInt16) throws { | |
} | |
public func encode(_ value: UInt32) throws { | |
} | |
public func encode(_ value: UInt64) throws { | |
} | |
public func encode(_ value: String) throws { | |
storage += Array(value.utf8) | |
} | |
public func encode(_ value: Float) throws { | |
} | |
public func encode(_ value: Double) throws { | |
} | |
public func encode<T : Encodable>(_ value: T) throws { | |
try value.encode(to: self) | |
} | |
} | |
// Testing | |
struct Emoji: Encodable { | |
private let value: String | |
init(_ value: String) { | |
self.value = value | |
} | |
} | |
let encoder = EmojiEncoder() | |
try! encoder.encode(Emoji("🥟")) | |
print(Array(encoder.data())) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment