ronantakizawa/codereview-bench huggingface dataset:
Repository: starship/starship
File: src/modules/meson.rs (Rust)

Code before:
use unicode_segmentation::UnicodeSegmentation;

use super::{Context, Module, ModuleConfig};

use crate::configs::meson::MesonConfig;
use crate::formatter::StringFormatter;

/// Creates a module with the current Meson dev environment
///
/// Will display the Meson environment if `$MESON_DEVENV` and `MESON_PROJECT_NAME` are set.
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
    let meson_env = context.get_env("MESON_DEVENV").unwrap_or_default();
    let project_env = context.get_env("MESON_PROJECT_NAME").unwrap_or_default();
    if meson_env != "1" || project_env.trim().is_empty() {
        return None;
    }

    let mut module = context.new_module("meson");
    let config: MesonConfig = MesonConfig::try_load(module.config);

    let truncation_symbol = get_first_grapheme(config.truncation_symbol);
    let len = if config.truncation_length <= 0 {
        log::warn!(
            "\"truncation_length\" should be a positive value, found {}",
            config.truncation_length
        );
        std::usize::MAX
    } else {
        config.truncation_length as usize
    };

    let mut project_name_graphemes: Vec<&str> = project_env.graphemes(true).collect();

    let e = &mut (&mut project_name_graphemes);
    let e = &mut **e;
    let trunc_len = len.min(e.len());
    if trunc_len < e.len() {
        // The truncation symbol should only be added if we truncate

Review comment (suggestion):
```suggestion
    let meson_env = context.get_env("MESON_DEVENV")?;
    let project_env = context.get_env("MESON_PROJECT_NAME")?;
```

Code after:
use super::{Context, Module, ModuleConfig};

use super::utils::truncate::truncate_text;
use crate::configs::meson::MesonConfig;
use crate::formatter::StringFormatter;

/// Creates a module with the current Meson dev environment
///
/// Will display the Meson environment if `$MESON_DEVENV` and `MESON_PROJECT_NAME` are set.
pub fn module<'a>(context: &'a Context) -> Option<Module<'a>> {
    let meson_env = context.get_env("MESON_DEVENV")?;
    let project_env = context.get_env("MESON_PROJECT_NAME")?;
    if meson_env != "1" || project_env.trim().is_empty() {
        return None;
    }

    let mut module = context.new_module("meson");
    let config: MesonConfig = MesonConfig::try_load(module.config);

    let truncated_text = truncate_text(
        &project_env,
        config.truncation_length as usize,
        config.truncation_symbol,
    );

    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 {
                "project" => Some(Ok(&truncated_text)),
                _ => None,
Repository: starship/starship
File: src/configs/meson.rs (Rust)

Code before:
use serde::{Deserialize, Serialize};

#[derive(Clone, Deserialize, Serialize)]
#[cfg_attr(
    feature = "config-schema",
    derive(schemars::JsonSchema),
    schemars(deny_unknown_fields)
)]
#[serde(default)]
pub struct MesonConfig<'a> {
    pub truncation_length: i64,
    pub truncation_symbol: &'a str,
    pub format: &'a str,
    pub symbol: &'a str,
    pub style: &'a str,
    pub disabled: bool,
}

impl<'a> Default for MesonConfig<'a> {
    fn default() -> Self {
        MesonConfig {
            truncation_length: std::i64::MAX,
            truncation_symbol: "…",
            format: "in [$symbol$project]($style) ",
            symbol: "⬢ ",
            style: "blue bold",
            disabled: false,
        }
    }
}


Review comment (suggestion):
The config parser supports unsigned integers now:
```suggestion
            truncation_length: std::u64::MAX,
```

Code after:
use serde::{Deserialize, Serialize};

#[derive(Clone, Deserialize, Serialize)]
#[cfg_attr(
    feature = "config-schema",
    derive(schemars::JsonSchema),
    schemars(deny_unknown_fields)
)]
#[serde(default)]
pub struct MesonConfig<'a> {
    pub truncation_length: u32,
    pub truncation_symbol: &'a str,
    pub format: &'a str,
    pub symbol: &'a str,
    pub style: &'a str,
    pub disabled: bool,
}

