code_moniker_core/lang/sdk/
imports.rs1use crate::core::moniker::Moniker;
2
3#[derive(Clone, Debug, Eq, PartialEq)]
4pub enum ImportTree {
5 Name(Vec<u8>),
6 Alias {
7 name: Vec<u8>,
8 alias: Vec<u8>,
9 },
10 SelfImport,
11 Wildcard,
12 Path {
13 prefix: Vec<Vec<u8>>,
14 tree: Box<ImportTree>,
15 },
16 Group(Vec<ImportTree>),
17}
18
19#[derive(Clone, Debug, Eq, PartialEq)]
20pub enum ImportLeafKind {
21 Symbol,
22 SelfImport,
23 Wildcard,
24}
25
26#[derive(Clone, Debug, Eq, PartialEq)]
27pub struct ImportLeaf {
28 pub kind: ImportLeafKind,
29 pub path: Vec<Vec<u8>>,
30 pub alias: Option<Vec<u8>>,
31}
32
33pub fn import_leaf_binding_name(leaf: &ImportLeaf) -> Option<&[u8]> {
34 leaf.alias
35 .as_deref()
36 .or_else(|| leaf.path.last().map(Vec::as_slice))
37}
38
39pub fn importable_parent(
40 target: &Moniker,
41 is_importable_namespace: impl Fn(&Moniker) -> bool,
42) -> Option<Moniker> {
43 target.parent().filter(is_importable_namespace)
44}
45
46pub fn flatten_import_tree(tree: &ImportTree) -> Vec<ImportLeaf> {
47 let mut leaves = Vec::new();
48 flatten_into(tree, &mut Vec::new(), &mut leaves);
49 leaves
50}
51
52fn flatten_into(tree: &ImportTree, prefix: &mut Vec<Vec<u8>>, leaves: &mut Vec<ImportLeaf>) {
53 match tree {
54 ImportTree::Name(name) => {
55 leaves.push(leaf(ImportLeafKind::Symbol, path_with(prefix, name), None))
56 }
57 ImportTree::Alias { name, alias } => leaves.push(leaf(
58 ImportLeafKind::Symbol,
59 path_with(prefix, name),
60 Some(alias.clone()),
61 )),
62 ImportTree::SelfImport => {
63 leaves.push(leaf(ImportLeafKind::SelfImport, prefix.clone(), None));
64 }
65 ImportTree::Wildcard => {
66 leaves.push(leaf(ImportLeafKind::Wildcard, prefix.clone(), None));
67 }
68 ImportTree::Path { prefix: path, tree } => {
69 let original_len = prefix.len();
70 prefix.extend(path.iter().cloned());
71 flatten_into(tree, prefix, leaves);
72 prefix.truncate(original_len);
73 }
74 ImportTree::Group(items) => {
75 for item in items {
76 flatten_into(item, prefix, leaves);
77 }
78 }
79 }
80}
81
82fn path_with(prefix: &[Vec<u8>], name: &[u8]) -> Vec<Vec<u8>> {
83 let mut path = prefix.to_vec();
84 path.push(name.to_vec());
85 path
86}
87
88fn leaf(kind: ImportLeafKind, path: Vec<Vec<u8>>, alias: Option<Vec<u8>>) -> ImportLeaf {
89 ImportLeaf { kind, path, alias }
90}