1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use std::collections::HashMap;

use super::Parameter;

 /// A type that maps parameters to their assigned names.
#[derive(Clone, Debug)]
 pub struct ParametersStore {
     dict: HashMap<Parameter, String>,
 }

 impl ParametersStore {
    pub fn new<T>(parameters: T) -> Self
    where
        T: IntoIterator<Item = Parameter>,
    {
        let mut dict = HashMap::new();
        for parameter in parameters {
            Self::_insert(parameter, &mut dict);
        }
        Self { dict }
    }

    pub fn insert(&mut self, parameter: Parameter) {
        Self::_insert(parameter, &mut self.dict);
    }

    pub fn assigned_name(&self, parameter: &Parameter) -> Option<&str> {
        self.dict.get(parameter).map(|name| name.as_str())
    }

    pub fn name(&self, parameter: &Parameter) -> String {
        self.assigned_name(parameter)
            .map(|name| name.to_string())
            .unwrap_or_else(|| parameter.name())
    }

    pub fn name_for_parameter(parameter: &Parameter, parameters: Option<&Self>) -> String {
        parameters
            .and_then(|parameters| parameters.assigned_name(parameter))
            .map(|name| name.to_string())
            .unwrap_or_else(|| parameter.name())
    }

    fn _insert(parameter: Parameter, dict: &mut HashMap<Parameter, String>) {
        match parameter {
            Parameter::Known(_, _) => {
                let name = parameter.name();
                dict.insert(parameter, name);
            }
            _ => panic!(),
        }
    }
}

impl Default for ParametersStore {
    fn default() -> Self {
        Self::new([])
    }
}