impl<'a> Default for MesonConfig<'a> {
    fn default() -> Self {
        MesonConfig {
            truncation_length: std::u32::MAX,
            truncation_symbol: "…",
            format: "via [$symbol$project]($style) ",
            symbol: "⬢ ",
            style: "blue bold",
            disabled: false,
        }
    }
}
Repository: starship/starship
File: src/modules/meson.rs (Rust)

Code before:

#[cfg(test)]
mod tests {
    use crate::test::ModuleRenderer;
    use nu_ansi_term::Color;

    #[test]
    fn not_in_env() {
        let actual = ModuleRenderer::new("meson").collect();

        let expected = None;

        assert_eq!(expected, actual);
    }

    #[test]
    fn env_set() {
        let actual = ModuleRenderer::new("meson")
            .env("MESON_DEVENV", "1")
            .env("MESON_PROJECT_NAME", "starship")
            .collect();

        let expected = Some(format!("via {} ", Color::Blue.bold().paint("⬢ starship")));

        assert_eq!(expected, actual);
    }
}


Review comment (suggestion):
I would prefer a few more tests here:
```suggestion
    }

    #[test]
    fn env_invalid_devenv() {
        let actual = ModuleRenderer::new("meson")
            .env("MESON_DEVENV", "0")
            .env("MESON_PROJECT_NAME", "starship")
            .collect();

        let expected = None;

        assert_eq!(expected, actual);
    }

    #[test]
    fn env_invalid_project_name() {
        let actual = ModuleRenderer::new("meson")
            .env("MESON_DEVENV", "1")
            .env("MESON_PROJECT_NAME", " ")
            .collect();

        let expected = None;

        assert_eq!(expected, actual);
    }
```

Code after:

#[cfg(test)]
mod tests {
    use crate::test::ModuleRenderer;
    use nu_ansi_term::Color;

    #[test]
    fn not_in_env() {
        let actual = ModuleRenderer::new("meson").collect();

        let expected = None;

        assert_eq!(expected, actual);
    }

    #[test]
    fn env_set() {
        let actual = ModuleRenderer::new("meson")
            .env("MESON_DEVENV", "1")
            .env("MESON_PROJECT_NAME", "starship")
            .collect();

        let expected = Some(format!("via {} ", Color::Blue.bold().paint("⬢ starship")));

        assert_eq!(expected, actual);
    }

    #[test]
    fn env_invalid_devenv() {
        let actual = ModuleRenderer::new("meson")
            .env("MESON_DEVENV", "0")
            .env("MESON_PROJECT_NAME", "starship")
            .collect();
        let expected = None;
        assert_eq!(expected, actual);
    }
    #[test]
    fn env_invalid_project_name() {
        let actual = ModuleRenderer::new("meson")
            .env("MESON_DEVENV", "1")
            .env("MESON_PROJECT_NAME", " ")
            .collect();
        let expected = None;
        assert_eq!(expected, actual);
    }
}
Repository: starship/starship
File: src/modules/haxe.rs (Rust)

Code before:
                    )
                    .map(Ok)
                }
                _ => None,
            })
            .parse(None, Some(context))
    });

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

    Some(module)
}

fn get_haxe_version(context: &Context) -> Option<String> {
    let file_contents = context.read_file_from_pwd(".haxerc");
    if file_contents.is_some() {
        let raw_json = match file_contents {
            Some(val) => val,
            None => panic!("failed to read contents of .haxerc!"),
        };
        let haxerc_json: json::Value = json::from_str(&raw_json).ok()?;
        let raw_version = haxerc_json.get("version")?.as_str()?;
        parse_haxe_version(raw_version)
    } else {
        let cmd_output = context.exec_cmd("haxe", &["--version"])?;
        let raw_version = cmd_output.stdout.as_str();
        parse_haxe_version(raw_version)
    }
}

fn parse_haxe_version(raw_version: &str) -> Option<String> {
    let re = Regex::new(HAXE_VERSION_PATTERN).ok()?;
    let captures = re.captures(raw_version)?;
    let version = &captures["version"];

    Some(version.to_string())
}

