1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use std::fmt;
/// One reason a search summary will not carry retrieval.
///
/// Each names what the writer has to change. They are reported together so a
/// summary is fixed in one pass, and they are written to be read by the
/// writer that produced the summary, which is usually a model.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SearchSummaryFault {
/// The function words lean to another language.
NotEnglish { read: String },
/// Fewer informative words than a rendering needs.
Thin { informative_terms: usize },
/// The same informative words as the text, in the same order.
RepeatsText,
/// Identifiers the text carries and the summary does not, folded and
/// sorted.
DropsIdentifiers(Vec<String>),
}
impl SearchSummaryFault {
/// All the faults of one summary in one sentence, for a warning.
pub fn describe(faults: &[Self]) -> String {
faults
.iter()
.map(ToString::to_string)
.collect::<Vec<_>>()
.join("; ")
}
}
impl fmt::Display for SearchSummaryFault {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NotEnglish { read } => {
write!(formatter, "leans to {read}, not to English")
}
Self::Thin { informative_terms } => write!(
formatter,
"carries {informative_terms} informative {}, at least {} are needed",
if *informative_terms == 1 {
"word"
} else {
"words"
},
super::SearchSummary::MINIMUM_INFORMATIVE_TERMS
),
Self::RepeatsText => write!(
formatter,
"repeats the text word for word, which adds nothing to search"
),
Self::DropsIdentifiers(identifiers) => write!(
formatter,
"drops identifiers the text carries: {}",
identifiers.join(", ")
),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
/// The wording is read by the writer that produced the summary, so it
/// names the change to make.
#[test]
fn every_fault_says_what_to_change() {
assert_eq!(
SearchSummaryFault::NotEnglish {
read: "spanish".to_string()
}
.to_string(),
"leans to spanish, not to English"
);
assert_eq!(
SearchSummaryFault::Thin {
informative_terms: 0
}
.to_string(),
"carries 0 informative words, at least 2 are needed"
);
assert_eq!(
SearchSummaryFault::RepeatsText.to_string(),
"repeats the text word for word, which adds nothing to search"
);
assert_eq!(
SearchSummaryFault::DropsIdentifiers(vec!["#469".to_string(), "v0.7.0".to_string()])
.to_string(),
"drops identifiers the text carries: #469, v0.7.0"
);
assert_eq!(SearchSummaryFault::describe(&[]), "");
}
}