fire_http_representation/header/
url.rs

1use super::Uri;
2
3use http::uri::{Authority, PathAndQuery, Scheme};
4
5pub use form_urlencoded::Parse as QueryIter;
6
7/// Contains a request url.
8///
9/// This is a wrapper around `Uri` with the caveat that a scheme
10/// and an authority is set, which makes it a Url.
11#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct Url {
13	scheme: Scheme,
14	authority: Authority,
15	path_and_query: PathAndQuery,
16}
17
18impl Url {
19	/// Creates a new `Uri` from an `http::Uri`
20	///
21	/// Returns None if the `http::Uri` does not contain a scheme or authority.
22	pub fn from_inner(inner: Uri) -> Option<Self> {
23		let parts = inner.into_parts();
24		Some(Self {
25			scheme: parts.scheme?,
26			authority: parts.authority?,
27			path_and_query: parts
28				.path_and_query
29				.unwrap_or_else(|| PathAndQuery::from_static("/")),
30		})
31	}
32
33	/// Returns the used scheme.
34	pub fn scheme(&self) -> &str {
35		self.scheme.as_str()
36	}
37
38	/// Returns true if the used scheme is https.
39	pub fn is_https(&self) -> bool {
40		self.scheme == Scheme::HTTPS
41	}
42
43	/// Returns true if the used scheme is http.
44	pub fn is_http(&self) -> bool {
45		self.scheme == Scheme::HTTP
46	}
47
48	/// Returns the host.
49	pub fn host(&self) -> &str {
50		self.authority.host()
51	}
52
53	/// Returns the used port if any.
54	pub fn port(&self) -> Option<u16> {
55		self.authority.port_u16()
56	}
57
58	/// Returns the path.
59	pub fn path(&self) -> &str {
60		self.path_and_query.path()
61	}
62
63	/// Returns the path as segments divided by a slash, first starting and
64	/// ending slash removed.
65	pub fn path_segments(&self) -> std::str::Split<'_, char> {
66		let path = self.path();
67		let path = path.strip_prefix('/').unwrap_or(path);
68		let path = path.strip_suffix('/').unwrap_or(path);
69		path.split('/')
70	}
71
72	/// Returns the query string.
73	pub fn query(&self) -> Option<&str> {
74		self.path_and_query.query()
75	}
76
77	// named as parse_query_pairs since maybe it would make sense
78	// to make a separate type which allows to lookup pairs
79	// and deserialize values in it which would be in `query_pairs`
80	//
81	/// Returns an iterator with the Item `(Cow<'_, str>, Cow<'_, str>)`
82	///
83	/// Key and values are percent decoded.
84	pub fn parse_query_pairs(&self) -> QueryIter {
85		form_urlencoded::parse(self.query().unwrap_or("").as_bytes())
86	}
87}