diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 16917443..88956dee 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -54,6 +54,7 @@ jobs:
cargo check --workspace
cargo build --workspace
cargo test --all-targets
+ cargo test --doc
- name: Show SCCache stats
if: always() && !cancelled()
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index b06fb00c..a3bdccaf 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -48,7 +48,7 @@ jobs:
- name: Build docs
run: |
set -eufo pipefail
- cargo doc --no-deps
+ cargo doc --document-private-items --no-deps
rm target/doc/.lock
echo '' > target/doc/index.html
diff --git a/Cargo.toml b/Cargo.toml
index a51df77d..091b263e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -26,10 +26,6 @@ suspicious = { level = "deny", priority = -1 }
# Personal Preferences
module_name_repetitions = "allow"
-# FIXME: Strict
-missing_panics_doc = "allow"
-missing_errors_doc = "allow"
-
[profile.dev.package]
insta.opt-level = 3
similar.opt-level = 3
diff --git a/src/path.rs b/src/path.rs
index c47e2ba3..a4274261 100644
--- a/src/path.rs
+++ b/src/path.rs
@@ -1,39 +1,65 @@
use crate::{decode::percent_decode, errors::decode::DecodeError};
use std::borrow::Cow;
+/// [`Path`] stores the URI data to be used to search for a matching route in a [`Router`](crate::Router).
#[derive(Debug)]
pub struct Path<'path> {
+ /// Original, unaltered path bytes.
+ raw: &'path [u8],
+
+ /// Percent-decoded path bytes.
decoded: Cow<'path, [u8]>,
}
impl<'path> Path<'path> {
+ /// Creates a new [`Path`] instance from a URI path string.
+ ///
+ /// # Errors
+ ///
+ /// Will error if the path fails percent-decoding.
+ ///
+ /// # Examples
+ ///
+ /// ## Valid
+ ///
+ /// ```rust
+ /// let path = wayfind::Path::new("/hello%20world").unwrap();
+ /// assert_eq!(path.raw_bytes(), b"/hello%20world");
+ /// assert_eq!(path.decoded_bytes(), b"/hello world");
+ /// ```
+ ///
+ /// ## Invalid
+ ///
+ /// ```rust
+ /// let path = wayfind::Path::new("/hello%GGworld").unwrap_err();
+ /// let error = "
+ /// invalid percent-encoding
+ ///
+ /// Input: /hello%GGworld
+ /// ^^^
+ ///
+ /// Expected: '%' followed by two hexadecimal digits (a-F, 0-9)
+ /// Found: '%GG'
+ /// ";
+ ///
+ /// assert_eq!(path.to_string(), error.trim());
+ /// ```
pub fn new(path: &'path str) -> Result {
Ok(Self {
+ raw: path.as_bytes(),
decoded: percent_decode(path.as_bytes())?,
})
}
+ /// Returns a reference to the original path bytes.
#[must_use]
- pub fn decoded_bytes(&'path self) -> &'path [u8] {
- &self.decoded
+ pub const fn raw_bytes(&'path self) -> &'path [u8] {
+ self.raw
}
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- #[test]
- fn test_path_invalid_encoding() {
- let error = Path::new("/hello%20world%GG").unwrap_err();
- insta::assert_snapshot!(error, @r###"
- invalid percent-encoding
-
- Input: /hello%20world%GG
- ^^^
-
- Expected: '%' followed by two hexadecimal digits (a-F, 0-9)
- Found: '%GG'
- "###);
+ /// Returns a reference to the percent-decoded path bytes.
+ #[must_use]
+ pub fn decoded_bytes(&'path self) -> &'path [u8] {
+ &self.decoded
}
}
diff --git a/src/router.rs b/src/router.rs
index ee0affab..eeba9d2c 100644
--- a/src/router.rs
+++ b/src/router.rs
@@ -28,6 +28,7 @@ pub struct Router {
impl Router {
#[must_use]
+ #[allow(clippy::missing_panics_doc)]
pub fn new() -> Self {
let mut router = Self {
root: Node {
@@ -68,6 +69,7 @@ impl Router {
router
}
+ #[allow(clippy::missing_errors_doc)]
pub fn constraint(&mut self) -> Result<(), ConstraintError> {
match self.constraints.entry(C::NAME.as_bytes().to_vec()) {
Entry::Vacant(entry) => {
@@ -86,6 +88,7 @@ impl Router {
}
}
+ #[allow(clippy::missing_errors_doc)]
pub fn insert(&mut self, route: &str, value: T) -> Result<(), InsertError> {
let path = Path::new(route)?;
if route.as_bytes() != path.decoded_bytes() {
@@ -119,6 +122,7 @@ impl Router {
self.root.insert(&mut parts, NodeData { path, value })
}
+ #[allow(clippy::missing_errors_doc)]
pub fn delete(&mut self, route: &str) -> Result<(), DeleteError> {
let mut parts = Parts::new(route.as_bytes())?;
self.root.delete(&mut parts)
diff --git a/tests/common.rs b/tests/common.rs
index e42dd788..bd6da651 100644
--- a/tests/common.rs
+++ b/tests/common.rs
@@ -44,6 +44,7 @@ pub struct ExpectedMatch<'k, 'v, T> {
pub params: Vec>,
}
+#[allow(clippy::missing_panics_doc)]
pub fn assert_router_match<'a, T: PartialEq + Debug>(
router: &'a Router,
input: &'a str,