aboutsummaryrefslogtreecommitdiff
path: root/crates/mbe/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/mbe/src/lib.rs')
-rw-r--r--crates/mbe/src/lib.rs50
1 files changed, 39 insertions, 11 deletions
diff --git a/crates/mbe/src/lib.rs b/crates/mbe/src/lib.rs
index f854ca09a..3ad609a00 100644
--- a/crates/mbe/src/lib.rs
+++ b/crates/mbe/src/lib.rs
@@ -12,6 +12,8 @@ mod subtree_source;
12#[cfg(test)] 12#[cfg(test)]
13mod tests; 13mod tests;
14 14
15use std::fmt;
16
15pub use tt::{Delimiter, Punct}; 17pub use tt::{Delimiter, Punct};
16 18
17use crate::{ 19use crate::{
@@ -33,6 +35,8 @@ pub enum ExpandError {
33 ConversionError, 35 ConversionError,
34 InvalidRepeat, 36 InvalidRepeat,
35 ProcMacroError(tt::ExpansionError), 37 ProcMacroError(tt::ExpansionError),
38 UnresolvedProcMacro,
39 Other(String),
36} 40}
37 41
38impl From<tt::ExpansionError> for ExpandError { 42impl From<tt::ExpansionError> for ExpandError {
@@ -41,6 +45,21 @@ impl From<tt::ExpansionError> for ExpandError {
41 } 45 }
42} 46}
43 47
48impl fmt::Display for ExpandError {
49 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50 match self {
51 ExpandError::NoMatchingRule => f.write_str("no rule matches input tokens"),
52 ExpandError::UnexpectedToken => f.write_str("unexpected token in input"),
53 ExpandError::BindingError(e) => f.write_str(e),
54 ExpandError::ConversionError => f.write_str("could not convert tokens"),
55 ExpandError::InvalidRepeat => f.write_str("invalid repeat expression"),
56 ExpandError::ProcMacroError(e) => e.fmt(f),
57 ExpandError::UnresolvedProcMacro => f.write_str("unresolved proc macro"),
58 ExpandError::Other(e) => f.write_str(e),
59 }
60 }
61}
62
44pub use crate::syntax_bridge::{ 63pub use crate::syntax_bridge::{
45 ast_to_token_tree, parse_to_token_tree, syntax_node_to_token_tree, token_tree_to_syntax_node, 64 ast_to_token_tree, parse_to_token_tree, syntax_node_to_token_tree, token_tree_to_syntax_node,
46 TokenMap, 65 TokenMap,
@@ -246,33 +265,42 @@ fn validate(pattern: &tt::Subtree) -> Result<(), ParseError> {
246 Ok(()) 265 Ok(())
247} 266}
248 267
249#[derive(Debug)] 268#[derive(Debug, Clone, Eq, PartialEq)]
250pub struct ExpandResult<T>(pub T, pub Option<ExpandError>); 269pub struct ExpandResult<T> {
270 pub value: T,
271 pub err: Option<ExpandError>,
272}
251 273
252impl<T> ExpandResult<T> { 274impl<T> ExpandResult<T> {
253 pub fn ok(t: T) -> ExpandResult<T> { 275 pub fn ok(value: T) -> Self {
254 ExpandResult(t, None) 276 Self { value, err: None }
277 }
278
279 pub fn only_err(err: ExpandError) -> Self
280 where
281 T: Default,
282 {
283 Self { value: Default::default(), err: Some(err) }
255 } 284 }
256 285
257 pub fn only_err(err: ExpandError) -> ExpandResult<T> 286 pub fn str_err(err: String) -> Self
258 where 287 where
259 T: Default, 288 T: Default,
260 { 289 {
261 ExpandResult(Default::default(), Some(err)) 290 Self::only_err(ExpandError::Other(err))
262 } 291 }
263 292
264 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> ExpandResult<U> { 293 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> ExpandResult<U> {
265 ExpandResult(f(self.0), self.1) 294 ExpandResult { value: f(self.value), err: self.err }
266 } 295 }
267 296
268 pub fn result(self) -> Result<T, ExpandError> { 297 pub fn result(self) -> Result<T, ExpandError> {
269 self.1.map(Err).unwrap_or(Ok(self.0)) 298 self.err.map(Err).unwrap_or(Ok(self.value))
270 } 299 }
271} 300}
272 301
273impl<T: Default> From<Result<T, ExpandError>> for ExpandResult<T> { 302impl<T: Default> From<Result<T, ExpandError>> for ExpandResult<T> {
274 fn from(result: Result<T, ExpandError>) -> ExpandResult<T> { 303 fn from(result: Result<T, ExpandError>) -> Self {
275 result 304 result.map_or_else(|e| Self::only_err(e), |it| Self::ok(it))
276 .map_or_else(|e| ExpandResult(Default::default(), Some(e)), |it| ExpandResult(it, None))
277 } 305 }
278} 306}