fluidattacks-blends-domain 0.41.0

Blends functional core: pure AST graph to syntax graph (no_std)
Documentation
use alloc::vec::Vec;

use crate::Language;

pub fn module_segments(language: Language, path: &str) -> Vec<&str> {
    let (directories, file) = path.rsplit_once('/').unwrap_or(("", path));
    let stem = file_stem(file);
    let module = (package_file(language) != Some(stem)).then_some(stem);
    directories
        .split('/')
        .chain(module)
        .flat_map(|part| part.split('.'))
        .filter(|segment| !segment.is_empty())
        .collect()
}

fn file_stem(file: &str) -> &str {
    match file.rsplit_once('.') {
        Some((stem, _)) if !stem.is_empty() => stem,
        _ => file,
    }
}

const fn package_file(language: Language) -> Option<&'static str> {
    match language {
        Language::Python => Some("__init__"),
        Language::JavaScript | Language::TypeScript => Some("index"),
        _ => None,
    }
}

#[cfg(test)]
mod tests {
    use super::module_segments;
    use crate::Language;

    #[test]
    fn a_python_file_is_a_module_inside_its_directories() {
        assert_eq!(
            module_segments(Language::Python, "pkg/mod.py"),
            ["pkg", "mod"]
        );
    }

    #[test]
    fn a_python_package_file_is_the_module_of_its_directory() {
        assert_eq!(
            module_segments(Language::Python, "pkg/__init__.py"),
            ["pkg"]
        );
    }

    #[test]
    fn a_package_file_at_the_root_names_no_module() {
        assert!(module_segments(Language::Python, "__init__.py").is_empty());
    }

    #[test]
    fn a_python_file_named_index_is_an_ordinary_module() {
        assert_eq!(
            module_segments(Language::Python, "pkg/index.py"),
            ["pkg", "index"]
        );
    }

    #[test]
    fn a_javascript_index_file_is_the_module_of_its_directory() {
        assert_eq!(
            module_segments(Language::JavaScript, "lib/index.js"),
            ["lib"]
        );
    }

    #[test]
    fn each_dot_of_a_file_name_separates_a_segment_as_in_a_dotted_import() {
        assert_eq!(
            module_segments(Language::JavaScript, "src/a.test.js"),
            ["src", "a", "test"]
        );
    }

    #[test]
    fn a_language_without_package_files_keeps_every_file_name() {
        assert_eq!(
            module_segments(Language::Go, "cmd/main.go"),
            ["cmd", "main"]
        );
    }
}