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 TyPtr => TyKind::Ptr,
47 TyFn => TyKind::Fn,
48 }
49 impl From for StmtKind {
50 Item => StmtKind::Item,
51 Expr => StmtKind::Expr,
52 }
53 impl From for ExprKind {
54 Let => ExprKind::Let,
55 Closure => ExprKind::Closure,
56 Quote => ExprKind::Quote,
57 Match => ExprKind::Match,
58 Assign => ExprKind::Assign,
59 Modify => ExprKind::Modify,
60 Binary => ExprKind::Binary,
61 Unary => ExprKind::Unary,
62 Cast => ExprKind::Cast,
63 Member => ExprKind::Member,
64 Index => ExprKind::Index,
65 Path => ExprKind::Path,
66 Literal => ExprKind::Literal,
67 Array => ExprKind::Array,
68 ArrayRep => ExprKind::ArrayRep,
69 AddrOf => ExprKind::AddrOf,
70 Block => ExprKind::Block,
71 Group => ExprKind::Group,
72 Tuple => ExprKind::Tuple,
73 While => ExprKind::While,
74 If => ExprKind::If,
75 For => ExprKind::For,
76 Break => ExprKind::Break,
77 Return => ExprKind::Return,
78 }
79 impl From for Literal {
80 bool => Literal::Bool,
81 char => Literal::Char,
82 u128 => Literal::Int,
83 String => Literal::String,
84 }
85}
86
87impl From<Option<Expr>> for Else {
88 fn from(value: Option<Expr>) -> Self {
89 Self { body: value.map(Into::into) }
90 }
91}
92impl From<Expr> for Else {
93 fn from(value: Expr) -> Self {
94 Self { body: Some(value.into()) }
95 }
96}
97
98impl TryFrom<Expr> for Pattern {
99 type Error = Expr;
100
101 fn try_from(value: Expr) -> Result<Self, Self::Error> {
103 Ok(match value.kind {
104 ExprKind::Literal(literal) => Pattern::Literal(literal),
105 ExprKind::Path(Path { absolute: false, ref parts }) => match parts.as_slice() {
106 [PathPart::Ident(name)] => Pattern::Name(*name),
107 _ => Err(value)?,
108 },
109 ExprKind::Empty => Pattern::Tuple(vec![]),
110 ExprKind::Group(Group { expr }) => Pattern::Tuple(vec![Pattern::try_from(*expr)?]),
111 ExprKind::Tuple(Tuple { exprs }) => Pattern::Tuple(
112 exprs
113 .into_iter()
114 .map(Pattern::try_from)
115 .collect::<Result<_, _>>()?,
116 ),
117 ExprKind::AddrOf(AddrOf { mutable, expr }) => {
118 Pattern::Ref(mutable, Box::new(Pattern::try_from(*expr)?))
119 }
120 ExprKind::Array(Array { values }) => Pattern::Array(
121 values
122 .into_iter()
123 .map(Pattern::try_from)
124 .collect::<Result<_, _>>()?,
125 ),
126 ExprKind::Binary(Binary { kind: BinaryKind::Call, parts }) => {
127 let (Expr { kind: ExprKind::Path(path), .. }, args) = *parts else {
128 return Err(parts.0);
129 };
130 match args.kind {
131 ExprKind::Empty | ExprKind::Tuple(_) => {}
132 _ => return Err(args),
133 }
134 let Pattern::Tuple(args) = Pattern::try_from(args)? else {
135 unreachable!("Arguments should be convertible to pattern!")
136 };
137 Pattern::TupleStruct(path, args)
138 }
139 ExprKind::Binary(Binary { kind: BinaryKind::RangeExc, parts }) => {
140 let (head, tail) = (Pattern::try_from(parts.0)?, Pattern::try_from(parts.1)?);
141 Pattern::RangeExc(head.into(), tail.into())
142 }
143 ExprKind::Binary(Binary { kind: BinaryKind::RangeInc, parts }) => {
144 let (head, tail) = (Pattern::try_from(parts.0)?, Pattern::try_from(parts.1)?);
145 Pattern::RangeInc(head.into(), tail.into())
146 }
147 ExprKind::Unary(Unary { kind: UnaryKind::RangeExc, tail }) => {
148 Pattern::Rest(Some(Pattern::try_from(*tail)?.into()))
149 }
150 ExprKind::Structor(Structor { to, init }) => {
151 let fields = init
152 .into_iter()
153 .map(|Fielder { name, init }| {
154 Ok((name, init.map(|i| Pattern::try_from(*i)).transpose()?))
155 })
156 .collect::<Result<_, Self::Error>>()?;
157 Pattern::Struct(to, fields)
158 }
159 _ => Err(value)?,
160 })
161 }
162}