const EMPTY: &str = "";
const KEY_DELIMITER: &str = ":";
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum ConfigurationPath {
Absolute,
Relative
}
impl ConfigurationPath {
pub fn key_delimiter() -> &'static str {
KEY_DELIMITER
}
pub fn combine(segments: &[&str]) -> String {
segments.join(KEY_DELIMITER)
}
pub fn section_key(path: &str) -> &str {
if let Some(index) = path.rfind(KEY_DELIMITER) {
&path[(index + 1)..]
} else {
path
}
}
pub fn parent_path(path: &str) -> &str {
if let Some(index) = path.rfind(KEY_DELIMITER) {
&path[..index]
} else {
EMPTY
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use test_case::test_case;
#[test_case(&["parent", ""], "parent:" ; "with 1 segment")]
#[test_case(&["parent", "", ""], "parent::" ; "with 2 segments")]
#[test_case(&["parent", "", "", "key"], "parent:::key" ; "with segments in between")]
fn combine_with_empty_segment_leaves_delimiter(segments: &[&str], expected: &str) {
let path = ConfigurationPath::combine(segments);
assert_eq!(&path, expected);
}
#[test_case("", "" ; "when empty")]
#[test_case(":::", "" ; "when only delimiters")]
#[test_case("a::b:::c", "c" ; "with empty segments in the middle")]
#[test_case("a:::b:", "" ; "when last segment is empty")]
#[test_case("key", "key" ; "with no parent")]
#[test_case(":key", "key" ; "with 1 empty parent")]
#[test_case("::key", "key" ; "with 2 empty parents")]
#[test_case("parent:key", "key" ; "with parent")]
fn section_key_should_return_expected_segment(path: &str, expected: &str) {
let key = ConfigurationPath::section_key(path);
assert_eq!(key, expected);
}
#[test_case("", "" ; "when empty")]
#[test_case(":::", "::" ; "when only delimiters")]
#[test_case("a::b:::c", "a::b::" ; "with empty segments in the middle")]
#[test_case("a:::b:", "a:::b" ; "when last segment is empty")]
#[test_case("key", "" ; "with no parent")]
#[test_case(":key", "" ; "with 1 empty parent")]
#[test_case("::key", ":" ; "with 2 empty parents")]
#[test_case("parent:key", "parent" ; "with parent")]
fn parent_path_should_return_expected_segment(path: &str, expected: &str) {
let key = ConfigurationPath::parent_path(path);
assert_eq!(key, expected);
}
}