diff --git a/Sources/ScreamURITemplate/TypedURITemplate.swift b/Sources/ScreamURITemplate/TypedURITemplate.swift new file mode 100644 index 0000000..e9814e6 --- /dev/null +++ b/Sources/ScreamURITemplate/TypedURITemplate.swift @@ -0,0 +1,37 @@ +// Copyright 2018-2024 Alex Deem +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import Foundation + +/// A wrapper around a ``URITemplate`` that limits the type of the variables provided when processing +/// This can be used to provide a strongly-typed interface for processing a template +public struct TypedURITemplate { + private let template: URITemplate + + /// Initializes a ``TypedURITemplate`` from a ``URITemplate`` + /// - Parameter template: the URI Template + public init(_ template: URITemplate) { + self.template = template + } + + /// Process a URI Template specifying variables with an instance of the templated type `Variables` + /// - Parameter variables: A ``Variables`` object that can provide values for the template variables + /// + /// - Returns: The result of processing the template + /// + /// - Throws: `URITemplate.Error` with `type = .expansionFailure` if an error occurs processing the template + public func process(variables: Variables) throws(URITemplate.Error) -> String { + try template.process(variables: variables) + } +} diff --git a/Sources/ScreamURITemplateExample/main.swift b/Sources/ScreamURITemplateExample/main.swift index fc770c9..3018951 100644 --- a/Sources/ScreamURITemplateExample/main.swift +++ b/Sources/ScreamURITemplateExample/main.swift @@ -45,3 +45,7 @@ struct GitHubRepoCollaborator { let expansion = try macroExpansion.process(variables: GitHubRepoCollaborator(owner: "SwiftScream", repo: "URITemplate", username: "alexdeem")) print(expansion) + +let typedTemplate = TypedURITemplate(macroExpansion) +let result = try typedTemplate.process(variables: .init(owner: "SwiftScream", repo: "SwiftScream", username: "alexdeem")) +print(result) diff --git a/Tests/ScreamURITemplateTests/Tests.swift b/Tests/ScreamURITemplateTests/Tests.swift index a7d8908..f343392 100644 --- a/Tests/ScreamURITemplateTests/Tests.swift +++ b/Tests/ScreamURITemplateTests/Tests.swift @@ -15,7 +15,7 @@ import ScreamURITemplate import XCTest -struct TestVariableProvider: VariableProvider { +private struct TestVariableProvider: VariableProvider { subscript(_ key: String) -> VariableValue? { switch key { case "missing": diff --git a/Tests/ScreamURITemplateTests/TypedURITemplateTests.swift b/Tests/ScreamURITemplateTests/TypedURITemplateTests.swift new file mode 100644 index 0000000..b403020 --- /dev/null +++ b/Tests/ScreamURITemplateTests/TypedURITemplateTests.swift @@ -0,0 +1,32 @@ +// Copyright 2018-2024 Alex Deem +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import XCTest + +import ScreamURITemplate + +private struct TestVariableProvider: VariableProvider { + subscript(_ key: String) -> VariableValue? { + return "_\(key)_" + } +} + +class TypedURITemplateTests: XCTestCase { + func testExpansion() throws { + let template: URITemplate = "https://api.github.com/repos/{owner}/{repo}/collaborators/{username}" + let typedTemplate = TypedURITemplate(template) + let urlString = try typedTemplate.process(variables: .init()) + XCTAssertEqual(urlString, "https://api.github.com/repos/_owner_/_repo_/collaborators/_username_") + } +}