+
diff --git a/Sources/RoutingKit/Docs.docc/Resources/vapor-routingkit-logo.svg b/Sources/RoutingKit/Docs.docc/Resources/vapor-routingkit-logo.svg
new file mode 100644
index 00000000..56d2e87c
--- /dev/null
+++ b/Sources/RoutingKit/Docs.docc/Resources/vapor-routingkit-logo.svg
@@ -0,0 +1,21 @@
+
diff --git a/Sources/RoutingKit/Docs.docc/theme-settings.json b/Sources/RoutingKit/Docs.docc/theme-settings.json
new file mode 100644
index 00000000..79054c92
--- /dev/null
+++ b/Sources/RoutingKit/Docs.docc/theme-settings.json
@@ -0,0 +1,21 @@
+{
+ "theme": {
+ "aside": { "border-radius": "16px", "border-style": "double", "border-width": "3px" },
+ "border-radius": "0",
+ "button": { "border-radius": "16px", "border-width": "1px", "border-style": "solid" },
+ "code": { "border-radius": "16px", "border-width": "1px", "border-style": "solid" },
+ "color": {
+ "routingkit": "#f00",
+ "documentation-intro-fill": "radial-gradient(circle at top, var(--color-routingkit) 30%, #000 100%)",
+ "documentation-intro-accent": "var(--color-routingkit)",
+ "logo-base": { "dark": "#fff", "light": "#000" },
+ "logo-shape": { "dark": "#000", "light": "#fff" },
+ "fill": { "dark": "#000", "light": "#fff" }
+ },
+ "icons": { "technology": "/routingkit/images/vapor-routingkit-logo.svg" }
+ },
+ "features": {
+ "quickNavigation": { "enable": true },
+ "i18n": { "enable": true }
+ }
+}
diff --git a/Sources/RoutingKit/Parameters.swift b/Sources/RoutingKit/Parameters.swift
index 200aa1ec..bc51fbb4 100644
--- a/Sources/RoutingKit/Parameters.swift
+++ b/Sources/RoutingKit/Parameters.swift
@@ -4,41 +4,42 @@ import Logging
/// Holds dynamic path components that were discovered while routing.
///
/// After this struct has been filled with parameter values, you can fetch
-/// them out by name using `get(_:)`.
+/// them out by name using ``get(_:)`` or ``get(_:as:)``.
///
/// let postID = parameters.get("post_id")
///
public struct Parameters: Sendable {
/// Internal storage.
private var values: [String: String]
- private var catchall: Catchall
+ private var catchall: [String]
+
+ /// The configured logger.
public let logger: Logger
/// Return a list of all parameter names which were captured. Does not include values listed in the catchall.
public var allNames: Set { .init(self.values.keys) }
- /// Creates a new `Parameters`.
+ /// Create a new `Parameters`.
///
- /// Pass this into the `Router.route(path:parameters:)` method to fill with values.
+ /// Pass this to ``Router/route(path:parameters:)`` to fill with values.
public init() {
- self.values = [:]
- self.catchall = Catchall()
- self.logger = Logger(label: "codes.vapor.routingkit")
+ self.init(nil)
}
- /// Creates a new `Parameters`.
- /// Pass this into the `Router.route(path:parameters:)` method to fill with values.
- /// - Parameters:
- /// - logger: The logger to be used. If none is provided, a default one will be created.
+ /// Create a new `Parameters`.
+ ///
+ /// Pass this to ``Router/route(path:parameters:)`` to fill with values.
+ ///
+ /// - Parameter logger: The logger to be used. If none is provided, a default one will be created.
public init(_ logger: Logger?) {
self.values = [:]
- self.catchall = Catchall()
- self.logger = logger ?? Logger(label: "codes.vapor.routingkit")
+ self.catchall = []
+ self.logger = logger ?? .init(label: "codes.vapor.routingkit")
}
/// Grabs the named parameter from the parameter bag.
///
- /// For example GET /posts/:post_id/comments/:comment_id
+ /// For example `GET /posts/:post_id/comments/:comment_id`
/// would be fetched using:
///
/// let postID = parameters.get("post_id")
@@ -51,27 +52,25 @@ public struct Parameters: Sendable {
/// Grabs the named parameter from the parameter bag, casting it to
/// a `LosslessStringConvertible` type.
///
- /// For example GET /posts/:post_id/comments/:comment_id
+ /// For example `GET /posts/:post_id/comments/:comment_id`
/// would be fetched using:
///
/// let postID = parameters.get("post_id", as: Int.self)
/// let commentID = parameters.get("comment_id", as: Int.self)
///
- public func get(_ name: String, as type: T.Type = T.self) -> T?
- where T: LosslessStringConvertible
- {
+ public func get(_ name: String, as type: T.Type = T.self) -> T? {
self.get(name).flatMap(T.init)
}
/// Adds a new parameter value to the bag.
///
- /// - note: The value will be percent-decoded.
+ /// > Note: The value will be percent-decoded.
///
- /// - parameters:
+ /// - Parameters:
/// - name: Unique parameter name
/// - value: Value (percent-encoded if necessary)
public mutating func set(_ name: String, to value: String?) {
- self.values[name] = value?.removingPercentEncoding
+ self.values[name] = value.map { $0.removingPercentEncoding ?? $0 }
}
/// Fetches the components matched by `catchall` (`**`).
@@ -85,30 +84,17 @@ public struct Parameters: Sendable {
/// // not hit
/// }
///
- /// - note: The value will be percent-decoded.
+ /// > Note: The value will be percent-decoded.
///
- /// - returns: The path components matched
- public mutating func getCatchall() -> [String] {
- if self.catchall.isPercentEncoded {
- self.catchall.values = self.catchall.values.map { $0.removingPercentEncoding ?? $0 }
- self.catchall.isPercentEncoded = false
- }
- return self.catchall.values
+ /// - Returns: The path components matched.
+ public func getCatchall() -> [String] {
+ self.catchall
}
/// Stores the components matched by `catchall` (`**`).
///
- /// - parameters:
- /// - matched: The subpaths matched (percent-encoded if necessary)
+ /// - Parameter matched: The subpaths matched (percent-encoded if necessary)
public mutating func setCatchall(matched: [String]) {
- self.catchall = Catchall(values: matched)
- }
-
- /// Holds path components that were matched by `catchall` (`**`).
- ///
- /// Used internally.
- private struct Catchall {
- var values: [String] = []
- var isPercentEncoded: Bool = true
+ self.catchall = matched.map { $0.removingPercentEncoding ?? $0 }
}
}