fastobo_syntax/
lib.rs

1#[macro_use]
2extern crate pest_derive;
3pub extern crate pest;
4
5use pest::error::Error;
6use pest::error::ErrorVariant;
7use pest::iterators::Pairs;
8
9/// The OBO format version 1.4 lexer.
10#[derive(Debug, Parser)]
11#[grammar = "obo14.pest"]
12#[grammar = "bcp47.pest"]
13#[grammar = "iso8601.pest"]
14#[grammar = "rfc3987.pest"]
15pub struct OboLexer;
16
17impl OboLexer {
18    /// Tokenize an input string using the given production rule.
19    ///
20    /// This is basically a specialized version of [`pest::Parser::parse`]
21    /// that only accepts [`Rule`], and does not need the `Parser` trait to
22    /// be in scope.
23    ///
24    /// [`Rule`]: ./enum.Rule.html
25    /// [`pest::Parser::parse`]: https://docs.rs/pest/latest/pest/trait.Parser.html
26    pub fn tokenize(rule: Rule, input: &str) -> Result<Pairs<Rule>, Error<Rule>> {
27        <Self as pest::Parser<Rule>>::parse(rule, input)
28    }
29
30    /// Tokenize the entirety of an input string.
31    ///
32    /// Contrary to [`OboLexer::tokenize`], this method will return an error if
33    /// if the input is not parsed in its entirety.
34    pub fn tokenize_all(rule: Rule, input: &str) -> Result<Pairs<Rule>, Error<Rule>> {
35        match Self::tokenize(rule, input) {
36            Ok(pairs) if pairs.as_str().len() == input.len() => Ok(pairs),
37            Err(err) => Err(err),
38            Ok(_) => {
39                let variant = ErrorVariant::ParsingError {
40                    positives: vec![rule],
41                    negatives: vec![],
42                };
43                let span = pest::Span::new(input, 0, input.len()).unwrap();
44                Err(Error::new_from_span(variant, span))
45            }
46        }
47    }
48}