1use f00_core::{IconsWhen, ListOptions, OutputMode, SortBy};
4
5#[derive(Debug, Clone, Default)]
7pub struct GnuProfile {
8 pub force_one_per_line_when_not_tty: bool,
10 pub disable_dirs_first: bool,
12 pub strict_name_sort: bool,
14 pub disable_decorations: bool,
16}
17
18impl GnuProfile {
19 pub fn enabled() -> Self {
20 Self {
21 force_one_per_line_when_not_tty: true,
22 disable_dirs_first: true,
23 strict_name_sort: true,
24 disable_decorations: true,
25 }
26 }
27}
28
29pub fn apply_gnu_list_options(opts: &mut ListOptions, gnu: bool) {
31 if !gnu {
32 return;
33 }
34 opts.gnu_mode = true;
35 opts.dirs_first = false;
37}
38
39pub fn apply_gnu_output(mode: OutputMode, is_tty: bool, gnu: bool) -> OutputMode {
41 if !gnu {
42 return mode;
43 }
44 match mode {
45 OutputMode::Default if !is_tty => OutputMode::OnePerLine,
46 other => other,
47 }
48}
49
50pub fn gnu_mode_active(gnu_flag: bool) -> bool {
52 gnu_flag
53}
54
55pub fn prefer_ls_defaults(
61 icons: &mut IconsWhen,
62 dirs_first: &mut bool,
63 icons_from_cli: bool,
64 dirs_first_from_cli: bool,
65) {
66 if !icons_from_cli {
67 *icons = IconsWhen::Never;
68 }
69 if !dirs_first_from_cli {
70 *dirs_first = false;
71 }
72}
73
74pub fn parse_sort_word(word: &str) -> Option<SortBy> {
76 match word.to_ascii_lowercase().as_str() {
77 "name" => Some(SortBy::Name),
78 "size" => Some(SortBy::Size),
79 "time" => Some(SortBy::Time),
80 "extension" | "ext" => Some(SortBy::Extension),
81 "version" | "v" => Some(SortBy::Version),
82 "none" => Some(SortBy::None),
83 _ => None,
84 }
85}
86
87pub fn parse_format_word(word: &str) -> Option<OutputMode> {
89 match word.to_ascii_lowercase().as_str() {
90 "across" | "horizontal" | "x" => Some(OutputMode::Across),
91 "commas" | "m" => Some(OutputMode::Commas),
92 "long" | "verbose" | "l" => Some(OutputMode::Long),
93 "single-column" | "single" | "1" => Some(OutputMode::OnePerLine),
94 "vertical" | "c" => Some(OutputMode::Columns),
95 _ => None,
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102
103 #[test]
104 fn apply_gnu_disables_dirs_first() {
105 let mut opts = ListOptions {
106 dirs_first: true,
107 ..Default::default()
108 };
109 apply_gnu_list_options(&mut opts, true);
110 assert!(!opts.dirs_first);
111 assert!(opts.gnu_mode);
112 }
113
114 #[test]
115 fn without_flag_leaves_options() {
116 let mut opts = ListOptions {
117 dirs_first: true,
118 ..Default::default()
119 };
120 apply_gnu_list_options(&mut opts, false);
121 assert!(opts.dirs_first);
122 assert!(!opts.gnu_mode);
123 }
124
125 #[test]
126 fn prefer_ls_clears_presentation_defaults() {
127 let mut icons = IconsWhen::Auto;
128 let mut dirs_first = true;
129 prefer_ls_defaults(&mut icons, &mut dirs_first, false, false);
130 assert_eq!(icons, IconsWhen::Never);
131 assert!(!dirs_first);
132 }
133
134 #[test]
135 fn prefer_ls_keeps_cli_overrides() {
136 let mut icons = IconsWhen::Always;
137 let mut dirs_first = true;
138 prefer_ls_defaults(&mut icons, &mut dirs_first, true, true);
139 assert_eq!(icons, IconsWhen::Always);
140 assert!(dirs_first);
141 }
142
143 #[test]
144 fn parse_sort_words() {
145 assert_eq!(parse_sort_word("size"), Some(SortBy::Size));
146 assert_eq!(parse_sort_word("none"), Some(SortBy::None));
147 assert_eq!(parse_sort_word("version"), Some(SortBy::Version));
148 assert_eq!(parse_sort_word("bogus"), None);
149 }
150
151 #[test]
152 fn parse_format_words() {
153 assert_eq!(parse_format_word("long"), Some(OutputMode::Long));
154 assert_eq!(parse_format_word("commas"), Some(OutputMode::Commas));
155 assert_eq!(parse_format_word("across"), Some(OutputMode::Across));
156 }
157}