Skip to content

Instantly share code, notes, and snippets.

@krzyzanowskim
Last active January 26, 2023 18:32
Show Gist options
  • Save krzyzanowskim/7f2c07a090f762c97be2780c2fea813c to your computer and use it in GitHub Desktop.
Save krzyzanowskim/7f2c07a090f762c97be2780c2fea813c to your computer and use it in GitHub Desktop.
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