sapi_lite/stt/grammar/rule/
mod.rs

1use std::borrow::Cow;
2use std::ops::{RangeInclusive, RangeToInclusive};
3
4use crate::stt::SemanticValue;
5
6mod arena;
7
8pub use arena::RuleArena;
9
10/// A rule that defines one or more phrases or fragments that can be recognized by the engine.
11#[derive(Debug)]
12pub enum Rule<'a> {
13    /// A sequence of words
14    Text(Cow<'a, str>),
15    /// A set of rules to choose from
16    Choice(Cow<'a, [&'a Rule<'a>]>),
17    /// A sequence of rules that must be recognized in order
18    Sequence(Cow<'a, [&'a Rule<'a>]>),
19    /// A rule repeated a certain number of times
20    Repeat(RepeatRange, &'a Rule<'a>),
21    /// A rule that will produce a node in the semantic tree when recognized
22    Semantic(SemanticValue<Cow<'a, str>>, &'a Rule<'a>),
23}
24
25impl<'a> Rule<'a> {
26    /// Creates a rule that defines a sequence of words to be recognized.
27    pub fn text<T: Into<Cow<'a, str>>>(text: T) -> Self {
28        Self::Text(text.into())
29    }
30
31    /// Creates a rule that defines a set of alternatives to choose from.
32    pub fn choice<L: Into<Cow<'a, [&'a Rule<'a>]>>>(options: L) -> Self {
33        Self::Choice(options.into())
34    }
35
36    /// Creates a rule the defines a sequence of sub-rules that must be recognized in order.
37    pub fn sequence<L: Into<Cow<'a, [&'a Rule<'a>]>>>(parts: L) -> Self {
38        Self::Sequence(parts.into())
39    }
40
41    /// Creates a rule that recognizes a sub-rule repeated a certain number of times.
42    pub fn repeat<R: Into<RepeatRange>>(times: R, target: &'a Rule<'a>) -> Self {
43        Self::Repeat(times.into(), target)
44    }
45
46    /// Creates a rule that produces a node in the resulting semantic tree when the given sub-rule
47    /// is recognized.
48    pub fn semantic<V: Into<SemanticValue<Cow<'a, str>>>>(value: V, target: &'a Rule<'a>) -> Self {
49        Self::Semantic(value.into(), target)
50    }
51}
52
53/// Specifies the bounds for how many times the target rule in a [`Rule::Repeat`] can be repeated.
54#[derive(Clone, Debug, PartialEq, Eq)]
55pub struct RepeatRange {
56    /// The target rule must be repeated at least this many times.
57    pub min: usize,
58    /// The target rule can be repeated at most this many times.
59    pub max: usize,
60}
61
62impl From<usize> for RepeatRange {
63    fn from(source: usize) -> Self {
64        Self {
65            min: source,
66            max: source,
67        }
68    }
69}
70
71impl From<RangeInclusive<usize>> for RepeatRange {
72    fn from(source: RangeInclusive<usize>) -> Self {
73        Self {
74            min: *source.start(),
75            max: *source.end(),
76        }
77    }
78}
79
80impl From<RangeToInclusive<usize>> for RepeatRange {
81    fn from(source: RangeToInclusive<usize>) -> Self {
82        Self {
83            min: 0,
84            max: source.end,
85        }
86    }
87}