syn_utils/
expr.rs

1use crate::*;
2
3pub trait ExprExt {
4  fn as_string(&self) -> syn::Result<String>;
5  fn as_path(&self) -> syn::Result<&Path>;
6  fn as_int<N>(&self) -> syn::Result<N>
7  where
8    N: FromStr,
9    N::Err: Display;
10  fn as_closure(&self) -> syn::Result<&ExprClosure>;
11  fn as_call_or_closure(&self) -> syn::Result<CallOrClosure>;
12  fn as_call(&self) -> syn::Result<&ExprCall>;
13  fn as_path_or_closure(&self) -> syn::Result<PathOrClosure>;
14  fn as_range(&self) -> syn::Result<&ExprRange>;
15}
16
17impl ExprExt for Expr {
18  fn as_range(&self) -> syn::Result<&ExprRange> {
19    if let Expr::Range(range) = &self {
20      Ok(range)
21    } else {
22      Err(error!(self, "Expected a range expression"))
23    }
24  }
25
26  fn as_path_or_closure(&self) -> syn::Result<PathOrClosure> {
27    match self {
28      Expr::Closure(closure) => Ok(PathOrClosure::Closure(closure.to_token_stream())),
29      Expr::Path(expr_path) => Ok(PathOrClosure::Path(expr_path.path.to_token_stream())),
30      _ => Err(error!(self, "Expected a path or a closure")),
31    }
32  }
33
34  fn as_call(&self) -> syn::Result<&ExprCall> {
35    if let Expr::Call(call) = self {
36      Ok(call)
37    } else {
38      Err(error!(self, "Expected a function call"))
39    }
40  }
41  fn as_string(&self) -> syn::Result<String> {
42    if let Expr::Lit(expr_lit) = self && let Lit::Str(value) = &expr_lit.lit {
43      Ok(value.value())
44    } else {
45      Err(error!(self, "Expected a string literal"))
46    }
47  }
48
49  fn as_path(&self) -> syn::Result<&Path> {
50    if let Expr::Path(expr_path) = self {
51      Ok(&expr_path.path)
52    } else {
53      Err(error!(self, "Expected a path"))
54    }
55  }
56
57  fn as_int<N>(&self) -> syn::Result<N>
58  where
59    N: FromStr,
60    N::Err: Display,
61  {
62    if let Expr::Lit(expr_lit) = self && let Lit::Int(value) = &expr_lit.lit {
63      Ok(value.base10_parse::<N>()?)
64    } else {
65      Err(error!(self, "Expected an integer literal"))
66    }
67  }
68
69  fn as_closure(&self) -> syn::Result<&ExprClosure> {
70    if let Expr::Closure(closure) = self {
71      Ok(closure)
72    } else {
73      Err(error!(self, "Expected a closure"))
74    }
75  }
76
77  fn as_call_or_closure(&self) -> syn::Result<CallOrClosure> {
78    match self {
79      Expr::Closure(closure) => Ok(CallOrClosure::Closure(closure.to_token_stream())),
80      Expr::Call(call) => Ok(CallOrClosure::Call(call.to_token_stream())),
81      _ => Err(error!(self, "Expected a function call or a closure")),
82    }
83  }
84}