Skip to content

Commit

Permalink
feat: Confidence value is decodable and encodable with schema (#92)
Browse files Browse the repository at this point in the history
confidence value is decodable and encodable with schema
  • Loading branch information
vahidlazio committed Apr 11, 2024
1 parent d0dddee commit 444a191
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 56 deletions.
49 changes: 8 additions & 41 deletions Sources/Confidence/ConfidenceValue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
}
}

Expand All @@ -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)
Expand Down Expand Up @@ -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)
}
}
}
20 changes: 5 additions & 15 deletions Tests/ConfidenceTests/ConfidenceValueTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}

0 comments on commit 444a191

Please sign in to comment.