#[cfg(test)]
mod tests {
    use super::parse_haxe_version;
    use crate::{test::ModuleRenderer, utils::CommandOutput};
    use nu_ansi_term::Color;
    use serde_json as json;
    use std::fs::File;

Review comment (suggestion):
```suggestion
    if let Some(raw_json) = file_contents {
```

Code after:
                    .map(Ok)
                }
                _ => None,
            })
            .parse(None, Some(context))
    });

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

    Some(module)
}

fn get_haxe_version(context: &Context) -> Option<String> {
    get_haxerc_version(context).or_else(|| {
        let cmd_output = context.exec_cmd("haxe", &["--version"])?;
        parse_haxe_version(cmd_output.stdout.as_str())
    })
}

fn get_haxerc_version(context: &Context) -> Option<String> {
    let raw_json = context.read_file_from_pwd(".haxerc")?;
    let package_json: json::Value = json::from_str(&raw_json).ok()?;

    let raw_version = package_json.get("version")?.as_str()?;
    if raw_version.contains('/') || raw_version.contains('\\') {
        return None;
    }
    Some(raw_version.to_string())
}

fn parse_haxe_version(raw_version: &str) -> Option<String> {
    let re = Regex::new(HAXERC_VERSION_PATTERN).ok()?;
    if !re.is_match(raw_version) {
        return None;
    }
    Some(raw_version.trim().to_string())
}

#[cfg(test)]
mod tests {
    use super::parse_haxe_version;
    use crate::{test::ModuleRenderer, utils::CommandOutput};
    use nu_ansi_term::Color;
    use serde_json as json;
    use std::fs::File;
Repository: starship/starship
File: src/modules/haxe.rs (Rust)

Code before:
                }
                _ => None,
            })
            .parse(None, Some(context))
    });

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

    Some(module)
}

fn get_haxe_version(context: &Context) -> Option<String> {
    let file_contents = context.read_file_from_pwd(".haxerc");
    if file_contents.is_some() {
        let raw_json = match file_contents {
            Some(val) => val,
            None => panic!("failed to read contents of .haxerc!"),
        };
        let haxerc_json: json::Value = json::from_str(&raw_json).ok()?;
        let raw_version = haxerc_json.get("version")?.as_str()?;
        parse_haxe_version(raw_version)
    } else {
        let cmd_output = context.exec_cmd("haxe", &["--version"])?;
        let raw_version = cmd_output.stdout.as_str();
        parse_haxe_version(raw_version)
    }
}

fn parse_haxe_version(raw_version: &str) -> Option<String> {
    let re = Regex::new(HAXE_VERSION_PATTERN).ok()?;
    let captures = re.captures(raw_version)?;
    let version = &captures["version"];

    Some(version.to_string())
}

#[cfg(test)]
mod tests {
    use super::parse_haxe_version;
    use crate::{test::ModuleRenderer, utils::CommandOutput};
    use nu_ansi_term::Color;
    use serde_json as json;
    use std::fs::File;
    use std::io;
    use std::io::Write;

Review comment (suggestion):
Does the `haxerc` always contain `version`? If not, it should fall back to `haxe --version`

Code after:
                _ => None,
            })
            .parse(None, Some(context))
    });

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

    Some(module)
}

fn get_haxe_version(context: &Context) -> Option<String> {
    get_haxerc_version(context).or_else(|| {
        let cmd_output = context.exec_cmd("haxe", &["--version"])?;
        parse_haxe_version(cmd_output.stdout.as_str())
    })
}

fn get_haxerc_version(context: &Context) -> Option<String> {
    let raw_json = context.read_file_from_pwd(".haxerc")?;
    let package_json: json::Value = json::from_str(&raw_json).ok()?;

    let raw_version = package_json.get("version")?.as_str()?;
    if raw_version.contains('/') || raw_version.contains('\\') {
        return None;
    }
    Some(raw_version.to_string())
}

fn parse_haxe_version(raw_version: &str) -> Option<String> {
    let re = Regex::new(HAXERC_VERSION_PATTERN).ok()?;
    if !re.is_match(raw_version) {
        return None;
    }
    Some(raw_version.trim().to_string())
}

