use anyhow::Context; use rfc6570_level_2::UriTemplate; macro_rules! test_cases { ($( $case:ident: ( $template:literal, $expressions:tt, $variables:tt, $var_map:tt, $uri:literal ) ),+) => {$( #[test] fn $case() -> anyhow::Result<()> { let template = UriTemplate::new($template).context(concat!("failed to create TemplateUri from `", $template, "`"))?; assert_eq!(template.uri(), $template); let expressions: Vec<&str> = template.expressions().collect(); assert_eq!(expressions, vec!$expressions); let variables: Vec<&str> = template.variables().collect(); assert_eq!(variables, vec!$variables); let var_map = $var_map.iter().cloned().collect(); let uri = template.expand(&var_map); assert_eq!(uri, $uri); Ok(()) } )+}; } test_cases! { case_example: ( "https://example.com/{resource}/{+id}{#field}", ["{resource}", "{+id}", "{#field}"], ["resource", "id", "field"], [("resource", "user"), ("id", "5"), ("field", "email")], "https://example.com/user/5#email" ), case_username: ( "http://example.com/~{username}/", ["{username}"], ["username"], [("username", "fred")], "http://example.com/~fred/" ), case_var: ( "{var}", ["{var}"], ["var"], [("var", "value"), ("hello", "Hello World!")], "value" ), case_hello: ( "{hello}", ["{hello}"], ["hello"], [("var", "value"), ("hello", "Hello World!")], "Hello%20World%21" ), case_plus_var: ( "{+var}", ["{+var}"], ["var"], [("var", "value"), ("hello", "Hello World!"), ("path", "/foo/bar")], "value" ), case_plus_hello: ( "{+hello}", ["{+hello}"], ["hello"], [("var", "value"), ("hello", "Hello World!"), ("path", "/foo/bar")], "Hello%20World!" ), case_plus_path_begin: ( "{+path}/here", ["{+path}"], ["path"], [("var", "value"), ("hello", "Hello World!"), ("path", "/foo/bar")], "/foo/bar/here" ), case_plus_path_end: ( "here?ref={+path}", ["{+path}"], ["path"], [("var", "value"), ("hello", "Hello World!"), ("path", "/foo/bar")], "here?ref=/foo/bar" ), case_hash_var: ( "X{#var}", ["{#var}"], ["var"], [("var", "value"), ("hello", "Hello World!"), ("path", "/foo/bar")], "X#value" ), case_hash_hello: ( "X{#hello}", ["{#hello}"], ["hello"], [("var", "value"), ("hello", "Hello World!"), ("path", "/foo/bar")], "X#Hello%20World!" ), case_var_semi: ( "{var}", ["{var}"], ["var"], [("var", "value"), ("semi", ";")], "value" ), case_semi: ( "{semi}", ["{semi}"], ["semi"], [("var", "value"), ("semi", ";")], "%3B" ), case_var_complex: ( "{var}", ["{var}"], ["var"], [ ("dub", "me/too"), ("hello", "Hello World!"), ("half", "50%"), ("var", "value"), ("who", "fred"), ("base", "https://example.com/home/"), ("path", "/foo/bar"), ("v", "6"), ("x", "1024"), ("y", "768"), ("empty", "") ], "value" ), case_hello_complex: ( "{hello}", ["{hello}"], ["hello"], [ ("dub", "me/too"), ("hello", "Hello World!"), ("half", "50%"), ("var", "value"), ("who", "fred"), ("base", "https://example.com/home/"), ("path", "/foo/bar"), ("v", "6"), ("x", "1024"), ("y", "768"), ("empty", "") ], "Hello%20World%21" ), case_half: ( "{half}", ["{half}"], ["half"], [ ("dub", "me/too"), ("hello", "Hello World!"), ("half", "50%"), ("var", "value"), ("who", "fred"), ("base", "https://example.com/home/"), ("path", "/foo/bar"), ("v", "6"), ("x", "1024"), ("y", "768"), ("empty", "") ], "50%25" ), case_empty: ( "O{empty}X", ["{empty}"], ["empty"], [ ("dub", "me/too"), ("hello", "Hello World!"), ("half", "50%"), ("var", "value"), ("who", "fred"), ("base", "https://example.com/home/"), ("path", "/foo/bar"), ("v", "6"), ("x", "1024"), ("y", "768"), ("empty", "") ], "OX" ), case_undef: ( "O{undef}X", ["{undef}"], ["undef"], [ ("dub", "me/too"), ("hello", "Hello World!"), ("half", "50%"), ("var", "value"), ("who", "fred"), ("base", "https://example.com/home/"), ("path", "/foo/bar"), ("v", "6"), ("x", "1024"), ("y", "768"), ("empty", "") ], "OX" ), case_plus_var_complex: ( "{+var}", ["{+var}"], ["var"], [ ("dub", "me/too"), ("hello", "Hello World!"), ("half", "50%"), ("var", "value"), ("who", "fred"), ("base", "https://example.com/home/"), ("path", "/foo/bar"), ("v", "6"), ("x", "1024"), ("y", "768"), ("empty", "") ], "value" ), case_plus_hello_complex: ( "{+hello}", ["{+hello}"], ["hello"], [ ("dub", "me/too"), ("hello", "Hello World!"), ("half", "50%"), ("var", "value"), ("who", "fred"), ("base", "https://example.com/home/"), ("path", "/foo/bar"), ("v", "6"), ("x", "1024"), ("y", "768"), ("empty", "") ], "Hello%20World!" ), case_plus_half: ( "{+half}", ["{+half}"], ["half"], [ ("dub", "me/too"), ("hello", "Hello World!"), ("half", "50%"), ("var", "value"), ("who", "fred"), ("base", "https://example.com/home/"), ("path", "/foo/bar"), ("v", "6"), ("x", "1024"), ("y", "768"), ("empty", "") ], "50%25" ), case_base: ( "{base}index", ["{base}"], ["base"], [ ("dub", "me/too"), ("hello", "Hello World!"), ("half", "50%"), ("var", "value"), ("who", "fred"), ("base", "https://example.com/home/"), ("path", "/foo/bar"), ("v", "6"), ("x", "1024"), ("y", "768"), ("empty", "") ], "https%3A%2F%2Fexample.com%2Fhome%2Findex" ), case_plus_base: ( "{+base}index", ["{+base}"], ["base"], [ ("dub", "me/too"), ("hello", "Hello World!"), ("half", "50%"), ("var", "value"), ("who", "fred"), ("base", "https://example.com/home/"), ("path", "/foo/bar"), ("v", "6"), ("x", "1024"), ("y", "768"), ("empty", "") ], "https://example.com/home/index" ), case_plus_empty: ( "O{+empty}X", ["{+empty}"], ["empty"], [ ("dub", "me/too"), ("hello", "Hello World!"), ("half", "50%"), ("var", "value"), ("who", "fred"), ("base", "https://example.com/home/"), ("path", "/foo/bar"), ("v", "6"), ("x", "1024"), ("y", "768"), ("empty", "") ], "OX" ), case_plus_undef: ( "O{+undef}X", ["{+undef}"], ["undef"], [ ("dub", "me/too"), ("hello", "Hello World!"), ("half", "50%"), ("var", "value"), ("who", "fred"), ("base", "https://example.com/home/"), ("path", "/foo/bar"), ("v", "6"), ("x", "1024"), ("y", "768"), ("empty", "") ], "OX" ), case_plus_path_begin_complex: ( "{+path}/here", ["{+path}"], ["path"], [ ("dub", "me/too"), ("hello", "Hello World!"), ("half", "50%"), ("var", "value"), ("who", "fred"), ("base", "https://example.com/home/"), ("path", "/foo/bar"), ("v", "6"), ("x", "1024"), ("y", "768"), ("empty", "") ], "/foo/bar/here" ), case_plus_path_end_complex: ( "here?ref={+path}", ["{+path}"], ["path"], [ ("dub", "me/too"), ("hello", "Hello World!"), ("half", "50%"), ("var", "value"), ("who", "fred"), ("base", "https://example.com/home/"), ("path", "/foo/bar"), ("v", "6"), ("x", "1024"), ("y", "768"), ("empty", "") ], "here?ref=/foo/bar" ), case_plus_path_var: ( "up{+path}{var}/here", ["{+path}", "{var}"], ["path", "var"], [ ("dub", "me/too"), ("hello", "Hello World!"), ("half", "50%"), ("var", "value"), ("who", "fred"), ("base", "https://example.com/home/"), ("path", "/foo/bar"), ("v", "6"), ("x", "1024"), ("y", "768"), ("empty", "") ], "up/foo/barvalue/here" ), case_hash_var_complex: ( "{#var}", ["{#var}"], ["var"], [ ("dub", "me/too"), ("hello", "Hello World!"), ("half", "50%"), ("var", "value"), ("who", "fred"), ("base", "https://example.com/home/"), ("path", "/foo/bar"), ("v", "6"), ("x", "1024"), ("y", "768"), ("empty", "") ], "#value" ), case_hash_hello_complex: ( "{#hello}", ["{#hello}"], ["hello"], [ ("dub", "me/too"), ("hello", "Hello World!"), ("half", "50%"), ("var", "value"), ("who", "fred"), ("base", "https://example.com/home/"), ("path", "/foo/bar"), ("v", "6"), ("x", "1024"), ("y", "768"), ("empty", "") ], "#Hello%20World!" ), case_hash_half: ( "{#half}", ["{#half}"], ["half"], [ ("dub", "me/too"), ("hello", "Hello World!"), ("half", "50%"), ("var", "value"), ("who", "fred"), ("base", "https://example.com/home/"), ("path", "/foo/bar"), ("v", "6"), ("x", "1024"), ("y", "768"), ("empty", "") ], "#50%25" ), case_hash_empty: ( "foo{#empty}", ["{#empty}"], ["empty"], [ ("dub", "me/too"), ("hello", "Hello World!"), ("half", "50%"), ("var", "value"), ("who", "fred"), ("base", "https://example.com/home/"), ("path", "/foo/bar"), ("v", "6"), ("x", "1024"), ("y", "768"), ("empty", "") ], "foo#" ), case_hash_undef: ( "foo{#undef}", ["{#undef}"], ["undef"], [ ("dub", "me/too"), ("hello", "Hello World!"), ("half", "50%"), ("var", "value"), ("who", "fred"), ("base", "https://example.com/home/"), ("path", "/foo/bar"), ("v", "6"), ("x", "1024"), ("y", "768"), ("empty", "") ], "foo" ) }