Skip to main content

helm_schema_core/
value_path.rs

1/// Joins structural `.Values` path segments into the contract path currency.
2///
3/// Dots and backslashes inside a segment are escaped so literal YAML keys
4/// remain distinct from selector boundaries.
5#[must_use]
6pub fn join_value_path<I, S>(segments: I) -> String
7where
8    I: IntoIterator<Item = S>,
9    S: AsRef<str>,
10{
11    let mut path = String::new();
12    for segment in segments {
13        let segment = segment.as_ref();
14        if segment.is_empty() {
15            continue;
16        }
17        if !path.is_empty() {
18            path.push('.');
19        }
20        for character in segment.chars() {
21            if matches!(character, '.' | '\\') {
22                path.push('\\');
23            }
24            path.push(character);
25        }
26    }
27    path
28}
29
30/// Splits the contract `.Values` path currency into structural segments.
31#[must_use]
32pub fn split_value_path(path: &str) -> Vec<String> {
33    let mut segments = Vec::new();
34    let mut segment = String::new();
35    let mut characters = path.chars().peekable();
36    while let Some(character) = characters.next() {
37        match character {
38            '.' => {
39                if !segment.is_empty() {
40                    segments.push(std::mem::take(&mut segment));
41                }
42            }
43            '\\' if characters
44                .peek()
45                .is_some_and(|next| matches!(next, '.' | '\\')) =>
46            {
47                if let Some(escaped) = characters.next() {
48                    segment.push(escaped);
49                }
50            }
51            _ => segment.push(character),
52        }
53    }
54    if !segment.is_empty() {
55        segments.push(segment);
56    }
57    segments
58}
59
60/// Appends one structural segment to an encoded `.Values` path.
61#[must_use]
62pub fn append_value_path(path: &str, segment: &str) -> String {
63    let mut segments = split_value_path(path);
64    segments.push(segment.to_string());
65    join_value_path(segments)
66}