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