Skip to main content

morphir_core/ir/classic/
module.rs

1//! Classic IR Module types
2//!
3//! Module structures for the Classic Morphir IR format.
4
5use serde::de::{self, IgnoredAny, SeqAccess, Visitor};
6use serde::ser::{SerializeTuple, Serializer};
7use serde::{Deserialize, Deserializer, Serialize};
8use std::fmt;
9
10use super::access::AccessControlled;
11use super::documented::Documented;
12use super::naming::{Name, Path};
13use super::types::TypeDefinition;
14use super::value::ValueDefinition;
15
16/// Module entry - [modulePath, AccessControlled<ModuleDefinition>]
17#[derive(Debug, Clone, PartialEq)]
18pub struct ModuleEntry<TA, VA> {
19    pub path: Path,
20    pub definition: AccessControlled<ModuleDefinition<TA, VA>>,
21}
22
23impl<TA: Serialize, VA: Serialize> Serialize for ModuleEntry<TA, VA> {
24    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
25    where
26        S: Serializer,
27    {
28        let mut tuple = serializer.serialize_tuple(2)?;
29        tuple.serialize_element(&self.path)?;
30        tuple.serialize_element(&self.definition)?;
31        tuple.end()
32    }
33}
34
35impl<'de, TA: Deserialize<'de>, VA: Deserialize<'de>> Deserialize<'de> for ModuleEntry<TA, VA> {
36    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
37    where
38        D: Deserializer<'de>,
39    {
40        struct ModuleEntryVisitor<TA, VA>(std::marker::PhantomData<(TA, VA)>);
41
42        impl<'de, TA: Deserialize<'de>, VA: Deserialize<'de>> Visitor<'de> for ModuleEntryVisitor<TA, VA> {
43            type Value = ModuleEntry<TA, VA>;
44
45            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
46                formatter.write_str("a ModuleEntry array [path, definition]")
47            }
48
49            fn visit_seq<V>(self, mut seq: V) -> Result<Self::Value, V::Error>
50            where
51                V: SeqAccess<'de>,
52            {
53                let path = seq
54                    .next_element()?
55                    .ok_or_else(|| de::Error::invalid_length(0, &self))?;
56                let definition = seq
57                    .next_element()?
58                    .ok_or_else(|| de::Error::invalid_length(1, &self))?;
59
60                if let Some(IgnoredAny) = seq.next_element()? {
61                    return Err(de::Error::custom("Expected end of ModuleEntry array"));
62                }
63
64                Ok(ModuleEntry { path, definition })
65            }
66        }
67
68        deserializer.deserialize_seq(ModuleEntryVisitor(std::marker::PhantomData))
69    }
70}
71
72/// Module specification (public interface only)
73pub type ModuleTypeSpecification<A> = (Name, Documented<super::types::TypeSpecification<A>>);
74pub type ModuleValueSpecification<A> = (Name, Documented<super::value::ValueSpecification<A>>);
75pub type ModuleTypeDefinition<A> = (Name, AccessControlled<Documented<TypeDefinition<A>>>);
76pub type ModuleValueDefinition<TA, VA> =
77    (Name, AccessControlled<Documented<ValueDefinition<TA, VA>>>);
78
79#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
80#[serde(rename_all = "camelCase")]
81#[serde(bound(deserialize = "A: Deserialize<'de>"))]
82pub struct ModuleSpecification<A> {
83    #[serde(default)]
84    pub types: Vec<ModuleTypeSpecification<A>>,
85    #[serde(default)]
86    pub values: Vec<ModuleValueSpecification<A>>,
87    pub doc: Option<String>,
88}
89
90/// Module definition (full implementation)
91#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
92#[serde(rename_all = "camelCase")]
93#[serde(bound(deserialize = "TA: Deserialize<'de>, VA: Deserialize<'de>"))]
94pub struct ModuleDefinition<TA, VA> {
95    #[serde(default)]
96    pub types: Vec<ModuleTypeDefinition<TA>>,
97    #[serde(default)]
98    pub values: Vec<ModuleValueDefinition<TA, VA>>,
99    pub doc: Option<String>,
100}