credence_lib/render/catalog/
annotation.rs1use super::{super::super::util::*, columns::*};
2
3use {
4 compris::{annotate::*, normal::*},
5 std::cmp::*,
6};
7
8pub struct CatalogAnnotation<'own> {
14 pub sort_column: Option<RefTraversal<'own, WithAnnotations>>,
16
17 pub sort_ascending: bool,
19
20 pub extra_columns: ExtraColumns<'own>,
22}
23
24impl<'own> CatalogAnnotation<'own> {
25 pub fn new(
27 sort_column: Option<RefTraversal<'own, WithAnnotations>>,
28 sort_ascending: bool,
29 extra_columns: ExtraColumns<'own>,
30 ) -> Self {
31 Self { sort_column, sort_ascending, extra_columns }
32 }
33
34 pub fn resolve(variant: &'own Variant<WithAnnotations>) -> Self {
36 let extra_columns = flatten_columns(
37 traverse!(variant, "columns").and_then(
38 |columns| {
39 if let Variant::Map(map) = columns { Some(map) } else { None }
40 },
41 ),
42 );
43
44 let (sort_column, sort_ascending) = traverse!(variant, "sort")
45 .and_then(|sort| match sort {
46 Variant::Map(map) => Some((
47 map.inner.get(&"column".into()).and_then(to_ref_traversal),
48 map.inner
49 .get(&"ascending".into())
50 .map(|ascending| match ascending {
51 Variant::Boolean(ascending) => ascending.inner,
52 _ => true,
53 })
54 .unwrap_or(true),
55 )),
56
57 Variant::List(_) | Variant::Text(_) => Some((to_ref_traversal(sort), true)),
58
59 _ => None,
60 })
61 .unwrap_or((None, true));
62
63 Self::new(sort_column, sort_ascending, extra_columns)
64 }
65
66 pub fn sort(self, rows: &mut Vec<Variant<WithAnnotations>>) {
68 let ascending = self.sort_ascending;
69 let sort_column = self.into_sort_column();
70 rows.sort_by(|row1, row2| cmp_rows_by_column(row1, row2, &sort_column, ascending));
71 }
72
73 fn into_sort_column(self) -> Traversal<WithAnnotations> {
75 self.sort_column.map(to_traversal).unwrap_or_else(|| vec!["title".into()])
76 }
77}
78
79fn cmp_rows_by_column<AnnotatedT>(
80 row1: &Variant<AnnotatedT>,
81 row2: &Variant<AnnotatedT>,
82 column_path: &Traversal<AnnotatedT>,
83 ascending: bool,
84) -> Ordering {
85 if let Some(a) = row1.traverse(column_path.iter())
86 && let Some(b) = row2.traverse(column_path.iter())
87 {
88 let ordering = cmp_variant_lowercase(a, b);
89 if ascending { ordering } else { ordering.reverse() }
90 } else {
91 Ordering::Less
92 }
93}