1#![warn(rust_2018_idioms)]
17#![warn(missing_docs)]
18#![allow(deprecated)]
19
20pub mod nom {
21 pub use nom::{error::ErrorKind, error::Error, Err, IResult, Needed};
23}
24pub mod expr;
25pub mod literal;
26pub mod token;
27
28#[derive(Debug)]
30pub enum ErrorKind {
31 ExactToken(token::Kind, &'static [u8]),
33 ExactTokens(token::Kind, &'static [&'static str]),
35 TypedToken(token::Kind),
37 UnknownIdentifier,
39 InvalidLiteral,
44 Partial,
46 Parser(nom::ErrorKind),
48}
49
50impl From<nom::ErrorKind> for ErrorKind {
51 fn from(k: nom::ErrorKind) -> Self {
52 ErrorKind::Parser(k)
53 }
54}
55
56impl From<u32> for ErrorKind {
57 fn from(_: u32) -> Self {
58 ErrorKind::InvalidLiteral
59 }
60}
61
62#[derive(Debug)]
67pub struct Error<I> {
68 pub input: I,
70 pub error: ErrorKind,
72}
73
74impl<I> From<(I, nom::ErrorKind)> for Error<I> {
75 fn from(e: (I, nom::ErrorKind)) -> Self {
76 Self::from((e.0, ErrorKind::from(e.1)))
77 }
78}
79
80impl<I> From<(I, ErrorKind)> for Error<I> {
81 fn from(e: (I, ErrorKind)) -> Self {
82 Self {
83 input: e.0,
84 error: e.1,
85 }
86 }
87}
88
89impl<I> From<::nom::error::Error<I>> for Error<I> {
90 fn from(e: ::nom::error::Error<I>) -> Self {
91 Self {
92 input: e.input,
93 error: e.code.into(),
94 }
95 }
96}
97
98impl<I> ::nom::error::ParseError<I> for Error<I> {
99 fn from_error_kind(input: I, kind: nom::ErrorKind) -> Self {
100 Self {
101 input,
102 error: kind.into(),
103 }
104 }
105
106 fn append(_: I, _: nom::ErrorKind, other: Self) -> Self {
107 other
108 }
109}
110
111trait ToCexprResult<I, O> {
113 fn to_cexpr_result(self) -> nom::IResult<I, O, Error<I>>;
114}
115impl<I, O, E> ToCexprResult<I, O> for nom::IResult<I, O, E>
116where
117 Error<I>: From<E>,
118{
119 fn to_cexpr_result(self) -> nom::IResult<I, O, Error<I>> {
120 match self {
121 Ok(v) => Ok(v),
122 Err(nom::Err::Incomplete(n)) => Err(nom::Err::Incomplete(n)),
123 Err(nom::Err::Error(e)) => Err(nom::Err::Error(e.into())),
124 Err(nom::Err::Failure(e)) => Err(nom::Err::Failure(e.into())),
125 }
126 }
127}
128
129pub fn assert_full_parse<'i, I: 'i, O, E>(
132 result: nom::IResult<&'i [I], O, E>,
133) -> nom::IResult<&'i [I], O, Error<&'i [I]>>
134where
135 Error<&'i [I]>: From<E>,
136{
137 match result.to_cexpr_result() {
138 Ok((rem, output)) => {
139 if rem.is_empty() {
140 Ok((rem, output))
141 } else {
142 Err(nom::Err::Error((rem, ErrorKind::Partial).into()))
143 }
144 }
145 Err(nom::Err::Incomplete(n)) => Err(nom::Err::Incomplete(n)),
146 Err(nom::Err::Failure(e)) => Err(nom::Err::Failure(e)),
147 Err(nom::Err::Error(e)) => Err(nom::Err::Error(e)),
148 }
149}