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

Code before:
use std::path::Path;

use crate::{
    config::ModuleConfig,
    configs::maven::MavenConfig,
    context::Context,
    formatter::{StringFormatter, VersionFormatter},
    module::Module,
    utils,
};

pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
    let mut module = context.new_module("maven");
    let config = MavenConfig::try_load(module.config);
    let wrapper_properties = get_wrapper_properties_file(context, config.recursive);
    let is_maven_project = context
        .try_begin_scan()?
        .set_files(&config.detect_files)
        .set_folders(&config.detect_folders)
        .is_match()
        || wrapper_properties.is_some();

    if !is_maven_project {
        return None;
    }

    let parsed = StringFormatter::new(config.format).and_then(|formatter| {
        formatter
            .map_meta(|var, _| match var {
                "symbol" => Some(config.symbol),
                _ => None,
            })
            .map_style(|variable| match variable {
                "style" => Some(Ok(config.style)),
                _ => None,
            })
            .map(|variable| match variable {
                "version" => {
                    let properties = wrapper_properties.as_deref()?;
                    let maven_version = parse_maven_version_from_properties(properties)?;

Review comment (performance):
Please handle `is_maven_project` first for performance. Running this early also diverges from the `gradle` behaviour. If you are planning to keep it this way please add a `TODO` comment to the gradle module to streamline them in the future.

Another potential alternative would be to conditionally handle `is_maven_project` with `begin_ancestor_scan` depending on the value of `upwards` (only using the config options), giving users more control.

Code after:
use std::path::Path;

use crate::{
    config::ModuleConfig,
    configs::maven::MavenConfig,
    context::Context,
    formatter::{StringFormatter, VersionFormatter},
    module::Module,
    utils,
};

pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
    let mut module = context.new_module("maven");
    let config = MavenConfig::try_load(module.config);
    let is_maven_project = context
        .try_begin_scan()?
        .set_files(&config.detect_files)
        .set_extensions(&config.detect_extensions)
        .set_folders(&config.detect_folders)
        .is_match();

    if !is_maven_project {
        return None;
    }

    let wrapper_properties = get_wrapper_properties_file(context, config.recursive);
    let parsed = StringFormatter::new(config.format).and_then(|formatter| {
        formatter
            .map_meta(|var, _| match var {
                "symbol" => Some(config.symbol),
                _ => None,
            })
            .map_style(|variable| match variable {
                "style" => Some(Ok(config.style)),
                _ => None,
            })
            .map(|variable| match variable {
                "version" => {
                    let properties = wrapper_properties.as_deref()?;
                    let maven_version = parse_maven_version_from_properties(properties)?;