iri_string/
raw.rs

1//! Raw IRI strings manipulation.
2//!
3//! Note that functions in this module may operates on raw `&str` types.
4//! It is caller's responsilibility to guarantee that the given string satisfies the precondition.
5
6#[cfg(all(feature = "alloc", not(feature = "std")))]
7use alloc::string::String;
8
9#[cfg(feature = "alloc")]
10use crate::parser::trusted as trusted_parser;
11
12/// Sets the fragment part to the given string.
13///
14/// Removes fragment part (and following `#` character) if `None` is given.
15#[cfg(feature = "alloc")]
16pub(crate) fn set_fragment(s: &mut String, fragment: Option<&str>) {
17    remove_fragment(s);
18    if let Some(fragment) = fragment {
19        s.reserve(fragment.len() + 1);
20        s.push('#');
21        s.push_str(fragment);
22    }
23}
24
25/// Removes the fragment part from the string.
26#[cfg(feature = "alloc")]
27#[inline]
28pub(crate) fn remove_fragment(s: &mut String) {
29    if let Some(colon_pos) = s.find('#') {
30        s.truncate(colon_pos);
31    }
32}
33
34/// Splits the string into the prefix and the fragment part.
35///
36/// A leading `#` character is truncated if the fragment part exists.
37#[cfg(feature = "alloc")]
38pub(crate) fn split_fragment_owned(mut s: String) -> (String, Option<String>) {
39    let prefix_len = match trusted_parser::split_fragment(&s) {
40        (_, None) => return (s, None),
41        (prefix, Some(_fragment)) => prefix.len(),
42    };
43
44    // `+ 1` is for leading `#` character.
45    let fragment = s.split_off(prefix_len + 1);
46    // Current `s` contains a trailing `#` character, which should be removed.
47    {
48        // Remove a trailing `#`.
49        let hash = s.pop();
50        assert_eq!(hash, Some('#'));
51    }
52    assert_eq!(s.len(), prefix_len);
53
54    (s, Some(fragment))
55}