diff --git a/Sources/Confidence/ConfidenceValue.swift b/Sources/Confidence/ConfidenceValue.swift index 7c6422c6..fd44ca90 100644 --- a/Sources/Confidence/ConfidenceValue.swift +++ b/Sources/Confidence/ConfidenceValue.swift @@ -11,7 +11,7 @@ public enum ConfidenceValue: Equatable, Encodable { case date(DateComponents) case timestamp(Date) case list([ConfidenceValue]) - case structure([String: ConfidenceValue]) + case structure(ConfidenceStruct) case null public func asBoolean() -> Bool? { diff --git a/Sources/ConfidenceProvider/Utils/ConfidenceTypeMapper.swift b/Sources/ConfidenceProvider/Utils/ConfidenceTypeMapper.swift new file mode 100644 index 00000000..9cf45dee --- /dev/null +++ b/Sources/ConfidenceProvider/Utils/ConfidenceTypeMapper.swift @@ -0,0 +1,36 @@ +import Foundation +import Confidence +import OpenFeature + +public enum ConfidenceTypeMapper { + static func from(value: Value) -> ConfidenceValue { + return convertValue(value) + } + + static func from(ctx: EvaluationContext) -> ConfidenceStruct { + var ctxMap = ctx.asMap() + ctxMap["targeting_key"] = .string(ctx.getTargetingKey()) + return ctxMap.compactMapValues(convertValue) + } + + static private func convertValue(_ value: Value) -> ConfidenceValue { + switch value { + case .boolean(let value): + return .boolean(value) + case .string(let value): + return .string(value) + case .integer(let value): + return .integer(value) + case .double(let value): + return .double(value) + case .date(let value): + return .timestamp(value) + case .list(let values): + return .list(values.compactMap(convertValue)) + case .structure(let values): + return .structure(values.compactMapValues(convertValue)) + case .null: + return .null + } + } +} diff --git a/Tests/ConfidenceProviderTests/ConfidenceTypeMapperTest.swift b/Tests/ConfidenceProviderTests/ConfidenceTypeMapperTest.swift new file mode 100644 index 00000000..156bf316 --- /dev/null +++ b/Tests/ConfidenceProviderTests/ConfidenceTypeMapperTest.swift @@ -0,0 +1,50 @@ +import Foundation +import Confidence +import OpenFeature +import XCTest + +@testable import ConfidenceProvider + +class ValueConverterTest: XCTestCase { + func testContextConversion() throws { + let openFeatureCtx = MutableContext( + targetingKey: "userid", + structure: MutableStructure(attributes: (["key": .string("value")]))) + let confidenceStruct = ConfidenceTypeMapper.from(ctx: openFeatureCtx) + let expected = [ + "key": ConfidenceValue.string("value"), + "targeting_key": ConfidenceValue.string("userid") + ] + XCTAssertEqual(confidenceStruct, expected) + } + + func testValueConversion() throws { + let formatter = DateFormatter() + formatter.dateFormat = "yyyy-MM-dd HH:mm:ss" + let date = try XCTUnwrap(formatter.date(from: "2022-01-01 12:00:00")) + + let openFeatureValue = Value.structure([ + "key": .string("value"), + "null": .null, + "bool": .boolean(true), + "int": .integer(3), + "double": .double(4.5), + "date": .date(date), + "list": .list([.integer(3), .integer(5)]), + "structure": .structure(["field1": .string("test"), "field2": .integer(12)]), + ]) + + let confidenceValue = ConfidenceTypeMapper.from(value: openFeatureValue) + let expected = ConfidenceValue.structure([ + "key": .string("value"), + "null": .null, + "bool": .boolean(true), + "int": .integer(3), + "double": .double(4.5), + "date": .timestamp(date), + "list": .list([.integer(3), .integer(5)]), + "structure": .structure(["field1": .string("test"), "field2": .integer(12)]), + ]) + XCTAssertEqual(confidenceValue, expected) + } +}