rocket_http_community/uri/fmt/part.rs
1use crate::parse::IndexedStr;
2
3/// Marker trait for types that mark a part of a URI.
4///
5/// This trait exists solely to categorize types that mark a part of the URI,
6/// currently [`Path`] and [`Query`]. Said another way, types that implement
7/// this trait are marker types that represent a part of a URI at the
8/// type-level.
9///
10/// This trait is _sealed_: it cannot be implemented outside of Rocket.
11///
12/// # Usage
13///
14/// You will find this trait in traits like [`UriDisplay`] or structs like
15/// [`Formatter`] as the bound on a generic parameter: `P: Part`. Because the
16/// trait is sealed, the generic type is guaranteed to be instantiated as one of
17/// [`Query`] or [`Path`], effectively creating two instances of the generic
18/// items: `UriDisplay<Query>` and `UriDisplay<Path>`, and `Formatter<Query>`
19/// and `Formatter<Path>`. Unlike having two distinct, non-generic traits, this
20/// approach enables succinct, type-checked generic implementations of these
21/// items.
22///
23/// [`UriDisplay`]: crate::uri::fmt::UriDisplay
24/// [`Formatter`]: crate::uri::fmt::Formatter
25pub trait Part: private::Sealed {
26 /// The dynamic version of `Self`.
27 #[doc(hidden)]
28 const KIND: Kind;
29
30 /// The delimiter used to separate components of this URI part.
31 /// Specifically, `/` for `Path` and `&` for `Query`.
32 #[doc(hidden)]
33 const DELIMITER: char;
34
35 /// The raw form of a segment in this part.
36 #[doc(hidden)]
37 type Raw: Send + Sync + 'static;
38}
39
40mod private {
41 pub trait Sealed {}
42 impl Sealed for super::Path {}
43 impl Sealed for super::Query {}
44}
45
46/// Dynamic version of the `Path` and `Query` parts.
47#[doc(hidden)]
48#[derive(Debug, PartialEq, Eq, Copy, Clone)]
49pub enum Kind {
50 Path,
51 Query,
52}
53
54/// Marker type indicating use of a type for the path [`Part`] of a URI.
55///
56/// In route URIs, this corresponds to all of the text before a `?`, if any, or
57/// all of the text in the URI otherwise:
58///
59/// ```text
60/// #[get("/home/<name>/<page>?<item>")]
61/// ^------------------ Path
62/// ```
63#[derive(Debug, Clone, Copy)]
64pub enum Path {}
65
66/// Marker type indicating use of a type for the query [`Part`] of a URI.
67///
68/// In route URIs, this corresponds to all of the text after a `?`, if any.
69///
70/// ```text
71/// #[get("/home/<name>/<page>?<item>&<form..>")]
72/// ^-------------- Query
73/// ```
74#[derive(Debug, Clone, Copy)]
75pub enum Query {}
76
77impl Part for Path {
78 const KIND: Kind = Kind::Path;
79 const DELIMITER: char = '/';
80 type Raw = IndexedStr<'static>;
81}
82
83impl Part for Query {
84 const KIND: Kind = Kind::Query;
85 const DELIMITER: char = '&';
86 type Raw = (IndexedStr<'static>, IndexedStr<'static>);
87}