json-trait-rs 0.11.0

Rust interface (aka trait) to deal with objects as they are JSON objects
Documentation
pub fn fragment_components_from_fragment(fragment: &str) -> impl Iterator<Item = String> {
    let fragment = fragment.trim_start_matches('/');
    if fragment.is_empty() {
        Vec::with_capacity(0).into_iter()
    } else {
        fragment
            .split('/')
            .map(|fragment_part| fragment_part.replace("~1", "/").replace("~0", "~"))
            .collect::<Vec<_>>()
            .into_iter()
    }
}

pub fn fragment_from_fragment_components<I: IntoIterator<Item = T>, T: ToString>(fragment_components: I) -> String {
    fragment_components
        .into_iter()
        .map(|fragment_part| fragment_part.to_string().replace("~", "~0").replace("/", "~1"))
        .fold("".to_string(), |mut result, item| {
            result.push('/');
            result.push_str(&item);
            result
        })
}

#[cfg(test)]
mod tests {
    use super::{fragment_components_from_fragment, fragment_from_fragment_components};
    use test_case::test_case;

    #[test_case(""       => Vec::<String>::new() ; "empty")]
    #[test_case("p1"     => vec!["p1"]           ; "one level withoout leading slash")]
    #[test_case("/p2"    => vec!["p2"]           ; "one level with leading slash")]
    #[test_case("p3/p4"  => vec!["p3", "p4"]     ; "two levels without leading slash")]
    #[test_case("/p5/p6" => vec!["p5", "p6"]     ; "two levels with leading slash")]
    #[test_case("/~0/~1" => vec!["~", "/"]       ; "two levels with special characters")]
    fn test_fragment_components_from_fragment(fragment: &str) -> Vec<String> {
        fragment_components_from_fragment(fragment).collect::<Vec<_>>()
    }

    #[test_case(vec![]           => ""       ; "empty")]
    #[test_case(vec!["p1"]       => "/p1"    ; "one level")]
    #[test_case(vec!["p2", "p3"] => "/p2/p3" ; "two levels")]
    #[test_case(vec!["~", "/"]   => "/~0/~1" ; "two levels with special characters")]
    fn test_fragment_from_fragment_components(fragment_components: Vec<&str>) -> String {
        fragment_from_fragment_components(fragment_components)
    }
}