1#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub enum HedgeMode {
12 #[default]
15 Adverb,
16 Modal,
19 Prefix,
23}
24
25pub fn hedge(score: i64, mode: HedgeMode) -> &'static str {
28 let bucket = bucket_of(score);
29 match (mode, bucket) {
30 (HedgeMode::Adverb, Bucket::Certain) => "certainly",
31 (HedgeMode::Adverb, Bucket::Likely) => "likely",
32 (HedgeMode::Adverb, Bucket::Probable) => "probably",
33 (HedgeMode::Adverb, Bucket::Possible) => "possibly",
34 (HedgeMode::Adverb, Bucket::Unlikely) => "perhaps",
35
36 (HedgeMode::Modal, Bucket::Certain) => "must",
37 (HedgeMode::Modal, Bucket::Likely) => "should",
38 (HedgeMode::Modal, Bucket::Probable) => "may",
39 (HedgeMode::Modal, Bucket::Possible) => "might",
40 (HedgeMode::Modal, Bucket::Unlikely) => "could",
41
42 (HedgeMode::Prefix, Bucket::Certain) => "it is certain that",
43 (HedgeMode::Prefix, Bucket::Likely) => "it is likely that",
44 (HedgeMode::Prefix, Bucket::Probable) => "probably",
45 (HedgeMode::Prefix, Bucket::Possible) => "possibly",
46 (HedgeMode::Prefix, Bucket::Unlikely) => "perhaps",
47 }
48}
49
50pub fn parse_mode(spec: &str) -> Option<HedgeMode> {
52 match spec {
53 "adverb" => Some(HedgeMode::Adverb),
54 "modal" => Some(HedgeMode::Modal),
55 "prefix" => Some(HedgeMode::Prefix),
56 _ => None,
57 }
58}
59
60#[derive(Debug, Clone, Copy)]
61enum Bucket {
62 Certain,
63 Likely,
64 Probable,
65 Possible,
66 Unlikely,
67}
68
69fn bucket_of(score: i64) -> Bucket {
70 match score.clamp(0, 100) {
71 90..=100 => Bucket::Certain,
72 70..=89 => Bucket::Likely,
73 50..=69 => Bucket::Probable,
74 30..=49 => Bucket::Possible,
75 _ => Bucket::Unlikely,
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82
83 #[test]
84 fn adverb_buckets() {
85 assert_eq!(hedge(95, HedgeMode::Adverb), "certainly");
86 assert_eq!(hedge(80, HedgeMode::Adverb), "likely");
87 assert_eq!(hedge(60, HedgeMode::Adverb), "probably");
88 assert_eq!(hedge(40, HedgeMode::Adverb), "possibly");
89 assert_eq!(hedge(10, HedgeMode::Adverb), "perhaps");
90 }
91
92 #[test]
93 fn modal_buckets() {
94 assert_eq!(hedge(95, HedgeMode::Modal), "must");
95 assert_eq!(hedge(80, HedgeMode::Modal), "should");
96 assert_eq!(hedge(60, HedgeMode::Modal), "may");
97 assert_eq!(hedge(40, HedgeMode::Modal), "might");
98 assert_eq!(hedge(10, HedgeMode::Modal), "could");
99 }
100
101 #[test]
102 fn prefix_buckets() {
103 assert_eq!(hedge(95, HedgeMode::Prefix), "it is certain that");
104 assert_eq!(hedge(80, HedgeMode::Prefix), "it is likely that");
105 assert_eq!(hedge(60, HedgeMode::Prefix), "probably");
106 assert_eq!(hedge(40, HedgeMode::Prefix), "possibly");
107 assert_eq!(hedge(10, HedgeMode::Prefix), "perhaps");
108 }
109
110 #[test]
111 fn out_of_range_scores_clamp() {
112 assert_eq!(hedge(-50, HedgeMode::Adverb), "perhaps");
113 assert_eq!(hedge(200, HedgeMode::Adverb), "certainly");
114 }
115
116 #[test]
117 fn bucket_boundaries() {
118 assert_eq!(hedge(89, HedgeMode::Adverb), "likely");
119 assert_eq!(hedge(90, HedgeMode::Adverb), "certainly");
120 assert_eq!(hedge(69, HedgeMode::Adverb), "probably");
121 assert_eq!(hedge(70, HedgeMode::Adverb), "likely");
122 }
123}