From 1c8d8091bfd74471577a89edbf0c61936efcecbb Mon Sep 17 00:00:00 2001 From: Brandon Sneed Date: Mon, 13 Oct 2025 12:46:58 -0700 Subject: [PATCH] Renamed keypath to JSONKeyPath prevent collision. --- Sources/Segment/Timeline.swift | 2 +- Sources/Segment/Utilities/JSON.swift | 6 +-- .../{KeyPath.swift => JSONKeyPath.swift} | 42 +++++++++---------- Tests/Segment-Tests/KeyPath_Tests.swift | 10 ++--- 4 files changed, 30 insertions(+), 30 deletions(-) rename Sources/Segment/Utilities/{KeyPath.swift => JSONKeyPath.swift} (76%) diff --git a/Sources/Segment/Timeline.swift b/Sources/Segment/Timeline.swift index 4f9901dd..2c0b4f6b 100644 --- a/Sources/Segment/Timeline.swift +++ b/Sources/Segment/Timeline.swift @@ -268,7 +268,7 @@ extension DestinationPlugin { internal func isDestinationEnabled(event: RawEvent) -> Bool { var customerDisabled = false - if let disabled: Bool = event.integrations?.value(forKeyPath: KeyPath(self.key)), disabled == false { + if let disabled: Bool = event.integrations?.value(forKeyPath: JSONKeyPath(self.key)), disabled == false { customerDisabled = true } diff --git a/Sources/Segment/Utilities/JSON.swift b/Sources/Segment/Utilities/JSON.swift index 4d118cbe..b436db43 100644 --- a/Sources/Segment/Utilities/JSON.swift +++ b/Sources/Segment/Utilities/JSON.swift @@ -438,7 +438,7 @@ extension JSON { } /// Directly access or set a value within the JSON object using a key path. - public subscript(keyPath keyPath: KeyPath) -> T? { + public subscript(keyPath keyPath: JSONKeyPath) -> T? { get { var result: T? = nil switch self { @@ -494,14 +494,14 @@ extension JSON { /// - forKeyPath: The keypath within the object to retrieve. eg: `context.device.ip` /// /// - Returns: The value as typed, or nil. - public func value(forKeyPath keyPath: KeyPath) -> T? { + public func value(forKeyPath keyPath: JSONKeyPath) -> T? { return self[keyPath: keyPath] } /// Directly access a value within the JSON object using a key path. /// - Parameters: /// - forKeyPath: The keypath within the object to set. eg: `context.device.ip` - public mutating func setValue(_ value: T?, forKeyPath keyPath: KeyPath) { + public mutating func setValue(_ value: T?, forKeyPath keyPath: JSONKeyPath) { self[keyPath: keyPath] = value } diff --git a/Sources/Segment/Utilities/KeyPath.swift b/Sources/Segment/Utilities/JSONKeyPath.swift similarity index 76% rename from Sources/Segment/Utilities/KeyPath.swift rename to Sources/Segment/Utilities/JSONKeyPath.swift index deecf0ef..e0535a53 100644 --- a/Sources/Segment/Utilities/KeyPath.swift +++ b/Sources/Segment/Utilities/JSONKeyPath.swift @@ -8,19 +8,19 @@ import Foundation protocol KeyPathHandler { - func isHandled(_ keyPath: KeyPath, forInput: Any?) -> Bool - func value(keyPath: KeyPath, input: Any?, reference: Any?) -> Any? + func isHandled(_ keyPath: JSONKeyPath, forInput: Any?) -> Bool + func value(keyPath: JSONKeyPath, input: Any?, reference: Any?) -> Any? } public struct BasicHandler: KeyPathHandler { - func value(keyPath: KeyPath, input: Any?, reference: Any?) -> Any? { + func value(keyPath: JSONKeyPath, input: Any?, reference: Any?) -> Any? { guard let input = input as? [String: Any] else { return nil } var result: Any? = nil if keyPath.remaining.isEmpty { result = input[keyPath.current] } else { if let nestedDict = input[keyPath.current] as? [String: Any] { - result = nestedDict[keyPath: KeyPath(keyPath.remainingPath)] + result = nestedDict[keyPath: JSONKeyPath(keyPath.remainingPath)] } else { result = nil } @@ -28,12 +28,12 @@ public struct BasicHandler: KeyPathHandler { return result } - func isHandled(_ keyPath: KeyPath, forInput: Any?) -> Bool { + func isHandled(_ keyPath: JSONKeyPath, forInput: Any?) -> Bool { return true } } -public struct KeyPath { +public struct JSONKeyPath { var current: String var remaining: [String] @@ -47,7 +47,7 @@ public struct KeyPath { internal static var handlers: [KeyPathHandler] = [PathHandler(), IfHandler(), BasicHandler()] static func register(_ handler: KeyPathHandler) { handlers.insert(handler, at: 0) } - static func handlerFor(keyPath: KeyPath, input: Any?) -> KeyPathHandler? { + static func handlerFor(keyPath: JSONKeyPath, input: Any?) -> KeyPathHandler? { guard let input = input as? [String: Any] else { return nil } for item in handlers { if item.isHandled(keyPath, forInput: input[keyPath.current]) { @@ -59,7 +59,7 @@ public struct KeyPath { } -extension KeyPath: ExpressibleByStringLiteral { +extension JSONKeyPath: ExpressibleByStringLiteral { public init(stringLiteral value: String) { self.init(value) } @@ -72,13 +72,13 @@ extension KeyPath: ExpressibleByStringLiteral { } extension Dictionary where Key: StringProtocol, Value: Any { - internal func value(keyPath: KeyPath, reference: Any?) -> Any? { - let handler = KeyPath.handlerFor(keyPath: keyPath, input: self) + internal func value(keyPath: JSONKeyPath, reference: Any?) -> Any? { + let handler = JSONKeyPath.handlerFor(keyPath: keyPath, input: self) let result = handler?.value(keyPath: keyPath, input: self, reference: reference) return result } - internal mutating func setValue(_ value: Any?, keyPath: KeyPath) { + internal mutating func setValue(_ value: Any?, keyPath: JSONKeyPath) { guard let key = keyPath.current as? Key else { return } if keyPath.remaining.isEmpty { @@ -89,28 +89,28 @@ extension Dictionary where Key: StringProtocol, Value: Any { } } else { if var nestedDict = self[key] as? [String: Any] { - nestedDict[keyPath: KeyPath(keyPath.remainingPath)] = value + nestedDict[keyPath: JSONKeyPath(keyPath.remainingPath)] = value self[key] = (nestedDict as! Value) } else { // this nested key doesn't exist but we're not at the end of the chain, need to create it var nestedDict = [String: Any]() - nestedDict[keyPath: KeyPath(keyPath.remainingPath)] = value + nestedDict[keyPath: JSONKeyPath(keyPath.remainingPath)] = value self[key] = (nestedDict as! Value) } } } - public subscript(keyPath keyPath: KeyPath) -> Any? { + public subscript(keyPath keyPath: JSONKeyPath) -> Any? { get { return value(keyPath: keyPath, reference: nil) } set { setValue(newValue as Any, keyPath: keyPath) } } - public subscript(keyPath keyPath: KeyPath, reference reference: Any?) -> Any? { + public subscript(keyPath keyPath: JSONKeyPath, reference reference: Any?) -> Any? { get { return value(keyPath: keyPath, reference: reference) } set { setValue(newValue as Any, keyPath: keyPath) } } - public func exists(keyPath: KeyPath, reference: Any? = nil) -> Bool { + public func exists(keyPath: JSONKeyPath, reference: Any? = nil) -> Bool { return (value(keyPath: keyPath, reference: reference) != nil) } } @@ -125,13 +125,13 @@ extension String { struct IfHandler: KeyPathHandler { - func isHandled(_ keyPath: KeyPath, forInput: Any?) -> Bool { + func isHandled(_ keyPath: JSONKeyPath, forInput: Any?) -> Bool { guard let input = forInput as? [String: Any] else { return false } if input["@if"] != nil { return true } return false } - func value(keyPath: KeyPath, input: Any?, reference: Any?) -> Any? { + func value(keyPath: JSONKeyPath, input: Any?, reference: Any?) -> Any? { guard let input = input as? [String: Any] else { return nil } let current = input[keyPath.current] as? [String: Any] let conditional = current?["@if"] as? [String: Any] @@ -166,7 +166,7 @@ struct IfHandler: KeyPathHandler { } struct PathHandler: KeyPathHandler { - func isHandled(_ keyPath: KeyPath, forInput: Any?) -> Bool { + func isHandled(_ keyPath: JSONKeyPath, forInput: Any?) -> Bool { guard let input = forInput as? [String: Any] else { return false } if input["@path"] != nil { return true @@ -174,14 +174,14 @@ struct PathHandler: KeyPathHandler { return false } - func value(keyPath: KeyPath, input: Any?, reference: Any?) -> Any? { + func value(keyPath: JSONKeyPath, input: Any?, reference: Any?) -> Any? { guard let input = input as? [String: Any] else { return nil } let current = input[keyPath.current] as? [String: Any] let path = (current?["@path"] as? String)?.strippedReference var result: Any? = nil if let path = path, let reference = reference as? [String: Any] { - result = reference[keyPath: KeyPath(path)] + result = reference[keyPath: JSONKeyPath(path)] } return result } diff --git a/Tests/Segment-Tests/KeyPath_Tests.swift b/Tests/Segment-Tests/KeyPath_Tests.swift index fa08df12..e2d0169a 100644 --- a/Tests/Segment-Tests/KeyPath_Tests.swift +++ b/Tests/Segment-Tests/KeyPath_Tests.swift @@ -133,7 +133,7 @@ class KeyPath_Tests: XCTestCase { "anonymousId": "123456" ] for key in keys { - dict[key] = mapping[keyPath: KeyPath(key), reference: event1] + dict[key] = mapping[keyPath: JSONKeyPath(key), reference: event1] } XCTAssertTrue(dict["device_id"] as? String == "ABCDEF") @@ -148,7 +148,7 @@ class KeyPath_Tests: XCTestCase { ] dict = [String: Any]() for key in keys { - dict[key] = mapping[keyPath: KeyPath(key), reference: event2] + dict[key] = mapping[keyPath: JSONKeyPath(key), reference: event2] } XCTAssertTrue(dict["device_id"] as? String == "123456") } @@ -167,7 +167,7 @@ class KeyPath_Tests: XCTestCase { "anonymousId": "123456" ] for key in keys { - dict[key] = mapping[keyPath: KeyPath(key), reference: event1] + dict[key] = mapping[keyPath: JSONKeyPath(key), reference: event1] } XCTAssertTrue(dict["blank_no"] as? String == "ABCDEF") @@ -177,7 +177,7 @@ class KeyPath_Tests: XCTestCase { ] dict = [String: Any]() for key in keys { - dict[key] = mapping[keyPath: KeyPath(key), reference: event2] + dict[key] = mapping[keyPath: JSONKeyPath(key), reference: event2] } XCTAssertTrue(dict["blank_yes"] as? String == "yep") } @@ -195,7 +195,7 @@ class KeyPath_Tests: XCTestCase { ] ] for key in keys { - dict[key] = mapping[keyPath: KeyPath(key), reference: event1] + dict[key] = mapping[keyPath: JSONKeyPath(key), reference: event1] } let traits = dict["user_properties"] as? [String: Any] XCTAssertTrue(traits?["hoot"] as? String == "nanny")