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
124
125
126
127
use crate::element::daml_package::DamlPackage;
use crate::element::visitor::{DamlElementVisitor, DamlVisitableElement};
use crate::element::{serialize, DamlData, DamlTyCon, DamlTyConName};
#[cfg(feature = "full")]
use crate::element::{DamlDefValue, DamlValueName};
use bounded_static::ToStatic;
use itertools::Itertools;
use serde::Serialize;
use std::borrow::Cow;
use std::collections::HashMap;
#[derive(Debug, Serialize, Clone, Default, ToStatic)]
pub struct DamlArchive<'a> {
name: Cow<'a, str>,
main_package_id: Cow<'a, str>,
#[serde(serialize_with = "serialize::serialize_map")]
packages: HashMap<Cow<'a, str>, DamlPackage<'a>>,
}
impl<'a> DamlArchive<'a> {
pub const fn new(
name: Cow<'a, str>,
main_package_id: Cow<'a, str>,
packages: HashMap<Cow<'a, str>, DamlPackage<'a>>,
) -> Self {
Self {
name,
main_package_id,
packages,
}
}
pub fn name(&self) -> &str {
&self.name
}
pub fn main_package_id(&self) -> &str {
&self.main_package_id
}
pub fn packages(&self) -> impl Iterator<Item = &DamlPackage<'_>> {
self.packages.values()
}
pub fn package_by_name(&self, name: &str) -> Option<&DamlPackage<'_>> {
self.packages.values().find(|p| p.name() == name)
}
pub fn main_package(&self) -> Option<&DamlPackage<'_>> {
self.packages.get(&self.main_package_id)
}
pub fn data_by_tycon<'b>(&'a self, tycon: &'b DamlTyCon<'_>) -> Option<&'a DamlData<'a>> {
self.data_by_tycon_name(tycon.tycon())
}
pub fn data_by_tycon_name<'b>(&'a self, tycon_name: &'b DamlTyConName<'_>) -> Option<&'a DamlData<'a>> {
let (package_id, module_path, data_name) = tycon_name.reference_parts();
self.data(package_id, module_path, data_name)
}
pub fn data<P, M, D>(&'a self, package_id: P, module_path: &[M], data_name: D) -> Option<&'a DamlData<'a>>
where
P: AsRef<str>,
M: AsRef<str>,
D: AsRef<str>,
{
self.packages
.get(package_id.as_ref())?
.root_module()
.child_module_path(module_path)?
.data_type(data_name.as_ref())
}
#[cfg(feature = "full")]
pub fn value_by_name<'b>(&'a self, name: &'b DamlValueName<'_>) -> Option<&'a DamlDefValue<'a>> {
let (package_id, module_path, name) = name.reference_parts();
self.value(package_id, module_path, name)
}
#[cfg(feature = "full")]
pub fn value<P, M, D>(&'a self, package_id: P, module_path: &[M], name: D) -> Option<&'a DamlDefValue<'a>>
where
P: AsRef<str>,
M: AsRef<str>,
D: AsRef<str>,
{
self.packages.get(package_id.as_ref())?.root_module().child_module_path(module_path)?.value(name.as_ref())
}
}
impl<'a> DamlVisitableElement<'a> for DamlArchive<'a> {
fn accept(&'a self, visitor: &'a mut impl DamlElementVisitor) {
visitor.pre_visit_archive(self);
if visitor.sort_elements() {
self.packages.values().sorted_by_key(|p| p.name()).for_each(|package| package.accept(visitor));
} else {
self.packages.values().for_each(|package| package.accept(visitor));
}
visitor.post_visit_archive(self);
}
}