Repository: starship/starship
File: src/formatter/string_formatter.rs (Rust)

Code before:
        let outer_style = Some(Color::Green.normal());
        let middle_style = Some(Color::Red.bold());
        let inner_style = Some(Color::Blue.normal());

        let formatter = StringFormatter::new(FORMAT_STR).unwrap().map(empty_mapper);
        let result = formatter.parse(outer_style, None).unwrap();
        let mut result_iter = result.iter();
        match_next!(result_iter, "outer ", outer_style);
        match_next!(result_iter, "middle ", middle_style);
        match_next!(result_iter, "inner", inner_style);
    }

    #[test]
    fn test_style_variable_nested() {
        const FORMAT_STR: &str = "[[text]($style)](blue)";
        let inner_style = Some(Color::Red.bold());

        let formatter = StringFormatter::new(FORMAT_STR)
            .unwrap()
            .map_style(|variable| match variable {
                "style" => Some(Ok("red bold".to_owned())),
                _ => None,
            });

        let result = formatter.parse(None, None).unwrap();
        let mut result_iter = result.iter();
        match_next!(result_iter, "text", inner_style);
    }

    #[test]
    fn test_styled_variable_as_text() {
        const FORMAT_STR: &str = "[$var](red bold)";
        let var_style = Some(Color::Red.bold());

        let formatter = StringFormatter::new(FORMAT_STR)
            .unwrap()
            .map(|variable| match variable {
                "var" => Some(Ok("text".to_owned())),
                _ => None,
            });
        let result = formatter.parse(None, None).unwrap();
        let mut result_iter = result.iter();
        match_next!(result_iter, "text", var_style);
    }

    #[test]
    fn test_styled_variable_as_segments() {
        const FORMAT_STR: &str = "[$var](red bold)";
        let var_style = Some(Color::Red.bold());
        let styled_style = Some(Color::Green.italic());
        let styled_no_modifier_style = Some(Color::Green.normal());

Review comment (suggestion):
The changes LGTM, but lets also test this:

```suggestion

        assert_eq!(
            formatter.style_variables.keys().collect::<Vec<_>>(),
            vec!["style"]
        );

```

Code after:
        let outer_style = Some(Color::Green.normal());
        let middle_style = Some(Color::Red.bold());
        let inner_style = Some(Color::Blue.normal());

        let formatter = StringFormatter::new(FORMAT_STR).unwrap().map(empty_mapper);
        let result = formatter.parse(outer_style, None).unwrap();
        let mut result_iter = result.iter();
        match_next!(result_iter, "outer ", outer_style);
        match_next!(result_iter, "middle ", middle_style);
        match_next!(result_iter, "inner", inner_style);
    }

    #[test]
    fn test_style_variable_nested() {
        const STYLE_VAR_NAME: &str = "style";

        let format_string = format!("[[text](${STYLE_VAR_NAME})](blue)");
        let inner_style = Some(Color::Red.bold());

        let formatter = StringFormatter::new(&format_string)
            .unwrap()
            .map_style(|variable| match variable {
                STYLE_VAR_NAME => Some(Ok("red bold".to_owned())),
                _ => None,
            });

        assert_eq!(
            BTreeSet::from([STYLE_VAR_NAME.into()]),
            formatter.get_style_variables()
        );

        let result = formatter.parse(None, None).unwrap();
        let mut result_iter = result.iter();
        match_next!(result_iter, "text", inner_style);
    }

    #[test]
    fn test_styled_variable_as_text() {
        const FORMAT_STR: &str = "[$var](red bold)";
        let var_style = Some(Color::Red.bold());

        let formatter = StringFormatter::new(FORMAT_STR)
            .unwrap()
            .map(|variable| match variable {
                "var" => Some(Ok("text".to_owned())),
                _ => None,
            });
        let result = formatter.parse(None, None).unwrap();
        let mut result_iter = result.iter();
        match_next!(result_iter, "text", var_style);
    }