Skip to content

Added wildcard feature#586

Draft
dharshan-0 wants to merge 8 commits into
cot-rs:masterfrom
dharshan-0:wildcard-feature
Draft

Added wildcard feature#586
dharshan-0 wants to merge 8 commits into
cot-rs:masterfrom
dharshan-0:wildcard-feature

Conversation

@dharshan-0

@dharshan-0 dharshan-0 commented Jun 3, 2026

Copy link
Copy Markdown

Related issue or discussion

Description

It closes #545 by adding wildcard routing feature.

It uses this *param_name to define wildcard.

Route::with_handler_and_name("/random/*path", generate_random, "generate-random"),

Type of change

  • Bug fix
  • New feature
  • Documentation
  • Refactor / cleanup
  • Performance improvement
  • Other (describe above)

Checklist

  • I've read the contributing guide
  • Tests pass locally (just test-all)
  • Code passes clippy (just clippy)
  • Code is properly formatted (cargo fmt)
  • New tests added (regression test for bugs, coverage for new features)
  • Documentation (both code and site) updated (if applicable)

@github-actions github-actions Bot added A-docs Area: Documentation C-lib Crate: cot (main library crate) labels Jun 3, 2026
@codecov

codecov Bot commented Jun 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Flag Coverage Δ
rust 90.29% <100.00%> (+0.03%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
cot/src/router/path.rs 99.71% <100.00%> (+0.07%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ElijahAhianyo ElijahAhianyo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dharshan-0 Thanks a lot for your contribution. This is a great start! Let's address the comments, and it's good to merge.

Comment thread cot/src/router/path.rs
(Some('/') | None, State::Param { start }) => {
panic!("Unclosed parameter: `{}`", &path_pattern[start..index]);
}
(Some('*'), State::Literal { start }) => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, this branch implies that routes such as /foo/va*path are valid. I don't think we should support this, as it introduces ambiguity around how characters preceding the * should be handled.

To keep the routing semantics simple and predictable, wildcard segments should be required to begin with the * operator. In other words, patterns like *path would be valid, whereas va*path would not.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also think that, for the sake of consistency with path params, we should have wildcards in curly braces as well. i.e {*path} instead of plain *path

Comment thread cot/src/router/path.rs
);

parts.push(PathPart::Literal(literal_name.to_string()));
parts.push(PathPart::Param {

@ElijahAhianyo ElijahAhianyo Jun 8, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to add some type safety here and model wildcards explicitly. Instead of encoding wildcard semantics in the parameter name, we could introduce a PathPart::Wildcard variant and help the compiler distinguish between wildcards and regular path params.

Comment thread cot/src/router/path.rs

parts.push(PathPart::Literal(literal_name.to_string()));
parts.push(PathPart::Param {
name: (*param_name).to_string(),

@ElijahAhianyo ElijahAhianyo Jun 8, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we should include the * when storing the parameter name. Doing so forces downstream consumers to handle the wildcard marker themselves, which feels like a leaky abstraction.

For example:

let path_parser = PathMatcher::new("/{*path}");
assert_eq!(
    path_parser.capture("/foo/bar"),
    Some(CaptureResult::new(
        vec![PathParam::new("*path", "foo/bar")],
        ""
    ))
);

Instead, the * should be treated as part of the route syntax rather than part of the parameter name:

let path_parser = PathMatcher::new("/{*path}");
assert_eq!(
    path_parser.capture("/foo/bar"),
    Some(CaptureResult::new(
        vec![PathParam::new("path", "foo/bar")],
        ""
    ))
);

Similarly, when using ReverseParamMap, callers should not have to include the * in the parameter name:

let path_parser = PathMatcher::new("/users/{*path}");

let mut params = ReverseParamMap::new();
params.insert("path", "foo"); // `path` instead of `*path`

assert_eq!(
    path_parser.reverse(&params).unwrap(),
    "/users/123/foo"
);

Comment thread cot/src/router/path.rs
let path_parser = PathMatcher::new("/users/rand/*path");
assert_eq!(
path_parser.capture("/users/rand/"),
Some(CaptureResult::new(vec![PathParam::new("*path", "")], ""))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency with matching params, users/rand/{*path} should not match users/rand (however, users/rand/foo should be a match).

@dharshan-0

dharshan-0 commented Jun 8, 2026

Copy link
Copy Markdown
Author

@ElijahAhianyo Thanks for your comments, I will look into it.

@dharshan-0 dharshan-0 marked this pull request as draft June 8, 2026 16:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-docs Area: Documentation C-lib Crate: cot (main library crate)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support Wildcard in Routes

2 participants