Skip to main content

code_moniker_core/lang/sdk/
imports.rs

1use 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}