1use f00_core::{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 }
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(dirs_first: &mut bool, dirs_first_from_cli: bool) {
64 if !dirs_first_from_cli {
65 *dirs_first = false;
66 }
67}
68
69pub fn parse_sort_word(word: &str) -> Option<SortBy> {
71 match word.to_ascii_lowercase().as_str() {
72 "name" => Some(SortBy::Name),
73 "size" => Some(SortBy::Size),
74 "time" => Some(SortBy::Time),
75 "extension" | "ext" => Some(SortBy::Extension),
76 "version" | "v" => Some(SortBy::Version),
77 "width" => Some(SortBy::Width),
78 "none" => Some(SortBy::None),
79 _ => None,
80 }
81}
82
83pub fn parse_format_word(word: &str) -> Option<OutputMode> {
85 match word.to_ascii_lowercase().as_str() {
86 "across" | "horizontal" | "x" => Some(OutputMode::Across),
87 "commas" | "m" => Some(OutputMode::Commas),
88 "long" | "verbose" | "l" => Some(OutputMode::Long),
89 "single-column" | "single" | "1" => Some(OutputMode::OnePerLine),
90 "vertical" | "c" => Some(OutputMode::Columns),
91 _ => None,
92 }
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98
99 #[test]
100 fn apply_gnu_sets_mode_preserves_dirs_first_flag() {
101 let mut opts = ListOptions {
102 dirs_first: true,
103 ..Default::default()
104 };
105 apply_gnu_list_options(&mut opts, true);
106 assert!(opts.dirs_first);
108 assert!(opts.gnu_mode);
109 }
110
111 #[test]
112 fn without_flag_leaves_options() {
113 let mut opts = ListOptions {
114 dirs_first: true,
115 ..Default::default()
116 };
117 apply_gnu_list_options(&mut opts, false);
118 assert!(opts.dirs_first);
119 assert!(!opts.gnu_mode);
120 }
121
122 #[test]
123 fn prefer_ls_defaults_dirs_first_off() {
124 let mut dirs_first = true;
125 prefer_ls_defaults(&mut dirs_first, false);
126 assert!(!dirs_first);
127 }
128
129 #[test]
130 fn prefer_ls_keeps_explicit_dirs_first() {
131 let mut dirs_first = true;
132 prefer_ls_defaults(&mut dirs_first, true);
133 assert!(dirs_first);
134 }
135
136 #[test]
137 fn parse_sort_words() {
138 assert_eq!(parse_sort_word("size"), Some(SortBy::Size));
139 assert_eq!(parse_sort_word("none"), Some(SortBy::None));
140 assert_eq!(parse_sort_word("version"), Some(SortBy::Version));
141 assert_eq!(parse_sort_word("bogus"), None);
142 }
143
144 #[test]
145 fn parse_format_words() {
146 assert_eq!(parse_format_word("long"), Some(OutputMode::Long));
147 assert_eq!(parse_format_word("commas"), Some(OutputMode::Commas));
148 assert_eq!(parse_format_word("across"), Some(OutputMode::Across));
149 }
150}