pub mod member;
pub use member::*;
use crate::{ConstParameter, Identifier, Indent, Mode, Node, NodeID, ProgramId, Type};
use leo_span::{Span, Symbol};
use itertools::Itertools;
use serde::{Deserialize, Serialize};
use std::fmt;
use snarkvm::{
console::program::{RecordType, StructType},
prelude::{
EntryType::{Constant, Private, Public},
Network,
},
};
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Composite {
pub identifier: Identifier,
pub const_parameters: Vec<ConstParameter>,
pub members: Vec<Member>,
pub is_record: bool,
pub span: Span,
pub id: NodeID,
}
impl PartialEq for Composite {
fn eq(&self, other: &Self) -> bool {
self.identifier == other.identifier
}
}
impl Eq for Composite {}
impl Composite {
pub fn name(&self) -> Symbol {
self.identifier.name
}
pub fn from_external_record<N: Network>(input: &RecordType<N>, program_id: ProgramId) -> Self {
let mut members = Vec::with_capacity(input.entries().len() + 1);
members.push(Member {
mode: if input.owner().is_private() { Mode::Public } else { Mode::Private },
identifier: Identifier::new(Symbol::intern("owner"), Default::default()),
type_: Type::Address,
span: Default::default(),
id: Default::default(),
});
members.extend(input.entries().iter().map(|(id, entry)| Member {
mode: if input.owner().is_public() { Mode::Public } else { Mode::Private },
identifier: Identifier::from(id),
type_: match entry {
Public(t) => Type::from_snarkvm(t, program_id),
Private(t) => Type::from_snarkvm(t, program_id),
Constant(t) => Type::from_snarkvm(t, program_id),
},
span: Default::default(),
id: Default::default(),
}));
Self {
identifier: Identifier::from(input.name()),
const_parameters: Vec::new(),
members,
is_record: true,
span: Default::default(),
id: Default::default(),
}
}
pub fn from_snarkvm<N: Network>(input: &StructType<N>, program: ProgramId) -> Self {
Self {
identifier: Identifier::from(input.name()),
const_parameters: Vec::new(),
members: input
.members()
.iter()
.map(|(id, type_)| Member {
mode: Mode::None,
identifier: Identifier::from(id),
type_: Type::from_snarkvm(type_, program),
span: Default::default(),
id: Default::default(),
})
.collect(),
is_record: false,
span: Default::default(),
id: Default::default(),
}
}
}
impl fmt::Display for Composite {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(if self.is_record { "record" } else { "struct" })?;
write!(f, " {}", self.identifier)?;
if !self.const_parameters.is_empty() {
write!(f, "::[{}]", self.const_parameters.iter().format(", "))?;
}
writeln!(f, " {{")?;
for field in self.members.iter() {
writeln!(f, "{},", Indent(field))?;
}
write!(f, "}}")
}
}
crate::simple_node_impl!(Composite);