use monostyle_core::Language;
use crate::profile::BlockStyle;
use crate::profile::HeredocSyntax;
use crate::profile::Interpolation;
use crate::profile::LanguageProfile;
use crate::profile::StringRule;
const C_LINE_COMMENTS: &[&str] = &["//"];
const C_BLOCK_COMMENTS: &[(&str, &str)] = &[("/*", "*/")];
const C_STRINGS: &[StringRule] = &[
StringRule::escaped("\"", "\""),
StringRule::escaped("'", "'"),
];
const C_STRING_PREFIXES: &[char] = &['L', 'u', 'U', 'R', 'B'];
const C_DECISIONS: &[&str] = &[
"if", "else if", "for", "while", "case", "when", "catch", "except", "rescue", "default",
];
const C_NESTING: &[&str] = &[
"if", "else if", "else", "for", "while", "switch", "match", "case", "when", "catch", "except",
"rescue", "loop", "try",
];
const C_LOGICAL: &[&str] = &["&&", "||"];
const GOTO: &[&str] = &["goto"];
const NONE: &[&str] = &[];
const NO_STRINGS: &[StringRule] = &[];
const NO_BLOCK_COMMENTS: &[(&str, &str)] = &[];
const NO_CHARS: &[char] = &[];
const NULLISH: &[&str] = &["??", "?.", "??="];
const RUST_STRINGS: &[StringRule] = &[
StringRule::escaped("\"", "\""),
StringRule::escaped("'", "'"),
];
const RUST_STRING_PREFIXES: &[char] = &['r', 'b'];
const RUST_DECISIONS: &[&str] = &["if", "else if", "for", "while", "loop", "match", "default"];
const RUST_NESTING: &[&str] = &["if", "else if", "else", "for", "while", "loop", "match"];
const TS_STRINGS: &[StringRule] = &[
StringRule::multiline_interpolated("`", "`"),
StringRule::escaped("\"", "\""),
StringRule::escaped("'", "'"),
];
const TS_DECISIONS: &[&str] = &["if", "else if", "for", "while", "case", "catch", "default"];
const CSHARP_STRINGS: &[StringRule] = &[
StringRule::multiline_raw("\"\"\"", "\"\"\""),
StringRule::multiline_raw("@\"", "\""),
StringRule::escaped("\"", "\""),
StringRule::escaped("'", "'"),
];
const CSHARP_STRING_PREFIXES: &[char] = &['@', '$'];
const CSHARP_DECISIONS: &[&str] = &[
"if", "else if", "for", "foreach", "while", "case", "catch", "when", "default",
];
const KOTLIN_STRINGS: &[StringRule] = &[
StringRule::multiline_interpolated("\"\"\"", "\"\"\""),
StringRule::interpolated("\"", "\""),
StringRule::escaped("'", "'"),
];
const KOTLIN_DECISIONS: &[&str] = &["if", "else if", "for", "while", "when", "catch", "default"];
const KOTLIN_NESTING: &[&str] = &[
"if", "else if", "else", "for", "while", "when", "catch", "try",
];
const KOTLIN_NULLISH: &[&str] = &["?:", "?."];
const DART_STRINGS: &[StringRule] = &[
StringRule::multiline_interpolated("'''", "'''"),
StringRule::multiline_interpolated("\"\"\"", "\"\"\""),
StringRule::interpolated("'", "'"),
StringRule::interpolated("\"", "\""),
];
const DART_STRING_PREFIXES: &[char] = &['r'];
const DART_DECISIONS: &[&str] = &[
"if", "else if", "for", "while", "do", "switch", "case", "catch", "on", "default",
];
const DART_NESTING: &[&str] = &[
"if", "else if", "else", "for", "while", "do", "switch", "case", "catch", "on", "try",
];
const SWIFT_STRINGS: &[StringRule] = &[
StringRule::multiline_interpolated("\"\"\"", "\"\"\""),
StringRule::interpolated("\"", "\""),
];
const SWIFT_DECISIONS: &[&str] = &[
"if", "else if", "guard", "for", "while", "repeat", "case", "catch", "default",
];
const SWIFT_NESTING: &[&str] = &[
"if", "else if", "else", "guard", "for", "while", "repeat", "switch", "case", "catch", "do",
];
const SWIFT_NULLISH: &[&str] = &["??", "?."];
const GO_STRINGS: &[StringRule] = &[
StringRule::multiline_raw("`", "`"),
StringRule::escaped("\"", "\""),
StringRule::escaped("'", "'"),
];
const GO_DECISIONS: &[&str] = &["if", "else if", "for", "case", "select", "default"];
const GO_NESTING: &[&str] = &["if", "else if", "else", "for", "switch", "case", "select"];
const PHP_LINE_COMMENTS: &[&str] = &["//", "#"];
const PHP_STRINGS: &[StringRule] = &[
StringRule::multiline_interpolated("\"", "\""),
StringRule::escaped("'", "'"),
];
const PHP_DECISIONS: &[&str] = &[
"if", "elseif", "else if", "for", "foreach", "while", "case", "catch", "default",
];
const PHP_NESTING: &[&str] = &[
"if", "elseif", "else if", "else", "for", "foreach", "while", "switch", "case", "catch", "try",
];
const PHP_NULLISH: &[&str] = &["??", "?->"];
const PHP_HEREDOC: HeredocSyntax = HeredocSyntax {
marker: "<<<",
allows_dash: false,
allows_tilde: false,
};
const SCALA_STRINGS: &[StringRule] = &[
StringRule::multiline_interpolated("\"\"\"", "\"\"\""),
StringRule::interpolated("\"", "\""),
StringRule::escaped("'", "'"),
];
const SCALA_DECISIONS: &[&str] = &["if", "else if", "for", "while", "case", "catch", "default"];
const SCALA_NESTING: &[&str] = &[
"if", "else if", "else", "for", "while", "match", "case", "catch", "try",
];
const PYTHON_LINE_COMMENTS: &[&str] = &["#"];
const PYTHON_STRINGS: &[StringRule] = &[
StringRule::multiline_interpolated("\"\"\"", "\"\"\""),
StringRule::multiline_interpolated("'''", "'''"),
StringRule::interpolated("\"", "\""),
StringRule::interpolated("'", "'"),
];
const PYTHON_STRING_PREFIXES: &[char] = &['r', 'b', 'f', 'u', 'R', 'B', 'F', 'U'];
const PYTHON_DECISIONS: &[&str] = &["if", "elif", "for", "while", "except", "case", "match"];
const PYTHON_NESTING: &[&str] = &[
"if", "elif", "else", "for", "while", "except", "with", "try", "match", "case",
];
const PYTHON_LOGICAL: &[&str] = &["and", "or"];
const RUBY_LINE_COMMENTS: &[&str] = &["#"];
const RUBY_BLOCK_COMMENTS: &[(&str, &str)] = &[("=begin", "=end")];
const RUBY_STRINGS: &[StringRule] = &[
StringRule::multiline_interpolated("\"", "\""),
StringRule::escaped("'", "'"),
StringRule::multiline_raw("`", "`"),
];
const RUBY_DECISIONS: &[&str] = &[
"if", "elsif", "unless", "for", "while", "until", "when", "rescue", "case",
];
const RUBY_NESTING: &[&str] = &[
"if", "elsif", "else", "unless", "for", "while", "until", "case", "when", "rescue", "begin",
"do",
];
const RUBY_LOGICAL: &[&str] = &["&&", "||", " and ", " or "];
const RUBY_HEREDOC: HeredocSyntax = HeredocSyntax {
marker: "<<",
allows_dash: true,
allows_tilde: true,
};
const RUBY_END: &[&str] = &["end"];
const LUA_LINE_COMMENTS: &[&str] = &["--"];
const LUA_BLOCK_COMMENTS: &[(&str, &str)] = &[("--[[", "]]")];
const LUA_STRINGS: &[StringRule] = &[
StringRule::multiline_raw("[[", "]]"),
StringRule::escaped("\"", "\""),
StringRule::escaped("'", "'"),
];
const LUA_DECISIONS: &[&str] = &["if", "elseif", "for", "while", "repeat"];
const LUA_NESTING: &[&str] = &[
"if", "elseif", "else", "for", "while", "repeat", "do", "function",
];
const LUA_LOGICAL: &[&str] = &[" and ", " or "];
const LUA_END: &[&str] = &["end", "until"];
const ELIXIR_LINE_COMMENTS: &[&str] = &["#"];
const ELIXIR_STRINGS: &[StringRule] = &[
StringRule::multiline_interpolated("\"\"\"", "\"\"\""),
StringRule::interpolated("\"", "\""),
];
const ELIXIR_DECISIONS: &[&str] = &["if", "unless", "case", "cond", "for", "rescue", "else"];
const ELIXIR_NESTING: &[&str] = &[
"if", "unless", "case", "cond", "for", "try", "rescue", "else",
];
const ELIXIR_LOGICAL: &[&str] = &["and", "or", "&&", "||"];
const ELIXIR_END: &[&str] = &["end"];
const HASKELL_LINE_COMMENTS: &[&str] = &["--"];
const HASKELL_BLOCK_COMMENTS: &[(&str, &str)] = &[("{-", "-}")];
const HASKELL_STRINGS: &[StringRule] = &[StringRule::escaped("\"", "\"")];
const HASKELL_DECISIONS: &[&str] = &["if", "case", "where"];
const HASKELL_NESTING: &[&str] = &["if", "case", "where", "let", "do"];
const NIX_LINE_COMMENTS: &[&str] = &["#"];
const NIX_BLOCK_COMMENTS: &[(&str, &str)] = &[("/*", "*/")];
const NIX_INDENTED_ESCAPES: &[&str] = &["''$", "'''", "''\\"];
const NIX_QUOTED_ESCAPES: &[&str] = &["\\\"", "\\$"];
const NIX_STRINGS: &[StringRule] = &[
StringRule::multiline_interpolated("''", "''").with_extra_escapes(NIX_INDENTED_ESCAPES),
StringRule::multiline_interpolated("\"", "\"").with_extra_escapes(NIX_QUOTED_ESCAPES),
];
const NIX_DECISIONS: &[&str] = &["if", "assert"];
const NIX_NESTING: &[&str] = &["if", "let", "with", "assert"];
const SHELL_LINE_COMMENTS: &[&str] = &["#"];
const SHELL_STRINGS: &[StringRule] = &[
StringRule::multiline_interpolated("\"", "\""),
StringRule::escaped("'", "'"),
StringRule::escaped("`", "`"),
];
const SHELL_DECISIONS: &[&str] = &["if", "elif", "for", "while", "until", "case"];
const SHELL_NESTING: &[&str] = &["if", "elif", "else", "for", "while", "until", "case"];
const SHELL_HEREDOC: HeredocSyntax = HeredocSyntax {
marker: "<<",
allows_dash: true,
allows_tilde: false,
};
const SHELL_END: &[&str] = &["fi", "done", "esac"];
fn c_family(language: Language) -> LanguageProfile {
LanguageProfile {
language,
line_comments: C_LINE_COMMENTS,
block_comments: C_BLOCK_COMMENTS,
nestable_comments: false,
strings: C_STRINGS,
string_prefixes: C_STRING_PREFIXES,
hashed_raw_strings: false,
raw_string_prefix: None,
interpolation: None,
heredoc: None,
regex_literals: false,
decision_keywords: C_DECISIONS,
nesting_keywords: C_NESTING,
logical_operators: C_LOGICAL,
jump_keywords: GOTO,
ternary_operator: Some('?'),
null_coalescing: NONE,
block_style: BlockStyle::Brace,
end_keywords: NONE,
parameter_list_start: Some('('),
variables_use_sigil: false,
}
}
#[must_use]
pub fn profile_for(language: Language) -> LanguageProfile {
match language {
Language::Rust => rust(language),
Language::Python => python(language),
Language::Dart => dart(language),
Language::Go => go(language),
Language::Swift => swift(language),
Language::Ruby => ruby(language),
Language::Php => php(language),
Language::Scala => scala(language),
Language::Shell => shell(language),
Language::Lua => lua(language),
Language::Elixir => elixir(language),
Language::Haskell => haskell(language),
Language::Nix => nix(language),
Language::TypeScript | Language::Tsx => typescript(language),
Language::JavaScript | Language::Mozjs => javascript(language),
Language::CSharp => csharp(language),
Language::Kotlin => kotlin(language),
Language::Markdown => markdown(language),
Language::C | Language::Cpp | Language::Java => c_family(language),
}
}
fn rust(language: Language) -> LanguageProfile {
LanguageProfile {
strings: RUST_STRINGS,
string_prefixes: RUST_STRING_PREFIXES,
hashed_raw_strings: true,
raw_string_prefix: Some('r'),
nestable_comments: true,
decision_keywords: RUST_DECISIONS,
nesting_keywords: RUST_NESTING,
jump_keywords: NONE,
ternary_operator: None,
..c_family(language)
}
}
fn typescript(language: Language) -> LanguageProfile {
LanguageProfile {
strings: TS_STRINGS,
interpolation: Some(Interpolation::DollarBrace),
regex_literals: true,
decision_keywords: TS_DECISIONS,
null_coalescing: NULLISH,
..c_family(language)
}
}
fn javascript(language: Language) -> LanguageProfile {
LanguageProfile {
strings: TS_STRINGS,
interpolation: Some(Interpolation::DollarBrace),
regex_literals: true,
null_coalescing: NULLISH,
..c_family(language)
}
}
fn csharp(language: Language) -> LanguageProfile {
LanguageProfile {
strings: CSHARP_STRINGS,
string_prefixes: CSHARP_STRING_PREFIXES,
interpolation: Some(Interpolation::Brace),
decision_keywords: CSHARP_DECISIONS,
null_coalescing: NULLISH,
..c_family(language)
}
}
fn kotlin(language: Language) -> LanguageProfile {
LanguageProfile {
strings: KOTLIN_STRINGS,
interpolation: Some(Interpolation::Dollar { braced: true }),
nestable_comments: true,
decision_keywords: KOTLIN_DECISIONS,
nesting_keywords: KOTLIN_NESTING,
null_coalescing: KOTLIN_NULLISH,
..c_family(language)
}
}
fn dart(language: Language) -> LanguageProfile {
LanguageProfile {
strings: DART_STRINGS,
string_prefixes: DART_STRING_PREFIXES,
interpolation: Some(Interpolation::Dollar { braced: true }),
decision_keywords: DART_DECISIONS,
nesting_keywords: DART_NESTING,
null_coalescing: NULLISH,
..c_family(language)
}
}
fn swift(language: Language) -> LanguageProfile {
LanguageProfile {
strings: SWIFT_STRINGS,
interpolation: Some(Interpolation::Dollar { braced: true }),
nestable_comments: true,
decision_keywords: SWIFT_DECISIONS,
nesting_keywords: SWIFT_NESTING,
null_coalescing: SWIFT_NULLISH,
..c_family(language)
}
}
fn go(language: Language) -> LanguageProfile {
LanguageProfile {
strings: GO_STRINGS,
decision_keywords: GO_DECISIONS,
nesting_keywords: GO_NESTING,
..c_family(language)
}
}
fn php(language: Language) -> LanguageProfile {
LanguageProfile {
line_comments: PHP_LINE_COMMENTS,
strings: PHP_STRINGS,
string_prefixes: NO_CHARS,
interpolation: Some(Interpolation::Dollar { braced: true }),
heredoc: Some(PHP_HEREDOC),
decision_keywords: PHP_DECISIONS,
nesting_keywords: PHP_NESTING,
null_coalescing: PHP_NULLISH,
variables_use_sigil: true,
..c_family(language)
}
}
fn scala(language: Language) -> LanguageProfile {
LanguageProfile {
strings: SCALA_STRINGS,
interpolation: Some(Interpolation::Dollar { braced: true }),
decision_keywords: SCALA_DECISIONS,
nesting_keywords: SCALA_NESTING,
..c_family(language)
}
}
fn python(language: Language) -> LanguageProfile {
LanguageProfile {
line_comments: PYTHON_LINE_COMMENTS,
block_comments: NO_BLOCK_COMMENTS,
strings: PYTHON_STRINGS,
string_prefixes: PYTHON_STRING_PREFIXES,
interpolation: Some(Interpolation::Brace),
decision_keywords: PYTHON_DECISIONS,
nesting_keywords: PYTHON_NESTING,
logical_operators: PYTHON_LOGICAL,
jump_keywords: NONE,
ternary_operator: None,
block_style: BlockStyle::Indentation,
..c_family(language)
}
}
fn ruby(language: Language) -> LanguageProfile {
LanguageProfile {
line_comments: RUBY_LINE_COMMENTS,
block_comments: RUBY_BLOCK_COMMENTS,
strings: RUBY_STRINGS,
string_prefixes: NO_CHARS,
interpolation: Some(Interpolation::Hash),
heredoc: Some(RUBY_HEREDOC),
regex_literals: true,
decision_keywords: RUBY_DECISIONS,
nesting_keywords: RUBY_NESTING,
logical_operators: RUBY_LOGICAL,
jump_keywords: NONE,
block_style: BlockStyle::EndKeyword,
end_keywords: RUBY_END,
variables_use_sigil: true,
..c_family(language)
}
}
fn lua(language: Language) -> LanguageProfile {
LanguageProfile {
line_comments: LUA_LINE_COMMENTS,
block_comments: LUA_BLOCK_COMMENTS,
strings: LUA_STRINGS,
string_prefixes: NO_CHARS,
decision_keywords: LUA_DECISIONS,
nesting_keywords: LUA_NESTING,
logical_operators: LUA_LOGICAL,
ternary_operator: None,
block_style: BlockStyle::EndKeyword,
end_keywords: LUA_END,
..c_family(language)
}
}
fn elixir(language: Language) -> LanguageProfile {
LanguageProfile {
line_comments: ELIXIR_LINE_COMMENTS,
block_comments: NO_BLOCK_COMMENTS,
strings: ELIXIR_STRINGS,
string_prefixes: NO_CHARS,
interpolation: Some(Interpolation::Hash),
decision_keywords: ELIXIR_DECISIONS,
nesting_keywords: ELIXIR_NESTING,
logical_operators: ELIXIR_LOGICAL,
ternary_operator: None,
block_style: BlockStyle::EndKeyword,
end_keywords: ELIXIR_END,
..c_family(language)
}
}
fn haskell(language: Language) -> LanguageProfile {
LanguageProfile {
line_comments: HASKELL_LINE_COMMENTS,
block_comments: HASKELL_BLOCK_COMMENTS,
nestable_comments: true,
strings: HASKELL_STRINGS,
string_prefixes: NO_CHARS,
decision_keywords: HASKELL_DECISIONS,
nesting_keywords: HASKELL_NESTING,
ternary_operator: None,
block_style: BlockStyle::Indentation,
..c_family(language)
}
}
fn nix(language: Language) -> LanguageProfile {
LanguageProfile {
line_comments: NIX_LINE_COMMENTS,
block_comments: NIX_BLOCK_COMMENTS,
strings: NIX_STRINGS,
string_prefixes: NO_CHARS,
interpolation: Some(Interpolation::Dollar { braced: true }),
decision_keywords: NIX_DECISIONS,
nesting_keywords: NIX_NESTING,
ternary_operator: None,
..c_family(language)
}
}
fn shell(language: Language) -> LanguageProfile {
LanguageProfile {
line_comments: SHELL_LINE_COMMENTS,
block_comments: NO_BLOCK_COMMENTS,
strings: SHELL_STRINGS,
string_prefixes: NO_CHARS,
interpolation: Some(Interpolation::Dollar { braced: true }),
heredoc: Some(SHELL_HEREDOC),
decision_keywords: SHELL_DECISIONS,
nesting_keywords: SHELL_NESTING,
ternary_operator: None,
block_style: BlockStyle::EndKeyword,
end_keywords: SHELL_END,
parameter_list_start: None,
variables_use_sigil: true,
..c_family(language)
}
}
fn markdown(language: Language) -> LanguageProfile {
LanguageProfile {
line_comments: NONE,
block_comments: NO_BLOCK_COMMENTS,
strings: NO_STRINGS,
string_prefixes: NO_CHARS,
decision_keywords: NONE,
nesting_keywords: NONE,
logical_operators: NONE,
jump_keywords: NONE,
ternary_operator: None,
null_coalescing: NONE,
end_keywords: NONE,
parameter_list_start: None,
..c_family(language)
}
}