1use std::ffi::OsStr;
2use std::path::Path;
3
4pub enum Indent {
5 AsIs,
6 Fixed(&'static str),
7}
8
9#[derive(Debug, Clone, Copy, PartialEq)]
10pub enum Language {
11 Plain,
12 C,
13 Rust,
14 JavaScript,
15 Go,
16 Cpp,
17 Python,
18 Julia,
19}
20
21impl Language {
22 pub fn name(self) -> &'static str {
23 use Language::*;
24 match self {
25 Plain => "plain",
26 C => "c",
27 Rust => "rust",
28 JavaScript => "javascript",
29 Go => "go",
30 Cpp => "c++",
31 Python => "python",
32 Julia => "julia",
33 }
34 }
35
36 fn file_exts(self) -> &'static [&'static str] {
37 use Language::*;
38 match self {
39 Plain => &[],
40 C => &["c", "h"],
41 Rust => &["rs"],
42 JavaScript => &["js"],
43 Go => &["go"],
44 Cpp => &["cpp", "hpp", "cxx", "hxx", "cc", "hh"],
45 Python => &["py"],
46 Julia => &["jl"],
47 }
48 }
49
50 pub fn indent(self) -> Indent {
51 use Language::*;
52 match self {
53 Plain | Go => Indent::AsIs,
54 C | Rust | Cpp | Python | Julia => Indent::Fixed(" "),
55 JavaScript => Indent::Fixed(" "),
56 }
57 }
58
59 pub fn detect<P: AsRef<Path>>(path: P) -> Language {
60 use Language::*;
61 if let Some(ext) = path.as_ref().extension().and_then(OsStr::to_str) {
62 for lang in &[C, Rust, JavaScript, Go, Cpp, Python, Julia] {
63 if lang.file_exts().contains(&ext) {
64 return *lang;
65 }
66 }
67 }
68 Plain
69 }
70}