【WIP】apple/swift - stdlib/public/core/Codable.swift.gyb コードリーディング
- 概要
- エンコード
- デコード
概要
https://github.com/apple/swift/blob/master/stdlib/public/core/Codable.swift.gyb
gyb : codable_types
gybによる定義で書かれていて、primitiveな型のみに絞って自動生成される? TBD
codable_types = ['Bool', 'String', 'Double', 'Float', 'Int', 'Int8', 'Int16', 'Int32', 'Int64', 'UInt', 'UInt8', 'UInt16', 'UInt32', 'UInt64']
CodingKey
エンコーディングとデコーディングのキーとして使用できる型とある
文字列と数値によって定義が分かれていて、
文字列
var stringValue: String { get } init?(stringValue: String)
数値
var intValue: Int? { get } init?(intValue: Int)
このようになっていて文字列がkeyは分かりやすいが、数値がkeyのパターンでの用途は珍しいように感じる
CodingKeyを使う場面としてはCodableプロトコルに準拠しつつエンコードorデコード時にkey名が違うような場面で必要になる
まだこの定義だけだとその辺りの組み替えは見受けられないので利用側の定義を見ていきたい
Codable
外部表現の出入りを変えることができる型定義
public typealias Codable = Encodable & Decodable
CodingUserInfoKey
エンコード・デコード時に用いられるユーザー定義key
RawRepresentable
プロトコルに準拠しており、associated typeとしてRawValueにStringを指定しそのままkeyとなる
_DictionaryCodingKey
@usableFromInline // FIXME(sil-serialize-all) @_fixed_layout // FIXME(sil-serialize-all) internal struct _DictionaryCodingKey : CodingKey
Dictionaryのextensionとしてconditional conformanceな以下の定義で利用されている内部コンテナのinternalなkey定義
extension Dictionary : Encodable where Key : Encodable, Value : Encodable extension Dictionary : Decodable where Key : Decodable, Value : Decodable
CodingKeyプロトコルを親としている
このようにDictionaryをEncodable&Decodableに準拠させることでCodableな要素のみを含んだ場合にCodableの枠組みとして扱えるになっている
_GenericIndexKey
@usableFromInline // FIXME(sil-serialize-all) @_fixed_layout // FIXME(sil-serialize-all) internal struct _GenericIndexKey : CodingKey
DecodingErrorで使われているcontainerのindexからkeyとして扱うのに用いられているinternalなkey定義
intValueとstringValueからkeyの値を取る方式のCodingKeyプロトコルのintValueのみをkeyとして扱うように制限を加えられている模様
エンコード
Encodable
外部の表現に自身をエンコードすることができる型
encode
Encodableに定義されている唯一の関数
func encode(to encoder: Encoder) throws
この値を指定されたEncoderにエンコードする
TBD
Encoder
TBD
codingPath
var codingPath: [CodingKey] { get }
エンコード時にこのポイントに到達するために使用されるCodingKeyのパス
userInfo
var userInfo: [CodingUserInfoKey : Any] { get }
エンコーディングのためにユーザーによって設定されたコンテキスト情報
container
func container<Key>(keyedBy type: Key.Type) throws -> KeyedEncodingContainer<Key>
unkeyedContainer
func unkeyedContainer() throws -> UnkeyedEncodingContainer
TBD
singleValueContainer
func singleValueContainer() throws -> SingleValueDecodingContainer
TBD
KeyedEncodingContainerProtocol
TBD
KeyedEncodingContainer<K : CodingKey>
TBD
UnkeyedEncodingContainer
TBD
SingleValueEncodingContainer
TBD
EncodingError
TBD
_KeyedEncodingContainerBase<Key : CodingKey>
TBD
_KeyedEncodingContainerBox<Concrete : KeyedEncodingContainerProtocol>
TBD
デコード
Decodable
外部の表現から自身をデコードすることができる型
decode
Decodableに定義されている唯一の関数
init(from decoder: Decoder) throws
TBD
Decoder
TBD
KeyedDecodingContainerProtocol
TBD
KeyedDecodingContainer<K : CodingKey>
TBD
UnkeyedDecodingContainer
TBD
SingleValueDecodingContainer
TBD
DecodingError
TBD
_KeyedDecodingContainerBase<Key : CodingKey>
TBD
_KeyedDecodingContainerBox<Concrete : KeyedDecodingContainerProtocol>
TBD