#[cfg(test)]
mod tests {
    use super::parse_haxe_version;
    use crate::{test::ModuleRenderer, utils::CommandOutput};
    use nu_ansi_term::Color;
    use serde_json as json;
    use std::fs::File;
    use std::io;
    use std::io::Write;
Repository: starship/starship
File: src/configs/haxe.rs (Rust)

Code before:
)]
#[serde(default)]
pub struct HaxeConfig<'a> {
    pub format: &'a str,
    pub version_format: &'a str,
    pub symbol: &'a str,
    pub style: &'a str,
    pub disabled: bool,
    pub detect_extensions: Vec<&'a str>,
    pub detect_files: Vec<&'a str>,
    pub detect_folders: Vec<&'a str>,
}

impl<'a> Default for HaxeConfig<'a> {
    fn default() -> Self {
        HaxeConfig {
            format: "via [$symbol($version )]($style)",
            version_format: "v${raw}",
            symbol: "⌘ ",
            style: "bold fg:202",
            disabled: false,
            detect_extensions: vec!["hx", "hxml"],
            detect_files: vec![
                "project.xml",
                "Project.xml",
                "application.xml",
                "haxelib.json",
                "hxformat.json",
                ".haxerc",
            ],
            detect_folders: vec![".haxelib", "haxe_libraries"],
        }
    }
}


Review comment (suggestion):
I think these filenames are a bit too generic for the default file list.
```suggestion
```

Code after:
)]
#[serde(default)]
pub struct HaxeConfig<'a> {
    pub format: &'a str,
    pub version_format: &'a str,
    pub symbol: &'a str,
    pub style: &'a str,
    pub disabled: bool,
    pub detect_extensions: Vec<&'a str>,
    pub detect_files: Vec<&'a str>,
    pub detect_folders: Vec<&'a str>,
}

impl<'a> Default for HaxeConfig<'a> {
    fn default() -> Self {
        HaxeConfig {
            format: "via [$symbol($version )]($style)",
            version_format: "v${raw}",
            symbol: "⌘ ",
            style: "bold fg:202",
            disabled: false,
            detect_extensions: vec!["hx", "hxml"],
            detect_files: vec!["haxelib.json", "hxformat.json", ".haxerc"],
            detect_folders: vec![".haxelib", "haxe_libraries"],
        }
    }
}
Repository: starship/starship
File: src/modules/haxe.rs (Rust)

Code before:
        Ok(segments) => segments,
        Err(error) => {
            log::warn!("Error in module `haxe`:\n{}", error);
            return None;
        }
    });

    Some(module)
}

fn get_haxe_version(context: &Context) -> Option<String> {
    if let Some(version) = get_haxerc_version(context) {
        Some(version)
    } else {
        let cmd_output = context.exec_cmd("haxe", &["--version"])?;
        parse_haxe_version(cmd_output.stdout.as_str())
    }
}

fn get_haxerc_version(context: &Context) -> Option<String> {
    let file_contents = context.read_file_from_pwd(".haxerc");
    if let Some(raw_json) = file_contents {
        let package_json: json::Value = json::from_str(&raw_json).ok()?;

        let raw_version = package_json.get("version")?.as_str()?;
        if raw_version == "null" {
            return None;
        };
        if raw_version.contains('/') || raw_version.contains('\\') {
            return None;
        }

        Some(raw_version.to_string())
    } else {
        None
    }
}

fn parse_haxe_version(raw_version: &str) -> Option<String> {
    let re = Regex::new(HAXERC_VERSION_PATTERN).ok()?;
    let captures = re.captures(raw_version)?;
    let version = &captures["version"];

    Some(version.to_string())
}

#[cfg(test)]
mod tests {
    use super::parse_haxe_version;
    use crate::{test::ModuleRenderer, utils::CommandOutput};
    use nu_ansi_term::Color;

Review comment (suggestion):
Is `"null"` (string) a possible value here? The line above should already handle regular non-string `null`.

Code after:
        Ok(segments) => segments,
        Err(error) => {
            log::warn!("Error in module `haxe`:\n{}", error);
            return None;
        }
    });

    Some(module)
}

