pub trait UriDisplay<P> where
P: Part, {
fn fmt(&self, f: &mut Formatter<'_, P>) -> Result<(), Error>;
}
Expand description
Trait implemented by types that can be displayed as part of a URI in
uri!
.
Types implementing this trait can be displayed in a URI-safe manner. Unlike
Display
, the string written by a UriDisplay
implementation must be
URI-safe. In practice, this means that the string must either be
percent-encoded or consist only of characters that are alphanumeric, “-”,
“.”, “_”, or “~” - the “unreserved” characters.
Marker Generic: Path
, Query
The Part
parameter P
in UriDisplay<P>
must be either Path
or
Query
(see the Part
documentation for how this is enforced),
resulting in either UriDisplay<Path>
or UriDisplay<Query>
.
As the names might imply, the Path
version of the trait is used when
displaying parameters in the path part of the URI while the Query
version
is used when displaying parameters in the query part of the URI. These
distinct versions of the trait exist exactly to differentiate, at the
type-level, where in the URI a value is to be written to, allowing for type
safety in the face of differences between the two locations. For example,
while it is valid to use a value of None
in the query part, omitting the
parameter entirely, doing so is not valid in the path part. By
differentiating in the type system, both of these conditions can be enforced
appropriately through distinct implementations of UriDisplay<Path>
and
UriDisplay<Query>
.
Occasionally, the implementation of UriDisplay
is independent of where the
parameter is to be displayed. When this is the case, the parameter may be
kept generic. That is, implementations can take the form:
impl<P: Part> UriDisplay<P> for SomeType
Code Generation
When the uri!
macro is used to generate a URI for a route, the types for
the route’s path URI parameters must implement UriDisplay<Path>
, while
types in the route’s query parameters must implement UriDisplay<Query>
.
Any parameters ignored with _
must be of a type that implements
Ignorable
. The UriDisplay
implementation for these types is used when
generating the URI.
To illustrate UriDisplay
’s role in code generation for uri!
, consider
the following route:
#[get("/item/<id>?<track>")]
fn get_item(id: i32, track: Option<String>) { /* .. */ }
A URI for this route can be generated as follows:
// With unnamed parameters.
uri!(get_item(100, Some("inbound")));
// With named parameters.
uri!(get_item(id = 100, track = Some("inbound")));
uri!(get_item(track = Some("inbound"), id = 100));
// Ignoring `track`.
uri!(get_item(100, _));
uri!(get_item(100, None as Option<String>));
uri!(get_item(id = 100, track = _));
uri!(get_item(track = _, id = 100));
uri!(get_item(id = 100, track = None as Option<&str>));
After verifying parameters and their types, Rocket will generate code similar (in spirit) to the following:
Origin::parse(&format!("/item/{}?track={}",
&100 as &dyn UriDisplay<Path>, &"inbound" as &dyn UriDisplay<Query>));
For this expression to typecheck, i32
must implement UriDisplay<Path>
and &str
must implement UriDisplay<Query>
. What’s more, when track
is
ignored, Option<String>
is required to implement Ignorable
. As can be
seen, the implementations will be used to display the value in a URI-safe
manner.
Provided Implementations
Rocket implements UriDisplay<P>
for all P: Part
for several built-in
types.
-
i8, i16, i32, i64, i128, isize, u8, u16, u32, u64, u128, usize, f32, f64, bool, IpAddr, Ipv4Addr, Ipv6Addr
The implementation of
UriDisplay
for these types is identical to theDisplay
implementation. -
String
,&str
,Cow<str>
The string is percent encoded.
-
&T
,&mut T
whereT: UriDisplay
Uses the implementation of
UriDisplay
forT
.
Rocket implements UriDisplay<Path>
(but not UriDisplay<Query>
) for
several built-in types.
-
T
forOption<T>
whereT: UriDisplay<Path>
Uses the implementation of
UriDisplay
forT::Target
.When a type of
Option<T>
appears in a route path, use a type ofT
as the parameter inuri!
. Note thatOption<T>
itself does not implementUriDisplay<Path>
. -
T
forResult<T, E>
whereT: UriDisplay<Path>
Uses the implementation of
UriDisplay
forT::Target
.When a type of
Result<T, E>
appears in a route path, use a type ofT
as the parameter inuri!
. Note thatResult<T, E>
itself does not implementUriDisplay<Path>
.
Rocket implements UriDisplay<Query>
(but not UriDisplay<Path>
) for
several built-in types.
-
Form<T>
,LenientForm<T>
whereT: FromUriParam + FromForm
Uses the implementation of
UriDisplay
forT::Target
.In general, when a type of
Form<T>
is to be displayed as part of a URI’s query, it suffices to deriveUriDisplay
forT
. Note that any type that can be converted into aT
usingFromUriParam
can be used in place of aForm<T>
in auri!
invocation. -
Option<T>
whereT: UriDisplay<Query>
If the
Option
isSome
, uses the implementation ofUriDisplay
forT
. Otherwise, nothing is rendered. -
Result<T, E>
whereT: UriDisplay<Query>
If the
Result
isOk
, uses the implementation ofUriDisplay
forT
. Otherwise, nothing is rendered.
Deriving
Manually implementing UriDisplay
should be done with care. For most use
cases, deriving UriDisplay
will suffice:
// Derives `UriDisplay<Query>`
#[derive(UriDisplayQuery)]
struct User {
name: String,
age: usize,
}
let user = User { name: "Michael Smith".into(), age: 31 };
let uri_string = format!("{}", &user as &dyn UriDisplay<Query>);
assert_eq!(uri_string, "name=Michael%20Smith&age=31");
// Derives `UriDisplay<Path>`
#[derive(UriDisplayPath)]
struct Name(String);
let name = Name("Bob Smith".into());
let uri_string = format!("{}", &name as &dyn UriDisplay<Path>);
assert_eq!(uri_string, "Bob%20Smith");
As long as every field in the structure (or enum) implements UriDisplay
,
the trait can be derived. The implementation calls
Formatter::write_named_value()
for every named field and
Formatter::write_value()
for every unnamed field. See the
UriDisplay<Path>
and UriDisplay<Query>
derive documentation for full
details.
Implementing
Implementing UriDisplay
is similar to implementing
Display
with the caveat that extra care must be
taken to ensure that the written string is URI-safe. As mentioned before, in
practice, this means that the string must either be percent-encoded or
consist only of characters that are alphanumeric, “-”, “.”, “_”, or “~”.
When manually implementing UriDisplay
for your types, you should defer to
existing implementations of UriDisplay
as much as possible. In the example
below, for instance, Name
’s implementation defers to String
’s
implementation. To percent-encode a string, use
Uri::percent_encode()
.
Example
The following snippet consists of a Name
type that implements both
FromParam
and UriDisplay<Path>
. The FromParam
implementation allows
Name
to be used as the target type of a dynamic parameter, while the
UriDisplay
implementation allows URIs to be generated for routes with
Name
as a dynamic path parameter type. Note the custom parsing in the
FromParam
implementation; as a result of this, a custom (reflexive)
UriDisplay
implementation is required.
use rocket::request::FromParam;
struct Name<'r>(&'r str);
const PREFIX: &str = "name:";
impl<'r> FromParam<'r> for Name<'r> {
type Error = &'r str;
/// Validates parameters that start with 'name:', extracting the text
/// after 'name:' as long as there is at least one character.
fn from_param(param: &'r str) -> Result<Self, Self::Error> {
if !param.starts_with(PREFIX) || param.len() < (PREFIX.len() + 1) {
return Err(param);
}
let real_name = ¶m[PREFIX.len()..];
Ok(Name(real_name))
}
}
use std::fmt;
use rocket::http::impl_from_uri_param_identity;
use rocket::http::uri::fmt::{Formatter, FromUriParam, UriDisplay, Path};
use rocket::response::Redirect;
impl UriDisplay<Path> for Name<'_> {
// Writes the raw string `name:`, which is URI-safe, and then delegates
// to the `UriDisplay` implementation for `str` which ensures that
// string is written in a URI-safe manner. In this case, the string will
// be percent encoded.
fn fmt(&self, f: &mut Formatter<Path>) -> fmt::Result {
f.write_raw("name:")?;
UriDisplay::fmt(&self.0, f)
}
}
impl_from_uri_param_identity!([Path] ('a) Name<'a>);
#[get("/name/<name>")]
fn redirector(name: Name<'_>) -> Redirect {
Redirect::to(uri!(real(name)))
}
#[get("/<name>")]
fn real(name: Name<'_>) -> String {
format!("Hello, {}!", name.0)
}
let uri = uri!(real(Name("Mike Smith".into())));
assert_eq!(uri.path(), "/name:Mike%20Smith");
Required Methods
Trait Implementations
Implementations on Foreign Types
sourceimpl<P> UriDisplay<P> for str where
P: Part,
impl<P> UriDisplay<P> for str where
P: Part,
Percent-encodes the raw string.
sourceimpl<'_, P> UriDisplay<P> for Cow<'_, str> where
P: Part,
impl<'_, P> UriDisplay<P> for Cow<'_, str> where
P: Part,
Percent-encodes the raw string. Defers to str
.
sourceimpl<P> UriDisplay<P> for NonZeroUsize where
P: Part,
impl<P> UriDisplay<P> for NonZeroUsize where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for u64 where
P: Part,
impl<P> UriDisplay<P> for u64 where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for Ipv6Addr where
P: Part,
impl<P> UriDisplay<P> for Ipv6Addr where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for usize where
P: Part,
impl<P> UriDisplay<P> for usize where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for f32 where
P: Part,
impl<P> UriDisplay<P> for f32 where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl UriDisplay<Path> for Path
impl UriDisplay<Path> for Path
Percent-encodes each segment in the path and normalizes separators.
sourceimpl<P> UriDisplay<P> for NonZeroU64 where
P: Part,
impl<P> UriDisplay<P> for NonZeroU64 where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for NonZeroI128 where
P: Part,
impl<P> UriDisplay<P> for NonZeroI128 where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for Ipv4Addr where
P: Part,
impl<P> UriDisplay<P> for Ipv4Addr where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for i16 where
P: Part,
impl<P> UriDisplay<P> for i16 where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for Time where
P: Part,
impl<P> UriDisplay<P> for Time where
P: Part,
This implementation is identical to a percent-encoded version of the
Display
implementation.
sourceimpl<P> UriDisplay<P> for u32 where
P: Part,
impl<P> UriDisplay<P> for u32 where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for NonZeroI64 where
P: Part,
impl<P> UriDisplay<P> for NonZeroI64 where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for NonZeroI16 where
P: Part,
impl<P> UriDisplay<P> for NonZeroI16 where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl UriDisplay<Path> for PathBuf
impl UriDisplay<Path> for PathBuf
Percent-encodes each segment in the path and normalizes separators.
sourceimpl<P> UriDisplay<P> for IpAddr where
P: Part,
impl<P> UriDisplay<P> for IpAddr where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for SocketAddrV4 where
P: Part,
impl<P> UriDisplay<P> for SocketAddrV4 where
P: Part,
This implementation is identical to a percent-encoded version of the
Display
implementation.
sourceimpl<P> UriDisplay<P> for i32 where
P: Part,
impl<P> UriDisplay<P> for i32 where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for NonZeroU128 where
P: Part,
impl<P> UriDisplay<P> for NonZeroU128 where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for i8 where
P: Part,
impl<P> UriDisplay<P> for i8 where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for NonZeroU32 where
P: Part,
impl<P> UriDisplay<P> for NonZeroU32 where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<'_, P, T> UriDisplay<P> for &'_ T where
P: Part,
T: UriDisplay<P> + ?Sized,
impl<'_, P, T> UriDisplay<P> for &'_ T where
P: Part,
T: UriDisplay<P> + ?Sized,
Defers to the UriDisplay<P>
implementation for T
.
sourceimpl<P> UriDisplay<P> for u128 where
P: Part,
impl<P> UriDisplay<P> for u128 where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for SocketAddrV6 where
P: Part,
impl<P> UriDisplay<P> for SocketAddrV6 where
P: Part,
This implementation is identical to a percent-encoded version of the
Display
implementation.
sourceimpl<P> UriDisplay<P> for u8 where
P: Part,
impl<P> UriDisplay<P> for u8 where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for PrimitiveDateTime where
P: Part,
impl<P> UriDisplay<P> for PrimitiveDateTime where
P: Part,
This implementation is identical to a percent-encoded version of the
Display
implementation.
sourceimpl<P> UriDisplay<P> for i64 where
P: Part,
impl<P> UriDisplay<P> for i64 where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for NonZeroU16 where
P: Part,
impl<P> UriDisplay<P> for NonZeroU16 where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for i128 where
P: Part,
impl<P> UriDisplay<P> for i128 where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for bool where
P: Part,
impl<P> UriDisplay<P> for bool where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for NonZeroIsize where
P: Part,
impl<P> UriDisplay<P> for NonZeroIsize where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for f64 where
P: Part,
impl<P> UriDisplay<P> for f64 where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for NonZeroI8 where
P: Part,
impl<P> UriDisplay<P> for NonZeroI8 where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for NonZeroI32 where
P: Part,
impl<P> UriDisplay<P> for NonZeroI32 where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for u16 where
P: Part,
impl<P> UriDisplay<P> for u16 where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for NonZeroU8 where
P: Part,
impl<P> UriDisplay<P> for NonZeroU8 where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for isize where
P: Part,
impl<P> UriDisplay<P> for isize where
P: Part,
This implementation is identical to the Display
implementation.
sourceimpl<P> UriDisplay<P> for Date where
P: Part,
impl<P> UriDisplay<P> for Date where
P: Part,
This implementation is identical to a percent-encoded version of the
Display
implementation.
sourceimpl<P> UriDisplay<P> for SocketAddr where
P: Part,
impl<P> UriDisplay<P> for SocketAddr where
P: Part,
This implementation is identical to a percent-encoded version of the
Display
implementation.
sourceimpl<'_, P, T> UriDisplay<P> for &'_ mut T where
P: Part,
T: UriDisplay<P> + ?Sized,
impl<'_, P, T> UriDisplay<P> for &'_ mut T where
P: Part,
T: UriDisplay<P> + ?Sized,
Defers to the UriDisplay<P>
implementation for T
.
Implementors
impl<K, V> UriDisplay<Query> for BTreeMap<K, V> where
K: UriDisplay<Query>,
V: UriDisplay<Query>,
impl<K, V> UriDisplay<Query> for HashMap<K, V, RandomState> where
K: UriDisplay<Query>,
V: UriDisplay<Query>,
impl<P> UriDisplay<P> for String where
P: Part,
Percent-encodes the raw string. Defers to str
.
impl<P> UriDisplay<P> for Uuid where
P: Part,
This implementation is identical to the Display
implementation.
impl<T> UriDisplay<Query> for Option<T> where
T: UriDisplay<Query>,
Defers to the UriDisplay<Query>
implementation for T
.
impl<T> UriDisplay<Query> for Vec<T, Global> where
T: UriDisplay<Query>,
impl<T, E> UriDisplay<Query> for Result<T, E> where
T: UriDisplay<Query>,
Defers to the UriDisplay<Query>
implementation for T
.
impl<T: Serialize> UriDisplay<Query> for Json<T>
json
only.