@@ -42,14 +42,37 @@ public struct RefDict<Root: ReferenceRoot, Name: RefName, RefType: Equatable & C
4242/// A Reference is the combination of
4343/// a path to a reference dictionary
4444/// and a selector that the dictionary is keyed off of.
45- public enum JSONReference < Root: ReferenceRoot , RefType: Equatable > : Equatable {
45+ public enum JSONReference < Root: ReferenceRoot , RefType: Equatable > : Equatable , CustomStringConvertible {
4646
47- case node( InternalReference )
48- case file( FileReference )
47+ case `internal`( Local )
48+ case external( FileReference , Local ? )
49+
50+ public static func external( _ ref: FileReference ) -> JSONReference {
51+ let parts = ref. split ( separator: " # " )
52+
53+ return . external( String ( parts [ 0 ] ) , parts. count > 1 ? . unsafe( " # " + String( parts [ 1 ] ) ) : nil )
54+ }
4955
5056 public typealias FileReference = String
5157
52- public struct InternalReference : Equatable {
58+ public enum Local : Equatable , CustomStringConvertible {
59+ case node( InternalReference )
60+ case unsafe( String )
61+
62+ public var description : String {
63+ switch self {
64+ case . node( let reference) :
65+ return reference. description
66+ case . unsafe( let string) :
67+ guard string. starts ( with: " # " ) else {
68+ return " #/ " + string
69+ }
70+ return string
71+ }
72+ }
73+ }
74+
75+ public struct InternalReference : Equatable , CustomStringConvertible {
5376 public let path : PartialKeyPath < Root >
5477 public let selector : String
5578
@@ -64,6 +87,19 @@ public enum JSONReference<Root: ReferenceRoot, RefType: Equatable>: Equatable {
6487 self . path = type
6588 self . selector = selector
6689 }
90+
91+ public var description : String {
92+ return " #/ \( Root . refName) / \( refName) / \( selector) "
93+ }
94+ }
95+
96+ public var description : String {
97+ switch self {
98+ case . external( let file, let path) :
99+ return path. map { file + $0. description } ?? file
100+ case . internal( let reference) :
101+ return reference. description
102+ }
67103 }
68104}
69105
@@ -79,16 +115,7 @@ extension JSONReference: Encodable {
79115 public func encode( to encoder: Encoder ) throws {
80116 var container = encoder. container ( keyedBy: CodingKeys . self)
81117
82- let referenceString : String = {
83- switch self {
84- case . file( let reference) :
85- return reference
86- case . node( let reference) :
87- return " #/ \( Root . refName) / \( reference. refName) / \( reference. selector) "
88- }
89- } ( )
90-
91- try container. encode ( referenceString, forKey: . ref)
118+ try container. encode ( description, forKey: . ref)
92119 }
93120}
94121
@@ -99,10 +126,10 @@ extension JSONReference: Decodable {
99126 let referenceString = try container. decode ( String . self, forKey: . ref)
100127
101128 if referenceString. first == " # " {
102- // TODO: parse local ref
103- fatalError ( " not implemented " )
129+ // TODO: try to parse ref to components
130+ self = . internal ( . unsafe ( referenceString ) )
104131 } else {
105- self = . file ( referenceString)
132+ self = . external ( referenceString)
106133 }
107134 }
108135}
0 commit comments