sway_core/language/
module.rs1use sway_types::Ident;
2
3pub type ModName = Ident;
8
9pub trait HasModule<T>
10where
11 T: HasSubmodules<Self>,
12 Self: Sized,
13{
14 fn module(&self) -> &T;
16}
17
18pub trait HasSubmodules<E>
19where
20 E: HasModule<Self>,
21 Self: Sized,
22{
23 fn submodules(&self) -> &[(ModName, E)];
25
26 fn submodules_recursive(&self) -> SubmodulesRecursive<Self, E> {
28 SubmodulesRecursive {
29 _module_type: std::marker::PhantomData,
30 submods: self.submodules().iter(),
31 current: None,
32 }
33 }
34}
35
36type NamedSubmodule<E> = (ModName, E);
37type SubmoduleItem<'module, T, E> = (
38 &'module NamedSubmodule<E>,
39 Box<SubmodulesRecursive<'module, T, E>>,
40);
41
42pub struct SubmodulesRecursive<'module, T, E> {
46 _module_type: std::marker::PhantomData<T>,
47 submods: std::slice::Iter<'module, NamedSubmodule<E>>,
48 current: Option<SubmoduleItem<'module, T, E>>,
49}
50
51impl<'module, T, E> Iterator for SubmodulesRecursive<'module, T, E>
52where
53 T: HasSubmodules<E> + 'module,
54 E: HasModule<T>,
55{
56 type Item = &'module (ModName, E);
57 fn next(&mut self) -> Option<Self::Item> {
58 loop {
59 self.current = match self.current.take() {
60 None => match self.submods.next() {
61 None => return None,
62 Some(submod) => {
63 Some((submod, Box::new(submod.1.module().submodules_recursive())))
64 }
65 },
66 Some((submod, mut submods)) => match submods.next() {
67 Some(next) => {
68 self.current = Some((submod, submods));
69 return Some(next);
70 }
71 None => return Some(submod),
72 },
73 }
74 }
75 }
76}