Repository: starship/starship
File: src/modules/mojo.rs (Rust)

Code before:
    if !is_mojo_project {
        return None;
    }

    let parsed = StringFormatter::new(config.format).and_then(|formatter| {
        formatter
            .map_meta(|variable, _| match variable {
                "symbol" => Some(config.symbol),
                _ => None,
            })
            .map_style(|variable| match variable {
                "style" => Some(Ok(config.style)),
                _ => None,
            })
            .map(|variable| match variable {
                "version" => {
                    let mojo_version_output = context.exec_cmd("mojo", &["--version"])?.stdout;
                    let version_items = mojo_version_output.split(' ').collect::<Vec<&str>>();

                    if version_items.len() <= 1 {
                        return None;
                    }

                    if version_items.len() == 2 || !config.show_commit {
                        return Some(Ok(version_items[1].trim().to_string()));
                    }

                    let mojo_version = version_items[1].trim();
                    let mojo_hash = version_items[2].trim();

                    Some(Ok(format!("{} {}", mojo_version, mojo_hash)))
                }
                _ => None,
            })
            .parse(None, Some(context))
    });

    module.set_segments(match parsed {
        Ok(segments) => segments,
        Err(error) => {
            log::warn!("Error in module `mojo`:\n{}", error);
            return None;
        }
    });

    Some(module)
}

#[cfg(test)]
mod tests {
    use crate::configs::mojo::MOJO_DEFAULT_COLOR;

Review comment (bug):
Instead of manual indexing, I would prefer something like this:
```rust
                    let (version, hash) = match version_items[..] {
                        [_, version] => (version, None),
                        [_, version, hash, ..] => (version, Some(hash)),
                        _ => {
                            log::debug!("Unexpected `mojo --version` output: {mojo_version_output}");
                            return None;
                        }
                    }
```


Code after:
        .set_folders(&config.detect_folders)
        .is_match();

    if !is_mojo_project {
        return None;
    }

    let version_hash = Lazy::new(|| get_mojo_version(context));

    let parsed = StringFormatter::new(config.format).and_then(|formatter| {
        formatter
            .map_meta(|variable, _| match variable {
                "symbol" => Some(config.symbol),
                _ => None,
            })
            .map_style(|variable| match variable {
                "style" => Some(Ok(config.style)),
                _ => None,
            })
            .map(|variable| match variable {
                "version" => match version_hash.deref() {
                    Some((version, _)) => Some(Ok(version)),
                    _ => None,
                },
                "hash" => match version_hash.deref() {
                    Some((_, Some(hash))) => Some(Ok(hash)),
                    _ => None,
                },
                _ => None,
            })
            .parse(None, Some(context))
    });

    module.set_segments(match parsed {
        Ok(segments) => segments,
        Err(error) => {
            log::warn!("Error in module `mojo`:\n{}", error);
            return None;
        }
    });

    Some(module)
}

fn get_mojo_version(context: &Context) -> Option<(String, Option<String>)> {
    let mojo_version_output = context.exec_cmd("mojo", &["--version"])?.stdout;

    let version_items = mojo_version_output
        .split_ascii_whitespace()
        .collect::<Vec<&str>>();