Skip to main content

plot/lib/logic/
path_sort.rs

1use std::cmp::Ordering;
2
3use crate::lib::{
4	job::{ModeFileGroupForValidSortBy, StrategyForValidSortBy, ValidResultMainRow, ValidSortByConfig},
5	logic::NodeIs,
6};
7
8// ============================================================================
9// SORT QUERIES (Silnik Sortowania)
10// ============================================================================
11
12#[derive(Debug, Clone)]
13pub struct SortQueries {
14	pub raw_config: ValidSortByConfig,
15}
16
17impl SortQueries {
18	pub fn new(config: ValidSortByConfig) -> Self { Self { raw_config: config } }
19
20	/// Główny komparator. Zwraca Ordering (Mniej, Więcej, Równe).
21	pub fn compare(&self, a: &ValidResultMainRow, b: &ValidResultMainRow) -> Ordering {
22		let a_is_dir = a.node.node == NodeIs::Dir;
23		let b_is_dir = b.node.node == NodeIs::Dir;
24		let a_name = &a.node.name;
25		let b_name = &b.node.name;
26
27		// 1. Wykonanie priorytetu sortowania z konfiguracji
28		let mut cmp = match &self.raw_config.strategy {
29			StrategyForValidSortBy::Date { .. } => a.dt_modified.cmp(&b.dt_modified),
30			StrategyForValidSortBy::Size { .. } => a.size_real.cmp(&b.size_real),
31
32			StrategyForValidSortBy::Name { file_group, .. } | StrategyForValidSortBy::Path { file_group, .. } => {
33				match file_group {
34					ModeFileGroupForValidSortBy::Name => {
35						// Sortowanie "Merge": Folder "mod" i plik "mod.rs" lądują obok siebie
36						let a_core = Self::get_core_name(a_name);
37						let b_core = Self::get_core_name(b_name);
38						let core_cmp = a_core.cmp(b_core);
39
40						if core_cmp == Ordering::Equal {
41							// Domyślnie foldery idą nad plikami o tej samej nazwie bazowej
42							b_is_dir.cmp(&a_is_dir).then(a_name.cmp(b_name))
43						} else {
44							core_cmp
45						}
46					}
47					ModeFileGroupForValidSortBy::Exte => {
48						// Grupowanie po rozszerzeniu
49						let a_ext = Self::get_extension(a_name);
50						let b_ext = Self::get_extension(b_name);
51						a_ext.cmp(b_ext).then(a_name.cmp(b_name))
52					}
53					ModeFileGroupForValidSortBy::None => {
54						// Klasyczne sortowanie (Foldery nad plikami)
55						b_is_dir.cmp(&a_is_dir).then(a_name.cmp(b_name))
56					}
57				}
58			}
59		};
60
61		// 2. Obsługa flagi Reverse
62		let reverse = match &self.raw_config.strategy {
63			StrategyForValidSortBy::Date { reverse } => *reverse,
64			StrategyForValidSortBy::Size { reverse } => *reverse,
65			StrategyForValidSortBy::Name { reverse, .. } => *reverse,
66			StrategyForValidSortBy::Path { reverse, .. } => *reverse,
67		};
68
69		if reverse {
70			cmp = cmp.reverse();
71		}
72
73		cmp
74	}
75
76	// Helper: Wydobywa nazwę bez rozszerzenia (np. "main.rs" -> "main")
77	fn get_core_name(name: &str) -> &str {
78		if let Some(idx) = name.rfind('.') {
79			if idx > 0 {
80				return &name[..idx];
81			}
82		}
83		name
84	}
85
86	// Helper: Wydobywa samo rozszerzenie (np. "main.rs" -> "rs")
87	fn get_extension(name: &str) -> &str {
88		if let Some(idx) = name.rfind('.') {
89			if idx > 0 {
90				return &name[idx + 1..];
91			}
92		}
93		""
94	}
95}