web_url/url/
fragment.rs

1use crate::{Fragment, WebUrl};
2
3impl WebUrl {
4    //! Fragment
5
6    /// Gets the optional fragment.
7    pub fn fragment(&self) -> Option<Fragment<'_>> {
8        let fragment: &str = self.fragment_str();
9        if fragment.is_empty() {
10            None
11        } else {
12            Some(unsafe { Fragment::new(fragment) })
13        }
14    }
15
16    /// Gets the fragment string.
17    ///
18    /// This will be a valid fragment starting with a '#' or empty.
19    fn fragment_str(&self) -> &str {
20        let start: usize = self.query_end as usize;
21        &self.url[start..]
22    }
23}
24
25impl WebUrl {
26    //! Fragment Mutation
27
28    /// Sets the `fragment`.
29    pub fn set_fragment<'a, F>(&mut self, fragment: F)
30    where
31        F: Into<Option<Fragment<'a>>>,
32    {
33        self.url
34            .truncate(self.url.len() - self.fragment_str().len());
35        if let Some(fragment) = fragment.into() {
36            self.url.push_str(fragment.as_str())
37        }
38    }
39
40    /// Sets the `fragment`.
41    pub fn with_fragment<'a, F>(mut self, fragment: F) -> Self
42    where
43        F: Into<Option<Fragment<'a>>>,
44    {
45        self.set_fragment(fragment);
46        self
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use crate::{Fragment, WebUrl};
53    use std::error::Error;
54    use std::str::FromStr;
55
56    #[test]
57    fn set_fragment() -> Result<(), Box<dyn Error>> {
58        let mut url: WebUrl = WebUrl::from_str("https://example.com")?;
59
60        url.set_fragment(Fragment::try_from("#fragment")?);
61        assert_eq!(url.as_str(), "https://example.com/#fragment");
62
63        Ok(())
64    }
65}