#![allow(dead_code, unused_variables)]
#[macro_use]
extern crate rkt;
use std::path::PathBuf;
use rkt::form::{
error::{ErrorKind, Errors},
Form,
};
use rkt::http::uri::fmt::{FromUriParam, Query};
use rkt::http::CookieJar;
macro_rules! assert_uri_eq {
($($uri:expr => $expected:expr,)+) => {
$(
let actual = $uri;
let expected = rkt::http::uri::Uri::parse_any($expected).expect("valid URI");
if actual != expected {
panic!("\nURI mismatch: got {}, expected {}\nGot) {:?}\nExpected) {:?}\n",
actual, expected, actual, expected);
}
)+
};
}
#[derive(FromForm, UriDisplayQuery)]
struct User<'a> {
name: &'a str,
nickname: String,
}
impl<'a, 'b> FromUriParam<Query, (&'a str, &'b str)> for User<'a> {
type Target = User<'a>;
fn from_uri_param((name, nickname): (&'a str, &'b str)) -> User<'a> {
User {
name,
nickname: nickname.to_string(),
}
}
}
#[derive(FromForm)]
struct Second {
nickname: String,
}
#[post("/")]
fn index() {}
#[post("/<id>")]
fn simple(id: i32) {}
#[post("/<id>/<name>")]
fn simple2(id: i32, name: String) {}
#[post("/<id>/<name>")]
fn simple2_flipped(name: String, id: i32) {}
#[post("/?<id>")]
fn simple3(id: i32) {}
#[post("/?<id>&<name>")]
fn simple4(id: i32, name: String) {}
#[post("/?<id>&<name>")]
fn simple4_flipped(name: String, id: i32) {}
#[post("/<used>/<_unused>")]
fn unused_param(used: i32, _unused: i32) {}
#[post("/<id>")]
fn guard_1(cookies: &CookieJar<'_>, id: i32) {}
#[post("/<id>/<name>")]
fn guard_2(name: String, cookies: &CookieJar<'_>, id: i32) {}
#[post("/a/<id>/hi/<name>/hey")]
fn guard_3(id: i32, name: String, cookies: &CookieJar<'_>) {}
#[post("/<id>", data = "<form>")]
fn no_uri_display_okay(id: i32, form: Form<Second>) {}
#[post(
"/name/<name>?<myfoo>&type=10&<type>&<query..>",
data = "<user>",
rank = 2
)]
fn complex<'r>(
myfoo: usize,
name: &str,
query: User<'r>,
user: Form<User<'r>>,
r#type: &str,
cookies: &CookieJar<'_>,
) {
}
#[post("/a/<path..>")]
fn segments(path: PathBuf) {}
#[post("/a/<id>/then/<path..>")]
fn param_and_segments(path: PathBuf, id: usize) {}
#[post("/a/<id>/then/<path..>")]
fn guarded_segments(cookies: &CookieJar<'_>, path: PathBuf, id: usize) {}
#[test]
fn check_simple_unnamed() {
assert_uri_eq! {
uri!(simple(100)) => "/100",
uri!(simple(-23)) => "/-23",
uri!(unused_param(1, 2)) => "/1/2",
}
assert_uri_eq! {
uri!(simple2(100, "hello".to_string())) => "/100/hello",
uri!(simple2(1349, "hey".to_string())) => "/1349/hey",
uri!(simple2_flipped(100, "hello".to_string())) => "/100/hello",
}
assert_uri_eq! {
uri!(simple2(100, "hello")) => "/100/hello",
uri!(simple2_flipped(1349, "hey")) => "/1349/hey",
}
assert_uri_eq! {
uri!(simple2(100, "hello there")) => "/100/hello%20there",
uri!(simple2_flipped(100, "hello there")) => "/100/hello%20there",
}
assert_uri_eq! {
uri!(simple3(100)) => "/?id=100",
uri!(simple3(1349)) => "/?id=1349",
uri!(simple4(100, "bob")) => "/?id=100&name=bob",
uri!(simple4(1349, "Bob Anderson")) => "/?id=1349&name=Bob%20Anderson",
uri!(simple4(-2, "@M+s&OU=")) => "/?id=-2&name=@M%2Bs%26OU%3D",
uri!(simple4_flipped(100, "bob")) => "/?id=100&name=bob",
uri!(simple4_flipped(1349, "Bob Anderson")) => "/?id=1349&name=Bob%20Anderson",
}
}
#[test]
fn check_simple_named() {
assert_uri_eq! {
uri!(simple(id = 100)) => "/100",
uri!(simple(id = -23)) => "/-23",
uri!(unused_param(used = 1, _unused = 2)) => "/1/2",
}
assert_uri_eq! {
uri!(simple2(id = 100, name = "hello".to_string())) => "/100/hello",
uri!(simple2(name = "hi".to_string(), id = 123)) => "/123/hi",
uri!(simple2_flipped(id = 1349, name = "hey".to_string())) => "/1349/hey",
uri!(simple2_flipped(name = "hello".to_string(), id = 100)) => "/100/hello",
}
assert_uri_eq! {
uri!(simple2(id = 100, name = "hello")) => "/100/hello",
uri!(simple2(id = 100, name = "hi")) => "/100/hi",
uri!(simple2(id = 1349, name = "hey")) => "/1349/hey",
uri!(simple2(name = "hello", id = 100)) => "/100/hello",
uri!(simple2(name = "hi", id = 100)) => "/100/hi",
uri!(simple2_flipped(id = 1349, name = "hey")) => "/1349/hey",
}
assert_uri_eq! {
uri!(simple2(id = 100, name = "hello there")) => "/100/hello%20there",
uri!(simple2(name = "hello there", id = 100)) => "/100/hello%20there",
uri!(simple2_flipped(id = 100, name = "hello there")) => "/100/hello%20there",
uri!(simple2_flipped(name = "hello there", id = 100)) => "/100/hello%20there",
}
assert_uri_eq! {
uri!(simple3(id = 100)) => "/?id=100",
uri!(simple3(id = 1349)) => "/?id=1349",
uri!(simple4(id = 100, name = "bob")) => "/?id=100&name=bob",
uri!(simple4(id = 1349, name = "Bob A")) => "/?id=1349&name=Bob%20A",
uri!(simple4(name = "Bob A", id = 1349)) => "/?id=1349&name=Bob%20A",
uri!(simple4_flipped(id = 1349, name = "Bob A")) => "/?id=1349&name=Bob%20A",
uri!(simple4_flipped(name = "Bob A", id = 1349)) => "/?id=1349&name=Bob%20A",
}
}
#[test]
fn check_route_prefix_suffix() {
assert_uri_eq! {
uri!(index) => "/",
uri!("/") => "/",
uri!("/", index) => "/",
uri!("/hi", index) => "/hi",
uri!("/myfoo", index) => "/myfoo",
uri!("/hi/", index) => "/hi/",
uri!("/myfoo/", index) => "/myfoo/",
uri!("/", simple3(10)) => "/?id=10",
uri!("/hi", simple3(11)) => "/hi?id=11",
uri!("/hi/", simple3(11)) => "/hi/?id=11",
uri!("/mount", simple(100)) => "/mount/100",
uri!("/mount", simple(id = 23)) => "/mount/23",
uri!("/mount/", simple(100)) => "/mount/100",
uri!("/mount/", simple(id = 23)) => "/mount/23",
uri!("/another", simple(100)) => "/another/100",
uri!("/another", simple(id = 23)) => "/another/23",
uri!("/myfoo") => "/myfoo",
uri!("/myfoo/") => "/myfoo/",
uri!("/myfoo///") => "/myfoo/",
uri!("/myfoo/bar/") => "/myfoo/bar/",
}
assert_uri_eq! {
uri!("http://rocket.rs", index) => "http://rocket.rs",
uri!("http://rocket.rs/", index) => "http://rocket.rs/",
uri!("http://rocket.rs///", index) => "http://rocket.rs/",
uri!("http://rocket.rs/myfoo", index) => "http://rocket.rs/myfoo",
uri!("http://rocket.rs/myfoo/", index) => "http://rocket.rs/myfoo/",
uri!("http://", index) => "http://",
uri!("http:///", index) => "http:///",
uri!("http:////", index) => "http:///",
uri!("ftp:/", index) => "ftp:/",
}
assert_uri_eq! {
uri!("http://rocket.rs", index, "?myfoo") => "http://rocket.rs?myfoo",
uri!("http://rocket.rs", index, "?") => "http://rocket.rs?",
uri!("http://rocket.rs", index, "#") => "http://rocket.rs#",
uri!("http://rocket.rs", index, "#bar") => "http://rocket.rs#bar",
uri!("http://rocket.rs", index, "?bar#baz") => "http://rocket.rs?bar#baz",
uri!("http://rocket.rs/", index, "?myfoo") => "http://rocket.rs/?myfoo",
uri!("http://rocket.rs/", index, "?") => "http://rocket.rs/?",
uri!("http://rocket.rs/", index, "#") => "http://rocket.rs/#",
uri!("http://rocket.rs/", index, "#bar") => "http://rocket.rs/#bar",
uri!("http://rocket.rs/", index, "?bar#baz") => "http://rocket.rs/?bar#baz",
uri!("http://", index, "?myfoo") => "http://?myfoo",
uri!("http://rocket.rs", simple3(id = 100), "?myfoo") => "http://rocket.rs?id=100",
uri!("http://rocket.rs", simple3(id = 100), "?myfoo#bar") => "http://rocket.rs?id=100#bar",
uri!("http://rocket.rs/", simple3(id = 100), "?myfoo") => "http://rocket.rs/?id=100",
uri!("http://rocket.rs/", simple3(id = 100), "?myfoo#bar") =>
"http://rocket.rs/?id=100#bar",
uri!(_, simple3(id = 100), "?myfoo#bar") => "/?id=100#bar",
}
let dyn_origin = uri!("/a/b/c");
let dyn_origin2 = uri!("/a/b/c?myfoo-bar");
let dyn_origin_slash = uri!("/a/b/c/");
assert_uri_eq! {
uri!(dyn_origin.clone(), index) => "/a/b/c",
uri!(dyn_origin2.clone(), index) => "/a/b/c",
uri!(dyn_origin.clone(), simple3(10)) => "/a/b/c?id=10",
uri!(dyn_origin2.clone(), simple3(10)) => "/a/b/c?id=10",
uri!(dyn_origin.clone(), simple(100)) => "/a/b/c/100",
uri!(dyn_origin2.clone(), simple(100)) => "/a/b/c/100",
uri!(dyn_origin.clone(), simple2(100, "hey")) => "/a/b/c/100/hey",
uri!(dyn_origin2.clone(), simple2(100, "hey")) => "/a/b/c/100/hey",
uri!(dyn_origin.clone(), simple2(id = 23, name = "hey")) => "/a/b/c/23/hey",
uri!(dyn_origin2.clone(), simple2(id = 23, name = "hey")) => "/a/b/c/23/hey",
uri!(dyn_origin_slash.clone(), index) => "/a/b/c/",
uri!(dyn_origin_slash.clone(), simple3(10)) => "/a/b/c/?id=10",
uri!(dyn_origin_slash.clone(), simple(100)) => "/a/b/c/100",
}
let dyn_absolute = uri!("http://rocket.rs");
let dyn_absolute_slash = uri!("http://rocket.rs/");
assert_uri_eq! {
uri!(dyn_absolute.clone(), index) => "http://rocket.rs",
uri!(dyn_absolute.clone(), simple(100)) => "http://rocket.rs/100",
uri!(dyn_absolute.clone(), simple3(123)) => "http://rocket.rs?id=123",
uri!(dyn_absolute_slash.clone(), index) => "http://rocket.rs/",
uri!(dyn_absolute_slash.clone(), simple(100)) => "http://rocket.rs/100",
uri!(dyn_absolute_slash.clone(), simple3(123)) => "http://rocket.rs/?id=123",
uri!(uri!("http://rocket.rs/a/b"), index) => "http://rocket.rs/a/b",
uri!("http://rocket.rs/a/b") => "http://rocket.rs/a/b",
uri!(uri!("http://rocket.rs/a/b"), index) => "http://rocket.rs/a/b",
uri!("http://rocket.rs/a/b") => "http://rocket.rs/a/b",
}
let dyn_abs = uri!("http://rocket.rs?myfoo");
assert_uri_eq! {
uri!(_, index, dyn_abs.clone()) => "/?myfoo",
uri!("http://rocket.rs", index, dyn_abs.clone()) => "http://rocket.rs?myfoo",
uri!("http://rocket.rs/", index, dyn_abs.clone()) => "http://rocket.rs/?myfoo",
uri!("http://", index, dyn_abs.clone()) => "http://?myfoo",
uri!(_, simple3(id = 123), dyn_abs) => "/?id=123",
}
let dyn_abs = uri!("http://rocket.rs/?myfoo");
assert_uri_eq! {
uri!(_, index, dyn_abs.clone()) => "/?myfoo",
uri!("http://rocket.rs", index, dyn_abs.clone()) => "http://rocket.rs?myfoo",
uri!("http://rocket.rs/", index, dyn_abs.clone()) => "http://rocket.rs/?myfoo",
uri!("http://", index, dyn_abs.clone()) => "http://?myfoo",
uri!("http:///", index, dyn_abs.clone()) => "http:///?myfoo",
uri!(_, simple3(id = 123), dyn_abs) => "/?id=123",
}
let dyn_ref = uri!("?myfoo#bar");
assert_uri_eq! {
uri!(_, index, dyn_ref.clone()) => "/?myfoo#bar",
uri!("http://rocket.rs", index, dyn_ref.clone()) => "http://rocket.rs?myfoo#bar",
uri!("http://rocket.rs/", index, dyn_ref.clone()) => "http://rocket.rs/?myfoo#bar",
uri!("http://", index, dyn_ref.clone()) => "http://?myfoo#bar",
uri!("http:///", index, dyn_ref.clone()) => "http:///?myfoo#bar",
uri!(_, simple3(id = 123), dyn_ref) => "/?id=123#bar",
}
}
#[test]
fn check_guards_ignored() {
assert_uri_eq! {
uri!("/mount", guard_1(100)) => "/mount/100",
uri!("/mount", guard_2(2938, "boo")) => "/mount/2938/boo",
uri!("/mount", guard_3(340, "Bob")) => "/mount/a/340/hi/Bob/hey",
uri!(guard_1(100)) => "/100",
uri!(guard_2(2938, "boo")) => "/2938/boo",
uri!(guard_3(340, "Bob")) => "/a/340/hi/Bob/hey",
uri!("/mount", guard_1(id = 100)) => "/mount/100",
uri!("/mount", guard_2(id = 2938, name = "boo")) => "/mount/2938/boo",
uri!("/mount", guard_3(id = 340, name = "Bob")) => "/mount/a/340/hi/Bob/hey",
uri!(guard_1(id = 100)) => "/100",
uri!(guard_2(name = "boo", id = 2938)) => "/2938/boo",
uri!(guard_3(name = "Bob", id = 340)) => "/a/340/hi/Bob/hey",
}
}
#[test]
fn check_with_segments() {
assert_uri_eq! {
uri!(segments(PathBuf::from("one/two/three"))) => "/a/one/two/three",
uri!(segments(path = PathBuf::from("one/two/three"))) => "/a/one/two/three",
uri!("/c", segments(PathBuf::from("one/tw o/"))) => "/c/a/one/tw%20o",
uri!("/c", segments(path = PathBuf::from("one/tw o/"))) => "/c/a/one/tw%20o",
uri!(segments(PathBuf::from("one/ tw?o/"))) => "/a/one/%20tw%3Fo",
uri!(param_and_segments(10, PathBuf::from("a/b"))) => "/a/10/then/a/b",
uri!(param_and_segments(id = 10, path = PathBuf::from("a/b"))) => "/a/10/then/a/b",
uri!(guarded_segments(10, PathBuf::from("a/b"))) => "/a/10/then/a/b",
uri!(guarded_segments(id = 10, path = PathBuf::from("a/b"))) => "/a/10/then/a/b",
}
assert_uri_eq! {
uri!(segments("one/two/three")) => "/a/one/two/three",
uri!("/", segments(path = "one/two/three")) => "/a/one/two/three",
uri!("/oh", segments(path = "one/two/three")) => "/oh/a/one/two/three",
uri!(segments("one/ tw?o/")) => "/a/one/%20tw%3Fo",
uri!(param_and_segments(id = 10, path = "a/b")) => "/a/10/then/a/b",
uri!(guarded_segments(10, "a/b")) => "/a/10/then/a/b",
uri!(guarded_segments(id = 10, path = "a/b")) => "/a/10/then/a/b",
}
}
#[test]
fn check_complex() {
assert_uri_eq! {
uri!(complex("no idea", 10, "high", ("A B C", "a c"))) =>
"/name/no%20idea?myfoo=10&type=10&type=high&name=A%20B%20C&nickname=a%20c",
uri!(complex("Bob", 248, "?", User { name: "Robert", nickname: "Bob".into() })) =>
"/name/Bob?myfoo=248&type=10&type=%3F&name=Robert&nickname=Bob",
uri!(complex("Bob", 248, "a a", &User { name: "Robert", nickname: "B".into() })) =>
"/name/Bob?myfoo=248&type=10&type=a%20a&name=Robert&nickname=B",
uri!(complex("no idea", 248, "", &User { name: "A B", nickname: "A".into() })) =>
"/name/no%20idea?myfoo=248&type=10&type=&name=A%20B&nickname=A",
uri!(complex("hi", 3, "b", &User { name: "A B C", nickname: "a b".into() })) =>
"/name/hi?myfoo=3&type=10&type=b&name=A%20B%20C&nickname=a%20b",
uri!(complex(name = "no idea", myfoo = 10, r#type = "high", query = ("A B C", "a c"))) =>
"/name/no%20idea?myfoo=10&type=10&type=high&name=A%20B%20C&nickname=a%20c",
uri!(complex(myfoo = 10, name = "no idea", r#type = "high", query = ("A B C", "a c"))) =>
"/name/no%20idea?myfoo=10&type=10&type=high&name=A%20B%20C&nickname=a%20c",
uri!(complex(query = ("A B C", "a c"), myfoo = 10, name = "no idea", r#type = "high", )) =>
"/name/no%20idea?myfoo=10&type=10&type=high&name=A%20B%20C&nickname=a%20c",
uri!(complex(query = ("A B C", "a c"), myfoo = 10, name = "no idea", r#type = "high")) =>
"/name/no%20idea?myfoo=10&type=10&type=high&name=A%20B%20C&nickname=a%20c",
uri!(complex(query = ("A B C", "a c"), myfoo = 10, name = "no idea", r#type = "high")) =>
"/name/no%20idea?myfoo=10&type=10&type=high&name=A%20B%20C&nickname=a%20c",
uri!(complex(myfoo = 3, name = "hi", r#type = "b",
query = &User { name: "A B C", nickname: "a b".into() })) =>
"/name/hi?myfoo=3&type=10&type=b&name=A%20B%20C&nickname=a%20b",
uri!(complex(query = &User { name: "A B C", nickname: "a b".into() },
myfoo = 3, name = "hi", r#type = "b")) =>
"/name/hi?myfoo=3&type=10&type=b&name=A%20B%20C&nickname=a%20b",
}
let user = User {
name: "Robert",
nickname: "Bob".into(),
};
assert_uri_eq! {
uri!(complex("complex", 0, "high", &user)) =>
"/name/complex?myfoo=0&type=10&type=high&name=Robert&nickname=Bob",
uri!(complex("complex", 0, "high", &user)) =>
"/name/complex?myfoo=0&type=10&type=high&name=Robert&nickname=Bob",
uri!(complex("complex", 0, "high", user)) =>
"/name/complex?myfoo=0&type=10&type=high&name=Robert&nickname=Bob",
}
}
#[test]
fn check_location_promotion() {
struct S1(String);
struct S2 {
name: String,
}
let s1 = S1("Bob".into());
let s2 = S2 { name: "Bob".into() };
assert_uri_eq! {
uri!(simple2(1, &S1("A".into()).0)) => "/1/A",
uri!(simple2(1, &mut S1("A".into()).0)) => "/1/A",
uri!(simple2(1, S1("A".into()).0)) => "/1/A",
uri!(simple2(1, &S2 { name: "A".into() }.name)) => "/1/A",
uri!(simple2(1, &mut S2 { name: "A".into() }.name)) => "/1/A",
uri!(simple2(1, S2 { name: "A".into() }.name)) => "/1/A",
uri!(simple2(1, &s1.0)) => "/1/Bob",
uri!(simple2(1, &s2.name)) => "/1/Bob",
uri!(simple2(2, &s1.0)) => "/2/Bob",
uri!(simple2(2, &s2.name)) => "/2/Bob",
uri!(simple2(2, s1.0)) => "/2/Bob",
uri!(simple2(2, s2.name)) => "/2/Bob",
}
let mut s1 = S1("Bob".into());
let mut s2 = S2 { name: "Bob".into() };
assert_uri_eq! {
uri!(simple2(1, &mut S1("A".into()).0)) => "/1/A",
uri!(simple2(1, S1("A".into()).0)) => "/1/A",
uri!(simple2(1, &mut S2 { name: "A".into() }.name)) => "/1/A",
uri!(simple2(1, S2 { name: "A".into() }.name)) => "/1/A",
uri!(simple2(1, &mut s1.0)) => "/1/Bob",
uri!(simple2(1, &mut s2.name)) => "/1/Bob",
uri!(simple2(2, &mut s1.0)) => "/2/Bob",
uri!(simple2(2, &mut s2.name)) => "/2/Bob",
uri!(simple2(2, s1.0)) => "/2/Bob",
uri!(simple2(2, s2.name)) => "/2/Bob",
}
}
#[test]
fn check_scoped() {
assert_uri_eq! {
uri!(typed_uris::simple(100)) => "/typed_uris/100",
uri!(typed_uris::simple(id = 100)) => "/typed_uris/100",
uri!(typed_uris::deeper::simple(100)) => "/typed_uris/deeper/100",
}
}
mod typed_uris {
#[post("/typed_uris/<id>")]
fn simple(id: i32) {}
#[test]
fn check_simple_scoped() {
assert_uri_eq! {
uri!(simple(id = 100)) => "/typed_uris/100",
uri!(crate::simple(id = 100)) => "/100",
uri!("/mount", crate::simple(id = 100)) => "/mount/100",
uri!(crate::simple2(id = 100, name = "hello")) => "/100/hello",
}
}
pub mod deeper {
#[post("/typed_uris/deeper/<id>")]
fn simple(id: i32) {}
#[test]
fn check_deep_scoped() {
assert_uri_eq! {
uri!(super::simple(id = 100)) => "/typed_uris/100",
uri!(crate::simple(id = 100)) => "/100",
}
}
}
}
#[derive(FromForm, UriDisplayQuery)]
struct Third<'r> {
one: String,
two: &'r str,
}
#[post("/<myfoo>/<bar>?<q1>&<rest..>")]
fn optionals(
myfoo: Option<usize>,
bar: Option<String>,
q1: Result<usize, Errors<'_>>,
rest: Option<Third<'_>>,
) {
}
#[test]
fn test_optional_uri_parameters() {
let mut some_10 = Some(10);
let mut third = Third {
one: "hi there".into(),
two: "a b",
};
assert_uri_eq! {
uri!(optionals(
myfoo = 10,
bar = &"hi there",
q1 = Some(10),
rest = Some(Third { one: "hi there".into(), two: "a b" }),
)) => "/10/hi%20there?q1=10&one=hi%20there&two=a%20b",
uri!(optionals(
myfoo = &10,
bar = &"hi there",
q1 = Some(&10),
rest = Some(&third),
)) => "/10/hi%20there?q1=10&one=hi%20there&two=a%20b",
uri!(optionals(
myfoo = &mut 10,
bar = &mut "hi there",
q1 = some_10.as_mut(),
rest = Some(&mut third),
)) => "/10/hi%20there?q1=10&one=hi%20there&two=a%20b",
uri!(optionals(
myfoo = 10,
bar = &"hi there",
q1 = _,
rest = Some(Third { one: "hi there".into(), two: "a b" }),
)) => "/10/hi%20there?one=hi%20there&two=a%20b",
uri!(optionals(
myfoo = 10,
bar = &"hi there",
q1 = Some(10),
rest = _,
)) => "/10/hi%20there?q1=10",
uri!(optionals(
myfoo = 10,
bar = &"hi there",
q1 = Err(ErrorKind::Missing.into()) as Result<usize, _>,
rest = _,
)) => "/10/hi%20there",
uri!(optionals(
myfoo = 10,
bar = &"hi there",
q1 = None as Option<usize>,
rest = _
)) => "/10/hi%20there",
uri!(optionals(
myfoo = 10,
bar = &"hi there",
q1 = _,
rest = None as Option<Third<'_>>,
)) => "/10/hi%20there",
uri!(optionals(
myfoo = 10,
bar = &"hi there",
q1 = _,
rest = _,
)) => "/10/hi%20there",
}
}
#[test]
fn test_simple_ignored() {
#[get("/<_>")]
fn ignore_one() {}
assert_uri_eq! {
uri!(ignore_one(100)) => "/100",
uri!(ignore_one("hello")) => "/hello",
uri!(ignore_one("cats r us")) => "/cats%20r%20us",
}
#[get("/<_>/<_>")]
fn ignore_two() {}
assert_uri_eq! {
uri!(ignore_two(100, "boop")) => "/100/boop",
uri!(ignore_two(&"hi", "bop")) => "/hi/bop",
}
#[get("/<_>/myfoo/<_>")]
fn ignore_inner_two() {}
#[get("/hi/<_>/myfoo")]
fn ignore_inner_one_a() {}
#[get("/hey/hi/<_>/myfoo/<_>")]
fn ignore_inner_two_b() {}
assert_uri_eq! {
uri!(ignore_inner_two(100, "boop")) => "/100/myfoo/boop",
uri!(ignore_inner_one_a("!?")) => "/hi/!%3F/myfoo",
uri!(ignore_inner_two_b(&mut 5, "boo")) => "/hey/hi/5/myfoo/boo",
}
#[get("/<_>/myfoo/<_>?hi")]
fn ignore_with_q() {}
#[get("/hi/<_>/myfoo/<_>?hi&<hey>")]
fn ignore_with_q2(hey: Option<usize>) {}
#[get("/hi/<_>/myfoo/<_>?<hi>&<hey>")]
fn ignore_with_q3(hi: &str, hey: &str) {}
assert_uri_eq! {
uri!(ignore_with_q(100, "boop")) => "/100/myfoo/boop?hi",
uri!(ignore_with_q2("!?", "bop", Some(3usize))) => "/hi/!%3F/myfoo/bop?hi&hey=3",
uri!(ignore_with_q3(&mut 5, "boo", "hi b", "ho")) => "/hi/5/myfoo/boo?hi=hi%20b&hey=ho",
}
}
#[test]
fn test_maps() {
use rkt::figment::util::map;
use std::collections::{BTreeMap, HashMap};
#[get("/?<bar>")]
fn hmap(mut bar: HashMap<String, usize>) {
let _ = uri!(bmap(&bar));
let _ = uri!(bmap(&mut bar));
let _ = uri!(bmap(bar));
}
assert_uri_eq! {
uri!(hmap(map!["myfoo" => 10])) => "/?bar.k:0=myfoo&bar.v:0=10",
uri!(hmap(map!["myfoo".to_string() => 10])) => "/?bar.k:0=myfoo&bar.v:0=10",
uri!(hmap(&map!["myfoo".to_string() => 10])) => "/?bar.k:0=myfoo&bar.v:0=10",
uri!(hmap(&mut map!["myfoo".to_string() => 10])) => "/?bar.k:0=myfoo&bar.v:0=10",
uri!(hmap(&map!["myfoo" => 10])) => "/?bar.k:0=myfoo&bar.v:0=10",
}
#[get("/?<bar>")]
fn bmap(mut bar: BTreeMap<&str, usize>) {
let _ = uri!(hmap(&bar));
let _ = uri!(hmap(&mut bar));
let _ = uri!(hmap(bar));
}
assert_uri_eq! {
uri!(bmap(map!["myfoo" => 10])) => "/?bar.k:0=myfoo&bar.v:0=10",
uri!(bmap(map!["myfoo".to_string() => 10])) => "/?bar.k:0=myfoo&bar.v:0=10",
uri!(bmap(&map!["myfoo".to_string() => 10])) => "/?bar.k:0=myfoo&bar.v:0=10",
uri!(bmap(&mut map!["myfoo".to_string() => 10])) => "/?bar.k:0=myfoo&bar.v:0=10",
uri!(bmap(&map!["myfoo" => 10])) => "/?bar.k:0=myfoo&bar.v:0=10",
}
}
#[test]
fn test_json() {
use rkt::serde::{json::Json, Deserialize, Serialize};
#[derive(Serialize, Deserialize, Copy, Clone)]
#[serde(crate = "rkt::serde")]
struct Inner<T> {
myfoo: Option<T>,
}
#[get("/?<json>")]
fn myfoo(json: Json<Inner<usize>>) {}
let mut inner = Inner { myfoo: Some(10) };
assert_uri_eq! {
uri!(myfoo(inner)) => "/?json=%7B%22myfoo%22:10%7D",
uri!(myfoo(&inner)) => "/?json=%7B%22myfoo%22:10%7D",
uri!(myfoo(&mut inner)) => "/?json=%7B%22myfoo%22:10%7D",
uri!(myfoo(Json(inner))) => "/?json=%7B%22myfoo%22:10%7D",
uri!(myfoo(&Json(inner))) => "/?json=%7B%22myfoo%22:10%7D",
uri!(myfoo(&mut Json(inner))) => "/?json=%7B%22myfoo%22:10%7D",
}
#[get("/?<json>")]
fn bar(json: Json<Inner<Inner<&str>>>) {}
let mut inner = Inner {
myfoo: Some(Inner { myfoo: Some("hi") }),
};
assert_uri_eq! {
uri!(bar(inner)) => "/?json=%7B%22myfoo%22:%7B%22myfoo%22:%22hi%22%7D%7D",
uri!(bar(&inner)) => "/?json=%7B%22myfoo%22:%7B%22myfoo%22:%22hi%22%7D%7D",
uri!(bar(&mut inner)) => "/?json=%7B%22myfoo%22:%7B%22myfoo%22:%22hi%22%7D%7D",
uri!(bar(Json(inner))) => "/?json=%7B%22myfoo%22:%7B%22myfoo%22:%22hi%22%7D%7D",
uri!(bar(&Json(inner))) => "/?json=%7B%22myfoo%22:%7B%22myfoo%22:%22hi%22%7D%7D",
uri!(bar(&mut Json(inner))) => "/?json=%7B%22myfoo%22:%7B%22myfoo%22:%22hi%22%7D%7D",
}
}
#[test]
fn test_route_uri_normalization_with_prefix() {
#[get("/world")]
fn world() {}
assert_uri_eq! {
uri!("/", index()) => "/",
uri!("/myfoo", index()) => "/myfoo",
uri!("/bar/", index()) => "/bar/",
uri!("/myfoo/bar", index()) => "/myfoo/bar",
uri!("/myfoo/bar/", index()) => "/myfoo/bar/",
uri!("/", world()) => "/world",
uri!("/myfoo", world()) => "/myfoo/world",
uri!("/bar/", world()) => "/bar/world",
uri!("/myfoo/bar", world()) => "/myfoo/bar/world",
uri!("/myfoo/bar/", world()) => "/myfoo/bar/world",
}
}
#[test]
fn test_vec_in_query() {
#[post("/?<v>")]
fn f(v: Vec<usize>) {}
#[post("/?<v>")]
fn g(v: Vec<String>) {}
#[post("/?<v>")]
fn h(v: &[u8]) {}
let bytes = vec![0u8, 1, 2];
assert_uri_eq! {
uri!(f(v = vec![1, 2, 3])) => "/?v=1&v=2&v=3",
uri!(f(v = &vec![1, 2, 3])) => "/?v=1&v=2&v=3",
uri!(f(v = &[1, 2, 3])) => "/?v=1&v=2&v=3",
uri!(f(v = [1, 2, 3])) => "/?v=1&v=2&v=3",
uri!(f(vec![1, 2, 3])) => "/?v=1&v=2&v=3",
uri!(f(&vec![1, 2, 3])) => "/?v=1&v=2&v=3",
uri!(f(&[1, 2, 3])) => "/?v=1&v=2&v=3",
uri!(f([1, 2, 3])) => "/?v=1&v=2&v=3",
uri!(g(v = vec!["a", "b=c", "d"])) => "/?v=a&v=b%3Dc&v=d",
uri!(g(v = &vec!["a", "b=c", "d"])) => "/?v=a&v=b%3Dc&v=d",
uri!(g(v = ["a", "b=c", "d"])) => "/?v=a&v=b%3Dc&v=d",
uri!(g(v = &["a", "b=c", "d"])) => "/?v=a&v=b%3Dc&v=d",
uri!(h(v = bytes.as_slice())) => "/?v=%00%01%02",
uri!(h(v = &[1, 2, 3][..])) => "/?v=%01%02%03",
}
}
#[test]
fn test_either() {
use rkt::either::{Either, Left, Right};
#[get("/<_myfoo>")]
fn f(_myfoo: Either<usize, &str>) {}
assert_uri_eq! {
uri!(f(Left::<usize, &str>(123))) => "/123",
uri!(f(_myfoo = Left::<usize, &str>(710))) => "/710",
uri!(f(Right::<usize, &str>("hello world"))) => "/hello%20world",
uri!(f(_myfoo = Right::<usize, &str>("bye?"))) => "/bye%3F",
}
}