pub fn protect<T: ProtectTest>(s: &str, test: T) -> String {
    // Determine the number of braces that need to be added to the left (`l`) and
    // right (`r`) to make `s` balanced. Furthermore, detect if any character at
    // brace `level` zero tests true using `test`, in which case we need
    // protection.
    let (l, r, needs_protection) = {
        let mut needs_protection = if T::UNCONDITIONAL {
            true
        } else {
            s.starts_with('{') && s.ends_with('}')
        };
        let mut level = 0;
        let mut l = 0;
        for ch in s.chars() {
            if ch == '{' {
                level += 1;
            } else if ch == '}' {
                level -= 1;
                if -level > l {
                    l = -level;
                }
            } else if !T::UNCONDITIONAL && !needs_protection && level == 0 && test.test(ch) {
                needs_protection = true;
            }
        }
        (l, level + l, needs_protection)
    };
    if needs_protection || l > 0 || r > 0 {
        // Prepend `'<{{...{>'` to `s` only if necessary to balance (`l > 0`) or if
        // `s` starts with something that can be parsed as a balancer
        // (`starts_with_balancer(s)`). Append `'<}...}}>'` to `s` following
        // similar rules.  Finally enclose in braces.
        let mut v = vec!["{"];
        if l > 0 || starts_with_balancer(s) {
            v.push("<");
            for _i in 0..l {
                v.push("{");
            }
            v.push(">");
        }
        v.push(s);
        if r > 0 || ends_with_balancer(s) {
            v.push("<");
            for _i in 0..r {
                v.push("}");
            }
            v.push(">");
        }
        v.push("}");
        v.concat()
    } else {
        s.to_owned()
    }
}
/// Conditionally encloses string in curly braces and makes balanced.
///
/// # Examples
///
/// The string `"a,b,c"` needs protection for `','`:
///
/// ```
/// assert_eq!(stringly::util::protect("a,b,c", ','), "{a,b,c}");
/// ```
///
/// The string `"a{b,c}"` does not need protection for `","` because the comma
/// is enclosed in curly braces:
///
/// ```
/// assert_eq!(stringly::util::protect("a{b,c}", ','), "a{b,c}");
/// ```
///
/// The strings `"a=b"` and `"a,b"` need proctection for `','` or `'='`:
///
/// ```
/// assert_eq!(stringly::util::protect("a=b", [',', '=']), "{a=b}");
/// assert_eq!(stringly::util::protect("a,b", [',', '=']), "{a,b}");
/// ```
///
/// Unbalanced strings or strings starting and ending with `'{'` and `'}'`,
/// respectively, are always protected:
///
/// ```
/// assert_eq!(stringly::util::protect("}", ','), "{<{>}}");
/// ```
Conditionally encloses string in curly braces and makes balanced.
Conditionally encloses string in curly braces and makes balanced .
pub fn protect<T: ProtectTest>(s: &str, test: T) -> String {
    // Determine the number of braces that need to be added to the left (`l`) and
    // right (`r`) to make `s` balanced. Furthermore, detect if any character at
    // brace `level` zero tests true using `test`, in which case we need
    // protection.
    let (l, r, needs_protection) = {
        let mut needs_protection = if T::UNCONDITIONAL {
            true
        } else {
            s.starts_with('{') && s.ends_with('}')
        };
        let mut level = 0;
        let mut l = 0;
        for ch in s.chars() {
            if ch == '{' {
                level += 1;
            } else if ch == '}' {
                level -= 1;
                if -level > l {
                    l = -level;
                }
            } else if !T::UNCONDITIONAL && !needs_protection && level == 0 && test.test(ch) {
                needs_protection = true;
            }
        }
        (l, level + l, needs_protection)
    };
    if needs_protection || l > 0 || r > 0 {
        // Prepend `'<{{...{>'` to `s` only if necessary to balance (`l > 0`) or if
        // `s` starts with something that can be parsed as a balancer
        // (`starts_with_balancer(s)`). Append `'<}...}}>'` to `s` following
        // similar rules.  Finally enclose in braces.
        let mut v = vec!["{"];
        if l > 0 || starts_with_balancer(s) {
            v.push("<");
            for _i in 0..l {
                v.push("{");
            }
            v.push(">");
        }
        v.push(s);
        if r > 0 || ends_with_balancer(s) {
            v.push("<");
            for _i in 0..r {
                v.push("}");
            }
            v.push(">");
        }
        v.push("}");
        v.concat()
    } else {
        s.to_owned()
    }
}
pub fn protect < T : ProtectTest > ( s : & str , test : T ) -> String { // Determine the number of braces that need to be added to the left (`l`) and // right (`r`) to make `s` balanced. Furthermore, detect if any character at // brace `level` zero tests true using `test`, in which case we need // protection. let ( l , r , needs_protection ) = { let mut needs_protection = if T :: UNCONDITIONAL { true } else { s . starts_with ( '{' ) && s . ends_with ( '}' ) } ; let mut level = 0 ; let mut l = 0 ; for ch in s . chars ( ) { if ch == '{' { level += 1 ; } else if ch == '}' { level -= 1 ; if - level > l { l = - level ; } } else if ! T :: UNCONDITIONAL && ! needs_protection && level == 0 && test . test ( ch ) { needs_protection = true ; } } ( l , level + l , needs_protection ) } ; if needs_protection || l > 0 || r > 0 { // Prepend `'<{{...{>'` to `s` only if necessary to balance (`l > 0`) or if // `s` starts with something that can be parsed as a balancer // (`starts_with_balancer(s)`). Append `'<}...}}>'` to `s` following // similar rules.  Finally enclose in braces. let mut v = vec ! [ " " ] ; if l > 0 || starts_with_balancer ( s ) { v . push ( " " ) ; for _i in 0 .. l { v . push ( " " ) ; } v . push ( " " ) ; } v . push ( s ) ; if r > 0 || ends_with_balancer ( s ) { v . push ( " " ) ; for _i in 0 .. r { v . push ( " " ) ; } v . push ( " " ) ; } v . push ( " " ) ; v . concat ( ) } else { s . to_owned ( ) } }
Conditionally encloses string in curly braces and makes balanced.
Conditionally encloses string in curly braces and makes balanced .
s
&str
test
T
s
&str
test
T
examples
The string `"a,b,c"` needs protection for `','`.



The string `"a{b,c}"` does not need protection for `","` because the comma
is enclosed in curly braces.







Unbalanced strings or strings starting and ending with `'{'` and `'}'`,
respectively, are always protected.


The string ` " a b c " ` needs protection for ` ' ' ` . The string ` " a { b c } " ` does not need protection for ` " " ` because the comma is enclosed in curly braces . Unbalanced strings or strings starting and ending with ` ' { ' ` and ` ' } ' ` respectively are always protected .