cl_ast/ast_impl/
convert.rs1use super::*;
3
4impl<T: AsRef<str>> From<T> for PathPart {
5 fn from(value: T) -> Self {
6 match value.as_ref() {
7 "super" => PathPart::SuperKw,
8 ident => PathPart::Ident(ident.into()),
9 }
10 }
11}
12
13macro impl_from ($(impl From for $T:ty {$($from:ty => $to:expr),*$(,)?})*) {$($(
14 impl From<$from> for $T {
15 fn from(value: $from) -> Self {
16 $to(value.into()) }
18 }
19 impl From<Box<$from>> for $T {
20 fn from(value: Box<$from>) -> Self {
21 $to((*value).into())
22 }
23 }
24)*)*}
25
26impl_from! {
27 impl From for ItemKind {
28 Alias => ItemKind::Alias,
29 Const => ItemKind::Const,
30 Static => ItemKind::Static,
31 Module => ItemKind::Module,
32 Function => ItemKind::Function,
33 Struct => ItemKind::Struct,
34 Enum => ItemKind::Enum,
35 Impl => ItemKind::Impl,
36 Use => ItemKind::Use,
37 }
38 impl From for StructKind {
39 Vec<Ty> => StructKind::Tuple,
40 }
42 impl From for TyKind {
43 Path => TyKind::Path,
44 TyTuple => TyKind::Tuple,
45 TyRef => TyKind::Ref,
46 TyFn => TyKind::Fn,
47 }
48 impl From for StmtKind {
49 Item => StmtKind::Item,
50 Expr => StmtKind::Expr,
51 }
52 impl From for ExprKind {
53 Let => ExprKind::Let,
54 Closure => ExprKind::Closure,
55 Quote => ExprKind::Quote,
56 Match => ExprKind::Match,
57 Assign => ExprKind::Assign,
58 Modify => ExprKind::Modify,
59 Binary => ExprKind::Binary,
60 Unary => ExprKind::Unary,
61 Cast => ExprKind::Cast,
62 Member => ExprKind::Member,
63 Index => ExprKind::Index,
64 Path => ExprKind::Path,
65 Literal => ExprKind::Literal,
66 Array => ExprKind::Array,
67 ArrayRep => ExprKind::ArrayRep,
68 AddrOf => ExprKind::AddrOf,
69 Block => ExprKind::Block,
70 Group => ExprKind::Group,
71 Tuple => ExprKind::Tuple,
72 While => ExprKind::While,
73 If => ExprKind::If,
74 For => ExprKind::For,
75 Break => ExprKind::Break,
76 Return => ExprKind::Return,
77 }
78 impl From for Literal {
79 bool => Literal::Bool,
80 char => Literal::Char,
81 u128 => Literal::Int,
82 String => Literal::String,
83 }
84}
85
86impl From<Option<Expr>> for Else {
87 fn from(value: Option<Expr>) -> Self {
88 Self { body: value.map(Into::into) }
89 }
90}
91impl From<Expr> for Else {
92 fn from(value: Expr) -> Self {
93 Self { body: Some(value.into()) }
94 }
95}
96
97impl TryFrom<Expr> for Pattern {
98 type Error = Expr;
99
100 fn try_from(value: Expr) -> Result<Self, Self::Error> {
102 Ok(match value.kind {
103 ExprKind::Literal(literal) => Pattern::Literal(literal),
104 ExprKind::Path(Path { absolute: false, ref parts }) => match parts.as_slice() {
105 [PathPart::Ident(name)] => Pattern::Name(*name),
106 _ => Err(value)?,
107 },
108 ExprKind::Empty => Pattern::Tuple(vec![]),
109 ExprKind::Group(Group { expr }) => Pattern::Tuple(vec![Pattern::try_from(*expr)?]),
110 ExprKind::Tuple(Tuple { exprs }) => Pattern::Tuple(
111 exprs
112 .into_iter()
113 .map(Pattern::try_from)
114 .collect::<Result<_, _>>()?,
115 ),
116 ExprKind::AddrOf(AddrOf { mutable, expr }) => {
117 Pattern::Ref(mutable, Box::new(Pattern::try_from(*expr)?))
118 }
119 ExprKind::Array(Array { values }) => Pattern::Array(
120 values
121 .into_iter()
122 .map(Pattern::try_from)
123 .collect::<Result<_, _>>()?,
124 ),
125 ExprKind::Binary(Binary { kind: BinaryKind::Call, parts }) => {
126 let (Expr { kind: ExprKind::Path(path), .. }, args) = *parts else {
127 return Err(parts.0);
128 };
129 match args.kind {
130 ExprKind::Empty | ExprKind::Tuple(_) => {}
131 _ => return Err(args),
132 }
133 let Pattern::Tuple(args) = Pattern::try_from(args)? else {
134 unreachable!("Arguments should be convertible to pattern!")
135 };
136 Pattern::TupleStruct(path, args)
137 }
138 ExprKind::Binary(Binary { kind: BinaryKind::RangeExc, parts }) => {
139 let (head, tail) = (Pattern::try_from(parts.0)?, Pattern::try_from(parts.1)?);
140 Pattern::RangeExc(head.into(), tail.into())
141 }
142 ExprKind::Binary(Binary { kind: BinaryKind::RangeInc, parts }) => {
143 let (head, tail) = (Pattern::try_from(parts.0)?, Pattern::try_from(parts.1)?);
144 Pattern::RangeInc(head.into(), tail.into())
145 }
146 ExprKind::Unary(Unary { kind: UnaryKind::RangeExc, tail }) => {
147 Pattern::Rest(Some(Pattern::try_from(*tail)?.into()))
148 }
149 ExprKind::Structor(Structor { to, init }) => {
150 let fields = init
151 .into_iter()
152 .map(|Fielder { name, init }| {
153 Ok((name, init.map(|i| Pattern::try_from(*i)).transpose()?))
154 })
155 .collect::<Result<_, Self::Error>>()?;
156 Pattern::Struct(to, fields)
157 }
158 _ => Err(value)?,
159 })
160 }
161}