use std::path::Path;
use crate::cli::FormatMappings;
pub const SUPPORTED_FORMATS: &[&str] = &[
"abap",
"actionscript",
"ada",
"apacheconf",
"apl",
"applescript",
"arduino",
"arff",
"asciidoc",
"asm6502",
"aspnet",
"autohotkey",
"autoit",
"bash",
"basic",
"batch",
"bison",
"brainfuck",
"bro",
"c",
"c-header",
"clike",
"clojure",
"coffeescript",
"comments",
"cpp",
"cpp-header",
"crystal",
"csharp",
"csp",
"css-extras",
"css",
"d",
"dart",
"diff",
"django",
"docker",
"eiffel",
"elixir",
"elm",
"erb",
"erlang",
"flow",
"fortran",
"fsharp",
"gdscript",
"gedcom",
"gherkin",
"git",
"glsl",
"go",
"graphql",
"groovy",
"haml",
"handlebars",
"haskell",
"haxe",
"hpkp",
"hsts",
"http",
"ichigojam",
"icon",
"inform7",
"ini",
"io",
"j",
"java",
"javascript",
"jolie",
"json",
"jsx",
"julia",
"keymap",
"kotlin",
"latex",
"less",
"liquid",
"lisp",
"livescript",
"lolcode",
"lua",
"makefile",
"markdown",
"markup",
"matlab",
"mel",
"mizar",
"monkey",
"n4js",
"nasm",
"nginx",
"nim",
"nix",
"nsis",
"objectivec",
"ocaml",
"opencl",
"oz",
"parigp",
"pascal",
"perl",
"php",
"plsql",
"powershell",
"processing",
"prolog",
"properties",
"protobuf",
"pug",
"puppet",
"pure",
"python",
"q",
"qore",
"r",
"reason",
"renpy",
"rest",
"rip",
"roboconf",
"ruby",
"rust",
"sas",
"sass",
"scala",
"scheme",
"scss",
"svelte",
"smalltalk",
"smarty",
"soy",
"sql",
"stylus",
"swift",
"tap",
"tcl",
"textile",
"tsx",
"tt2",
"twig",
"typescript",
"txt",
"vbnet",
"velocity",
"verilog",
"vhdl",
"vim",
"visual-basic",
"astro",
"vue",
"wasm",
"wiki",
"xeora",
"xojo",
"xquery",
"yaml",
"abnf",
"agda",
"antlr4",
"apex",
"aql",
"armasm",
"awk",
"bicep",
"bnf",
"cfscript",
"cfml",
"cmake",
"cobol",
"csv",
"cypher",
"dhall",
"dns-zone-file",
"dot",
"ebnf",
"editorconfig",
"excel-formula",
"factor",
"ftl",
"gcode",
"gettext",
"gml",
"go-module",
"hcl",
"hlsl",
"idris",
"ignore",
"jq",
"json5",
"kusto",
"lilypond",
"linker-script",
"llvm",
"log",
"mermaid",
"mongodb",
"n1ql",
"odin",
"openqasm",
"plant-uml",
"powerquery",
"promql",
"purescript",
"qsharp",
"racket",
"regex",
"rego",
"rescript",
"robotframework",
"shell-session",
"smali",
"solidity",
"sparql",
"stata",
"toml",
"turtle",
"typoscript",
"unrealscript",
"uri",
"vala",
"wgsl",
"wolfram",
"zig",
];
const EXTENSION_FORMATS: &[(&str, &str)] = &[
("as", "actionscript"),
("ada", "ada"),
("apl", "apl"),
("asp", "aspnet"),
("aspx", "aspnet"),
("sh", "bash"),
("ksh", "bash"),
("bash", "bash"),
("bas", "basic"),
("b", "brainfuck"),
("bf", "brainfuck"),
("c", "c"),
("z80", "c"),
("h", "c-header"),
("cljs", "clojure"),
("clj", "clojure"),
("cljc", "clojure"),
("cljx", "clojure"),
("edn", "clojure"),
("coffee", "coffeescript"),
("cpp", "cpp"),
("c++", "cpp"),
("cc", "cpp"),
("cxx", "cpp"),
("hpp", "cpp-header"),
("h++", "cpp-header"),
("hh", "cpp-header"),
("hxx", "cpp-header"),
("cr", "crystal"),
("cs", "csharp"),
("css", "css"),
("gss", "css"),
("d", "d"),
("dart", "dart"),
("diff", "diff"),
("patch", "diff"),
("e", "eiffel"),
("elm", "elm"),
("erl", "erlang"),
("erlang", "erlang"),
("f", "fortran"),
("for", "fortran"),
("f77", "fortran"),
("f90", "fortran"),
("fs", "fsharp"),
("gd", "gdscript"),
("feature", "gherkin"),
("go", "go"),
("graphql", "graphql"),
("groovy", "groovy"),
("gradle", "groovy"),
("haml", "haml"),
("hb", "handlebars"),
("hbs", "handlebars"),
("handlebars", "handlebars"),
("hs", "haskell"),
("lhs", "haskell"),
("hx", "haxe"),
("hxml", "haxe"),
("ini", "ini"),
("java", "java"),
("js", "javascript"),
("es", "javascript"),
("es6", "javascript"),
("mjs", "javascript"),
("cjs", "javascript"),
("json", "json"),
("map", "json"),
("jsonld", "json"),
("jsx", "jsx"),
("jl", "julia"),
("kt", "kotlin"),
("kts", "kotlin"),
("tex", "latex"),
("less", "less"),
("cl", "lisp"),
("lisp", "lisp"),
("el", "lisp"),
("ls", "livescript"),
("lua", "lua"),
("md", "markdown"),
("markdown", "markdown"),
("mkd", "markdown"),
("html", "markup"),
("htm", "markup"),
("xml", "markup"),
("xsl", "markup"),
("xslt", "markup"),
("svg", "markup"),
("ejs", "markup"),
("jsp", "markup"),
("nsh", "nsis"),
("nsi", "nsis"),
("m", "objectivec"),
("mm", "objectivec"),
("ocaml", "ocaml"),
("ml", "ocaml"),
("mli", "ocaml"),
("mll", "ocaml"),
("mly", "ocaml"),
("oz", "oz"),
("pas", "pascal"),
("p", "pascal"),
("pl", "perl"),
("pm", "perl"),
("php", "php"),
("phtml", "php"),
("plsql", "plsql"),
("ps1", "powershell"),
("psd1", "powershell"),
("psm1", "powershell"),
("pro", "prolog"),
("properties", "properties"),
("proto", "protobuf"),
("pug", "pug"),
("jade", "pug"),
("pp", "puppet"),
("puppet", "puppet"),
("py", "python"),
("pyx", "python"),
("pxd", "python"),
("pxi", "python"),
("q", "q"),
("r", "r"),
("R", "r"),
("rb", "ruby"),
("rs", "rust"),
("sas", "sas"),
("sass", "sass"),
("scala", "scala"),
("scm", "scheme"),
("ss", "scheme"),
("scss", "scss"),
("svelte", "svelte"),
("st", "smalltalk"),
("smarty", "smarty"),
("tpl", "smarty"),
("soy", "soy"),
("sql", "sql"),
("cql", "sql"),
("styl", "stylus"),
("stylus", "stylus"),
("swift", "swift"),
("tap", "tap"),
("tcl", "tcl"),
("textile", "textile"),
("tsx", "tsx"),
("tt2", "tt2"),
("twig", "twig"),
("ts", "typescript"),
("mts", "typescript"),
("cts", "typescript"),
("txt", "txt"),
("vb", "vbnet"),
("vtl", "velocity"),
("v", "verilog"),
("vhd", "vhdl"),
("vhdl", "vhdl"),
("astro", "astro"),
("vue", "vue"),
("xy", "xquery"),
("xquery", "xquery"),
("yaml", "yaml"),
("yml", "yaml"),
("g4", "antlr4"),
("cls", "apex"),
("trigger", "apex"),
("apex", "apex"),
("awk", "awk"),
("bicep", "bicep"),
("cfc", "cfscript"),
("cfm", "cfml"),
("cmake", "cmake"),
("csv", "csv"),
("dot", "dot"),
("gv", "dot"),
("xlsx", "excel-formula"),
("xls", "excel-formula"),
("po", "gettext"),
("tf", "hcl"),
("hcl", "hcl"),
("idr", "idris"),
("gitignore", "ignore"),
("json5", "json5"),
("ly", "lilypond"),
("ld", "linker-script"),
("ll", "llvm"),
("log", "log"),
("qasm", "openqasm"),
("puml", "plant-uml"),
("plantuml", "plant-uml"),
("pq", "powerquery"),
("purs", "purescript"),
("qs", "qsharp"),
("rkt", "racket"),
("res", "rescript"),
("robot", "robotframework"),
("sol", "solidity"),
("rq", "sparql"),
("toml", "toml"),
("ttl", "turtle"),
("uc", "unrealscript"),
("wgsl", "wgsl"),
("wl", "wolfram"),
("nb", "wolfram"),
("zig", "zig"),
];
pub fn format_for_path<'a>(
path: &Path,
formats_exts: &'a FormatMappings,
formats_names: &'a FormatMappings,
) -> Option<&'a str> {
let file_name = path.file_name()?.to_string_lossy();
if !formats_names.is_empty()
&& let Some(format) = formats_names.find_format_for_value(&file_name)
{
return Some(format);
}
let ext = path.extension()?.to_string_lossy();
if !formats_exts.is_empty() {
return formats_exts.find_format_for_value(&ext);
}
EXTENSION_FORMATS
.iter()
.find_map(|(candidate, format)| (*candidate == ext).then_some(*format))
}
pub fn supported_formats() -> Vec<&'static str> {
SUPPORTED_FORMATS.to_vec()
}
#[cfg(test)]
mod tests {
use std::path::Path;
use crate::cli::FormatMappings;
#[test]
fn maps_module_typescript_extensions_like_upstream() {
let formats_exts = FormatMappings::default();
let formats_names = FormatMappings::default();
assert_eq!(
super::format_for_path(Path::new("index.mts"), &formats_exts, &formats_names),
Some("typescript")
);
assert_eq!(
super::format_for_path(Path::new("index.cts"), &formats_exts, &formats_names),
Some("typescript")
);
}
#[test]
fn maps_javascript_module_extensions_like_upstream() {
let formats_exts = FormatMappings::default();
let formats_names = FormatMappings::default();
assert_eq!(
super::format_for_path(Path::new("index.es"), &formats_exts, &formats_names),
Some("javascript")
);
assert_eq!(
super::format_for_path(Path::new("index.es6"), &formats_exts, &formats_names),
Some("javascript")
);
}
#[test]
fn syncs_supported_format_surface_from_upstream() {
assert_eq!(super::SUPPORTED_FORMATS.len(), 223);
assert_eq!(super::EXTENSION_FORMATS.len(), 206);
assert_eq!(super::supported_formats().first(), Some(&"abap"));
assert!(super::supported_formats().contains(&"typescript"));
assert!(super::supported_formats().contains(&"excel-formula"));
}
#[test]
fn maps_long_tail_extensions_like_upstream() {
let formats_exts = FormatMappings::default();
let formats_names = FormatMappings::default();
assert_eq!(
super::format_for_path(Path::new("schema.g4"), &formats_exts, &formats_names),
Some("antlr4")
);
assert_eq!(
super::format_for_path(Path::new("component.bicep"), &formats_exts, &formats_names),
Some("bicep")
);
assert_eq!(
super::format_for_path(Path::new("formula.xlsx"), &formats_exts, &formats_names),
Some("excel-formula")
);
}
#[test]
fn maps_header_extensions_like_upstream() {
let formats_exts = FormatMappings::default();
let formats_names = FormatMappings::default();
assert_eq!(
super::format_for_path(Path::new("foo.h"), &formats_exts, &formats_names),
Some("c-header")
);
assert_eq!(
super::format_for_path(Path::new("foo.hpp"), &formats_exts, &formats_names),
Some("cpp-header")
);
}
#[test]
fn extensionless_names_require_formats_names_like_upstream() {
let formats_exts = FormatMappings::default();
let formats_names = FormatMappings::default();
assert_eq!(
super::format_for_path(Path::new("Makefile"), &formats_exts, &formats_names),
None
);
let formats_names = FormatMappings::from_pairs(vec![(
"makefile".to_string(),
vec!["Makefile".to_string(), "GNUmakefile".to_string()],
)]);
assert_eq!(
super::format_for_path(Path::new("Makefile"), &formats_exts, &formats_names),
Some("makefile")
);
}
}