diff --git a/Sources/JSONAST/JSON.Node.swift b/Sources/JSONAST/JSON.Node.swift index 831dac1..8fad977 100644 --- a/Sources/JSONAST/JSON.Node.swift +++ b/Sources/JSONAST/JSON.Node.swift @@ -231,6 +231,15 @@ extension JSON.Node { @inlinable public func `as`(_: Float.Type) -> Float? { self.as(JSON.Number.self)?.as(Float.self) } + /// Attempts to load an instance of ``Float16`` from this variant. + /// + /// - Returns: + /// The closest value of ``Float16`` to the payload of this variant if it matches + /// ``number(_:) [case]``, `nil` otherwise. + @available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *) + @inlinable public func `as`(_: Float16.Type) -> Float16? { + self.as(JSON.Number.self)?.as(Float16.self) + } /// Attempts to load an instance of ``Number`` from this variant. /// /// - Returns: diff --git a/Sources/JSONAST/JSON.Number.swift b/Sources/JSONAST/JSON.Number.swift index b8baa78..d48aa4b 100644 --- a/Sources/JSONAST/JSON.Number.swift +++ b/Sources/JSONAST/JSON.Number.swift @@ -158,6 +158,12 @@ extension JSON.Number { public func `as`(_: Float.Type) -> Float { self.nearest(Float.self) } + /// Converts this numeric literal to a ``Float16`` value, or its closest + /// floating-point representation. + @available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *) + public func `as`(_: Float16.Type) -> Float16 { + self.nearest(Float16.self) + } /// Converts this numeric literal to a floating-point value, or its closest /// floating-point representation. diff --git a/Sources/JSONDecoding/Conformances/Float16 (ext).swift b/Sources/JSONDecoding/Conformances/Float16 (ext).swift new file mode 100644 index 0000000..e05d061 --- /dev/null +++ b/Sources/JSONDecoding/Conformances/Float16 (ext).swift @@ -0,0 +1,6 @@ +@available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *) +extension Float16: JSONDecodable { + @inlinable public init(json: JSON.Node) throws { + self = try json.cast { $0.as(Self.self) } + } +} diff --git a/Sources/JSONDecoding/JSONDecodable.swift b/Sources/JSONDecoding/JSONDecodable.swift index bf5f964..e02085e 100644 --- a/Sources/JSONDecoding/JSONDecodable.swift +++ b/Sources/JSONDecoding/JSONDecodable.swift @@ -15,6 +15,29 @@ extension JSONDecodable where Self: UnsignedInteger & FixedWidthInteger { self = try json.cast { try $0.as(Self.self) } } } +#if (os(Linux) || os(macOS)) && arch(x86_64) +extension JSONDecodable where Self == Float80 { + @inlinable public init(json: JSON.Node) throws { + self = try json.cast { $0.as(Self.self) } + } +} +#endif +extension JSONDecodable where Self == Double { + @inlinable public init(json: JSON.Node) throws { + self = try json.cast { $0.as(Self.self) } + } +} +extension JSONDecodable where Self == Float { + @inlinable public init(json: JSON.Node) throws { + self = try json.cast { $0.as(Self.self) } + } +} +@available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *) +extension JSONDecodable where Self == Float16 { + @inlinable public init(json: JSON.Node) throws { + self = try json.cast { $0.as(Self.self) } + } +} extension JSONDecodable where Self: RawRepresentable, RawValue: JSONDecodable & Sendable { @inlinable public init(json: JSON.Node) throws { let rawValue: RawValue = try .init(json: json) diff --git a/Sources/JSONEncoding/Conformances/Double (ext).swift b/Sources/JSONEncoding/Conformances/Double (ext).swift new file mode 100644 index 0000000..02ef479 --- /dev/null +++ b/Sources/JSONEncoding/Conformances/Double (ext).swift @@ -0,0 +1,2 @@ +extension Double: JSONEncodable { +} diff --git a/Sources/JSONEncoding/Conformances/Float (ext).swift b/Sources/JSONEncoding/Conformances/Float (ext).swift new file mode 100644 index 0000000..4ba767c --- /dev/null +++ b/Sources/JSONEncoding/Conformances/Float (ext).swift @@ -0,0 +1,2 @@ +extension Float: JSONEncodable { +} diff --git a/Sources/JSONEncoding/Conformances/Float16 (ext).swift b/Sources/JSONEncoding/Conformances/Float16 (ext).swift new file mode 100644 index 0000000..ceef6ca --- /dev/null +++ b/Sources/JSONEncoding/Conformances/Float16 (ext).swift @@ -0,0 +1,3 @@ +@available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *) +extension Float16: JSONEncodable { +} diff --git a/Sources/JSONEncoding/Conformances/Float80 (ext).swift b/Sources/JSONEncoding/Conformances/Float80 (ext).swift new file mode 100644 index 0000000..ab5e434 --- /dev/null +++ b/Sources/JSONEncoding/Conformances/Float80 (ext).swift @@ -0,0 +1,4 @@ +#if (os(Linux) || os(macOS)) && arch(x86_64) +extension Float80: JSONEncodable { +} +#endif diff --git a/Sources/JSONEncoding/Encoders/JSON.Literal (ext).swift b/Sources/JSONEncoding/Encoders/JSON.Literal (ext).swift index 522c4fb..c6476ab 100644 --- a/Sources/JSONEncoding/Encoders/JSON.Literal (ext).swift +++ b/Sources/JSONEncoding/Encoders/JSON.Literal (ext).swift @@ -12,8 +12,8 @@ extension JSON.Literal { json.utf8 += (self.value ? "true" : "false").utf8 } } -extension JSON.Literal where Value: BinaryInteger { - /// Encodes this literal’s integer ``value`` to the provided JSON stream. The value’s +extension JSON.Literal where Value: Numeric & CustomStringConvertible { + /// Encodes this literal’s numeric ``value`` to the provided JSON stream. The value’s /// ``CustomStringConvertible description`` witness must format the value in base-10. @inlinable internal static func += (json: inout JSON, self: Self) { json.utf8 += self.value.description.utf8 diff --git a/Sources/JSONEncoding/JSONEncodable.swift b/Sources/JSONEncoding/JSONEncodable.swift index 07a49b5..f0e9ae8 100644 --- a/Sources/JSONEncoding/JSONEncodable.swift +++ b/Sources/JSONEncoding/JSONEncodable.swift @@ -9,7 +9,7 @@ extension JSONEncodable where Self: StringProtocol { json += JSON.Literal.init(self) } } -extension JSONEncodable where Self: BinaryInteger { +extension JSONEncodable where Self: Numeric & CustomStringConvertible { @inlinable public func encode(to json: inout JSON) { json += JSON.Literal.init(self) }