@@ -27,9 +27,9 @@ public enum JSONValue: Equatable {
2727 /// An object containing JSON values and `null` values keyed by strings.
2828 case object( _ properties: JSONObject )
2929
30- /// Initializes a JSON value representing the given string .
31- public init ( _ string : String ) {
32- self = . string ( string )
30+ /// Initializes a JSON value representing the given JSON value–convertible instance .
31+ public init ( _ value : JSONValueConvertible ) {
32+ self = value . jsonValue
3333 }
3434
3535 /**
@@ -38,27 +38,22 @@ public enum JSONValue: Equatable {
3838 - parameter number: An integer. JSON does not distinguish numeric types of different precisions, so the integer is stored as a floating-point number.
3939 */
4040 public init < Source> ( _ number: Source ) where Source: BinaryInteger {
41- self = . number ( Double ( number) )
41+ self . init ( Double ( number) )
4242 }
4343
4444 /// Initializes a JSON value representing the given floating-point number.
4545 public init < Source> ( _ number: Source ) where Source: BinaryFloatingPoint {
46- self = . number ( Double ( number) )
46+ self . init ( Double ( number) )
4747 }
4848
49- /// Initializes a JSON value representing the given Boolean value .
50- public init ( _ bool : Bool ) {
51- self = . boolean ( bool )
49+ /// Initializes a JSON value representing the given JSON-convertible array .
50+ public init ( _ values : [ JSONValueConvertible ? ] ) {
51+ self = . array ( JSONArray ( values ) )
5252 }
5353
54- /// Initializes a JSON value representing the given JSON array.
55- public init ( _ values: JSONArray ) {
56- self = . array( values)
57- }
58-
59- /// Initializes a JSON value representing the given JSON object.
60- public init ( _ properties: JSONObject ) {
61- self = . object( properties)
54+ /// Initializes a JSON value representing the given JSON-convertible object.
55+ public init ( _ properties: [ String : JSONValueConvertible ? ] ) {
56+ self = . object( JSONObject ( properties) )
6257 }
6358}
6459
@@ -105,6 +100,13 @@ extension JSONValue: RawRepresentable {
105100 */
106101public typealias JSONArray = [ JSONValue ? ]
107102
103+ extension JSONArray {
104+ public init ( _ elements: [ JSONValueConvertible ? ] ) {
105+ let values = elements. map { $0? . jsonValue }
106+ self . init ( values)
107+ }
108+ }
109+
108110extension JSONArray : RawRepresentable {
109111 public typealias RawValue = [ Any ? ]
110112
@@ -122,6 +124,12 @@ extension JSONArray: RawRepresentable {
122124 */
123125public typealias JSONObject = [ String : JSONValue ? ]
124126
127+ extension JSONObject {
128+ public init ( _ elements: [ String : JSONValueConvertible ? ] ) {
129+ self . init ( uniqueKeysWithValues: elements. map { ( $0. 0 , $0. 1 ? . jsonValue) } )
130+ }
131+ }
132+
125133extension JSONObject : RawRepresentable {
126134 public typealias RawValue = [ String : Any ? ]
127135
@@ -136,42 +144,42 @@ extension JSONObject: RawRepresentable {
136144
137145extension JSONValue : ExpressibleByStringLiteral {
138146 public init ( stringLiteral value: StringLiteralType ) {
139- self = . init( value)
147+ self . init ( value)
140148 }
141149}
142150
143151extension JSONValue : ExpressibleByIntegerLiteral {
144152 public init ( integerLiteral value: IntegerLiteralType ) {
145- self = . init( value)
153+ self . init ( value)
146154 }
147155}
148156
149157extension JSONValue : ExpressibleByFloatLiteral {
150158 public init ( floatLiteral value: FloatLiteralType ) {
151- self = . init( value)
159+ self . init ( value)
152160 }
153161}
154162
155163extension JSONValue : ExpressibleByBooleanLiteral {
156164 public init ( booleanLiteral value: BooleanLiteralType ) {
157- self = . init( value)
165+ self . init ( value)
158166 }
159167}
160168
161169extension JSONValue : ExpressibleByArrayLiteral {
162- public typealias ArrayLiteralElement = JSONValue ?
170+ public typealias ArrayLiteralElement = JSONValueConvertible ?
163171
164172 public init ( arrayLiteral elements: ArrayLiteralElement ... ) {
165- self = . init( elements)
173+ self . init ( elements)
166174 }
167175}
168176
169177extension JSONValue : ExpressibleByDictionaryLiteral {
170178 public typealias Key = String
171- public typealias Value = JSONValue ?
179+ public typealias Value = JSONValueConvertible ?
172180
173181 public init ( dictionaryLiteral elements: ( Key , Value ) ... ) {
174- self = . init ( . init ( uniqueKeysWithValues: elements) )
182+ self = . object ( JSONObject ( uniqueKeysWithValues: elements. map { ( $0 . 0 , $0 . 1 ? . jsonValue ) } ) )
175183 }
176184}
177185
@@ -209,3 +217,39 @@ extension JSONValue: Codable {
209217 }
210218 }
211219}
220+
221+ /**
222+ A type that can be represented as a `JSONValue` instance.
223+ */
224+ public protocol JSONValueConvertible {
225+ /// The instance wrapped in a `JSONValue` instance.
226+ var jsonValue : JSONValue { get }
227+ }
228+
229+ extension String : JSONValueConvertible {
230+ public var jsonValue : JSONValue { return . string( self ) }
231+ }
232+
233+ extension Int : JSONValueConvertible {
234+ public var jsonValue : JSONValue { return . number( Double ( self ) ) }
235+ }
236+
237+ extension Double : JSONValueConvertible {
238+ public var jsonValue : JSONValue { return . number( Double ( self ) ) }
239+ }
240+
241+ extension Bool : JSONValueConvertible {
242+ public var jsonValue : JSONValue { return . boolean( self ) }
243+ }
244+
245+ extension Array : JSONValueConvertible where Element == JSONValueConvertible ? {
246+ public var jsonValue : JSONValue {
247+ return . array( map { $0? . jsonValue } )
248+ }
249+ }
250+
251+ extension Dictionary : JSONValueConvertible where Key == String , Value == JSONValueConvertible ? {
252+ public var jsonValue : JSONValue {
253+ return . object( JSONObject ( uniqueKeysWithValues: map { ( $0. 0 , $0. 1 ? . jsonValue) } ) )
254+ }
255+ }
0 commit comments