harper_core/patterns/
implies_quantity.rs1use crate::{Token, TokenKind};
2
3use super::Pattern;
4
5pub struct ImpliesQuantity;
12
13impl ImpliesQuantity {
14 pub fn implies_plurality(tokens: &[Token], source: &[char]) -> Option<bool> {
15 let token = tokens.first()?;
16
17 match &token.kind {
18 TokenKind::Word(Some(word_metadata)) => {
19 if word_metadata.determiner {
20 return Some(false);
21 }
22
23 let source = token.span.get_content(source);
24
25 match source {
26 ['a'] => Some(false),
27 ['a', 'n'] => Some(false),
28 ['m', 'a', 'n', 'y'] => Some(true),
29 _ => None,
30 }
31 }
32 TokenKind::Number(number) => Some((number.value.abs() - 1.).abs() > f64::EPSILON),
33 _ => None,
34 }
35 }
36}
37
38impl Pattern for ImpliesQuantity {
39 fn matches(&self, tokens: &[Token], source: &[char]) -> usize {
40 if Self::implies_plurality(tokens, source).is_some() {
41 1
42 } else {
43 0
44 }
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use crate::{
51 Document, Span,
52 patterns::{DocPattern, ImpliesQuantity},
53 };
54
55 #[test]
56 fn number_implies() {
57 let doc = Document::new_plain_english_curated("There are 60 minutes in an hour.");
58
59 assert_eq!(
60 ImpliesQuantity.find_all_matches_in_doc(&doc),
61 vec![Span::new(4, 5), Span::new(10, 11)]
62 )
63 }
64}