diary_cli/
sort.rs

1use soulog::*;
2use lazy_db::*;
3use crate::{list, archive::Archive};
4
5pub fn younger(this: &[u16; 3], other: &[u16; 3]) -> bool {
6    let this_date = this[2] as u32 * 10000 + this[1] as u32 * 100 + this[0] as u32;
7    let other_date = other[2] as u32 * 10000 + other[1] as u32 * 100 + other[0] as u32;
8    this_date > other_date
9}
10
11pub fn sort(mut logger: impl Logger) {
12    // load archive
13    let archive = Archive::load(logger.hollow());
14
15    let unsorted = list::read(
16        |x| x.collect_string(),
17        &if_err!((logger) [Sort, err => ("While reading unsorted stack length: {err:?}")] retry search_database!((archive.database()) /order/unsorted)),
18        logger.hollow(),
19    );
20
21    if unsorted.len() == 0 {
22        log!((logger.verbose) Sort("No unsorted items on unsorted stack; doing nothing") as Inconvenience);
23        return;
24    }
25
26    let mut sorted = list::read(
27        |x| x.collect_string(),
28        &if_err!((logger) [Sort, err => ("While reading sorted list length: {err:?}")] retry search_database!((archive.database()) /order/sorted)),
29        logger.hollow(),
30    ).into_vec();
31
32    log!((logger) Sort("Sorting unsorted entries..."));
33    // main sorting code
34    for usort_uid in unsorted.into_vec() {
35        let usort_date = *archive.get_entry(usort_uid.clone(), logger.hollow()).unwrap().date(logger.hollow());
36        
37        sorted.retain(|item| item != &usort_uid); // remove duplicates
38
39        let mut is_oldest = true;
40        for i in (0..sorted.len()).rev() {
41            let sort_date = *archive.get_entry(sorted[i].clone(), logger.hollow()).unwrap().date(logger.hollow());
42
43            if younger(&usort_date, &sort_date) {
44                sorted.insert(i + 1, usort_uid.clone()); // replace the one before
45                is_oldest = false;
46                break;
47            }
48        } if is_oldest {
49            sorted.insert(0, usort_uid);
50        }
51    }
52
53    // Store updates
54    log!((logger) Sort("Sorted list length: {}", sorted.len()));
55    list::write( // store newly sorted list
56        sorted.as_ref(),
57        |file, x| LazyData::new_string(file, x),
58        &if_err!((logger) [Sort, err => ("While initing sorted list: {err:?}")] retry search_database!((archive.database()) /order/sorted)),
59        logger.hollow(),
60    );
61
62    list::write(
63        &[],
64        |file, x: &String| LazyData::new_string(file, x),
65        &if_err!((logger) [Sort, err => ("While initing unsorted list: {err:?}")] retry search_database!((archive.database()) /order/unsorted)),
66        logger.hollow()
67    );
68
69    log!((logger.vital) Sort("Successfully sorted entries") as Log);
70}
71
72pub fn sort_uids(uids: &[String], logger: impl Logger) -> Box<[String]> {
73    // load archive & sort if sorting is needed
74    let archive = Archive::load(logger.hollow());
75    sort(logger.hollow());
76
77    let sorted = read_sorted(&archive, logger.hollow()).into_vec();
78    
79    // remove unspecified
80    sorted.into_iter().filter(|x| uids.contains(x)).collect()
81}
82
83pub fn read_sorted(archive: &Archive, mut logger: impl Logger) -> Box<[String]> {
84    list::read(
85        |x| x.collect_string(),
86        &if_err!((logger) [Sort, err => ("While reading sorted list: {err:?}")] retry search_database!((archive.database()) /order/sorted)),
87        logger.hollow(),
88    )
89}