1pub mod member;
18pub use member::*;
19
20use crate::{ConstParameter, 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 const_parameters: Vec<ConstParameter>,
47 pub members: Vec<Member>,
49 pub external: Option<Symbol>,
51 pub is_record: bool,
54 pub span: Span,
56 pub id: NodeID,
58}
59
60impl PartialEq for Composite {
61 fn eq(&self, other: &Self) -> bool {
62 self.identifier == other.identifier && self.external == other.external
63 }
64}
65
66impl Eq for Composite {}
67
68impl Composite {
69 pub fn name(&self) -> Symbol {
71 self.identifier.name
72 }
73
74 pub fn from_external_record<N: Network>(input: &RecordType<N>, external_program: Symbol) -> Self {
75 Self {
76 identifier: Identifier::from(input.name()),
77 const_parameters: Vec::new(),
78 members: [
79 vec![Member {
80 mode: if input.owner().is_private() { Mode::Public } else { Mode::Private },
81 identifier: Identifier::new(Symbol::intern("owner"), Default::default()),
82 type_: Type::Address,
83 span: Default::default(),
84 id: Default::default(),
85 }],
86 input
87 .entries()
88 .iter()
89 .map(|(id, entry)| Member {
90 mode: if input.owner().is_public() { Mode::Public } else { Mode::Private },
91 identifier: Identifier::from(id),
92 type_: match entry {
93 Public(t) => Type::from_snarkvm(t, None),
94 Private(t) => Type::from_snarkvm(t, None),
95 Constant(t) => Type::from_snarkvm(t, None),
96 },
97 span: Default::default(),
98 id: Default::default(),
99 })
100 .collect_vec(),
101 ]
102 .concat(),
103 external: Some(external_program),
104 is_record: true,
105 span: Default::default(),
106 id: Default::default(),
107 }
108 }
109
110 pub fn from_snarkvm<N: Network>(input: &StructType<N>) -> Self {
111 Self {
112 identifier: Identifier::from(input.name()),
113 const_parameters: Vec::new(),
114 members: input
115 .members()
116 .iter()
117 .map(|(id, type_)| Member {
118 mode: Mode::None,
119 identifier: Identifier::from(id),
120 type_: Type::from_snarkvm(type_, None),
121 span: Default::default(),
122 id: Default::default(),
123 })
124 .collect(),
125 external: None,
126 is_record: false,
127 span: Default::default(),
128 id: Default::default(),
129 }
130 }
131}
132
133impl fmt::Display for Composite {
134 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
135 f.write_str(if self.is_record { "record" } else { "struct" })?;
136 write!(f, " {}", self.identifier)?;
137 if !self.const_parameters.is_empty() {
138 write!(f, "::[{}]", self.const_parameters.iter().format(", "))?;
139 }
140 writeln!(f, " {{")?;
141
142 for field in self.members.iter() {
143 writeln!(f, "{},", Indent(field))?;
144 }
145 write!(f, "}}")
146 }
147}
148
149crate::simple_node_impl!(Composite);