1use super::*;
2
3pub struct Derive(HashMap<TypeName, Vec<String>>);
4
5impl Derive {
6 pub fn new(reader: &Reader, types: &TypeMap, derive: &[&str]) -> Self {
7 let mut map = HashMap::new();
8
9 for derive in derive {
10 let Some((name, derive)) = derive.split_once('=') else {
11 panic!("`--derive` must be `<type name>=Comma,Separated,List");
12 };
13
14 let tn = get_type_name(reader, name);
15
16 if !types.contains_key(&tn) {
17 panic!("type not included: `{name}`");
18 }
19
20 let derive = derive
21 .split(',')
22 .filter(|&derive| (!derive.is_empty()))
23 .map(|derive| derive.to_string())
24 .collect();
25 map.insert(tn, derive);
26 }
27
28 Self(map)
29 }
30
31 pub fn get(&self, type_name: TypeName) -> impl Iterator<Item = String> + '_ {
32 self.0.get(&type_name).into_iter().flatten().cloned()
33 }
34}
35
36fn get_type_name(reader: &Reader, path: &str) -> TypeName {
37 if let Some((namespace: &str, name: &str)) = path.rsplit_once(delimiter:'.') {
38 if let Some((namespace: &&str, types: &HashMap<&str, Vec>)) = reader.get_key_value(namespace) {
39 if let Some((name: &&str, _)) = types.get_key_value(name) {
40 return TypeName(namespace, name);
41 }
42 }
43 } else {
44 for (namespace: &&str, types: &HashMap<&str, Vec>) in reader.iter() {
45 if let Some((name: &&str, _)) = types.get_key_value(path) {
46 return TypeName(namespace, name);
47 }
48 }
49 }
50
51 panic!("type not found: `{path}`");
52}
53