Skip to content

feat: add query parameter support to the reverse! macro - #642

Open
ChrisJr404 wants to merge 2 commits into
cot-rs:masterfrom
ChrisJr404:reverse-query-params
Open

feat: add query parameter support to the reverse! macro#642
ChrisJr404 wants to merge 2 commits into
cot-rs:masterfrom
ChrisJr404:reverse-query-params

Conversation

@ChrisJr404

Copy link
Copy Markdown

Related issue or discussion

Closes #430

Description

Adds query parameter support to reverse!. Path params are still passed right after the view name, and query params can now be added after a ;, using the same key = value syntax:

reverse!(request, "article", id = 5; page = 2, sort = "new")?
// -> "/articles/5?page=2&sort=new"

They get appended as a percent-encoded query string (built with form_urlencoded, which we already depend on). Values only need to implement ToString, just like path params do. When no query params are given the URL is returned unchanged, so existing reverse! calls behave exactly as before.

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)

Path parameters are passed right after the view name, and query
parameters can now be added after a semicolon. They get appended to the
generated URL as a percent-encoded query string, so you don't have to
build it by hand anymore.
@github-actions github-actions Bot added the C-lib Crate: cot (main library crate) label Aug 25, 2026

@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.

Thanks for the contribution @ChrisJr404! Aside the comment on replicating this for the reverse_redirect! macro, this looks good to me.

Comment thread cot/src/router.rs
#[macro_export]
macro_rules! reverse {
($request:expr, $view_name:literal $(, $($key:ident = $value:expr),*)?) => {{
($request:expr, $view_name:literal

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.

would be nice to have this for reverse_redirect! as well

@m4tx m4tx left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hey, thanks for the contribution! I think we could do better on the actual API, but otherwise the change looks good.

Comment thread cot/src/router.rs
/// let url = reverse!(request, "my_custom_app:home")?;
///
/// // with query parameters, this returns `/?page=2&search=cot`:
/// let url = reverse!(request, "home"; page = 2, search = "cot")?;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm not really sold on this API. Semicolon make it feel like an end of a statement, and it's also visually difficult to distinct between route params and query params. Maybe we should do something like this instead?

Suggested change
/// let url = reverse!(request, "home"; page = 2, search = "cot")?;
/// let url = reverse!(request, "home", query: { page = 2, search = "cot" })?;

What do you think? The question also goes to @seqre @ElijahAhianyo

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.

To be honest, I don't really have an issue with the semicolon syntax, since arrays use it too, just in a different context (eg. [0u8; 10]), not as the end of a statement. But I do agree with the visual concern. I'm definitely okay with the explicit query: keyword suggestion, but my only issue is its verbosity, but I couldn't come up with anything meaningfully better.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I tried to come up with alternative approach, but the only thing I came up with is using different character, like question mark shown below, but I think it's actually worse.

let url = reverse!(request, "home" ? page = 2, search = "cot" )?;

So +1 to above, I think the explicit query is fine!

@ChrisJr404

Copy link
Copy Markdown
Author

I like the query: { page = 2, search = "cot" } block better than the semicolon form. It reads as clearly distinct from the path parameters and avoids the statement-terminator feel of the semicolon, which was my main worry with the current syntax. It also leaves room to extend with other named sections later without more punctuation overloading. Happy to rework the macro toward that shape once @seqre / @ElijahAhianyo weigh in, in case they have a preference.

@codecov

codecov Bot commented Sep 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Flag Coverage Δ
rust 90.14% <100.00%> (+0.01%) ⬆️

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

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

C-lib Crate: cot (main library crate)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Query param helper

4 participants