From 9b8d0bea9dd9e1db6b3ad56fccd4cb8d32663089 Mon Sep 17 00:00:00 2001 From: Alex Deem Date: Wed, 20 Dec 2023 23:28:32 +1100 Subject: [PATCH 1/4] add dependency on swift-docc-plugin --- Package.resolved | 25 +++++++++++++++++++++++++ Package.swift | 1 + 2 files changed, 26 insertions(+) create mode 100644 Package.resolved diff --git a/Package.resolved b/Package.resolved new file mode 100644 index 0000000..9ad5a83 --- /dev/null +++ b/Package.resolved @@ -0,0 +1,25 @@ +{ + "object": { + "pins": [ + { + "package": "SwiftDocCPlugin", + "repositoryURL": "https://github.com/apple/swift-docc-plugin", + "state": { + "branch": null, + "revision": "26ac5758409154cc448d7ab82389c520fa8a8247", + "version": "1.3.0" + } + }, + { + "package": "SymbolKit", + "repositoryURL": "https://github.com/apple/swift-docc-symbolkit", + "state": { + "branch": null, + "revision": "b45d1f2ed151d057b54504d653e0da5552844e34", + "version": "1.0.0" + } + } + ] + }, + "version": 1 +} diff --git a/Package.swift b/Package.swift index 69d682c..5006247 100644 --- a/Package.swift +++ b/Package.swift @@ -10,6 +10,7 @@ let package = Package( targets: ["ScreamURITemplate"]), ], dependencies: [ + .package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"), ], targets: [ .target( From 9ff4d59912ce088f8382515eae9618365bb85981 Mon Sep 17 00:00:00 2001 From: Alex Deem Date: Thu, 13 Jun 2024 22:49:28 +1000 Subject: [PATCH 2/4] Add docc documentation comments --- Sources/ScreamURITemplate/URITemplate.swift | 33 +++++++++++++++++++ .../ScreamURITemplate/VariableProvider.swift | 26 +++++++++++++++ Sources/ScreamURITemplate/VariableValue.swift | 25 ++++++++++++++ 3 files changed, 84 insertions(+) diff --git a/Sources/ScreamURITemplate/URITemplate.swift b/Sources/ScreamURITemplate/URITemplate.swift index 770f348..c1e309b 100644 --- a/Sources/ScreamURITemplate/URITemplate.swift +++ b/Sources/ScreamURITemplate/URITemplate.swift @@ -14,15 +14,23 @@ import Foundation +/// An [RFC6570](https://tools.ietf.org/html/rfc6570) URI Template public struct URITemplate { + /// An error that may be thrown when parsing or processing a template public enum Error: Swift.Error { + /// Represents an error parsing a string into a URI Template case malformedTemplate(position: String.Index, reason: String) + /// Represents an error processing a template case expansionFailure(position: String.Index, reason: String) } private let string: String private let components: [Component] + /// Initializes a URITemplate from a string + /// - Parameter string: the string representation of the URI Template + /// + /// - Throws: `URITemplate.Error.malformedTemplate` if the string is not a valid URI Template public init(string: String) throws { var components: [Component] = [] var scanner = Scanner(string: string) @@ -33,6 +41,12 @@ public struct URITemplate { self.components = components } + /// Process a URI Template with the specified variables + /// - Parameter variables: A ``TypedVariableProvider`` that can provide values for the templates variables + /// + /// - Returns: The result of processing the template + /// + /// - Throws: `URITemplate.Error.expansionFailure` if an error occurs processing the template public func process(variables: TypedVariableProvider) throws -> String { var result = "" for component in components { @@ -41,6 +55,15 @@ public struct URITemplate { return result } + /// Process a URI Template with the specified variables + /// + /// This method allows for specifying variables in a more ergonomic manner compared to using ``TypedVariableValue`` directly + /// + /// - Parameter variables: A ``VariableProvider`` that can provide values for the templates variables + /// + /// - Returns: The result of processing the template + /// + /// - Throws: `URITemplate.Error.expansionFailure` if an error occurs processing the template public func process(variables: VariableProvider) throws -> String { struct TypedVariableProviderWrapper: TypedVariableProvider { let variables: VariableProvider @@ -53,10 +76,20 @@ public struct URITemplate { return try process(variables: TypedVariableProviderWrapper(variables: variables)) } + /// Process a URI Template with the specified string variables + /// + /// This method is an override allowing for the special case of string-only variables without needing to typecast + /// + /// - Parameter variables: A [String: String] dictionary representing the variables + /// + /// - Returns: The result of processing the template + /// + /// - Throws: `URITemplate.Error.expansionFailure` if an error occurs processing the template public func process(variables: [String: String]) throws -> String { return try process(variables: variables as VariableDictionary) } + /// An array of all variable names used in the template public var variableNames: [String] { return components.flatMap { component in return component.variableNames diff --git a/Sources/ScreamURITemplate/VariableProvider.swift b/Sources/ScreamURITemplate/VariableProvider.swift index fe1677b..cbf8d0f 100644 --- a/Sources/ScreamURITemplate/VariableProvider.swift +++ b/Sources/ScreamURITemplate/VariableProvider.swift @@ -13,22 +13,48 @@ import Foundation +/// A type that provides variable values to use in template processing +/// +/// This type provides values using ``VariableValue`` which allows for an ergonomic way to provide values. public protocol VariableProvider { + /// Get the ``VariableValue`` for a given variable + /// + /// - Parameters: + /// - _: the name of the variable + /// + /// - Returns: the ``VariableValue`` for the variable, or `nil` if the variable has no value subscript(_: String) -> VariableValue? { get } } +/// A type that provides variable values to use in template processing +/// +/// This type provides values using ``TypedVariableValue`` +/// +/// Consider using ``VariableProvider`` for a more ergonomic way of providing variable values. public protocol TypedVariableProvider { + /// Get the ``TypedVariableValue`` for a given variable + /// + /// - Parameters: + /// - _: the name of the variable + /// + /// - Returns: the ``TypedVariableValue`` for the variable, or `nil` if the variable has no value subscript(_: String) -> TypedVariableValue? { get } } +/// A typealias for the most simple ``VariableProvider`` implementation: `[String: VariableValue]` public typealias VariableDictionary = [String: VariableValue] extension VariableDictionary: VariableProvider {} +/// A typealias for the most simple ``TypedVariableProvider`` implementation: `[String: TypedVariableValue]` public typealias TypedVariableDictionary = [String: TypedVariableValue] extension TypedVariableDictionary: TypedVariableProvider {} +/// An object that aggregates a `Sequence` of ``VariableProvider`` as a single ``VariableProvider`` +/// +/// This object allows using a prioritised sequence of VariableProvider as a single VariableProvider. +/// The first VariableProvider in the sequence that provides a value for a given variable name is the value that is returned. public struct SequenceVariableProvider: VariableProvider, ExpressibleByArrayLiteral { let sequence: any Sequence diff --git a/Sources/ScreamURITemplate/VariableValue.swift b/Sources/ScreamURITemplate/VariableValue.swift index a4e7314..23cea2b 100644 --- a/Sources/ScreamURITemplate/VariableValue.swift +++ b/Sources/ScreamURITemplate/VariableValue.swift @@ -14,21 +14,45 @@ import Foundation +/// The value of a URITemplate variable to use during processing +/// +/// This type represents the value of a variable, as defined by [RFC6570](https://tools.ietf.org/html/rfc6570), to be used in +/// template processing. +/// +/// Variables can be either a string, a list of strings, or an associative array of string key, value pairs. +/// +/// While you can process a template by providing variable values using this type (via ``TypedVariableProvider``) you may find it +/// more ergonomic to provide ``VariableValue`` using ``VariableProvider``, or for simple cases simply `[String: String]` public enum TypedVariableValue { + /// A simple string value case string(String) + /// An ordered list of strings case list([String]) + /// An associative array of string key, value pairs + /// + /// Note that the elements are ordered case associativeArray([(key: String, value: String)]) } +/// A protocol enabling ergonomic expression of variable values +/// +/// Conforming a type to this protocol will enable it to be directly provided as a variable value via ``VariableProvider`` public protocol VariableValue { + /// Converts this value to a TypedVariableValue to be used for template processing func asTypedVariableValue() -> TypedVariableValue? } +/// A protocol enabling ergonomic expression of simple string variable values +/// +/// Conforming a type to this protocol will enable it to be directly provided as a variable value, or as an element in a list or +/// associative array value via ``VariableProvider`` public protocol StringVariableValue: VariableValue { + /// Converts this value to a `String` to be used for template processing func asString() -> String } public extension StringVariableValue { + /// Converts this value to a TypedVariableValue to be used for template processing func asTypedVariableValue() -> TypedVariableValue? { .string(asString()) } @@ -53,6 +77,7 @@ extension [String: StringVariableValue]: VariableValue { } public extension LosslessStringConvertible { + /// Converts this value to a `String` to be used for template processing func asString() -> String { description } From f0cbb075cbb2a0b4d6c1402de43c8d665b21456e Mon Sep 17 00:00:00 2001 From: Alex Deem Date: Thu, 13 Jun 2024 22:55:22 +1000 Subject: [PATCH 3/4] Have swiftlint complain about missing documentation --- .swiftlint.yml | 1 + Sources/ScreamURITemplate/URITemplate.swift | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.swiftlint.yml b/.swiftlint.yml index 87d4f48..63ffd9b 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -3,6 +3,7 @@ disabled_rules: - redundant_optional_initialization opt_in_rules: + - missing_docs included: diff --git a/Sources/ScreamURITemplate/URITemplate.swift b/Sources/ScreamURITemplate/URITemplate.swift index c1e309b..dbd1398 100644 --- a/Sources/ScreamURITemplate/URITemplate.swift +++ b/Sources/ScreamURITemplate/URITemplate.swift @@ -41,8 +41,8 @@ public struct URITemplate { self.components = components } - /// Process a URI Template with the specified variables - /// - Parameter variables: A ``TypedVariableProvider`` that can provide values for the templates variables + /// Process a URI Template specifying variables with a ``TypedVariableProvider`` + /// - Parameter variables: A ``TypedVariableProvider`` that can provide values for the template variables /// /// - Returns: The result of processing the template /// @@ -55,11 +55,11 @@ public struct URITemplate { return result } - /// Process a URI Template with the specified variables + /// Process a URI Template specifying variables with a ``VariableProvider`` /// /// This method allows for specifying variables in a more ergonomic manner compared to using ``TypedVariableValue`` directly /// - /// - Parameter variables: A ``VariableProvider`` that can provide values for the templates variables + /// - Parameter variables: A ``VariableProvider`` that can provide values for the template variables /// /// - Returns: The result of processing the template /// @@ -76,7 +76,7 @@ public struct URITemplate { return try process(variables: TypedVariableProviderWrapper(variables: variables)) } - /// Process a URI Template with the specified string variables + /// Process a URI Template where the variable values are all of type string /// /// This method is an override allowing for the special case of string-only variables without needing to typecast /// From 8f853a832561f90ea73156d8afed8647aa8cf155 Mon Sep 17 00:00:00 2001 From: Alex Deem Date: Thu, 13 Jun 2024 22:56:58 +1000 Subject: [PATCH 4/4] Update Copyright Headers --- Sources/ScreamURITemplate/Internal/CharacterSets.swift | 2 +- Sources/ScreamURITemplate/Internal/Components.swift | 2 +- Sources/ScreamURITemplate/Internal/ExpansionConfiguration.swift | 2 +- Sources/ScreamURITemplate/Internal/ExpressionOperator.swift | 2 +- Sources/ScreamURITemplate/Internal/Scanner.swift | 2 +- Sources/ScreamURITemplate/Internal/ValueFormatting.swift | 2 +- Sources/ScreamURITemplate/Internal/VariableSpec.swift | 2 +- Sources/ScreamURITemplate/URITemplate.swift | 2 +- Sources/ScreamURITemplate/VariableProvider.swift | 1 + Sources/ScreamURITemplate/VariableValue.swift | 2 +- Sources/ScreamURITemplateExample/main.swift | 2 +- Tests/ScreamURITemplateTests/JSONValue.swift | 2 +- Tests/ScreamURITemplateTests/TestFileTests.swift | 2 +- Tests/ScreamURITemplateTests/TestModels.swift | 2 +- Tests/ScreamURITemplateTests/Tests.swift | 2 +- 15 files changed, 15 insertions(+), 14 deletions(-) diff --git a/Sources/ScreamURITemplate/Internal/CharacterSets.swift b/Sources/ScreamURITemplate/Internal/CharacterSets.swift index 6c3b1f0..40565cd 100644 --- a/Sources/ScreamURITemplate/Internal/CharacterSets.swift +++ b/Sources/ScreamURITemplate/Internal/CharacterSets.swift @@ -1,4 +1,4 @@ -// Copyright 2018-2023 Alex Deem +// 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. diff --git a/Sources/ScreamURITemplate/Internal/Components.swift b/Sources/ScreamURITemplate/Internal/Components.swift index a8eae7e..4280d4f 100644 --- a/Sources/ScreamURITemplate/Internal/Components.swift +++ b/Sources/ScreamURITemplate/Internal/Components.swift @@ -1,4 +1,4 @@ -// Copyright 2018-2023 Alex Deem +// 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. diff --git a/Sources/ScreamURITemplate/Internal/ExpansionConfiguration.swift b/Sources/ScreamURITemplate/Internal/ExpansionConfiguration.swift index bbe038a..5e533c7 100644 --- a/Sources/ScreamURITemplate/Internal/ExpansionConfiguration.swift +++ b/Sources/ScreamURITemplate/Internal/ExpansionConfiguration.swift @@ -1,4 +1,4 @@ -// Copyright 2018-2023 Alex Deem +// 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. diff --git a/Sources/ScreamURITemplate/Internal/ExpressionOperator.swift b/Sources/ScreamURITemplate/Internal/ExpressionOperator.swift index 6aae900..08d3b53 100644 --- a/Sources/ScreamURITemplate/Internal/ExpressionOperator.swift +++ b/Sources/ScreamURITemplate/Internal/ExpressionOperator.swift @@ -1,4 +1,4 @@ -// Copyright 2018-2023 Alex Deem +// 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. diff --git a/Sources/ScreamURITemplate/Internal/Scanner.swift b/Sources/ScreamURITemplate/Internal/Scanner.swift index 331a80d..24af5cd 100644 --- a/Sources/ScreamURITemplate/Internal/Scanner.swift +++ b/Sources/ScreamURITemplate/Internal/Scanner.swift @@ -1,4 +1,4 @@ -// Copyright 2018-2023 Alex Deem +// 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. diff --git a/Sources/ScreamURITemplate/Internal/ValueFormatting.swift b/Sources/ScreamURITemplate/Internal/ValueFormatting.swift index 9b31efb..bf6d7bc 100644 --- a/Sources/ScreamURITemplate/Internal/ValueFormatting.swift +++ b/Sources/ScreamURITemplate/Internal/ValueFormatting.swift @@ -1,4 +1,4 @@ -// Copyright 2018-2023 Alex Deem +// 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. diff --git a/Sources/ScreamURITemplate/Internal/VariableSpec.swift b/Sources/ScreamURITemplate/Internal/VariableSpec.swift index 8834570..370edf1 100644 --- a/Sources/ScreamURITemplate/Internal/VariableSpec.swift +++ b/Sources/ScreamURITemplate/Internal/VariableSpec.swift @@ -1,4 +1,4 @@ -// Copyright 2018-2023 Alex Deem +// 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. diff --git a/Sources/ScreamURITemplate/URITemplate.swift b/Sources/ScreamURITemplate/URITemplate.swift index dbd1398..2ec7c13 100644 --- a/Sources/ScreamURITemplate/URITemplate.swift +++ b/Sources/ScreamURITemplate/URITemplate.swift @@ -1,4 +1,4 @@ -// Copyright 2018-2023 Alex Deem +// 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. diff --git a/Sources/ScreamURITemplate/VariableProvider.swift b/Sources/ScreamURITemplate/VariableProvider.swift index cbf8d0f..d969a61 100644 --- a/Sources/ScreamURITemplate/VariableProvider.swift +++ b/Sources/ScreamURITemplate/VariableProvider.swift @@ -1,3 +1,4 @@ +// 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. diff --git a/Sources/ScreamURITemplate/VariableValue.swift b/Sources/ScreamURITemplate/VariableValue.swift index 23cea2b..a3a66fa 100644 --- a/Sources/ScreamURITemplate/VariableValue.swift +++ b/Sources/ScreamURITemplate/VariableValue.swift @@ -1,4 +1,4 @@ -// Copyright 2018-2023 Alex Deem +// 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. diff --git a/Sources/ScreamURITemplateExample/main.swift b/Sources/ScreamURITemplateExample/main.swift index 7c5870d..13d8d9d 100644 --- a/Sources/ScreamURITemplateExample/main.swift +++ b/Sources/ScreamURITemplateExample/main.swift @@ -1,4 +1,4 @@ -// Copyright 2018-2023 Alex Deem +// 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. diff --git a/Tests/ScreamURITemplateTests/JSONValue.swift b/Tests/ScreamURITemplateTests/JSONValue.swift index 16e39eb..13a574b 100644 --- a/Tests/ScreamURITemplateTests/JSONValue.swift +++ b/Tests/ScreamURITemplateTests/JSONValue.swift @@ -1,4 +1,4 @@ -// Copyright 2018-2023 Alex Deem +// 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. diff --git a/Tests/ScreamURITemplateTests/TestFileTests.swift b/Tests/ScreamURITemplateTests/TestFileTests.swift index c008a8f..f96bdff 100644 --- a/Tests/ScreamURITemplateTests/TestFileTests.swift +++ b/Tests/ScreamURITemplateTests/TestFileTests.swift @@ -1,4 +1,4 @@ -// Copyright 2018-2023 Alex Deem +// 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. diff --git a/Tests/ScreamURITemplateTests/TestModels.swift b/Tests/ScreamURITemplateTests/TestModels.swift index 15f6776..4cf5a2a 100644 --- a/Tests/ScreamURITemplateTests/TestModels.swift +++ b/Tests/ScreamURITemplateTests/TestModels.swift @@ -1,4 +1,4 @@ -// Copyright 2018-2023 Alex Deem +// 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. diff --git a/Tests/ScreamURITemplateTests/Tests.swift b/Tests/ScreamURITemplateTests/Tests.swift index 281ab24..a7d8908 100644 --- a/Tests/ScreamURITemplateTests/Tests.swift +++ b/Tests/ScreamURITemplateTests/Tests.swift @@ -1,4 +1,4 @@ -// Copyright 2018-2023 Alex Deem +// 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.