1use super::ZshOptionState;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
5pub enum ShellDialect {
6 Posix,
8 Mksh,
10 #[default]
12 Bash,
13 Zsh,
15}
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub(super) struct DialectFeatures {
19 pub(super) double_bracket: bool,
20 pub(super) arithmetic_command: bool,
21 pub(super) arithmetic_for: bool,
22 pub(super) function_keyword: bool,
23 pub(super) select_loop: bool,
24 pub(super) coproc_keyword: bool,
25 pub(super) zsh_repeat_loop: bool,
26 pub(super) zsh_foreach_loop: bool,
27 pub(super) zsh_parameter_modifiers: bool,
28 pub(super) zsh_brace_if: bool,
29 pub(super) zsh_always: bool,
30 pub(super) zsh_background_operators: bool,
31 pub(super) zsh_glob_qualifiers: bool,
32}
33
34impl ShellDialect {
35 pub fn from_name(name: &str) -> Self {
37 match name.trim().to_ascii_lowercase().as_str() {
38 "sh" | "dash" | "ksh" | "posix" => Self::Posix,
39 "mksh" => Self::Mksh,
40 "zsh" => Self::Zsh,
41 _ => Self::Bash,
42 }
43 }
44
45 pub(super) const fn features(self) -> DialectFeatures {
46 match self {
47 Self::Posix => DialectFeatures {
48 double_bracket: false,
49 arithmetic_command: false,
50 arithmetic_for: false,
51 function_keyword: true,
52 select_loop: false,
53 coproc_keyword: false,
54 zsh_repeat_loop: false,
55 zsh_foreach_loop: false,
56 zsh_parameter_modifiers: false,
57 zsh_brace_if: false,
58 zsh_always: false,
59 zsh_background_operators: false,
60 zsh_glob_qualifiers: false,
61 },
62 Self::Mksh => DialectFeatures {
63 double_bracket: true,
64 arithmetic_command: true,
65 arithmetic_for: false,
66 function_keyword: true,
67 select_loop: true,
68 coproc_keyword: false,
69 zsh_repeat_loop: false,
70 zsh_foreach_loop: false,
71 zsh_parameter_modifiers: false,
72 zsh_brace_if: false,
73 zsh_always: false,
74 zsh_background_operators: false,
75 zsh_glob_qualifiers: false,
76 },
77 Self::Bash => DialectFeatures {
78 double_bracket: true,
79 arithmetic_command: true,
80 arithmetic_for: true,
81 function_keyword: true,
82 select_loop: true,
83 coproc_keyword: true,
84 zsh_repeat_loop: false,
85 zsh_foreach_loop: false,
86 zsh_parameter_modifiers: false,
87 zsh_brace_if: false,
88 zsh_always: false,
89 zsh_background_operators: false,
90 zsh_glob_qualifiers: false,
91 },
92 Self::Zsh => DialectFeatures {
93 double_bracket: true,
94 arithmetic_command: true,
95 arithmetic_for: true,
96 function_keyword: true,
97 select_loop: true,
98 coproc_keyword: true,
99 zsh_repeat_loop: true,
100 zsh_foreach_loop: true,
101 zsh_parameter_modifiers: true,
102 zsh_brace_if: true,
103 zsh_always: true,
104 zsh_background_operators: true,
105 zsh_glob_qualifiers: true,
106 },
107 }
108 }
109}
110
111#[derive(Debug, Clone, PartialEq, Eq, Hash)]
113pub struct ShellProfile {
114 pub dialect: ShellDialect,
116 pub options: Option<ZshOptionState>,
118}
119
120impl ShellProfile {
121 pub fn native(dialect: ShellDialect) -> Self {
123 Self {
124 dialect,
125 options: (dialect == ShellDialect::Zsh).then(ZshOptionState::zsh_default),
126 }
127 }
128
129 pub fn with_zsh_options(dialect: ShellDialect, options: ZshOptionState) -> Self {
131 Self {
132 dialect,
133 options: (dialect == ShellDialect::Zsh).then_some(options),
134 }
135 }
136
137 pub fn zsh_options(&self) -> Option<&ZshOptionState> {
139 self.options.as_ref()
140 }
141}