morphir_core/ir/classic/
package.rs1use super::module::{ModuleEntry, ModuleSpecification};
2use super::naming::Path;
3use serde::de::{self, IgnoredAny, MapAccess, SeqAccess, Visitor};
4use serde::ser::{SerializeTuple, Serializer};
5use serde::{Deserialize, Deserializer, Serialize};
6use std::fmt;
7
8#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
10pub struct PackageSpecification<A> {
11 pub modules: Vec<ModuleSpecEntry<A>>,
12}
13
14#[derive(Debug, Clone, PartialEq)]
16pub struct ModuleSpecEntry<A> {
17 pub path: Path,
18 pub specification: ModuleSpecification<A>,
19}
20
21impl<A: Serialize> Serialize for ModuleSpecEntry<A> {
22 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
23 where
24 S: Serializer,
25 {
26 let mut tuple = serializer.serialize_tuple(2)?;
27 tuple.serialize_element(&self.path)?;
28 tuple.serialize_element(&self.specification)?;
29 tuple.end()
30 }
31}
32
33impl<'de, A: Deserialize<'de>> Deserialize<'de> for ModuleSpecEntry<A> {
34 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
35 where
36 D: Deserializer<'de>,
37 {
38 struct ModuleSpecEntryVisitor<A>(std::marker::PhantomData<A>);
39
40 impl<'de, A: Deserialize<'de>> Visitor<'de> for ModuleSpecEntryVisitor<A> {
41 type Value = ModuleSpecEntry<A>;
42
43 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
44 formatter.write_str("a ModuleSpecEntry array [path, specification]")
45 }
46
47 fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
48 where
49 V: SeqAccess<'de>,
50 {
51 let path = seq
52 .next_element()?
53 .ok_or_else(|| de::Error::invalid_length(0, &self))?;
54 let specification = seq
55 .next_element()?
56 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
57
58 if let Some(IgnoredAny) = seq.next_element()? {
59 return Err(de::Error::custom("Expected end of ModuleSpecEntry array"));
60 }
61
62 Ok(ModuleSpecEntry {
63 path,
64 specification,
65 })
66 }
67 }
68
69 deserializer.deserialize_seq(ModuleSpecEntryVisitor(std::marker::PhantomData))
70 }
71}
72
73const SPECS_HOLD_SPECIFICATIONS: &str =
75 "a v3 Specs distribution holds module specifications, not definitions";
76
77#[derive(Debug, Clone, PartialEq)]
85pub struct SpecsModuleEntry<A>(pub ModuleSpecEntry<A>);
86
87impl<A> From<SpecsModuleEntry<A>> for ModuleSpecEntry<A> {
88 fn from(entry: SpecsModuleEntry<A>) -> Self {
89 entry.0
90 }
91}
92
93impl<'de, A: Deserialize<'de>> Deserialize<'de> for SpecsModuleEntry<A> {
94 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
95 where
96 D: Deserializer<'de>,
97 {
98 struct EntryVisitor<A>(std::marker::PhantomData<A>);
99
100 impl<'de, A: Deserialize<'de>> Visitor<'de> for EntryVisitor<A> {
101 type Value = SpecsModuleEntry<A>;
102
103 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
104 formatter.write_str("a Specs module array [path, specification]")
105 }
106
107 fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
108 where
109 V: SeqAccess<'de>,
110 {
111 let path = seq
112 .next_element()?
113 .ok_or_else(|| de::Error::invalid_length(0, &self))?;
114 let StrictModuleSpecification(specification) = seq
115 .next_element()?
116 .ok_or_else(|| de::Error::invalid_length(1, &self))?;
117 if let Some(IgnoredAny) = seq.next_element()? {
118 return Err(de::Error::custom("Expected end of ModuleSpecEntry array"));
119 }
120 Ok(SpecsModuleEntry(ModuleSpecEntry {
121 path,
122 specification,
123 }))
124 }
125 }
126
127 deserializer.deserialize_seq(EntryVisitor(std::marker::PhantomData))
128 }
129}
130
131struct StrictModuleSpecification<A>(ModuleSpecification<A>);
133
134impl<'de, A: Deserialize<'de>> Deserialize<'de> for StrictModuleSpecification<A> {
135 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
136 where
137 D: Deserializer<'de>,
138 {
139 struct SpecificationVisitor<A>(std::marker::PhantomData<A>);
140
141 impl<'de, A: Deserialize<'de>> Visitor<'de> for SpecificationVisitor<A> {
142 type Value = StrictModuleSpecification<A>;
143
144 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
145 formatter.write_str("a module specification object {types, values, doc}")
146 }
147
148 fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
149 where
150 M: MapAccess<'de>,
151 {
152 let mut types = None;
153 let mut values = None;
154 let mut doc = None;
155 while let Some(key) = map.next_key::<String>()? {
156 match key.as_str() {
157 "types" if types.is_none() => types = Some(map.next_value()?),
158 "values" if values.is_none() => values = Some(map.next_value()?),
159 "doc" if doc.is_none() => doc = Some(map.next_value()?),
160 "types" | "values" | "doc" => {
161 return Err(de::Error::custom(format!("duplicate field `{key}`")));
162 }
163 _ => {
164 return Err(de::Error::custom(format!(
165 "{SPECS_HOLD_SPECIFICATIONS}: unexpected member `{key}`"
166 )));
167 }
168 }
169 }
170 Ok(StrictModuleSpecification(ModuleSpecification {
171 types: types.unwrap_or_default(),
172 values: values.unwrap_or_default(),
173 doc: doc.flatten(),
174 }))
175 }
176 }
177
178 deserializer.deserialize_map(SpecificationVisitor(std::marker::PhantomData))
179 }
180}
181
182#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
184pub struct PackageDefinition<TA, VA> {
185 pub modules: Vec<ModuleEntry<TA, VA>>,
186}