Skip to main content

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 fragment_accessor() -> Result<(), Box<dyn Error>> {
58        let url = WebUrl::from_str("https://example.com/path#section")?;
59        let fragment = url.fragment().unwrap();
60        assert_eq!(fragment.as_str(), "#section");
61        assert_eq!(fragment.value(), "section");
62
63        let url = WebUrl::from_str("https://example.com/path")?;
64        assert!(url.fragment().is_none());
65
66        Ok(())
67    }
68
69    #[test]
70    fn set_fragment() -> Result<(), Box<dyn Error>> {
71        let mut url: WebUrl = WebUrl::from_str("https://example.com")?;
72
73        url.set_fragment(Fragment::try_from("#fragment")?);
74        assert_eq!(url.as_str(), "https://example.com/#fragment");
75
76        Ok(())
77    }
78
79    #[test]
80    fn set_fragment_none() -> Result<(), Box<dyn Error>> {
81        let mut url = WebUrl::from_str("https://example.com/path#fragment")?;
82        assert!(url.fragment().is_some());
83
84        url.set_fragment(None);
85        assert!(url.fragment().is_none());
86        assert_eq!(url.as_str(), "https://example.com/path");
87
88        Ok(())
89    }
90
91    #[test]
92    fn with_fragment() -> Result<(), Box<dyn Error>> {
93        let url =
94            WebUrl::from_str("https://example.com")?.with_fragment(Fragment::try_from("#frag")?);
95        assert_eq!(url.as_str(), "https://example.com/#frag");
96
97        let url = WebUrl::from_str("https://example.com/path#old")?.with_fragment(None);
98        assert_eq!(url.as_str(), "https://example.com/path");
99
100        Ok(())
101    }
102}