From 444a1914c13a974fb779cb047ad225e5d0ef4a2a Mon Sep 17 00:00:00 2001 From: vahidlazio Date: Thu, 11 Apr 2024 17:27:19 +0200 Subject: [PATCH] feat: Confidence value is decodable and encodable with schema (#92) confidence value is decodable and encodable with schema --- Sources/Confidence/ConfidenceValue.swift | 49 +++---------------- .../ConfidenceValueTests.swift | 20 ++------ 2 files changed, 13 insertions(+), 56 deletions(-) diff --git a/Sources/Confidence/ConfidenceValue.swift b/Sources/Confidence/ConfidenceValue.swift index 29f580a0..303220c8 100644 --- a/Sources/Confidence/ConfidenceValue.swift +++ b/Sources/Confidence/ConfidenceValue.swift @@ -2,12 +2,17 @@ import Foundation public typealias ConfidenceStruct = [String: ConfidenceValue] -public class ConfidenceValue: Equatable, Encodable, CustomStringConvertible { +public class ConfidenceValue: Equatable, Codable, CustomStringConvertible { private let value: ConfidenceValueInternal public var description: String { return value.description } + public required init(from decoder: Decoder) throws { + let container = try decoder.singleValueContainer() + self.value = try container.decode(ConfidenceValueInternal.self) + } + public init(boolean: Bool) { self.value = .boolean(boolean) } @@ -181,8 +186,7 @@ public class ConfidenceValue: Equatable, Encodable, CustomStringConvertible { extension ConfidenceValue { public func encode(to encoder: Encoder) throws { - var container = encoder.singleValueContainer() - try container.encode(value) + try value.encode(to: encoder) } } @@ -200,7 +204,7 @@ public enum ConfidenceValueType: CaseIterable { /// Serializable data structure meant for event sending via Confidence -private enum ConfidenceValueInternal: Equatable, Encodable { +private enum ConfidenceValueInternal: Equatable, Codable { case boolean(Bool) case string(String) case integer(Int64) @@ -236,40 +240,3 @@ extension ConfidenceValueInternal: CustomStringConvertible { } } } - -extension ConfidenceValueInternal { - public func encode(to encoder: Encoder) throws { - var container = encoder.singleValueContainer() - - switch self { - case .null: - try container.encodeNil() - case .integer(let integer): - try container.encode(integer) - case .double(let double): - try container.encode(double) - case .string(let string): - try container.encode(string) - case .boolean(let boolean): - try container.encode(boolean) - case .date(let dateComponents): - let dateFormatter = ISO8601DateFormatter() - dateFormatter.timeZone = TimeZone.current - dateFormatter.formatOptions = [.withFullDate] - if let date = Calendar.current.date(from: dateComponents) { - try container.encode(dateFormatter.string(from: date)) - } else { - throw ConfidenceError.internalError(message: "Could not create date from components") - } - case .timestamp(let date): - let timestampFormatter = ISO8601DateFormatter() - timestampFormatter.timeZone = TimeZone.init(identifier: "UTC") - let timestamp = timestampFormatter.string(from: date) - try container.encode(timestamp) - case .structure(let structure): - try container.encode(structure) - case .list(let list): - try container.encode(list) - } - } -} diff --git a/Tests/ConfidenceTests/ConfidenceValueTests.swift b/Tests/ConfidenceTests/ConfidenceValueTests.swift index 08617c7d..775fbd23 100644 --- a/Tests/ConfidenceTests/ConfidenceValueTests.swift +++ b/Tests/ConfidenceTests/ConfidenceValueTests.swift @@ -124,20 +124,10 @@ final class ConfidenceConfidenceValueTests: XCTestCase { ])) let encoder = JSONEncoder() encoder.outputFormatting = .sortedKeys - let resultString = String(data: try encoder.encode(value), encoding: .utf8) - - let expectedString = """ - {\"bool\":true, - \"date\":\"2024-04-03\", - \"double\":4.5, - \"int\":3, - \"list\":[3,5], - \"null\":null, - \"string\":\"value\", - \"structure\":{\"int\":5}, - \"timestamp\":\"2024-04-05T20:00:00Z"} - """.replacingOccurrences(of: "\n", with: "") // Newlines were added for readability - - XCTAssertEqual(resultString, expectedString) + let resultString = try XCTUnwrap(String(data: try encoder.encode(value), encoding: .utf8)) + let resultData = try XCTUnwrap(resultString.data(using: .utf8)) + let decodedValue = try JSONDecoder().decode(ConfidenceValue.self, from: resultData) + + XCTAssertEqual(value, decodedValue) } }