Skip to main content

morphir_core/ir/classic/
value.rs

1//! Classic IR Value types
2//!
3//! Value expressions for the Classic Morphir IR format (V1-V3 compatible).
4
5use 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;
13use super::pattern::Pattern;
14use super::types::Type;
15
16// ----------------------------------------------------------------------------
17// Value Enum
18// ----------------------------------------------------------------------------
19
20/// Value with generic type and value attributes
21#[derive(Debug, Clone, PartialEq)]
22pub enum Value<TA, VA> {
23    Apply(VA, Box<Value<TA, VA>>, Box<Value<TA, VA>>),
24    Constructor(VA, FQName),
25    Destructure(VA, Pattern<VA>, Box<Value<TA, VA>>, Box<Value<TA, VA>>),
26    Field(VA, Box<Value<TA, VA>>, Name),
27    FieldFunction(VA, Name),
28    IfThenElse(
29        VA,
30        Box<Value<TA, VA>>,
31        Box<Value<TA, VA>>,
32        Box<Value<TA, VA>>,
33    ),
34    Lambda(VA, Pattern<VA>, Box<Value<TA, VA>>),
35    LetDefinition(VA, Name, Box<ValueDefinition<TA, VA>>, Box<Value<TA, VA>>),
36    LetRecursion(
37        VA,
38        Vec<(Name, Box<ValueDefinition<TA, VA>>)>,
39        Box<Value<TA, VA>>,
40    ),
41    List(VA, Vec<Value<TA, VA>>),
42    Literal(VA, Literal),
43    PatternMatch(VA, Box<Value<TA, VA>>, Vec<(Pattern<VA>, Value<TA, VA>)>),
44    Record(VA, Vec<(Name, Value<TA, VA>)>),
45    Tuple(VA, Vec<Value<TA, VA>>),
46    Unit(VA),
47    Update(VA, Box<Value<TA, VA>>, Vec<(Name, Value<TA, VA>)>),
48    Variable(VA, Name),
49    Reference(VA, FQName),
50}
51
52impl<TA: Serialize, VA: Serialize> Serialize for Value<TA, VA> {
53    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
54    where
55        S: Serializer,
56    {
57        match self {
58            Value::Apply(va, func, arg) => {
59                let mut tuple = serializer.serialize_tuple(4)?;
60                tuple.serialize_element("Apply")?;
61                tuple.serialize_element(va)?;
62                tuple.serialize_element(func)?;
63                tuple.serialize_element(arg)?;
64                tuple.end()
65            }
66            Value::Constructor(va, name) => {
67                let mut tuple = serializer.serialize_tuple(3)?;
68                tuple.serialize_element("Constructor")?;
69                tuple.serialize_element(va)?;
70                tuple.serialize_element(name)?;
71                tuple.end()
72            }
73            Value::Destructure(va, pattern, value, in_expr) => {
74                let mut tuple = serializer.serialize_tuple(5)?;
75                tuple.serialize_element("Destructure")?;
76                tuple.serialize_element(va)?;
77                tuple.serialize_element(pattern)?;
78                tuple.serialize_element(value)?;
79                tuple.serialize_element(in_expr)?;
80                tuple.end()
81            }
82            Value::Field(va, record, name) => {
83                let mut tuple = serializer.serialize_tuple(4)?;
84                tuple.serialize_element("Field")?;
85                tuple.serialize_element(va)?;
86                tuple.serialize_element(record)?;
87                tuple.serialize_element(name)?;
88                tuple.end()
89            }
90            Value::FieldFunction(va, name) => {
91                let mut tuple = serializer.serialize_tuple(3)?;
92                tuple.serialize_element("FieldFunction")?;
93                tuple.serialize_element(va)?;
94                tuple.serialize_element(name)?;
95                tuple.end()
96            }
97            Value::IfThenElse(va, cond, then_branch, else_branch) => {
98                let mut tuple = serializer.serialize_tuple(5)?;
99                tuple.serialize_element("IfThenElse")?;
100                tuple.serialize_element(va)?;
101                tuple.serialize_element(cond)?;
102                tuple.serialize_element(then_branch)?;
103                tuple.serialize_element(else_branch)?;
104                tuple.end()
105            }
106            Value::Lambda(va, pattern, body) => {
107                let mut tuple = serializer.serialize_tuple(4)?;
108                tuple.serialize_element("Lambda")?;
109                tuple.serialize_element(va)?;
110                tuple.serialize_element(pattern)?;
111                tuple.serialize_element(body)?;
112                tuple.end()
113            }
114            Value::LetDefinition(va, name, def, in_expr) => {
115                let mut tuple = serializer.serialize_tuple(5)?;
116                tuple.serialize_element("LetDefinition")?;
117                tuple.serialize_element(va)?;
118                tuple.serialize_element(name)?;
119                tuple.serialize_element(def)?;
120                tuple.serialize_element(in_expr)?;
121                tuple.end()
122            }
123            Value::LetRecursion(va, defs, in_expr) => {
124                let mut tuple = serializer.serialize_tuple(4)?;
125                tuple.serialize_element("LetRecursion")?;
126                tuple.serialize_element(va)?;
127                tuple.serialize_element(defs)?;
128                tuple.serialize_element(in_expr)?;
129                tuple.end()
130            }
131            Value::List(va, elements) => {
132                let mut tuple = serializer.serialize_tuple(3)?;
133                tuple.serialize_element("List")?;
134                tuple.serialize_element(va)?;
135                tuple.serialize_element(elements)?;
136                tuple.end()
137            }
138            Value::Literal(va, lit) => {
139                let mut tuple = serializer.serialize_tuple(3)?;
140                tuple.serialize_element("Literal")?;
141                tuple.serialize_element(va)?;
142                tuple.serialize_element(lit)?;
143                tuple.end()
144            }
145            Value::PatternMatch(va, expr, cases) => {
146                let mut tuple = serializer.serialize_tuple(4)?;
147                tuple.serialize_element("PatternMatch")?;
148                tuple.serialize_element(va)?;
149                tuple.serialize_element(expr)?;
150                tuple.serialize_element(cases)?;
151                tuple.end()
152            }
153            Value::Record(va, fields) => {
154                let mut tuple = serializer.serialize_tuple(3)?;
155                tuple.serialize_element("Record")?;
156                tuple.serialize_element(va)?;
157                tuple.serialize_element(fields)?;
158                tuple.end()
159            }
160            Value::Tuple(va, elements) => {
161                let mut tuple = serializer.serialize_tuple(3)?;
162                tuple.serialize_element("Tuple")?;
163                tuple.serialize_element(va)?;
164                tuple.serialize_element(elements)?;
165                tuple.end()
166            }
167            Value::Unit(va) => {
168                let mut tuple = serializer.serialize_tuple(2)?;
169                tuple.serialize_element("Unit")?;
170                tuple.serialize_element(va)?;
171                tuple.end()
172            }
173            Value::Update(va, record, fields) => {
174                let mut tuple = serializer.serialize_tuple(4)?;
175                tuple.serialize_element("Update")?;
176                tuple.serialize_element(va)?;
177                tuple.serialize_element(record)?;
178                tuple.serialize_element(fields)?;
179                tuple.end()
180            }
181            Value::Variable(va, name) => {
182                let mut tuple = serializer.serialize_tuple(3)?;
183                tuple.serialize_element("Variable")?;
184                tuple.serialize_element(va)?;
185                tuple.serialize_element(name)?;
186                tuple.end()
187            }
188            Value::Reference(va, name) => {
189                let mut tuple = serializer.serialize_tuple(3)?;
190                tuple.serialize_element("Reference")?;
191                tuple.serialize_element(va)?;
192                tuple.serialize_element(name)?;
193                tuple.end()
194            }
195        }
196    }
197}
198
199impl<'de, TA: Deserialize<'de>, VA: Deserialize<'de>> Deserialize<'de> for Value<TA, VA> {
200    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
201    where
202        D: Deserializer<'de>,
203    {
204        struct ValueVisitor<TA, VA>(std::marker::PhantomData<(TA, VA)>);
205
206        impl<'de, TA: Deserialize<'de>, VA: Deserialize<'de>> Visitor<'de> for ValueVisitor<TA, VA> {
207            type Value = Value<TA, VA>;
208
209            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
210                formatter.write_str("a classic Value array")
211            }
212
213            fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
214            where
215                V: SeqAccess<'de>,
216            {
217                let tag: Cow<'de, str> = seq
218                    .next_element()?
219                    .ok_or_else(|| de::Error::invalid_length(0, &self))?;
220
221                match tag.as_ref() {
222                    "Apply" | "apply" => {
223                        let va = seq
224                            .next_element()?
225                            .ok_or_else(|| de::Error::invalid_length(1, &self))?;
226                        let func = seq
227                            .next_element()?
228                            .ok_or_else(|| de::Error::invalid_length(2, &self))?;
229                        let arg = seq
230                            .next_element()?
231                            .ok_or_else(|| de::Error::invalid_length(3, &self))?;
232                        if seq.next_element::<IgnoredAny>()?.is_some() {
233                            return Err(de::Error::custom("Expected end of Apply array"));
234                        }
235                        Ok(Value::Apply(va, func, arg))
236                    }
237                    "Constructor" | "constructor" => {
238                        let va = seq
239                            .next_element()?
240                            .ok_or_else(|| de::Error::invalid_length(1, &self))?;
241                        let name = seq
242                            .next_element()?
243                            .ok_or_else(|| de::Error::invalid_length(2, &self))?;
244                        if seq.next_element::<IgnoredAny>()?.is_some() {
245                            return Err(de::Error::custom("Expected end of Constructor array"));
246                        }
247                        Ok(Value::Constructor(va, name))
248                    }
249                    "Destructure" | "destructure" => {
250                        let va = seq
251                            .next_element()?
252                            .ok_or_else(|| de::Error::invalid_length(1, &self))?;
253                        let pattern = seq
254                            .next_element()?
255                            .ok_or_else(|| de::Error::invalid_length(2, &self))?;
256                        let value = seq
257                            .next_element()?
258                            .ok_or_else(|| de::Error::invalid_length(3, &self))?;
259                        let in_expr = seq
260                            .next_element()?
261                            .ok_or_else(|| de::Error::invalid_length(4, &self))?;
262                        if seq.next_element::<IgnoredAny>()?.is_some() {
263                            return Err(de::Error::custom("Expected end of Destructure array"));
264                        }
265                        Ok(Value::Destructure(va, pattern, value, in_expr))
266                    }
267                    "Field" | "field" => {
268                        let va = seq
269                            .next_element()?
270                            .ok_or_else(|| de::Error::invalid_length(1, &self))?;
271                        let record = seq
272                            .next_element()?
273                            .ok_or_else(|| de::Error::invalid_length(2, &self))?;
274                        let name = seq
275                            .next_element()?
276                            .ok_or_else(|| de::Error::invalid_length(3, &self))?;
277                        if seq.next_element::<IgnoredAny>()?.is_some() {
278                            return Err(de::Error::custom("Expected end of Field array"));
279                        }
280                        Ok(Value::Field(va, record, name))
281                    }
282                    "FieldFunction" | "field_function" => {
283                        let va = seq
284                            .next_element()?
285                            .ok_or_else(|| de::Error::invalid_length(1, &self))?;
286                        let name = seq
287                            .next_element()?
288                            .ok_or_else(|| de::Error::invalid_length(2, &self))?;
289                        if seq.next_element::<IgnoredAny>()?.is_some() {
290                            return Err(de::Error::custom("Expected end of FieldFunction array"));
291                        }
292                        Ok(Value::FieldFunction(va, name))
293                    }
294                    "IfThenElse" | "if_then_else" => {
295                        let va = seq
296                            .next_element()?
297                            .ok_or_else(|| de::Error::invalid_length(1, &self))?;
298                        let cond = seq
299                            .next_element()?
300                            .ok_or_else(|| de::Error::invalid_length(2, &self))?;
301                        let then_branch = seq
302                            .next_element()?
303                            .ok_or_else(|| de::Error::invalid_length(3, &self))?;
304                        let else_branch = seq
305                            .next_element()?
306                            .ok_or_else(|| de::Error::invalid_length(4, &self))?;
307                        if seq.next_element::<IgnoredAny>()?.is_some() {
308                            return Err(de::Error::custom("Expected end of IfThenElse array"));
309                        }
310                        Ok(Value::IfThenElse(va, cond, then_branch, else_branch))
311                    }
312                    "Lambda" | "lambda" => {
313                        let va = seq
314                            .next_element()?
315                            .ok_or_else(|| de::Error::invalid_length(1, &self))?;
316                        let pattern = seq
317                            .next_element()?
318                            .ok_or_else(|| de::Error::invalid_length(2, &self))?;
319                        let body = seq
320                            .next_element()?
321                            .ok_or_else(|| de::Error::invalid_length(3, &self))?;
322                        if seq.next_element::<IgnoredAny>()?.is_some() {
323                            return Err(de::Error::custom("Expected end of Lambda array"));
324                        }
325                        Ok(Value::Lambda(va, pattern, body))
326                    }
327                    "LetDefinition" | "let_definition" => {
328                        let va = seq
329                            .next_element()?
330                            .ok_or_else(|| de::Error::invalid_length(1, &self))?;
331                        let name = seq
332                            .next_element()?
333                            .ok_or_else(|| de::Error::invalid_length(2, &self))?;
334                        let def = seq
335                            .next_element()?
336                            .ok_or_else(|| de::Error::invalid_length(3, &self))?;
337                        let in_expr = seq
338                            .next_element()?
339                            .ok_or_else(|| de::Error::invalid_length(4, &self))?;
340                        if seq.next_element::<IgnoredAny>()?.is_some() {
341                            return Err(de::Error::custom("Expected end of LetDefinition array"));
342                        }
343                        Ok(Value::LetDefinition(va, name, def, in_expr))
344                    }
345                    "LetRecursion" | "let_recursion" => {
346                        let va = seq
347                            .next_element()?
348                            .ok_or_else(|| de::Error::invalid_length(1, &self))?;
349                        let defs = seq
350                            .next_element()?
351                            .ok_or_else(|| de::Error::invalid_length(2, &self))?;
352                        let in_expr = seq
353                            .next_element()?
354                            .ok_or_else(|| de::Error::invalid_length(3, &self))?;
355                        if seq.next_element::<IgnoredAny>()?.is_some() {
356                            return Err(de::Error::custom("Expected end of LetRecursion array"));
357                        }
358                        Ok(Value::LetRecursion(va, defs, in_expr))
359                    }
360                    "List" | "list" => {
361                        let va = seq
362                            .next_element()?
363                            .ok_or_else(|| de::Error::invalid_length(1, &self))?;
364                        let elements = seq
365                            .next_element()?
366                            .ok_or_else(|| de::Error::invalid_length(2, &self))?;
367                        if seq.next_element::<IgnoredAny>()?.is_some() {
368                            return Err(de::Error::custom("Expected end of List array"));
369                        }
370                        Ok(Value::List(va, elements))
371                    }
372                    "Literal" | "literal" => {
373                        let va = seq
374                            .next_element()?
375                            .ok_or_else(|| de::Error::invalid_length(1, &self))?;
376                        let lit = seq
377                            .next_element()?
378                            .ok_or_else(|| de::Error::invalid_length(2, &self))?;
379                        if seq.next_element::<IgnoredAny>()?.is_some() {
380                            return Err(de::Error::custom("Expected end of Literal array"));
381                        }
382                        Ok(Value::Literal(va, lit))
383                    }
384                    "PatternMatch" | "pattern_match" => {
385                        let va = seq
386                            .next_element()?
387                            .ok_or_else(|| de::Error::invalid_length(1, &self))?;
388                        let expr = seq
389                            .next_element()?
390                            .ok_or_else(|| de::Error::invalid_length(2, &self))?;
391                        let cases = seq
392                            .next_element()?
393                            .ok_or_else(|| de::Error::invalid_length(3, &self))?;
394                        if seq.next_element::<IgnoredAny>()?.is_some() {
395                            return Err(de::Error::custom("Expected end of PatternMatch array"));
396                        }
397                        Ok(Value::PatternMatch(va, expr, cases))
398                    }
399                    "Record" | "record" => {
400                        let va = seq
401                            .next_element()?
402                            .ok_or_else(|| de::Error::invalid_length(1, &self))?;
403                        let fields = seq
404                            .next_element()?
405                            .ok_or_else(|| de::Error::invalid_length(2, &self))?;
406                        if seq.next_element::<IgnoredAny>()?.is_some() {
407                            return Err(de::Error::custom("Expected end of Record array"));
408                        }
409                        Ok(Value::Record(va, fields))
410                    }
411                    "Tuple" | "tuple" => {
412                        let va = seq
413                            .next_element()?
414                            .ok_or_else(|| de::Error::invalid_length(1, &self))?;
415                        let elements = seq
416                            .next_element()?
417                            .ok_or_else(|| de::Error::invalid_length(2, &self))?;
418                        if seq.next_element::<IgnoredAny>()?.is_some() {
419                            return Err(de::Error::custom("Expected end of Tuple array"));
420                        }
421                        Ok(Value::Tuple(va, elements))
422                    }
423                    "Unit" | "unit" => {
424                        let va = seq
425                            .next_element()?
426                            .ok_or_else(|| de::Error::invalid_length(1, &self))?;
427                        if seq.next_element::<IgnoredAny>()?.is_some() {
428                            return Err(de::Error::custom("Expected end of Unit array"));
429                        }
430                        Ok(Value::Unit(va))
431                    }
432                    "Update" | "update" | "UpdateRecord" | "update_record" => {
433                        let va = seq
434                            .next_element()?
435                            .ok_or_else(|| de::Error::invalid_length(1, &self))?;
436                        let record = seq
437                            .next_element()?
438                            .ok_or_else(|| de::Error::invalid_length(2, &self))?;
439                        let fields = seq
440                            .next_element()?
441                            .ok_or_else(|| de::Error::invalid_length(3, &self))?;
442                        if seq.next_element::<IgnoredAny>()?.is_some() {
443                            return Err(de::Error::custom("Expected end of Update array"));
444                        }
445                        Ok(Value::Update(va, record, fields))
446                    }
447                    "Variable" | "variable" => {
448                        let va = seq
449                            .next_element()?
450                            .ok_or_else(|| de::Error::invalid_length(1, &self))?;
451                        let name = seq
452                            .next_element()?
453                            .ok_or_else(|| de::Error::invalid_length(2, &self))?;
454                        if seq.next_element::<IgnoredAny>()?.is_some() {
455                            return Err(de::Error::custom("Expected end of Variable array"));
456                        }
457                        Ok(Value::Variable(va, name))
458                    }
459                    "Reference" | "reference" => {
460                        let va = seq
461                            .next_element()?
462                            .ok_or_else(|| de::Error::invalid_length(1, &self))?;
463                        let name = seq
464                            .next_element()?
465                            .ok_or_else(|| de::Error::invalid_length(2, &self))?;
466                        if seq.next_element::<IgnoredAny>()?.is_some() {
467                            return Err(de::Error::custom("Expected end of Reference array"));
468                        }
469                        Ok(Value::Reference(va, name))
470                    }
471                    _ => Err(de::Error::unknown_variant(
472                        &tag,
473                        &[
474                            "Apply",
475                            "Constructor",
476                            "Destructure",
477                            "Field",
478                            "FieldFunction",
479                            "IfThenElse",
480                            "Lambda",
481                            "LetDefinition",
482                            "LetRecursion",
483                            "List",
484                            "Literal",
485                            "PatternMatch",
486                            "Record",
487                            "Tuple",
488                            "Unit",
489                            "Update",
490                            "Variable",
491                            "Reference",
492                        ],
493                    )),
494                }
495            }
496        }
497        deserializer.deserialize_seq(ValueVisitor(std::marker::PhantomData))
498    }
499}
500
501// ----------------------------------------------------------------------------
502// Value Specification and Definition
503// ----------------------------------------------------------------------------
504
505/// Value parameter - [name, type]
506#[derive(Debug, Clone, PartialEq, Eq)]
507pub struct ValueParameter<A> {
508    pub name: Name,
509    pub ty: Type<A>,
510}
511
512impl<A: Serialize> Serialize for ValueParameter<A> {
513    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
514    where
515        S: Serializer,
516    {
517        let mut tuple = serializer.serialize_tuple(2)?;
518        tuple.serialize_element(&self.name)?;
519        tuple.serialize_element(&self.ty)?;
520        tuple.end()
521    }
522}
523
524impl<'de, A: Deserialize<'de>> Deserialize<'de> for ValueParameter<A> {
525    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
526    where
527        D: Deserializer<'de>,
528    {
529        struct VPVisitor<A>(std::marker::PhantomData<A>);
530        impl<'de, A: Deserialize<'de>> Visitor<'de> for VPVisitor<A> {
531            type Value = ValueParameter<A>;
532            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
533                formatter.write_str("a ValueParameter array [name, type]")
534            }
535            fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
536            where
537                V: SeqAccess<'de>,
538            {
539                let name = seq
540                    .next_element()?
541                    .ok_or_else(|| de::Error::invalid_length(0, &self))?;
542                let ty = seq
543                    .next_element()?
544                    .ok_or_else(|| de::Error::invalid_length(1, &self))?;
545                if let Some(IgnoredAny) = seq.next_element()? {
546                    return Err(de::Error::custom("Expected end of ValueParameter array"));
547                }
548                Ok(ValueParameter { name, ty })
549            }
550        }
551        deserializer.deserialize_seq(VPVisitor(std::marker::PhantomData))
552    }
553}
554
555/// Value argument - [name, va, type]
556#[derive(Debug, Clone, PartialEq)]
557pub struct ValueArgument<TA, VA> {
558    pub name: Name,
559    pub annotation: VA,
560    pub ty: Type<TA>,
561}
562
563impl<TA: Serialize, VA: Serialize> Serialize for ValueArgument<TA, VA> {
564    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
565    where
566        S: Serializer,
567    {
568        let mut tuple = serializer.serialize_tuple(3)?;
569        tuple.serialize_element(&self.name)?;
570        tuple.serialize_element(&self.annotation)?;
571        tuple.serialize_element(&self.ty)?;
572        tuple.end()
573    }
574}
575
576impl<'de, TA: Deserialize<'de>, VA: Deserialize<'de>> Deserialize<'de> for ValueArgument<TA, VA> {
577    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
578    where
579        D: Deserializer<'de>,
580    {
581        struct VAVisitor<TA, VA>(std::marker::PhantomData<(TA, VA)>);
582        impl<'de, TA: Deserialize<'de>, VA: Deserialize<'de>> Visitor<'de> for VAVisitor<TA, VA> {
583            type Value = ValueArgument<TA, VA>;
584            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
585                formatter.write_str("a ValueArgument array [name, va, type]")
586            }
587            fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
588            where
589                V: SeqAccess<'de>,
590            {
591                let name = seq
592                    .next_element()?
593                    .ok_or_else(|| de::Error::invalid_length(0, &self))?;
594                let annotation = seq
595                    .next_element()?
596                    .ok_or_else(|| de::Error::invalid_length(1, &self))?;
597                let ty = seq
598                    .next_element()?
599                    .ok_or_else(|| de::Error::invalid_length(2, &self))?;
600                if let Some(IgnoredAny) = seq.next_element()? {
601                    return Err(de::Error::custom("Expected end of ValueArgument array"));
602                }
603                Ok(ValueArgument {
604                    name,
605                    annotation,
606                    ty,
607                })
608            }
609        }
610        deserializer.deserialize_seq(VAVisitor(std::marker::PhantomData))
611    }
612}
613
614/// Value specification (inputs and output type)
615#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
616#[serde(rename_all = "camelCase")]
617pub struct ValueSpecification<A> {
618    pub inputs: Vec<ValueParameter<A>>,
619    pub output: Type<A>,
620}
621
622/// Value definition (implementation)
623#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
624#[serde(rename_all = "camelCase")]
625pub struct ValueDefinition<TA, VA> {
626    pub input_types: Vec<ValueArgument<TA, VA>>,
627    pub output_type: Type<TA>,
628    pub body: Value<TA, VA>,
629}
630
631#[cfg(test)]
632mod tests {
633    use super::*;
634    use crate::ir::classic::naming::Path;
635
636    #[test]
637    fn test_serialize_value_apply() {
638        let v: Value<(), ()> = Value::Apply(
639            (),
640            Box::new(Value::Variable((), Name::from_str("f"))),
641            Box::new(Value::Variable((), Name::from_str("x"))),
642        );
643        let json = serde_json::to_string(&v).unwrap();
644        assert_eq!(
645            json,
646            r#"["Apply",null,["Variable",null,["f"]],["Variable",null,["x"]]]"#
647        );
648        let deserialized: Value<(), ()> = serde_json::from_str(&json).unwrap();
649        assert_eq!(deserialized, v);
650    }
651
652    #[test]
653    fn test_serialize_value_variable() {
654        let v: Value<(), ()> = Value::Variable((), Name::from_str("x"));
655        let json = serde_json::to_string(&v).unwrap();
656        assert_eq!(json, r#"["Variable",null,["x"]]"#);
657        let deserialized: Value<(), ()> = serde_json::from_str(&json).unwrap();
658        assert_eq!(deserialized, v);
659    }
660
661    #[test]
662    fn test_serialize_value_literal() {
663        let v: Value<(), ()> = Value::Literal((), Literal::WholeNumber(123));
664        let json = serde_json::to_string(&v).unwrap();
665        assert_eq!(json, r#"["Literal",null,["WholeNumberLiteral",123]]"#);
666        let deserialized: Value<(), ()> = serde_json::from_str(&json).unwrap();
667        assert_eq!(deserialized, v);
668    }
669
670    #[test]
671    fn test_serialize_value_lambda() {
672        let v: Value<(), ()> = Value::Lambda(
673            (),
674            Pattern::As((), Box::new(Pattern::Wildcard(())), Name::from_str("x")),
675            Box::new(Value::Variable((), Name::from_str("x"))),
676        );
677        let json = serde_json::to_string(&v).unwrap();
678        assert_eq!(
679            json,
680            r#"["Lambda",null,["AsPattern",null,["WildcardPattern",null],["x"]],["Variable",null,["x"]]]"#
681        );
682        let deserialized: Value<(), ()> = serde_json::from_str(&json).unwrap();
683        assert_eq!(deserialized, v);
684    }
685
686    #[test]
687    fn test_serialize_value_let_definition() {
688        let def = ValueDefinition {
689            input_types: vec![],
690            output_type: Type::Unit(()),
691            body: Value::Unit(()),
692        };
693        let v: Value<(), ()> = Value::LetDefinition(
694            (),
695            Name::from_str("x"),
696            Box::new(def),
697            Box::new(Value::Variable((), Name::from_str("x"))),
698        );
699        let json = serde_json::to_string(&v).unwrap();
700        assert!(json.contains(r#"["LetDefinition",null,["x"],"#));
701        let deserialized: Value<(), ()> = serde_json::from_str(&json).unwrap();
702        assert_eq!(deserialized, v);
703    }
704
705    #[test]
706    fn test_serialize_value_reference() {
707        let fq = FQName::new(
708            Path::new(vec![Name::from_str("pkg")]),
709            Path::new(vec![Name::from_str("mod")]),
710            Name::from_str("ref"),
711        );
712        let v: Value<(), ()> = Value::Reference((), fq);
713        let json = serde_json::to_string(&v).unwrap();
714        assert_eq!(json, r#"["Reference",null,[[["pkg"]],[["mod"]],["ref"]]]"#);
715        let deserialized: Value<(), ()> = serde_json::from_str(&json).unwrap();
716        assert_eq!(deserialized, v);
717    }
718
719    #[test]
720    fn test_serialize_value_if_then_else() {
721        let v: Value<(), ()> = Value::IfThenElse(
722            (),
723            Box::new(Value::Literal((), Literal::Bool(true))),
724            Box::new(Value::Literal((), Literal::WholeNumber(1))),
725            Box::new(Value::Literal((), Literal::WholeNumber(0))),
726        );
727        let json = serde_json::to_string(&v).unwrap();
728        assert_eq!(
729            json,
730            r#"["IfThenElse",null,["Literal",null,["BoolLiteral",true]],["Literal",null,["WholeNumberLiteral",1]],["Literal",null,["WholeNumberLiteral",0]]]"#
731        );
732        let deserialized: Value<(), ()> = serde_json::from_str(&json).unwrap();
733        assert_eq!(deserialized, v);
734    }
735}