word_tally/options/
sort.rs1use core::{
4 cmp::Reverse,
5 fmt::{self, Display, Formatter},
6};
7
8use clap::ValueEnum;
9use rayon::slice::ParallelSliceMut;
10use serde::{Deserialize, Serialize};
11
12use crate::{Count, Io, Word};
13
14#[derive(
27 Clone,
28 Copy,
29 Debug,
30 Default,
31 PartialEq,
32 Eq,
33 PartialOrd,
34 Ord,
35 Hash,
36 Serialize,
37 Deserialize,
38 ValueEnum,
39)]
40#[serde(rename_all = "camelCase")]
41pub enum Sort {
42 #[default]
44 Desc,
45 Asc,
47 Unsorted,
49}
50
51impl Display for Sort {
52 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
53 match self {
54 Self::Desc => write!(f, "desc"),
55 Self::Asc => write!(f, "asc"),
56 Self::Unsorted => write!(f, "unsorted"),
57 }
58 }
59}
60
61impl Sort {
62 #[must_use]
64 pub const fn should_sort(&self) -> bool {
65 !matches!(self, Self::Unsorted)
66 }
67
68 #[must_use]
70 pub const fn is_descending(&self) -> bool {
71 matches!(self, Self::Desc)
72 }
73
74 pub fn apply(&self, tally: &mut [(Word, Count)], io: Io) {
76 match (self, io) {
77 (Self::Unsorted, _) => {}
79
80 (Self::Desc, Io::Stream) => {
82 tally.sort_unstable_by_key(|&(_, count)| Reverse(count));
83 }
84 (Self::Asc, Io::Stream) => {
85 tally.sort_unstable_by_key(|&(_, count)| count);
86 }
87
88 (
90 Self::Desc,
91 Io::Auto
92 | Io::ParallelStream
93 | Io::ParallelInMemory
94 | Io::ParallelMmap
95 | Io::ParallelBytes,
96 ) => {
97 tally.par_sort_unstable_by_key(|&(_, count)| Reverse(count));
98 }
99 (
100 Self::Asc,
101 Io::Auto
102 | Io::ParallelStream
103 | Io::ParallelInMemory
104 | Io::ParallelMmap
105 | Io::ParallelBytes,
106 ) => {
107 tally.par_sort_unstable_by_key(|&(_, count)| count);
108 }
109 }
110 }
111}