fn get_haxe_version(context: &Context) -> Option<String> {
    get_haxerc_version(context).or_else(|| {
        let cmd_output = context.exec_cmd("haxe", &["--version"])?;
        parse_haxe_version(cmd_output.stdout.as_str())
    })
}

fn get_haxerc_version(context: &Context) -> Option<String> {
    let raw_json = context.read_file_from_pwd(".haxerc")?;
    let package_json: json::Value = json::from_str(&raw_json).ok()?;

    let raw_version = package_json.get("version")?.as_str()?;
    if raw_version.contains('/') || raw_version.contains('\\') {
        return None;
    }
    Some(raw_version.to_string())
}

fn parse_haxe_version(raw_version: &str) -> Option<String> {
    let re = Regex::new(HAXERC_VERSION_PATTERN).ok()?;
    if !re.is_match(raw_version) {
        return None;
    }
    Some(raw_version.trim().to_string())
}

#[cfg(test)]
mod tests {
    use super::parse_haxe_version;
    use crate::{test::ModuleRenderer, utils::CommandOutput};
    use nu_ansi_term::Color;
    use serde_json as json;
    use std::fs::File;
    use std::io;
    use std::io::Write;
    use tempfile::TempDir;

    #[test]
    fn haxe_version() {
        let ok_versions = [
            "4.2.5",
Repository: starship/starship
File: src/modules/haxe.rs (Rust)

Code before:
                    )
                    .map(Ok)
                }
                _ => None,
            })
            .parse(None, Some(context))
    });

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

    Some(module)
}

fn get_haxe_version(context: &Context) -> Option<String> {
    if let Some(version) = get_haxerc_version(context) {
        Some(version)
    } else {
        let cmd_output = context.exec_cmd("haxe", &["--version"])?;
        parse_haxe_version(cmd_output.stdout.as_str())
    }
}

fn get_haxerc_version(context: &Context) -> Option<String> {
    let file_contents = context.read_file_from_pwd(".haxerc");
    if let Some(raw_json) = file_contents {
        let package_json: json::Value = json::from_str(&raw_json).ok()?;

        let raw_version = package_json.get("version")?.as_str()?;
        if raw_version == "null" {
            return None;
        };
        if raw_version.contains('/') || raw_version.contains('\\') {
            return None;
        }

        Some(raw_version.to_string())
    } else {
        None
    }
}

fn parse_haxe_version(raw_version: &str) -> Option<String> {
    let re = Regex::new(HAXERC_VERSION_PATTERN).ok()?;
    let captures = re.captures(raw_version)?;
    let version = &captures["version"];

Review comment (suggestion):
This would look better with `or_else`:
```suggestion
    get_haxerc_version(context).or_else(|| {
        context.exec_cmd("haxe", &["--version"])?;
        parse_haxe_version(cmd_output.stdout.as_str())
    })
```

Code after:
                    )
                    .map(Ok)
                }
                _ => None,
            })
            .parse(None, Some(context))
    });

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

    Some(module)
}

fn get_haxe_version(context: &Context) -> Option<String> {
    get_haxerc_version(context).or_else(|| {
        let cmd_output = context.exec_cmd("haxe", &["--version"])?;
        parse_haxe_version(cmd_output.stdout.as_str())
    })
}

fn get_haxerc_version(context: &Context) -> Option<String> {
    let raw_json = context.read_file_from_pwd(".haxerc")?;
    let package_json: json::Value = json::from_str(&raw_json).ok()?;

    let raw_version = package_json.get("version")?.as_str()?;
    if raw_version.contains('/') || raw_version.contains('\\') {
        return None;
    }
    Some(raw_version.to_string())
}

fn parse_haxe_version(raw_version: &str) -> Option<String> {
    let re = Regex::new(HAXERC_VERSION_PATTERN).ok()?;
    if !re.is_match(raw_version) {
        return None;
    }
    Some(raw_version.trim().to_string())
}

#[cfg(test)]
mod tests {
    use super::parse_haxe_version;
    use crate::{test::ModuleRenderer, utils::CommandOutput};
    use nu_ansi_term::Color;
    use serde_json as json;