From b4c562647d01bf6c634b72d7e2d2920e28075ac1 Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Fri, 5 Dec 2025 09:37:50 +0000 Subject: [PATCH 1/2] Remove fromRESP parameter label from RESPTokenDecodable.init(_:) Signed-off-by: Adam Fowler --- .../Custom/ClusterCustomCommands.swift | 74 +++++++++---------- .../Custom/GenericCustomCommands.swift | 2 +- .../Commands/Custom/GeoCustomCommands.swift | 6 +- .../Commands/Custom/HashCustomCommands.swift | 22 +++--- .../Commands/Custom/ListCustomCommands.swift | 4 +- .../Custom/ScriptingCustomCommands.swift | 48 ++++++------ .../Custom/ServerCustomCommands.swift | 24 +++--- .../Commands/Custom/SetCustomCommands.swift | 2 +- .../Custom/SortedSetCustomCommands.swift | 12 +-- .../Custom/StreamCustomCommands.swift | 24 +++--- .../Custom/StringCustomCommands.swift | 18 ++--- .../Valkey/Connection/ValkeyConnection.swift | 4 +- .../Documentation.docc/RESPToken-Decoding.md | 2 +- Sources/Valkey/RESP/RESPBulkString.swift | 4 +- Sources/Valkey/RESP/RESPTokenDecodable.swift | 50 ++++++------- Sources/Valkey/Subscriptions/PushToken.swift | 42 +++++------ .../Subscriptions/ValkeySubscriptions.swift | 2 +- Sources/Valkey/ValkeyKey.swift | 2 +- .../ValkeyClusterDescriptionTests.swift | 16 ++-- Tests/ValkeyTests/RESPDecodeErrorTests.swift | 12 +-- .../ValkeyTests/RESPTokenDecodableTests.swift | 20 ++--- 21 files changed, 195 insertions(+), 195 deletions(-) diff --git a/Sources/Valkey/Commands/Custom/ClusterCustomCommands.swift b/Sources/Valkey/Commands/Custom/ClusterCustomCommands.swift index d5854a73..f2d1ca17 100644 --- a/Sources/Valkey/Commands/Custom/ClusterCustomCommands.swift +++ b/Sources/Valkey/Commands/Custom/ClusterCustomCommands.swift @@ -180,7 +180,7 @@ public struct ValkeyClusterDescription: Hashable, Sendable, RESPTokenDecodable { /// Creates a cluster description from the response token you provide. /// - Parameter respToken: The response token. - public init(fromRESP respToken: RESPToken) throws { + public init(_ respToken: RESPToken) throws { self = try Self.makeClusterDescription(respToken: respToken) } @@ -264,7 +264,7 @@ public struct ValkeyClusterLink: Hashable, Sendable, RESPTokenDecodable { /// Creates a cluster link from the response token you provide. /// - Parameter respToken: The response token. - public init(fromRESP respToken: RESPToken) throws { + public init(_ respToken: RESPToken) throws { self = try Self.makeClusterLink(respToken: respToken) } @@ -275,7 +275,7 @@ public struct ValkeyClusterLink: Hashable, Sendable, RESPTokenDecodable { case .map(let map): let mapped = map.lazy.compactMap { (keyNode, value) -> (String, RESPToken)? in - if let key = try? String(fromRESP: keyNode) { + if let key = try? String(keyNode) { return (key, value) } else { return nil @@ -302,7 +302,7 @@ public struct ValkeyClusterLink: Hashable, Sendable, RESPTokenDecodable { for (key, value) in sequence { switch key { case "direction": - guard let directionString = try? String(fromRESP: value), + guard let directionString = try? String(value), let directionValue = ValkeyClusterLink.Direction(rawValue: directionString) else { throw RESPDecodeError.missingToken(key: "direction", token: respToken) @@ -310,19 +310,19 @@ public struct ValkeyClusterLink: Hashable, Sendable, RESPTokenDecodable { direction = directionValue case "node": - node = try? String(fromRESP: value) + node = try? String(value) case "create-time": - createTime = try? Int64(fromRESP: value) + createTime = try? Int64(value) case "events": - events = try? String(fromRESP: value) + events = try? String(value) case "send-buffer-allocated": - sendBufferAllocated = try? Int64(fromRESP: value) + sendBufferAllocated = try? Int64(value) case "send-buffer-used": - sendBufferUsed = try? Int64(fromRESP: value) + sendBufferUsed = try? Int64(value) default: // ignore unexpected keys for forward compatibility @@ -379,7 +379,7 @@ public struct ValkeyClusterSlotStats: Hashable, Sendable, RESPTokenDecodable { /// Creates a cluster slot stats from the response token you provide. /// - Parameter respToken: The response token. - public init(fromRESP respToken: RESPToken) throws { + public init(_ respToken: RESPToken) throws { self = try Self.makeClusterSlotStats(respToken: respToken) } @@ -419,7 +419,7 @@ public struct ValkeyClusterSlotStats: Hashable, Sendable, RESPTokenDecodable { case .map(let map): // For RESP3, handle RESPToken stats as map let mapped = map.lazy.compactMap { (keyNode, value) -> (String, RESPToken)? in - if let key = try? String(fromRESP: keyNode) { + if let key = try? String(keyNode) { return (key, value) } else { return nil @@ -428,16 +428,16 @@ public struct ValkeyClusterSlotStats: Hashable, Sendable, RESPTokenDecodable { for (key, value) in mapped { switch key { case "key-count": - keyCount = try? Int64(fromRESP: value) + keyCount = try? Int64(value) case "cpu-usec": - cpuUsec = try? Int64(fromRESP: value) + cpuUsec = try? Int64(value) case "network-bytes-in": - networkBytesIn = try? Int64(fromRESP: value) + networkBytesIn = try? Int64(value) case "network-bytes-out": - networkBytesOut = try? Int64(fromRESP: value) + networkBytesOut = try? Int64(value) default: // ignore unexpected keys for forward compatibility @@ -451,16 +451,16 @@ public struct ValkeyClusterSlotStats: Hashable, Sendable, RESPTokenDecodable { for (key, valueToken) in mapArray { switch key { case "key-count": - keyCount = try? Int64(fromRESP: valueToken) + keyCount = try? Int64(valueToken) case "cpu-usec": - cpuUsec = try? Int64(fromRESP: valueToken) + cpuUsec = try? Int64(valueToken) case "network-bytes-in": - networkBytesIn = try? Int64(fromRESP: valueToken) + networkBytesIn = try? Int64(valueToken) case "network-bytes-out": - networkBytesOut = try? Int64(fromRESP: valueToken) + networkBytesOut = try? Int64(valueToken) default: // ignore unexpected keys for forward compatibility @@ -536,7 +536,7 @@ public struct ValkeyClusterSlotRange: Hashable, Sendable, RESPTokenDecodable { /// Creates a cluster slot range from the response token you provide. /// - Parameter respToken: The response token. - public init(fromRESP respToken: RESPToken) throws { + public init(_ respToken: RESPToken) throws { self = try Self.makeClusterSlotRange(respToken: respToken) } @@ -639,7 +639,7 @@ extension ValkeyClusterDescription.Shard { case .map(let map): let mapped = map.lazy.compactMap { (keyNode, value) -> (String, RESPToken)? in - if let key = try? String(fromRESP: keyNode) { + if let key = try? String(keyNode) { return (key, value) } else { return nil @@ -692,7 +692,7 @@ extension ValkeyClusterDescription.Node { case .map(let map): let mapped = map.lazy.compactMap { (keyNode, value) -> (String, RESPToken)? in - if let key = try? String(fromRESP: keyNode) { + if let key = try? String(keyNode) { return (key, value) } else { return nil @@ -736,27 +736,27 @@ extension ValkeyClusterDescription.Node { while let (key, nodeVal) = nodeIterator.next() { switch key { case "id": - id = try? String(fromRESP: nodeVal) + id = try? String(nodeVal) case "port": - port = try? Int64(fromRESP: nodeVal) + port = try? Int64(nodeVal) case "tls-port": - tlsPort = try? Int64(fromRESP: nodeVal) + tlsPort = try? Int64(nodeVal) case "ip": - ip = try? String(fromRESP: nodeVal) + ip = try? String(nodeVal) case "hostname": - hostname = try? String(fromRESP: nodeVal) + hostname = try? String(nodeVal) case "endpoint": - endpoint = try? String(fromRESP: nodeVal) + endpoint = try? String(nodeVal) case "role": - guard let roleString = try? String(fromRESP: nodeVal), let roleValue = ValkeyClusterDescription.Node.Role(rawValue: roleString) else { + guard let roleString = try? String(nodeVal), let roleValue = ValkeyClusterDescription.Node.Role(rawValue: roleString) else { throw .decodeError(RESPDecodeError(.unexpectedToken, token: nodeVal, message: "Invalid Role String")) } role = roleValue case "replication-offset": - replicationOffset = try? Int64(fromRESP: nodeVal) + replicationOffset = try? Int64(nodeVal) case "health": - guard let healthString = try? String(fromRESP: nodeVal), + guard let healthString = try? String(nodeVal), let healthValue = ValkeyClusterDescription.Node.Health(rawValue: healthString) else { throw .decodeError(RESPDecodeError(.unexpectedToken, token: nodeVal, message: "Invalid Node Health String")) @@ -808,7 +808,7 @@ extension ValkeyClusterSlotRange.Node { // First element: IP address guard let ipToken = iterator.next(), - let ip = try? String(fromRESP: ipToken) + let ip = try? String(ipToken) else { throw RESPDecodeError.missingToken(key: "ip", token: respToken) } @@ -823,7 +823,7 @@ extension ValkeyClusterSlotRange.Node { // Third element: node ID guard let nodeIdToken = iterator.next(), - let nodeId = try? String(fromRESP: nodeIdToken) + let nodeId = try? String(nodeIdToken) else { throw RESPDecodeError.missingToken(key: "node id", token: respToken) } @@ -836,8 +836,8 @@ extension ValkeyClusterSlotRange.Node { case .map(let map): // Handle metadata as a map for (keyToken, valueToken) in map { - if let key = try? String(fromRESP: keyToken), - let value = try? String(fromRESP: valueToken) + if let key = try? String(keyToken), + let value = try? String(valueToken) { metadata[key] = value } @@ -849,7 +849,7 @@ extension ValkeyClusterSlotRange.Node { // Handle metadata as key-value pairs in array format (using MapStyleArray) let mapArray = MapStyleArray(underlying: array) for (key, valueToken) in mapArray { - if let value = try? String(fromRESP: valueToken) { + if let value = try? String(valueToken) { metadata[key] = value } } @@ -879,7 +879,7 @@ struct MapStyleArray: Sequence { mutating func next() -> (String, RESPToken)? { guard let nodeKey = self.underlying.next(), - let key = try? String(fromRESP: nodeKey), + let key = try? String(nodeKey), let nodeVal = self.underlying.next() else { return nil diff --git a/Sources/Valkey/Commands/Custom/GenericCustomCommands.swift b/Sources/Valkey/Commands/Custom/GenericCustomCommands.swift index 9a5e27e8..faab603b 100644 --- a/Sources/Valkey/Commands/Custom/GenericCustomCommands.swift +++ b/Sources/Valkey/Commands/Custom/GenericCustomCommands.swift @@ -12,7 +12,7 @@ extension SCAN { public let cursor: Int public let keys: RESPToken.Array - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { (self.cursor, self.keys) = try token.decodeArrayElements(as: (Int, RESPToken.Array).self) } } diff --git a/Sources/Valkey/Commands/Custom/GeoCustomCommands.swift b/Sources/Valkey/Commands/Custom/GeoCustomCommands.swift index 446aeca4..55e93925 100644 --- a/Sources/Valkey/Commands/Custom/GeoCustomCommands.swift +++ b/Sources/Valkey/Commands/Custom/GeoCustomCommands.swift @@ -13,7 +13,7 @@ public struct GeoCoordinates: RESPTokenDecodable, Sendable { public let longitude: Double public let latitude: Double - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { (self.longitude, self.latitude) = try token.decodeArrayElements() } } @@ -41,14 +41,14 @@ extension GEOSEARCH { public let member: String public let attributes: [RESPToken] - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { switch token.value { case .array(let array): var arrayIterator = array.makeIterator() guard let member = arrayIterator.next() else { throw RESPDecodeError.invalidArraySize(array, expectedSize: 1) } - self.member = try String(fromRESP: member) + self.member = try String(member) self.attributes = array.dropFirst().map { $0 } case .bulkString(let buffer): diff --git a/Sources/Valkey/Commands/Custom/HashCustomCommands.swift b/Sources/Valkey/Commands/Custom/HashCustomCommands.swift index 6cb256c8..030d5bc4 100644 --- a/Sources/Valkey/Commands/Custom/HashCustomCommands.swift +++ b/Sources/Valkey/Commands/Custom/HashCustomCommands.swift @@ -18,7 +18,7 @@ public struct HashEntry: RESPTokenDecodable, Sendable { self.value = value } - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { switch token.value { case .array(let array): (self.field, self.value) = try array.decodeElements() @@ -34,7 +34,7 @@ extension HSCAN { /// List of members and possibly scores. public let elements: RESPToken.Array - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { self.elements = try token.decode(as: RESPToken.Array.self) } @@ -49,8 +49,8 @@ extension HSCAN { public func withValues() throws -> [HashEntry] { var array: [HashEntry] = [] for respElement in try self.elements.asMap() { - let field = try RESPBulkString(fromRESP: respElement.key) - let value = try RESPBulkString(fromRESP: respElement.value) + let field = try RESPBulkString(respElement.key) + let value = try RESPBulkString(respElement.value) array.append(.init(field: field, value: value)) } return array @@ -61,7 +61,7 @@ extension HSCAN { /// Sorted set members public let members: Members - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { (self.cursor, self.members) = try token.decodeArrayElements() } } @@ -73,7 +73,7 @@ extension HRANDFIELD { /// The raw RESP token containing the response public let token: RESPToken - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { self.token = token } @@ -85,7 +85,7 @@ extension HRANDFIELD { if token.value == .null { return nil } - return try RESPBulkString(fromRESP: token) + return try RESPBulkString(token) } /// Get multiple random fields when HRANDFIELD was called with COUNT but without WITHVALUES @@ -93,7 +93,7 @@ extension HRANDFIELD { /// - Throws: RESPDecodeError if response format is unexpected @inlinable public func multipleFields() throws -> [RESPBulkString]? { - try [RESPBulkString]?(fromRESP: token) + try [RESPBulkString]?(token) } /// Get multiple random field-value pairs when HRANDFIELD was called with COUNT and WITHVALUES @@ -116,7 +116,7 @@ extension HRANDFIELD { switch firstElement.value { case .array: // Array of arrays format - can use HashEntry decode - return try [HashEntry]?(fromRESP: token) + return try [HashEntry]?(token) default: // Flat array format - handle manually return try _decodeFlatArrayFormat(array) @@ -141,8 +141,8 @@ extension HRANDFIELD { // Iterate over pairs var iterator = array.makeIterator() while let field = iterator.next(), let value = iterator.next() { - let fieldBuffer = try RESPBulkString(fromRESP: field) - let valueBuffer = try RESPBulkString(fromRESP: value) + let fieldBuffer = try RESPBulkString(field) + let valueBuffer = try RESPBulkString(value) entries.append(HashEntry(field: fieldBuffer, value: valueBuffer)) } diff --git a/Sources/Valkey/Commands/Custom/ListCustomCommands.swift b/Sources/Valkey/Commands/Custom/ListCustomCommands.swift index daf78148..feb1a048 100644 --- a/Sources/Valkey/Commands/Custom/ListCustomCommands.swift +++ b/Sources/Valkey/Commands/Custom/ListCustomCommands.swift @@ -14,7 +14,7 @@ public struct ListEntry: RESPTokenDecodable, Sendable { public let key: ValkeyKey public let value: RESPBulkString - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { (self.key, self.value) = try token.decodeArrayElements() } } @@ -31,7 +31,7 @@ extension LMPOP { public let key: ValkeyKey public let values: RESPToken.Array - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { switch token.value { case .array(let array): (self.key, self.values) = try array.decodeElements() diff --git a/Sources/Valkey/Commands/Custom/ScriptingCustomCommands.swift b/Sources/Valkey/Commands/Custom/ScriptingCustomCommands.swift index e9927a81..ac610da2 100644 --- a/Sources/Valkey/Commands/Custom/ScriptingCustomCommands.swift +++ b/Sources/Valkey/Commands/Custom/ScriptingCustomCommands.swift @@ -21,14 +21,14 @@ extension FUNCTION.LIST { public let description: String? public let flags: [String] - public init(fromRESP token: RESPToken) throws { - let map = try [String: RESPToken](fromRESP: token) + public init(_ token: RESPToken) throws { + let map = try [String: RESPToken](token) guard let name = map["name"] else { throw RESPDecodeError.missingToken(key: "name", token: token) } guard let description = map["description"] else { throw RESPDecodeError.missingToken(key: "description", token: token) } guard let flags = map["flags"] else { throw RESPDecodeError.missingToken(key: "flags", token: token) } - self.name = try String(fromRESP: name) - self.description = try String?(fromRESP: description) - self.flags = try [String](fromRESP: flags) + self.name = try String(name) + self.description = try String?(description) + self.flags = try [String](flags) } } public let libraryName: String @@ -36,16 +36,16 @@ extension FUNCTION.LIST { public let functions: [Function] public let libraryCode: String? - public init(fromRESP token: RESPToken) throws { - let map = try [String: RESPToken](fromRESP: token) + public init(_ token: RESPToken) throws { + let map = try [String: RESPToken](token) guard let libraryName = map["library_name"] else { throw RESPDecodeError.missingToken(key: "library_name", token: token) } guard let engine = map["engine"] else { throw RESPDecodeError.missingToken(key: "engine", token: token) } guard let functions = map["functions"] else { throw RESPDecodeError.missingToken(key: "functions", token: token) } let libraryCode = map["library_code"] - self.libraryName = try String(fromRESP: libraryName) - self.engine = try String(fromRESP: engine) - self.functions = try [Function](fromRESP: functions) - self.libraryCode = try libraryCode.map { try String(fromRESP: $0) } + self.libraryName = try String(libraryName) + self.engine = try String(engine) + self.functions = try [Function](functions) + self.libraryCode = try libraryCode.map { try String($0) } } } } @@ -62,36 +62,36 @@ extension FUNCTION.STATS { public let command: [RESPBulkString] public let durationInMilliseconds: Double - public init(fromRESP token: RESPToken) throws { - let map = try [String: RESPToken](fromRESP: token) + public init(_ token: RESPToken) throws { + let map = try [String: RESPToken](token) guard let name = map["name"] else { throw RESPDecodeError.missingToken(key: "name", token: token) } guard let command = map["command"] else { throw RESPDecodeError.missingToken(key: "command", token: token) } guard let duration = map["duration_ms"] else { throw RESPDecodeError.missingToken(key: "duration_ms", token: token) } - self.name = try .init(fromRESP: name) - self.command = try .init(fromRESP: command) - self.durationInMilliseconds = try Double(fromRESP: duration) + self.name = try .init(name) + self.command = try .init(command) + self.durationInMilliseconds = try Double(duration) } } public struct Engine: RESPTokenDecodable, Sendable { public let libraryCount: Int public let functionCount: Int - public init(fromRESP token: RESPToken) throws { - let map = try [String: RESPToken](fromRESP: token) + public init(_ token: RESPToken) throws { + let map = try [String: RESPToken](token) guard let libraryCount = map["libraries_count"] else { throw RESPDecodeError.missingToken(key: "libraries_count", token: token) } guard let functionCount = map["functions_count"] else { throw RESPDecodeError.missingToken(key: "functions_count", token: token) } - self.libraryCount = try .init(fromRESP: libraryCount) - self.functionCount = try .init(fromRESP: functionCount) + self.libraryCount = try .init(libraryCount) + self.functionCount = try .init(functionCount) } } public let runningScript: Script public let engines: [String: Engine] - public init(fromRESP token: RESPToken) throws { - let map = try [String: RESPToken](fromRESP: token) + public init(_ token: RESPToken) throws { + let map = try [String: RESPToken](token) guard let runningScript = map["running_script"] else { throw RESPDecodeError.missingToken(key: "running_script", token: token) } guard let engines = map["engines"] else { throw RESPDecodeError.missingToken(key: "engines", token: token) } - self.runningScript = try .init(fromRESP: runningScript) - self.engines = try .init(fromRESP: engines) + self.runningScript = try .init(runningScript) + self.engines = try .init(engines) } } } diff --git a/Sources/Valkey/Commands/Custom/ServerCustomCommands.swift b/Sources/Valkey/Commands/Custom/ServerCustomCommands.swift index 7416c2cc..3b1b3344 100644 --- a/Sources/Valkey/Commands/Custom/ServerCustomCommands.swift +++ b/Sources/Valkey/Commands/Custom/ServerCustomCommands.swift @@ -16,7 +16,7 @@ extension ROLE { public let port: Int public let replicationOffset: Int - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { (self.ip, self.port, self.replicationOffset) = try token.decodeArrayElements() } } @@ -27,8 +27,8 @@ extension ROLE { guard let replicationOffsetToken = arrayIterator.next(), let replicasToken = arrayIterator.next() else { throw MissingValueDecodeError(expectedNumberOfValues: 2) } - self.replicationOffset = try .init(fromRESP: replicationOffsetToken) - self.replicas = try .init(fromRESP: replicasToken) + self.replicationOffset = try .init(replicationOffsetToken) + self.replicas = try .init(replicasToken) } } public struct Replica: Sendable { @@ -38,8 +38,8 @@ extension ROLE { case sync case connected - public init(fromRESP token: RESPToken) throws { - let string = try String(fromRESP: token) + public init(_ token: RESPToken) throws { + let string = try String(token) guard let state = State(rawValue: string) else { throw RESPDecodeError(.unexpectedToken, token: token) } @@ -59,10 +59,10 @@ extension ROLE { else { throw MissingValueDecodeError(expectedNumberOfValues: 4) } - self.primaryIP = try .init(fromRESP: primaryIPToken) - self.primaryPort = try .init(fromRESP: primaryPortToken) - self.state = try .init(fromRESP: stateToken) - self.replicationOffset = try .init(fromRESP: replicationToken) + self.primaryIP = try .init(primaryIPToken) + self.primaryPort = try .init(primaryPortToken) + self.state = try .init(stateToken) + self.replicationOffset = try .init(replicationToken) } } public struct Sentinel: Sendable { @@ -70,14 +70,14 @@ extension ROLE { init(arrayIterator: inout RESPToken.Array.Iterator) throws { guard let primaryNamesToken = arrayIterator.next() else { throw MissingValueDecodeError(expectedNumberOfValues: 1) } - self.primaryNames = try .init(fromRESP: primaryNamesToken) + self.primaryNames = try .init(primaryNamesToken) } } case primary(Primary) case replica(Replica) case sentinel(Sentinel) - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { switch token.value { case .array(let array): do { @@ -85,7 +85,7 @@ extension ROLE { guard let roleToken = iterator.next() else { throw RESPDecodeError.invalidArraySize(array, expectedSize: 1) } - let role = try String(fromRESP: roleToken) + let role = try String(roleToken) switch role { case "master": let primary = try Primary(arrayIterator: &iterator) diff --git a/Sources/Valkey/Commands/Custom/SetCustomCommands.swift b/Sources/Valkey/Commands/Custom/SetCustomCommands.swift index f3d76f0c..4f086571 100644 --- a/Sources/Valkey/Commands/Custom/SetCustomCommands.swift +++ b/Sources/Valkey/Commands/Custom/SetCustomCommands.swift @@ -10,7 +10,7 @@ extension SSCAN { public let cursor: Int public let elements: RESPToken.Array - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { // cursor is encoded as a bulkString, but should be let (cursor, elements) = try token.decodeArrayElements(as: (Int, RESPToken.Array).self) self.cursor = cursor diff --git a/Sources/Valkey/Commands/Custom/SortedSetCustomCommands.swift b/Sources/Valkey/Commands/Custom/SortedSetCustomCommands.swift index 0a7e2032..424c3728 100644 --- a/Sources/Valkey/Commands/Custom/SortedSetCustomCommands.swift +++ b/Sources/Valkey/Commands/Custom/SortedSetCustomCommands.swift @@ -18,7 +18,7 @@ public struct SortedSetEntry: RESPTokenDecodable, Sendable { self.score = score } - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { switch token.value { case .array(let array): (self.value, self.score) = try array.decodeElements() @@ -56,7 +56,7 @@ extension ZMPOP { public let key: ValkeyKey public let values: [SortedSetEntry] - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { switch token.value { case .array(let array): (self.key, self.values) = try array.decodeElements() @@ -88,7 +88,7 @@ extension ZSCAN { /// List of members and possibly scores. public let elements: RESPToken.Array - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { self.elements = try token.decode(as: RESPToken.Array.self) } @@ -103,8 +103,8 @@ extension ZSCAN { public func withScores() throws -> [SortedSetEntry] { var array: [SortedSetEntry] = [] for respElement in try self.elements.asMap() { - let value = try RESPBulkString(fromRESP: respElement.key) - let score = try Double(fromRESP: respElement.value) + let value = try RESPBulkString(respElement.key) + let score = try Double(respElement.value) array.append(.init(value: value, score: score)) } return array @@ -115,7 +115,7 @@ extension ZSCAN { /// Sorted set members public let members: Members - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { (self.cursor, self.members) = try token.decodeArrayElements() } } diff --git a/Sources/Valkey/Commands/Custom/StreamCustomCommands.swift b/Sources/Valkey/Commands/Custom/StreamCustomCommands.swift index 806ea3c0..1681ba93 100644 --- a/Sources/Valkey/Commands/Custom/StreamCustomCommands.swift +++ b/Sources/Valkey/Commands/Custom/StreamCustomCommands.swift @@ -12,7 +12,7 @@ public struct XREADMessage: RESPTokenDecodable, Sendable { public let id: String public let fields: [(key: String, value: RESPBulkString)] - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { switch token.value { case .array(let array): let (id, values) = try array.decodeElements(as: (String, RESPToken.Array).self) @@ -66,7 +66,7 @@ public struct XREADGroupMessage: RESPTokenDecodable, Sendable { public let id: String public let fields: [(key: String, value: RESPBulkString)]? - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { switch token.value { case .array(let array): let (id, values) = try array.decodeElements(as: (String, RESPToken.Array?).self) @@ -91,7 +91,7 @@ public struct XREADStreams: RESPTokenDecodable, Sendable where Message: public let streams: [Stream] - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { switch token.value { case .map(let map): self.streams = try map.map { @@ -111,7 +111,7 @@ public struct XAUTOCLAIMResponse: RESPTokenDecodable, Sendable { public let messages: [XREADMessage] public let deletedMessages: [String] - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { switch token.value { case .array(let array): (self.streamID, self.messages, self.deletedMessages) = try array.decodeElements() @@ -130,7 +130,7 @@ public enum XCLAIMResponse: RESPTokenDecodable, Sendable { case messages([XREADMessage]) case ids([String]) - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { switch token.value { case .array(let array): if array.count == 0 { @@ -159,7 +159,7 @@ public enum XPENDINGResponse: RESPTokenDecodable, Sendable { public let consumer: String public let count: String - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { switch token.value { case .array(let array): (self.consumer, self.count) = try array.decodeElements() @@ -173,7 +173,7 @@ public enum XPENDINGResponse: RESPTokenDecodable, Sendable { public let maximumID: String public let consumers: [Consumer] - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { switch token.value { case .array(let array): (self.pendingMessageCount, self.minimumID, self.maximumID, self.consumers) = try array.decodeElements() @@ -189,7 +189,7 @@ public enum XPENDINGResponse: RESPTokenDecodable, Sendable { public let millisecondsSinceDelivered: Int public let numberOfTimesDelivered: Int - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { switch token.value { case .array(let array): (self.id, self.consumer, self.millisecondsSinceDelivered, self.numberOfTimesDelivered) = try array.decodeElements() @@ -200,7 +200,7 @@ public enum XPENDINGResponse: RESPTokenDecodable, Sendable { } let messages: [PendingMessage] - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { switch token.value { case .array(let array): self.messages = try array.decode(as: [PendingMessage].self) @@ -213,11 +213,11 @@ public enum XPENDINGResponse: RESPTokenDecodable, Sendable { case standard(Standard) case extended(Extended) - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { do { - self = try .standard(.init(fromRESP: token)) + self = try .standard(.init(token)) } catch { - self = try .extended(.init(fromRESP: token)) + self = try .extended(.init(token)) } } } diff --git a/Sources/Valkey/Commands/Custom/StringCustomCommands.swift b/Sources/Valkey/Commands/Custom/StringCustomCommands.swift index 9749669e..0bc4a628 100644 --- a/Sources/Valkey/Commands/Custom/StringCustomCommands.swift +++ b/Sources/Valkey/Commands/Custom/StringCustomCommands.swift @@ -17,7 +17,7 @@ extension LCS { public let first: ClosedRange public let second: ClosedRange - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { (self.first, self.second) = try token.decodeArrayElements() } } @@ -26,15 +26,15 @@ extension LCS { public let matches: [Match] public let length: Int64 - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { switch token.value { case .map(let map): var matches: [Match]? var length: Int64? for entry in map { - switch try String(fromRESP: entry.key) { - case "len": length = try .init(fromRESP: entry.value) - case "matches": matches = try .init(fromRESP: entry.value) + switch try String(entry.key) { + case "len": length = try .init(entry.value) + case "matches": matches = try .init(entry.value) default: break } } @@ -50,7 +50,7 @@ extension LCS { let token: RESPToken - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { self.token = token } @@ -60,7 +60,7 @@ extension LCS { /// - Throws: RESPDecodeError /// - Returns: sub-sequence string public func longestMatch() throws -> String { - try String(fromRESP: self.token) + try String(self.token) } /// Return length of longest common sub-sequence @@ -69,7 +69,7 @@ extension LCS { /// - Throws: RESPDecodeError /// - Returns: Length of sub-sequence string public func longestMatchLength() throws -> Int { - try Int(fromRESP: self.token) + try Int(self.token) } /// Return length and range in each string of each match @@ -78,7 +78,7 @@ extension LCS { /// - Throws: RESPDecodeError /// - Returns: Length of sub-sequence string public func matches() throws -> Matches { - try Matches(fromRESP: self.token) + try Matches(self.token) } } } diff --git a/Sources/Valkey/Connection/ValkeyConnection.swift b/Sources/Valkey/Connection/ValkeyConnection.swift index eaf35f41..2b5cd5d5 100644 --- a/Sources/Valkey/Connection/ValkeyConnection.swift +++ b/Sources/Valkey/Connection/ValkeyConnection.swift @@ -202,7 +202,7 @@ public final actor ValkeyConnection: ValkeyClientProtocol, Sendable { } onCancel: { self.cancel(requestID: requestID) } - return try .init(fromRESP: token) + return try .init(token) } catch let error as ValkeyClientError { #if DistributedTracingSupport if let span { @@ -810,7 +810,7 @@ extension Result where Success == RESPToken, Failure == any Error { func convertFromRESP(to: Response.Type) -> Result { self.flatMap { do { - return try .success(Response(fromRESP: $0)) + return try .success(Response($0)) } catch { return .failure(error) } diff --git a/Sources/Valkey/Documentation.docc/RESPToken-Decoding.md b/Sources/Valkey/Documentation.docc/RESPToken-Decoding.md index 409d578e..92df9be8 100644 --- a/Sources/Valkey/Documentation.docc/RESPToken-Decoding.md +++ b/Sources/Valkey/Documentation.docc/RESPToken-Decoding.md @@ -15,7 +15,7 @@ The majority of the Valkey commands return the Swift types equivalent to their e A `RESPToken` contains the raw serialized bytes returned by the Valkey server. Valkey-swift introduces a protocol ``RESPTokenDecodable`` for types that can be decoded from a `RESPToken`. Many of Swift core types have been extended to conform to `RESPTokenDecodable`. There are two ways to decode a `RESPToken`. You can call ``RESPTokenDecodable/init(fromRESP:)``. ```swift -let string = String(fromRESP: respToken) +let string = String(respToken) ``` Or you can call the `RESPToken` method ``RESPToken/decode(as:)``. This can be chained onto the end of a command call eg `RPOP` can return a single value or an array of values so the function returns a `RESPToken` and the user should decode it based on whether they asked for multiple or a single value to be popped. diff --git a/Sources/Valkey/RESP/RESPBulkString.swift b/Sources/Valkey/RESP/RESPBulkString.swift index 6b6cd124..dd59f543 100644 --- a/Sources/Valkey/RESP/RESPBulkString.swift +++ b/Sources/Valkey/RESP/RESPBulkString.swift @@ -105,8 +105,8 @@ extension RESPBulkString { extension RESPBulkString: RESPTokenDecodable { @inlinable - public init(fromRESP token: RESPToken) throws { - self.buffer = try .init(fromRESP: token) + public init(_ token: RESPToken) throws { + self.buffer = try .init(token) self.range = buffer.readerIndex..(as type: Value.Type = Value.self) throws -> Value { - try Value(fromRESP: self) + try Value(self) } @inlinable - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { self = token } @@ -47,7 +47,7 @@ extension RESPToken: RESPTokenDecodable { extension ByteBuffer: RESPTokenDecodable { @inlinable - public init(fromRESP token: RESPToken) throws(RESPDecodeError) { + public init(_ token: RESPToken) throws(RESPDecodeError) { switch token.value { case .simpleString(let buffer), .bulkString(let buffer), @@ -76,7 +76,7 @@ extension ByteBuffer: RESPTokenDecodable { extension String: RESPTokenDecodable { @inlinable - public init(fromRESP token: RESPToken) throws(RESPDecodeError) { + public init(_ token: RESPToken) throws(RESPDecodeError) { switch token.value { case .simpleString(let buffer), .bulkString(let buffer), @@ -110,7 +110,7 @@ extension String: RESPTokenDecodable { } extension Int64: RESPTokenDecodable { - public init(fromRESP token: RESPToken) throws(RESPDecodeError) { + public init(_ token: RESPToken) throws(RESPDecodeError) { switch token.value { case .number(let value): self = value @@ -141,7 +141,7 @@ extension Int64: RESPTokenDecodable { extension Int: RESPTokenDecodable { @inlinable - public init(fromRESP token: RESPToken) throws(RESPDecodeError) { + public init(_ token: RESPToken) throws(RESPDecodeError) { switch token.value { case .number(let value): guard let value = Int(exactly: value) else { @@ -175,7 +175,7 @@ extension Int: RESPTokenDecodable { extension Double: RESPTokenDecodable { @inlinable - public init(fromRESP token: RESPToken) throws(RESPDecodeError) { + public init(_ token: RESPToken) throws(RESPDecodeError) { switch token.value { case .double(let value): self = value @@ -200,7 +200,7 @@ extension Double: RESPTokenDecodable { extension Bool: RESPTokenDecodable { @inlinable - public init(fromRESP token: RESPToken) throws(RESPDecodeError) { + public init(_ token: RESPToken) throws(RESPDecodeError) { switch token.value { case .boolean(let value): self = value @@ -212,25 +212,25 @@ extension Bool: RESPTokenDecodable { extension Optional: RESPTokenDecodable where Wrapped: RESPTokenDecodable { @inlinable - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { switch token.value { case .null: self = nil default: - self = try Wrapped(fromRESP: token) + self = try Wrapped(token) } } } extension Array: RESPTokenDecodable where Element: RESPTokenDecodable { @inlinable - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { switch token.value { case .array(let respArray), .set(let respArray), .push(let respArray): do { var array: [Element] = [] for respElement in respArray { - let element = try Element(fromRESP: respElement) + let element = try Element(respElement) array.append(element) } self = array @@ -239,7 +239,7 @@ extension Array: RESPTokenDecodable where Element: RESPTokenDecodable { case .tokenMismatch: // if decoding array failed it is possible `Element` is represented by an array and we have a single array // that represents one element of `Element` instead of Array. We should attempt to decode this as a single element - let value = try Element(fromRESP: token) + let value = try Element(token) self = [value] default: throw error @@ -248,7 +248,7 @@ extension Array: RESPTokenDecodable where Element: RESPTokenDecodable { case .null: throw RESPDecodeError.tokenMismatch(expected: [.array], token: token) default: - let value = try Element(fromRESP: token) + let value = try Element(token) self = [value] } } @@ -256,19 +256,19 @@ extension Array: RESPTokenDecodable where Element: RESPTokenDecodable { extension Set: RESPTokenDecodable where Element: RESPTokenDecodable { @inlinable - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { switch token.value { case .set(let respSet): var set: Set = .init() for respElement in respSet { - let element = try Element(fromRESP: respElement) + let element = try Element(respElement) set.insert(element) } self = set case .null: throw RESPDecodeError.tokenMismatch(expected: [.set], token: token) default: - let value = try Element(fromRESP: token) + let value = try Element(token) self = [value] } } @@ -276,7 +276,7 @@ extension Set: RESPTokenDecodable where Element: RESPTokenDecodable { extension Dictionary: RESPTokenDecodable where Value: RESPTokenDecodable, Key: RESPTokenDecodable { @inlinable - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { switch token.value { case .map(let respMap), .attribute(let respMap): self = try respMap.decode(as: Self.self) @@ -287,7 +287,7 @@ extension Dictionary: RESPTokenDecodable where Value: RESPTokenDecodable, Key: R } extension ClosedRange: RESPTokenDecodable where Bound: RESPTokenDecodable { - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { let (min, max) = try token.decodeArrayElements(as: (Bound, Bound).self) self = min...max } @@ -295,7 +295,7 @@ extension ClosedRange: RESPTokenDecodable where Bound: RESPTokenDecodable { extension RESPToken.Array: RESPTokenDecodable { @inlinable - public init(fromRESP token: RESPToken) throws(RESPDecodeError) { + public init(_ token: RESPToken) throws(RESPDecodeError) { switch token.value { case .array(let respArray), .set(let respArray), .push(let respArray): self = respArray @@ -324,7 +324,7 @@ extension RESPToken.Array: RESPTokenDecodable { func decodeOptionalRESPToken(_ token: RESPToken?, as: T.Type) throws -> T { switch token { case .some(let value): - return try T(fromRESP: value) + return try T(value) case .none: throw RESPDecodeError.invalidArraySize(self, expectedSize: self._parameterPackTypeSize(type)) } @@ -353,7 +353,7 @@ extension RESPToken.Array: RESPTokenDecodable { return .failure(ValkeyClientError(.commandError, message: value.errorString.map { Swift.String(buffer: $0) })) default: do { - return try .success(T(fromRESP: value)) + return try .success(T(value)) } catch { return .failure(error) } @@ -391,7 +391,7 @@ extension RESPToken.Array: RESPTokenDecodable { extension RESPToken.Map: RESPTokenDecodable { @inlinable - public init(fromRESP token: RESPToken) throws(RESPDecodeError) { + public init(_ token: RESPToken) throws(RESPDecodeError) { switch token.value { case .map(let respArray): self = respArray @@ -421,7 +421,7 @@ extension RESPToken.Map: RESPTokenDecodable { as type: [(Key, Value)].Type = [(Key, Value)].self ) throws -> [(Key, Value)] { try self.map { - try (Key(fromRESP: $0.key), Value(fromRESP: $0.value)) + try (Key($0.key), Value($0.value)) } } } diff --git a/Sources/Valkey/Subscriptions/PushToken.swift b/Sources/Valkey/Subscriptions/PushToken.swift index a58f95b3..fa4310e2 100644 --- a/Sources/Valkey/Subscriptions/PushToken.swift +++ b/Sources/Valkey/Subscriptions/PushToken.swift @@ -38,7 +38,7 @@ struct PushToken: RESPTokenDecodable { let value: ValkeySubscriptionFilter let type: TokenType - init(fromRESP token: RESPToken) throws { + init(_ token: RESPToken) throws { switch token.value { case .push(let respArray): var arrayIterator = respArray.makeIterator() @@ -53,76 +53,76 @@ struct PushToken: RESPTokenDecodable { guard respArray.count == 3 else { throw ValkeyClientError(.subscriptionError, message: "Received invalid subscribe push notification") } - self.value = .channel(try String(fromRESP: arrayIterator.next()!)) - self.type = try TokenType.subscribe(subscriptionCount: Int(fromRESP: arrayIterator.next()!)) + self.value = .channel(try String(arrayIterator.next()!)) + self.type = try TokenType.subscribe(subscriptionCount: Int(arrayIterator.next()!)) case Self.unsubscribeString: guard respArray.count == 3 else { throw ValkeyClientError(.subscriptionError, message: "Received invalid unsubscribe push notification") } - self.value = .channel(try String(fromRESP: arrayIterator.next()!)) - self.type = try TokenType.unsubscribe(subscriptionCount: Int(fromRESP: arrayIterator.next()!)) + self.value = .channel(try String(arrayIterator.next()!)) + self.type = try TokenType.unsubscribe(subscriptionCount: Int(arrayIterator.next()!)) case Self.messageString: guard respArray.count == 3 else { throw ValkeyClientError(.subscriptionError, message: "Received invalid message push notification") } - let channel = try String(fromRESP: arrayIterator.next()!) + let channel = try String(arrayIterator.next()!) self.value = .channel(channel) - self.type = try TokenType.message(channel: channel, message: ByteBuffer(fromRESP: arrayIterator.next()!)) + self.type = try TokenType.message(channel: channel, message: ByteBuffer(arrayIterator.next()!)) case Self.psubscribeString: guard respArray.count == 3 else { throw ValkeyClientError(.subscriptionError, message: "Received invalid psubscribe push notification") } - self.value = .pattern(try String(fromRESP: arrayIterator.next()!)) - self.type = try TokenType.subscribe(subscriptionCount: Int(fromRESP: arrayIterator.next()!)) + self.value = .pattern(try String(arrayIterator.next()!)) + self.type = try TokenType.subscribe(subscriptionCount: Int(arrayIterator.next()!)) case Self.punsubscribeString: guard respArray.count == 3 else { throw ValkeyClientError(.subscriptionError, message: "Received invalid punsubscribe push notification") } - self.value = .pattern(try String(fromRESP: arrayIterator.next()!)) - self.type = try TokenType.unsubscribe(subscriptionCount: Int(fromRESP: arrayIterator.next()!)) + self.value = .pattern(try String(arrayIterator.next()!)) + self.type = try TokenType.unsubscribe(subscriptionCount: Int(arrayIterator.next()!)) case Self.pmessageString: guard respArray.count == 4 else { throw ValkeyClientError(.subscriptionError, message: "Received invalid pmessage push notification") } - self.value = .pattern(try String(fromRESP: arrayIterator.next()!)) + self.value = .pattern(try String(arrayIterator.next()!)) self.type = try TokenType.message( - channel: String(fromRESP: arrayIterator.next()!), - message: ByteBuffer(fromRESP: arrayIterator.next()!) + channel: String(arrayIterator.next()!), + message: ByteBuffer(arrayIterator.next()!) ) case Self.ssubscribeString: guard respArray.count == 3 else { throw ValkeyClientError(.subscriptionError, message: "Received invalid ssubscribe push notification") } - self.value = .shardChannel(try String(fromRESP: arrayIterator.next()!)) - self.type = try TokenType.subscribe(subscriptionCount: Int(fromRESP: arrayIterator.next()!)) + self.value = .shardChannel(try String(arrayIterator.next()!)) + self.type = try TokenType.subscribe(subscriptionCount: Int(arrayIterator.next()!)) case Self.sunsubscribeString: guard respArray.count == 3 else { throw ValkeyClientError(.subscriptionError, message: "Received invalid sunsubscribe push notification") } - self.value = .shardChannel(try String(fromRESP: arrayIterator.next()!)) - self.type = try TokenType.unsubscribe(subscriptionCount: Int(fromRESP: arrayIterator.next()!)) + self.value = .shardChannel(try String(arrayIterator.next()!)) + self.type = try TokenType.unsubscribe(subscriptionCount: Int(arrayIterator.next()!)) case Self.smessageString: guard respArray.count == 3 else { throw ValkeyClientError(.subscriptionError, message: "Received invalid smessage push notification") } - let channel = try String(fromRESP: arrayIterator.next()!) + let channel = try String(arrayIterator.next()!) self.value = .shardChannel(channel) - self.type = try TokenType.message(channel: channel, message: ByteBuffer(fromRESP: arrayIterator.next()!)) + self.type = try TokenType.message(channel: channel, message: ByteBuffer(arrayIterator.next()!)) case Self.invalidateString: guard respArray.count == 2 else { throw ValkeyClientError(.subscriptionError, message: "Received invalid invalidate push notification") } self.value = .channel(ValkeySubscriptions.invalidateChannel) - self.type = try TokenType.invalidate(keys: [ValkeyKey](fromRESP: arrayIterator.next()!)) + self.type = try TokenType.invalidate(keys: [ValkeyKey](arrayIterator.next()!)) default: throw ValkeyClientError(.subscriptionError, message: "Received unrecognised notification \(String(buffer: notification))") } diff --git a/Sources/Valkey/Subscriptions/ValkeySubscriptions.swift b/Sources/Valkey/Subscriptions/ValkeySubscriptions.swift index e601363e..1093f017 100644 --- a/Sources/Valkey/Subscriptions/ValkeySubscriptions.swift +++ b/Sources/Valkey/Subscriptions/ValkeySubscriptions.swift @@ -34,7 +34,7 @@ struct ValkeySubscriptions { mutating func notify(_ token: RESPToken) throws -> Bool { let pushToken: PushToken do { - pushToken = try PushToken(fromRESP: token) + pushToken = try PushToken(token) } catch { // push error to all subscriptions on this channel. We're about to close // the channel we should tell them why diff --git a/Sources/Valkey/ValkeyKey.swift b/Sources/Valkey/ValkeyKey.swift index 6b511f1d..f7f60b60 100644 --- a/Sources/Valkey/ValkeyKey.swift +++ b/Sources/Valkey/ValkeyKey.swift @@ -56,7 +56,7 @@ public struct ValkeyKey: Sendable, Equatable, Hashable { extension ValkeyKey: RESPTokenDecodable { @inlinable - public init(fromRESP token: RESPToken) throws { + public init(_ token: RESPToken) throws { switch token.value { case .simpleString(let buffer), .bulkString(let buffer): self._storage = .buffer(buffer) diff --git a/Tests/ValkeyTests/Cluster/ValkeyClusterDescriptionTests.swift b/Tests/ValkeyTests/Cluster/ValkeyClusterDescriptionTests.swift index 5b03b902..377bdc29 100644 --- a/Tests/ValkeyTests/Cluster/ValkeyClusterDescriptionTests.swift +++ b/Tests/ValkeyTests/Cluster/ValkeyClusterDescriptionTests.swift @@ -46,7 +46,7 @@ struct ValkeyClusterDescriptionTests { ]) ]) let token = RESPToken(val) - let description = try ValkeyClusterDescription(fromRESP: token) + let description = try ValkeyClusterDescription(token) #expect( description @@ -104,7 +104,7 @@ struct ValkeyClusterDescriptionTests { let token = RESPToken(val) #expect(throws: RESPDecodeError(.unexpectedToken, token: .init(.bulkString("invalid-health-state")), message: "Invalid Node Health String")) { - _ = try ValkeyClusterDescription(fromRESP: token) + _ = try ValkeyClusterDescription(token) } } @@ -113,7 +113,7 @@ struct ValkeyClusterDescriptionTests { // Non-array token for cluster description let singleValueToken = RESPToken(RESP3Value.bulkString("not-an-array")) #expect(throws: RESPDecodeError.tokenMismatch(expected: [.array], token: .init(.bulkString("not-an-array")))) { - _ = try ValkeyClusterDescription(fromRESP: singleValueToken) + _ = try ValkeyClusterDescription(singleValueToken) } // Non-array token for slots @@ -146,7 +146,7 @@ struct ValkeyClusterDescriptionTests { ) #expect(throws: RESPDecodeError.tokenMismatch(expected: [.array], token: .init(.bulkString("not-an-array")))) { - try ValkeyClusterDescription(fromRESP: invalidSlotsToken) + try ValkeyClusterDescription(invalidSlotsToken) } // Non-array token for nodes @@ -162,7 +162,7 @@ struct ValkeyClusterDescriptionTests { ) #expect(throws: RESPDecodeError.tokenMismatch(expected: [.array], token: .init(.bulkString("not-an-array")))) { - _ = try ValkeyClusterDescription(fromRESP: invalidNodesToken) + _ = try ValkeyClusterDescription(invalidNodesToken) } } @@ -198,7 +198,7 @@ struct ValkeyClusterDescriptionTests { // The error we expect to see first is the invalid role #expect(throws: RESPDecodeError(.unexpectedToken, token: .init(.bulkString("invalid-role")), message: "Invalid Role String")) { - _ = try ValkeyClusterDescription(fromRESP: token) + _ = try ValkeyClusterDescription(token) } } @@ -228,7 +228,7 @@ struct ValkeyClusterDescriptionTests { ]) let token = RESPToken(val) - let description = try ValkeyClusterDescription(fromRESP: token) + let description = try ValkeyClusterDescription(token) #expect( description @@ -305,7 +305,7 @@ struct ValkeyClusterDescriptionTests { ]) let token = RESPToken(val) - let description = try ValkeyClusterDescription(fromRESP: token) + let description = try ValkeyClusterDescription(token) #expect( description diff --git a/Tests/ValkeyTests/RESPDecodeErrorTests.swift b/Tests/ValkeyTests/RESPDecodeErrorTests.swift index 7fc52e2c..b7693823 100644 --- a/Tests/ValkeyTests/RESPDecodeErrorTests.swift +++ b/Tests/ValkeyTests/RESPDecodeErrorTests.swift @@ -13,7 +13,7 @@ struct RESPDecodeErrorTests { func testTokenMismatchWith() { let resp = RESPToken(.null) let error = #expect(throws: RESPDecodeError.self) { - _ = try Bool(fromRESP: resp) + _ = try Bool(resp) } #expect(error?.errorCode == .tokenMismatch) #expect(error?.message == #"Expected to find a boolean"#) @@ -23,7 +23,7 @@ struct RESPDecodeErrorTests { func testTokenMismatchWithMultipleMatches() { let resp = RESPToken(.null) let error = #expect(throws: RESPDecodeError.self) { - _ = try Double(fromRESP: resp) + _ = try Double(resp) } #expect(error?.errorCode == .tokenMismatch) #expect(error?.message == #"Expected to find a double, integer or bulkString token"#) @@ -35,13 +35,13 @@ struct RESPDecodeErrorTests { struct Test: RESPTokenDecodable { let number: Double let number2: Double - init(fromRESP token: RESPToken) throws { + init(_ token: RESPToken) throws { (self.number, self.number2) = try token.decodeArrayElements() } } let resp = RESPToken(.array([.double(1.0)])) let error = #expect(throws: RESPDecodeError.self) { - _ = try Test(fromRESP: resp) + _ = try Test(resp) } #expect(error?.errorCode == .invalidArraySize) #expect(error?.message == "Expected array of size 2 but got an array of size 1") @@ -51,7 +51,7 @@ struct RESPDecodeErrorTests { func testCannotParseInt() { let resp = RESPToken(.bulkString("1.0")) let error = #expect(throws: RESPDecodeError.self) { - _ = try Int(fromRESP: resp) + _ = try Int(resp) } #expect(error?.errorCode == .cannotParseInteger) print(error!) @@ -61,7 +61,7 @@ struct RESPDecodeErrorTests { func testCannotParseDouble() { let resp = RESPToken(.bulkString("1.0a")) let error = #expect(throws: RESPDecodeError.self) { - _ = try Double(fromRESP: resp) + _ = try Double(resp) } #expect(error?.errorCode == .cannotParseDouble) } diff --git a/Tests/ValkeyTests/RESPTokenDecodableTests.swift b/Tests/ValkeyTests/RESPTokenDecodableTests.swift index 2b128377..5e21e844 100644 --- a/Tests/ValkeyTests/RESPTokenDecodableTests.swift +++ b/Tests/ValkeyTests/RESPTokenDecodableTests.swift @@ -19,7 +19,7 @@ struct RESPTokenDecodableTests { func string(testValues: (String, String)) throws { var buffer = ByteBuffer(string: testValues.0) let token = try #require(try RESPToken(consuming: &buffer)) - let string = try String(fromRESP: token) + let string = try String(token) #expect(string == testValues.1) } @@ -30,7 +30,7 @@ struct RESPTokenDecodableTests { func integer(testValues: (String, Int)) throws { var buffer = ByteBuffer(string: testValues.0) let token = try #require(try RESPToken(consuming: &buffer)) - let value = try Int(fromRESP: token) + let value = try Int(token) #expect(value == testValues.1) } @@ -41,7 +41,7 @@ struct RESPTokenDecodableTests { func double(testValues: (String, Double)) throws { var buffer = ByteBuffer(string: testValues.0) let token = try #require(try RESPToken(consuming: &buffer)) - let value = try Double(fromRESP: token) + let value = try Double(token) #expect(value == testValues.1) } @@ -52,7 +52,7 @@ struct RESPTokenDecodableTests { func boolean(testValues: (String, Bool)) throws { var buffer = ByteBuffer(string: testValues.0) let token = try #require(try RESPToken(consuming: &buffer)) - let value = try Bool(fromRESP: token) + let value = try Bool(token) #expect(value == testValues.1) } @@ -63,7 +63,7 @@ struct RESPTokenDecodableTests { func optional(testValues: (String, String?)) throws { var buffer = ByteBuffer(string: testValues.0) let token = try #require(try RESPToken(consuming: &buffer)) - let value = try String?(fromRESP: token) + let value = try String?(token) #expect(value == testValues.1) } @@ -75,7 +75,7 @@ struct RESPTokenDecodableTests { func array(testValues: (String, [String])) throws { var buffer = ByteBuffer(string: testValues.0) let token = try #require(try RESPToken(consuming: &buffer)) - let value = try [String](fromRESP: token) + let value = try [String](token) #expect(value == testValues.1) } @@ -86,7 +86,7 @@ struct RESPTokenDecodableTests { func set(testValues: (String, Set)) throws { var buffer = ByteBuffer(string: testValues.0) let token = try #require(try RESPToken(consuming: &buffer)) - let value = try Set(fromRESP: token) + let value = try Set(token) #expect(value == testValues.1) } @@ -97,7 +97,7 @@ struct RESPTokenDecodableTests { func dictionary(testValues: (String, [String: Int])) throws { var buffer = ByteBuffer(string: testValues.0) let token = try #require(try RESPToken(consuming: &buffer)) - let value = try [String: Int](fromRESP: token) + let value = try [String: Int](token) #expect(value == testValues.1) } @@ -105,7 +105,7 @@ struct RESPTokenDecodableTests { func closedRange() throws { var buffer = ByteBuffer(string: "*2\r\n:1\r\n:10\r\n") let token = try #require(try RESPToken(consuming: &buffer)) - let value = try ClosedRange(fromRESP: token) + let value = try ClosedRange(token) #expect(value == 1...10) } @@ -127,7 +127,7 @@ struct RESPTokenDecodableTests { func arrayOfRanges(testValues: (String, [ClosedRange])) throws { var buffer = ByteBuffer(string: testValues.0) let token = try #require(try RESPToken(consuming: &buffer)) - let value = try [ClosedRange](fromRESP: token) + let value = try [ClosedRange](token) #expect(value == testValues.1) } From 2ad9f9903deac26c4c82d754a454705b03c863a8 Mon Sep 17 00:00:00 2001 From: Adam Fowler Date: Fri, 5 Dec 2025 11:06:01 +0000 Subject: [PATCH 2/2] Fix documentation issue Signed-off-by: Adam Fowler --- Sources/Valkey/Documentation.docc/RESPToken-Decoding.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Valkey/Documentation.docc/RESPToken-Decoding.md b/Sources/Valkey/Documentation.docc/RESPToken-Decoding.md index 92df9be8..42072022 100644 --- a/Sources/Valkey/Documentation.docc/RESPToken-Decoding.md +++ b/Sources/Valkey/Documentation.docc/RESPToken-Decoding.md @@ -12,7 +12,7 @@ The majority of the Valkey commands return the Swift types equivalent to their e ### Decoding RESPToken -A `RESPToken` contains the raw serialized bytes returned by the Valkey server. Valkey-swift introduces a protocol ``RESPTokenDecodable`` for types that can be decoded from a `RESPToken`. Many of Swift core types have been extended to conform to `RESPTokenDecodable`. There are two ways to decode a `RESPToken`. You can call ``RESPTokenDecodable/init(fromRESP:)``. +A `RESPToken` contains the raw serialized bytes returned by the Valkey server. Valkey-swift introduces a protocol ``RESPTokenDecodable`` for types that can be decoded from a `RESPToken`. Many of Swift core types have been extended to conform to `RESPTokenDecodable`. There are two ways to decode a `RESPToken`. You can call ``RESPTokenDecodable/init(_:)``. ```swift let string = String(respToken)