1use super::naming::{FQName, Name};
6use serde::de::{self, IgnoredAny, SeqAccess, Visitor};
7use serde::ser::{SerializeTuple, Serializer};
8use serde::{Deserialize, Deserializer, Serialize};
9use std::borrow::Cow;
10use std::fmt;
11
12use super::literal::Literal;
13
14#[derive(Debug, Clone, PartialEq)]
19pub enum Pattern<A> {
20 Wildcard(A),
21 As(A, Box<Pattern<A>>, Name),
22 Tuple(A, Vec<Pattern<A>>),
23 Constructor(A, FQName, Vec<Pattern<A>>),
24 EmptyList(A),
25 HeadTail(A, Box<Pattern<A>>, Box<Pattern<A>>),
26 Literal(A, Literal),
27 Unit(A),
28}
29
30impl<A: Serialize> Serialize for Pattern<A> {
31 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
32 where
33 S: Serializer,
34 {
35 match self {
36 Pattern::Wildcard(a) => {
37 let mut tuple = serializer.serialize_tuple(2)?;
38 tuple.serialize_element("WildcardPattern")?;
39 tuple.serialize_element(a)?;
40 tuple.end()
41 }
42 Pattern::As(a, pattern, name) => {
43 let mut tuple = serializer.serialize_tuple(4)?;
44 tuple.serialize_element("AsPattern")?;
45 tuple.serialize_element(a)?;
46 tuple.serialize_element(pattern)?;
47 tuple.serialize_element(name)?;
48 tuple.end()
49 }
50 Pattern::Tuple(a, patterns) => {
51 let mut tuple = serializer.serialize_tuple(3)?;
52 tuple.serialize_element("TuplePattern")?;
53 tuple.serialize_element(a)?;
54 tuple.serialize_element(patterns)?;
55 tuple.end()
56 }
57 Pattern::Constructor(a, name, args) => {
58 let mut tuple = serializer.serialize_tuple(4)?;
59 tuple.serialize_element("ConstructorPattern")?;
60 tuple.serialize_element(a)?;
61 tuple.serialize_element(name)?;
62 tuple.serialize_element(args)?;
63 tuple.end()
64 }
65 Pattern::EmptyList(a) => {
66 let mut tuple = serializer.serialize_tuple(2)?;
67 tuple.serialize_element("EmptyListPattern")?;
68 tuple.serialize_element(a)?;
69 tuple.end()
70 }
71 Pattern::HeadTail(a, head, tail) => {
72 let mut tuple = serializer.serialize_tuple(4)?;
73 tuple.serialize_element("HeadTailPattern")?;
74 tuple.serialize_element(a)?;
75 tuple.serialize_element(head)?;
76 tuple.serialize_element(tail)?;
77 tuple.end()
78 }
79 Pattern::Literal(a, lit) => {
80 let mut tuple = serializer.serialize_tuple(3)?;
81 tuple.serialize_element("LiteralPattern")?;
82 tuple.serialize_element(a)?;
83 tuple.serialize_element(lit)?;
84 tuple.end()
85 }
86 Pattern::Unit(a) => {
87 let mut tuple = serializer.serialize_tuple(2)?;
88 tuple.serialize_element("UnitPattern")?;
89 tuple.serialize_element(a)?;
90 tuple.end()
91 }
92 }
93 }
94}
95
96impl<'de, A: Deserialize<'de>> Deserialize<'de> for Pattern<A> {
97 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
98 where
99 D: Deserializer<'de>,
100 {
101 struct PatternVisitor<A>(std::marker::PhantomData<A>);
102
103 impl<'de, A: Deserialize<'de>> Visitor<'de> for PatternVisitor<A> {
104 type Value = Pattern<A>;
105
106 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
107 formatter.write_str("a classic Pattern array")
108 }
109
110 fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
111 where
112 V: SeqAccess<'de>,
113 {
114 let tag: Cow<'de, str> = seq
115 .next_element()?
116 .ok_or_else(|| de::Error::invalid_length(0, &self))?;
117
118 match tag.as_ref() {
119 "WildcardPattern" | "wildcard" => {
120 let a = seq
121 .next_element()?
122 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
123
124 if seq.next_element::<IgnoredAny>()?.is_some() {
125 return Err(de::Error::custom("Expected end of WildcardPattern array"));
126 }
127
128 Ok(Pattern::Wildcard(a))
129 }
130 "AsPattern" | "as_pattern" => {
131 let a = seq
132 .next_element()?
133 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
134 let pattern = seq
135 .next_element()?
136 .ok_or_else(|| de::Error::invalid_length(2, &self))?;
137 let name = seq
138 .next_element()?
139 .ok_or_else(|| de::Error::invalid_length(3, &self))?;
140
141 if seq.next_element::<IgnoredAny>()?.is_some() {
142 return Err(de::Error::custom("Expected end of AsPattern array"));
143 }
144
145 Ok(Pattern::As(a, pattern, name))
146 }
147 "TuplePattern" | "tuple_pattern" => {
148 let a = seq
149 .next_element()?
150 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
151 let patterns = seq
152 .next_element()?
153 .ok_or_else(|| de::Error::invalid_length(2, &self))?;
154
155 if seq.next_element::<IgnoredAny>()?.is_some() {
156 return Err(de::Error::custom("Expected end of TuplePattern array"));
157 }
158
159 Ok(Pattern::Tuple(a, patterns))
160 }
161 "ConstructorPattern" | "constructor_pattern" => {
162 let a = seq
163 .next_element()?
164 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
165 let name = seq
166 .next_element()?
167 .ok_or_else(|| de::Error::invalid_length(2, &self))?;
168 let args = seq
169 .next_element()?
170 .ok_or_else(|| de::Error::invalid_length(3, &self))?;
171
172 if seq.next_element::<IgnoredAny>()?.is_some() {
173 return Err(de::Error::custom(
174 "Expected end of ConstructorPattern array",
175 ));
176 }
177
178 Ok(Pattern::Constructor(a, name, args))
179 }
180 "EmptyListPattern" | "empty_list_pattern" => {
181 let a = seq
182 .next_element()?
183 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
184
185 if seq.next_element::<IgnoredAny>()?.is_some() {
186 return Err(de::Error::custom(
187 "Expected end of EmptyListPattern array",
188 ));
189 }
190
191 Ok(Pattern::EmptyList(a))
192 }
193 "HeadTailPattern" | "head_tail_pattern" => {
194 let a = seq
195 .next_element()?
196 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
197 let head = seq
198 .next_element()?
199 .ok_or_else(|| de::Error::invalid_length(2, &self))?;
200 let tail = seq
201 .next_element()?
202 .ok_or_else(|| de::Error::invalid_length(3, &self))?;
203
204 if seq.next_element::<IgnoredAny>()?.is_some() {
205 return Err(de::Error::custom("Expected end of HeadTailPattern array"));
206 }
207
208 Ok(Pattern::HeadTail(a, head, tail))
209 }
210 "LiteralPattern" | "literal_pattern" => {
211 let a = seq
212 .next_element()?
213 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
214 let lit = seq
215 .next_element()?
216 .ok_or_else(|| de::Error::invalid_length(2, &self))?;
217
218 if seq.next_element::<IgnoredAny>()?.is_some() {
219 return Err(de::Error::custom("Expected end of LiteralPattern array"));
220 }
221
222 Ok(Pattern::Literal(a, lit))
223 }
224 "UnitPattern" | "unit_pattern" => {
225 let a = seq
226 .next_element()?
227 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
228
229 if seq.next_element::<IgnoredAny>()?.is_some() {
230 return Err(de::Error::custom("Expected end of UnitPattern array"));
231 }
232
233 Ok(Pattern::Unit(a))
234 }
235 _ => Err(de::Error::unknown_variant(
236 tag.as_ref(),
237 &[
238 "WildcardPattern",
239 "AsPattern",
240 "TuplePattern",
241 "ConstructorPattern",
242 "EmptyListPattern",
243 "HeadTailPattern",
244 "LiteralPattern",
245 "UnitPattern",
246 ],
247 )),
248 }
249 }
250 }
251 deserializer.deserialize_seq(PatternVisitor(std::marker::PhantomData))
252 }
253}
254#[cfg(test)]
255mod tests {
256 use super::*;
257 use crate::ir::classic::naming::Path;
258
259 #[test]
260 fn test_serialize_pattern_wildcard() {
261 let p: Pattern<()> = Pattern::Wildcard(());
262 let json = serde_json::to_string(&p).unwrap();
263 assert_eq!(json, r#"["WildcardPattern",null]"#);
264 let deserialized: Pattern<()> = serde_json::from_str(&json).unwrap();
265 assert_eq!(deserialized, p);
266 }
267
268 #[test]
269 fn a_variable_pattern_is_refused() {
270 assert!(serde_json::from_str::<Pattern<()>>(r#"["VariablePattern",null,["x"]]"#).is_err());
272 }
273
274 #[test]
275 fn test_serialize_pattern_as() {
276 let p: Pattern<()> = Pattern::As((), Box::new(Pattern::Wildcard(())), Name::from_str("x"));
277 let json = serde_json::to_string(&p).unwrap();
278 assert_eq!(json, r#"["AsPattern",null,["WildcardPattern",null],["x"]]"#);
279 let deserialized: Pattern<()> = serde_json::from_str(&json).unwrap();
280 assert_eq!(deserialized, p);
281 }
282
283 #[test]
284 fn test_serialize_pattern_tuple() {
285 let p: Pattern<()> = Pattern::Tuple((), vec![Pattern::Wildcard(()), Pattern::Wildcard(())]);
286 let json = serde_json::to_string(&p).unwrap();
287 assert_eq!(
288 json,
289 r#"["TuplePattern",null,[["WildcardPattern",null],["WildcardPattern",null]]]"#
290 );
291 let deserialized: Pattern<()> = serde_json::from_str(&json).unwrap();
292 assert_eq!(deserialized, p);
293 }
294
295 #[test]
296 fn test_serialize_pattern_constructor() {
297 let fq = FQName::new(
298 Path::new(vec![Name::from_str("pkg")]),
299 Path::new(vec![Name::from_str("mod")]),
300 Name::from_str("ctor"),
301 );
302 let p: Pattern<()> = Pattern::Constructor((), fq, vec![Pattern::Wildcard(())]);
303 let json = serde_json::to_string(&p).unwrap();
304 assert_eq!(
305 json,
306 r#"["ConstructorPattern",null,[[["pkg"]],[["mod"]],["ctor"]],[["WildcardPattern",null]]]"#
307 );
308 let deserialized: Pattern<()> = serde_json::from_str(&json).unwrap();
309 assert_eq!(deserialized, p);
310 }
311
312 #[test]
313 fn test_serialize_pattern_empty_list() {
314 let p: Pattern<()> = Pattern::EmptyList(());
315 let json = serde_json::to_string(&p).unwrap();
316 assert_eq!(json, r#"["EmptyListPattern",null]"#);
317 let deserialized: Pattern<()> = serde_json::from_str(&json).unwrap();
318 assert_eq!(deserialized, p);
319 }
320
321 #[test]
322 fn test_serialize_pattern_head_tail() {
323 let p: Pattern<()> = Pattern::HeadTail(
324 (),
325 Box::new(Pattern::Wildcard(())),
326 Box::new(Pattern::Wildcard(())),
327 );
328 let json = serde_json::to_string(&p).unwrap();
329 assert_eq!(
330 json,
331 r#"["HeadTailPattern",null,["WildcardPattern",null],["WildcardPattern",null]]"#
332 );
333 let deserialized: Pattern<()> = serde_json::from_str(&json).unwrap();
334 assert_eq!(deserialized, p);
335 }
336
337 #[test]
338 fn test_serialize_pattern_literal() {
339 let p: Pattern<()> = Pattern::Literal((), Literal::WholeNumber(123));
340 let json = serde_json::to_string(&p).unwrap();
341 assert_eq!(
342 json,
343 r#"["LiteralPattern",null,["WholeNumberLiteral",123]]"#
344 );
345 let deserialized: Pattern<()> = serde_json::from_str(&json).unwrap();
346 assert_eq!(deserialized, p);
347 }
348
349 #[test]
350 fn test_serialize_pattern_unit() {
351 let p: Pattern<()> = Pattern::Unit(());
352 let json = serde_json::to_string(&p).unwrap();
353 assert_eq!(json, r#"["UnitPattern",null]"#);
354 let deserialized: Pattern<()> = serde_json::from_str(&json).unwrap();
355 assert_eq!(deserialized, p);
356 }
357}