]> git.lizzy.rs Git - rust.git/blob - crates/hir_def/src/per_ns.rs
a594afce6686761f409ad25fdd4832cb61139596
[rust.git] / crates / hir_def / src / per_ns.rs
1 //! In rust, it is possible to have a value, a type and a macro with the same
2 //! name without conflicts.
3 //!
4 //! `PerNs` (per namespace) captures this.
5
6 use hir_expand::MacroDefId;
7
8 use crate::{item_scope::ItemInNs, visibility::Visibility, ModuleDefId};
9
10 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
11 pub struct PerNs {
12     pub types: Option<(ModuleDefId, Visibility)>,
13     pub values: Option<(ModuleDefId, Visibility)>,
14     pub macros: Option<(MacroDefId, Visibility)>,
15 }
16
17 impl Default for PerNs {
18     fn default() -> Self {
19         PerNs { types: None, values: None, macros: None }
20     }
21 }
22
23 impl PerNs {
24     pub fn none() -> PerNs {
25         PerNs { types: None, values: None, macros: None }
26     }
27
28     pub fn values(t: ModuleDefId, v: Visibility) -> PerNs {
29         PerNs { types: None, values: Some((t, v)), macros: None }
30     }
31
32     pub fn types(t: ModuleDefId, v: Visibility) -> PerNs {
33         PerNs { types: Some((t, v)), values: None, macros: None }
34     }
35
36     pub fn both(types: ModuleDefId, values: ModuleDefId, v: Visibility) -> PerNs {
37         PerNs { types: Some((types, v)), values: Some((values, v)), macros: None }
38     }
39
40     pub fn macros(macro_: MacroDefId, v: Visibility) -> PerNs {
41         PerNs { types: None, values: None, macros: Some((macro_, v)) }
42     }
43
44     pub fn is_none(&self) -> bool {
45         self.types.is_none() && self.values.is_none() && self.macros.is_none()
46     }
47
48     pub fn take_types(self) -> Option<ModuleDefId> {
49         self.types.map(|it| it.0)
50     }
51
52     pub fn take_types_vis(self) -> Option<(ModuleDefId, Visibility)> {
53         self.types
54     }
55
56     pub fn take_values(self) -> Option<ModuleDefId> {
57         self.values.map(|it| it.0)
58     }
59
60     pub fn take_macros(self) -> Option<MacroDefId> {
61         self.macros.map(|it| it.0)
62     }
63
64     pub fn filter_visibility(self, mut f: impl FnMut(Visibility) -> bool) -> PerNs {
65         PerNs {
66             types: self.types.filter(|(_, v)| f(*v)),
67             values: self.values.filter(|(_, v)| f(*v)),
68             macros: self.macros.filter(|(_, v)| f(*v)),
69         }
70     }
71
72     pub fn with_visibility(self, vis: Visibility) -> PerNs {
73         PerNs {
74             types: self.types.map(|(it, _)| (it, vis)),
75             values: self.values.map(|(it, _)| (it, vis)),
76             macros: self.macros.map(|(it, _)| (it, vis)),
77         }
78     }
79
80     pub fn or(self, other: PerNs) -> PerNs {
81         PerNs {
82             types: self.types.or(other.types),
83             values: self.values.or(other.values),
84             macros: self.macros.or(other.macros),
85         }
86     }
87
88     pub fn iter_items(self) -> impl Iterator<Item = ItemInNs> {
89         self.types
90             .map(|it| ItemInNs::Types(it.0))
91             .into_iter()
92             .chain(self.values.map(|it| ItemInNs::Values(it.0)).into_iter())
93             .chain(self.macros.map(|it| ItemInNs::Macros(it.0)).into_iter())
94     }
95 }