ecore_rs/
prelude.rs

1/// Imports this crate's prelude.
2#[macro_export]
3macro_rules! prelude {
4    ($($imports:tt)*) => (
5        use $crate::prelude::{*, $($imports)*};
6    )
7}
8
9pub use std::{
10    borrow::{Borrow, Cow},
11    collections::{BTreeSet, HashMap},
12    fmt::{self, Display},
13    mem,
14};
15
16pub use log;
17pub use regex;
18pub use smallvec::{smallvec, SmallVec};
19
20#[macro_use]
21pub mod res;
22
23pub use crate::{
24    bail,
25    ctx::{self, Ctx},
26    error, parser,
27    prelude::{
28        path_map::PathMap,
29        res::{Res, WithCtx},
30    },
31    repr::{self, builtin, idx},
32    traits::*,
33};
34
35mod path_map {
36    prelude! {
37        repr::Path,
38    }
39
40    pub struct PathMap<K, V>
41    where
42        K: std::hash::Hash + Eq,
43    {
44        map: HashMap<Path, HashMap<K, V>>,
45    }
46
47    impl<K, V> std::ops::Deref for PathMap<K, V>
48    where
49        K: std::hash::Hash + Eq,
50    {
51        type Target = HashMap<Path, HashMap<K, V>>;
52        fn deref(&self) -> &Self::Target {
53            &self.map
54        }
55    }
56    impl<K, V> std::ops::DerefMut for PathMap<K, V>
57    where
58        K: std::hash::Hash + Eq,
59    {
60        fn deref_mut(&mut self) -> &mut Self::Target {
61            &mut self.map
62        }
63    }
64
65    impl<K, V> PathMap<K, V>
66    where
67        K: std::hash::Hash + Eq,
68    {
69        pub fn with_capacity(capa: usize) -> Self {
70            Self {
71                map: HashMap::with_capacity(capa),
72            }
73        }
74        pub fn new() -> Self {
75            Self::with_capacity(3)
76        }
77
78        pub fn at(&self, path: &Path) -> Option<&HashMap<K, V>> {
79            self.map.get(path)
80        }
81        pub fn at_mut(&mut self, path: &Path) -> Option<&mut HashMap<K, V>> {
82            self.map.get_mut(path)
83        }
84        pub fn at_mut_or_new(&mut self, path: Path) -> &mut HashMap<K, V> {
85            self.map.entry(path).or_insert_with(HashMap::new)
86        }
87
88        pub fn unwrap_at(
89            &self,
90            path: &Path,
91            display: impl FnOnce(&Path) -> String,
92        ) -> Res<&HashMap<K, V>> {
93            self.map
94                .get(path)
95                .ok_or_else(|| error!(@unknown("package path") display(path)))
96        }
97        pub fn unwrap_at_mut(
98            &mut self,
99            path: &Path,
100            display: impl FnOnce(&Path) -> String,
101        ) -> Res<&mut HashMap<K, V>> {
102            self.map
103                .get_mut(path)
104                .ok_or_else(|| error!(@unknown("package path") display(path)))
105        }
106    }
107}
108
109pub trait CollPrintExt: Sized {
110    type Elm;
111    fn show_iter<S>(self, show_elm: impl Fn(Self::Elm) -> S, sep: impl AsRef<str>) -> String
112    where
113        S: AsRef<str>;
114
115    fn show_iter_cs<S>(self, show_elm: impl Fn(Self::Elm) -> S) -> String
116    where
117        S: AsRef<str>,
118    {
119        self.show_iter(show_elm, ", ")
120    }
121}
122impl<'a, T, E> CollPrintExt for T
123where
124    T: IntoIterator<Item = E>,
125{
126    type Elm = E;
127    fn show_iter<S>(self, show_elm: impl Fn(Self::Elm) -> S, sep: impl AsRef<str>) -> String
128    where
129        S: AsRef<str>,
130    {
131        let sep = sep.as_ref();
132        let mut s = String::new();
133        for elm in self {
134            if !s.is_empty() {
135                s.push_str(sep);
136            }
137            s.push_str(show_elm(elm).as_ref())
138        }
139        s
140    }
141}