1pub mod member;
18pub use member::*;
19
20use crate::{Identifier, Indent, Mode, Node, NodeID, Type};
21use leo_span::{Span, Symbol};
22
23use itertools::Itertools;
24use serde::{Deserialize, Serialize};
25use std::fmt;
26
27use snarkvm::{
28 console::program::{RecordType, StructType},
29 prelude::{
30 EntryType::{Constant, Private, Public},
31 Network,
32 },
33};
34
35#[derive(Clone, Debug, Serialize, Deserialize)]
42pub struct Composite {
43 pub identifier: Identifier,
45 pub members: Vec<Member>,
47 pub external: Option<Symbol>,
49 pub is_record: bool,
52 pub span: Span,
54 pub id: NodeID,
56}
57
58impl PartialEq for Composite {
59 fn eq(&self, other: &Self) -> bool {
60 self.identifier == other.identifier && self.external == other.external
61 }
62}
63
64impl Eq for Composite {}
65
66impl Composite {
67 pub fn name(&self) -> Symbol {
69 self.identifier.name
70 }
71
72 pub fn from_external_record<N: Network>(input: &RecordType<N>, external_program: Symbol) -> Self {
73 Self {
74 identifier: Identifier::from(input.name()),
75 members: [
76 vec![Member {
77 mode: if input.owner().is_private() { Mode::Public } else { Mode::Private },
78 identifier: Identifier::new(Symbol::intern("owner"), Default::default()),
79 type_: Type::Address,
80 span: Default::default(),
81 id: Default::default(),
82 }],
83 input
84 .entries()
85 .iter()
86 .map(|(id, entry)| Member {
87 mode: if input.owner().is_public() { Mode::Public } else { Mode::Private },
88 identifier: Identifier::from(id),
89 type_: match entry {
90 Public(t) => Type::from_snarkvm(t, None),
91 Private(t) => Type::from_snarkvm(t, None),
92 Constant(t) => Type::from_snarkvm(t, None),
93 },
94 span: Default::default(),
95 id: Default::default(),
96 })
97 .collect_vec(),
98 ]
99 .concat(),
100 external: Some(external_program),
101 is_record: true,
102 span: Default::default(),
103 id: Default::default(),
104 }
105 }
106
107 pub fn from_snarkvm<N: Network>(input: &StructType<N>) -> Self {
108 Self {
109 identifier: Identifier::from(input.name()),
110 members: input
111 .members()
112 .iter()
113 .map(|(id, type_)| Member {
114 mode: Mode::None,
115 identifier: Identifier::from(id),
116 type_: Type::from_snarkvm(type_, None),
117 span: Default::default(),
118 id: Default::default(),
119 })
120 .collect(),
121 external: None,
122 is_record: false,
123 span: Default::default(),
124 id: Default::default(),
125 }
126 }
127}
128
129impl fmt::Display for Composite {
130 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
131 f.write_str(if self.is_record { "record" } else { "struct" })?;
132 writeln!(f, " {} {{", self.identifier)?;
133 for field in self.members.iter() {
134 writeln!(f, "{},", Indent(field))?;
135 }
136 write!(f, "}}")
137 }
138}
139
140crate::simple_node_impl!(Composite);