From 8e1772805b39f3c54ba509e075059dc48a7f7992 Mon Sep 17 00:00:00 2001 From: Alex Deem Date: Wed, 12 Jun 2024 22:52:15 +1000 Subject: [PATCH] Support processing by directly providing TypedVariableValue --- .../ScreamURITemplate/Internal/Components.swift | 10 +++++----- Sources/ScreamURITemplate/URITemplate.swift | 14 +++++++++++++- Sources/ScreamURITemplate/VariableProvider.swift | 8 ++++++++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/Sources/ScreamURITemplate/Internal/Components.swift b/Sources/ScreamURITemplate/Internal/Components.swift index 9e63fbc..a8eae7e 100644 --- a/Sources/ScreamURITemplate/Internal/Components.swift +++ b/Sources/ScreamURITemplate/Internal/Components.swift @@ -17,7 +17,7 @@ import Foundation typealias ComponentBase = Sendable protocol Component: ComponentBase { - func expand(variables: VariableProvider) throws -> String + func expand(variables: TypedVariableProvider) throws -> String var variableNames: [String] { get } } @@ -33,7 +33,7 @@ struct LiteralComponent: Component { literal = string } - func expand(variables _: VariableProvider) throws -> String { + func expand(variables _: TypedVariableProvider) throws -> String { let expansion = String(literal) guard let encodedExpansion = expansion.addingPercentEncoding(withAllowedCharacters: reservedAndUnreservedCharacterSet) else { throw URITemplate.Error.expansionFailure(position: literal.startIndex, reason: "Percent Encoding Failed") @@ -48,7 +48,7 @@ struct LiteralPercentEncodedTripletComponent: Component { literal = string } - func expand(variables _: VariableProvider) throws -> String { + func expand(variables _: TypedVariableProvider) throws -> String { return String(literal) } } @@ -64,10 +64,10 @@ struct ExpressionComponent: Component { self.templatePosition = templatePosition } - func expand(variables: VariableProvider) throws -> String { + func expand(variables: TypedVariableProvider) throws -> String { let configuration = expressionOperator.expansionConfiguration() let expansions = try variableList.compactMap { variableSpec -> String? in - guard let value = variables[String(variableSpec.name)]?.asTypedVariableValue() else { + guard let value = variables[String(variableSpec.name)] else { return nil } do { diff --git a/Sources/ScreamURITemplate/URITemplate.swift b/Sources/ScreamURITemplate/URITemplate.swift index 70175c5..770f348 100644 --- a/Sources/ScreamURITemplate/URITemplate.swift +++ b/Sources/ScreamURITemplate/URITemplate.swift @@ -33,7 +33,7 @@ public struct URITemplate { self.components = components } - public func process(variables: VariableProvider) throws -> String { + public func process(variables: TypedVariableProvider) throws -> String { var result = "" for component in components { result += try component.expand(variables: variables) @@ -41,6 +41,18 @@ public struct URITemplate { return result } + public func process(variables: VariableProvider) throws -> String { + struct TypedVariableProviderWrapper: TypedVariableProvider { + let variables: VariableProvider + + subscript(_ key: String) -> TypedVariableValue? { + return variables[key]?.asTypedVariableValue() + } + } + + return try process(variables: TypedVariableProviderWrapper(variables: variables)) + } + public func process(variables: [String: String]) throws -> String { return try process(variables: variables as VariableDictionary) } diff --git a/Sources/ScreamURITemplate/VariableProvider.swift b/Sources/ScreamURITemplate/VariableProvider.swift index 2467e9c..17c4cf6 100644 --- a/Sources/ScreamURITemplate/VariableProvider.swift +++ b/Sources/ScreamURITemplate/VariableProvider.swift @@ -17,10 +17,18 @@ public protocol VariableProvider { subscript(_: String) -> VariableValue? { get } } +public protocol TypedVariableProvider { + subscript(_: String) -> TypedVariableValue? { get } +} + public typealias VariableDictionary = [String: VariableValue] extension VariableDictionary: VariableProvider {} +public typealias TypedVariableDictionary = [String: TypedVariableValue] + +extension TypedVariableDictionary: TypedVariableProvider {} + public struct SequenceVariableProvider: VariableProvider, ExpressibleByArrayLiteral { let sequence: any Sequence