1use crate::*;
2
3pub trait ParseExpr {
4 fn parse_string(&self) -> syn::Result<String>;
5 fn parse_path(&self) -> syn::Result<&Path>;
6 fn parse_int<N>(&self) -> syn::Result<N>
7 where
8 N: FromStr,
9 N::Err: Display;
10 fn parse_closure(&self) -> syn::Result<&ExprClosure>;
11 fn parse_call_or_closure(self) -> syn::Result<CallOrClosure>;
12 fn parse_call(&self) -> syn::Result<&ExprCall>;
13}
14
15impl ParseExpr for Expr {
16 fn parse_call(&self) -> syn::Result<&ExprCall> {
17 if let Expr::Call(call) = self {
18 Ok(call)
19 } else {
20 Err(error!(self, "Expected a function call"))
21 }
22 }
23 fn parse_string(&self) -> syn::Result<String> {
24 if let Expr::Lit(expr_lit) = self && let Lit::Str(value) = &expr_lit.lit {
25 Ok(value.value())
26 } else {
27 Err(error!(self, "Expected a string literal"))
28 }
29 }
30
31 fn parse_path(&self) -> syn::Result<&Path> {
32 if let Expr::Path(expr_path) = self {
33 Ok(&expr_path.path)
34 } else {
35 Err(error!(self, "Expected a path"))
36 }
37 }
38
39 fn parse_int<N>(&self) -> syn::Result<N>
40 where
41 N: FromStr,
42 N::Err: Display,
43 {
44 if let Expr::Lit(expr_lit) = self && let Lit::Int(value) = &expr_lit.lit {
45 Ok(value.base10_parse::<N>()?)
46 } else {
47 Err(error!(self, "Expected an integer literal"))
48 }
49 }
50
51 fn parse_closure(&self) -> syn::Result<&ExprClosure> {
52 if let Expr::Closure(closure) = self {
53 Ok(closure)
54 } else {
55 Err(error!(self, "Expected a closure"))
56 }
57 }
58
59 fn parse_call_or_closure(self) -> syn::Result<CallOrClosure> {
60 match self {
61 Expr::Closure(closure) => Ok(CallOrClosure::Closure(closure)),
62 Expr::Call(call) => Ok(CallOrClosure::Call(call)),
63 _ => Err(error!(self, "Expected a path or a closure")),
64 }
65 }
66}