1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use crate::{
unstable::blake2s::{Blake2sCircuit, CORE_UNSTABLE_BLAKE2S_NAME},
CoreCircuit,
CoreCircuitStructList,
CorePackageError,
};
use leo_ast::{Identifier, ImportSymbol, Package, PackageAccess};
use std::convert::TryFrom;
#[derive(Debug, Clone)]
pub struct CorePackage {
name: Identifier,
unstable: bool,
circuits: Vec<ImportSymbol>,
}
impl CorePackage {
pub(crate) fn new(name: Identifier) -> Self {
Self {
name,
unstable: false,
circuits: vec![],
}
}
pub(crate) fn set_unstable(&mut self) {
self.unstable = true;
}
fn get_circuit_names(&mut self, access: PackageAccess) -> Result<(), CorePackageError> {
match access {
PackageAccess::SubPackage(package) => return self.get_circuit_names(package.access),
PackageAccess::Star(span) => return Err(CorePackageError::core_package_star(span)),
PackageAccess::Multiple(accesses) => {
for access in accesses {
self.get_circuit_names(access)?;
}
}
PackageAccess::Symbol(symbol) => self.circuits.push(symbol),
}
Ok(())
}
fn circuit_name_to_ast_name(circuit_name: &str) -> Option<String> {
let first_character = &circuit_name[..1];
let remaining_characters = &circuit_name[1..];
if first_character.to_uppercase() != first_character
|| remaining_characters != remaining_characters.to_lowercase()
{
return None;
}
Some(format!("#{}", circuit_name.to_lowercase()))
}
pub(crate) fn get_circuit_structs(
&self,
circuit_structs: &mut CoreCircuitStructList,
) -> Result<(), CorePackageError> {
for circuit in &self.circuits {
let circuit_name = circuit.symbol.name.as_str();
let span = circuit.span.clone();
let id = circuit.alias.clone().unwrap_or_else(|| circuit.symbol.clone());
let name = id.name.clone();
let circuit = if self.unstable {
match &*Self::circuit_name_to_ast_name(circuit_name).unwrap_or_default() {
CORE_UNSTABLE_BLAKE2S_NAME => Blake2sCircuit::ast(circuit.symbol.clone(), span),
name => {
return Err(CorePackageError::undefined_unstable_core_circuit(
name.to_string(),
span,
));
}
}
} else {
return Err(CorePackageError::undefined_core_circuit(circuit_name.to_string(), span));
};
circuit_structs.push(name, circuit)
}
Ok(())
}
}
impl TryFrom<Package> for CorePackage {
type Error = CorePackageError;
fn try_from(package: Package) -> Result<Self, Self::Error> {
let mut core_package = Self::new(package.name);
core_package.get_circuit_names(package.access)?;
Ok(core_package)
}
}