syncthing_types/
utils.rs

1pub struct QueryChars(bool);
2
3impl Default for QueryChars {
4    fn default() -> Self {
5        Self(false)
6    }
7}
8
9impl QueryChars {
10    pub fn next_char(&mut self) -> char {
11        if self.0 {
12            '&'
13        } else {
14            self.0 = true;
15            '?'
16        }
17    }
18}
19
20use serde::{Deserialize, Deserializer};
21
22pub fn default_on_null<'de, D, T: Default + Deserialize<'de>>(
23    deserializer: D,
24) -> Result<T, D::Error>
25where
26    D: Deserializer<'de>,
27{
28    let opt = Option::deserialize(deserializer)?;
29    Ok(opt.unwrap_or_default())
30}
31
32pub fn construct_event_path_and_query(
33    since: Option<u64>,
34    limit: Option<u64>,
35    events: impl AsRef<[crate::events::EventType]>,
36) -> serde_json::Result<String> {
37    let mut path_and_query = crate::routes::EVENTS.to_owned();
38    let events = events.as_ref();
39    let mut query_chars = QueryChars::default();
40    if !events.is_empty() {
41        let events = serde_json::to_string(&events)?
42            .chars()
43            .filter(|e| !matches!(e, '\"' | '[' | ']'))
44            .collect::<String>();
45        path_and_query.push(query_chars.next_char());
46        path_and_query.push_str("events=");
47        path_and_query.push_str(events.as_ref());
48    }
49    if let Some(since) = since {
50        path_and_query.push(query_chars.next_char());
51        path_and_query.push_str("since=");
52        path_and_query.push_str(since.to_string().as_ref());
53    }
54    if let Some(limit) = limit {
55        path_and_query.push(query_chars.next_char());
56        path_and_query.push_str("limit=");
57        path_and_query.push_str(limit.to_string().as_ref());
58    }
59    Ok(path_and_query)
60}
61
62use http::uri::{Authority, Parts as UriParts, PathAndQuery, Scheme, Uri};
63
64pub fn construct_uri<T>(authority: &Authority, path_and_query: T) -> Result<Uri, http::Error>
65where
66    T: AsRef<[u8]> + 'static,
67{
68    let mut uri_parts = UriParts::default();
69    uri_parts.authority = Some(authority.clone());
70    uri_parts.scheme = Some(Scheme::HTTP);
71    uri_parts.path_and_query = Some(PathAndQuery::from_maybe_shared(path_and_query)?);
72    Ok(Uri::from_parts(uri_parts)?)
73}