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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
use std::collections::hash_map::{Iter, RandomState, Values};
use std::collections::HashMap;
use std::fmt::Debug;
use std::hash::Hash;
use std::rc::Rc;
use crate::models::{FromDirective, HasAliases, HasName};
use crate::LedgerError;
#[derive(Debug, Clone)]
pub struct List<T> {
aliases: HashMap<String, String>,
list: HashMap<String, Rc<T>>,
}
impl<T> Into<HashMap<String, Rc<T>>> for List<T> {
fn into(self) -> HashMap<String, Rc<T>, RandomState> {
self.list
}
}
impl<'a, T: Eq + Hash + HasName + Clone + FromDirective + HasAliases + Debug> List<T> {
pub fn new() -> Self {
let aliases: HashMap<String, String> = HashMap::new();
let list: HashMap<String, Rc<T>> = HashMap::new();
List { aliases, list }
}
pub fn insert(&mut self, element: T) {
let found = self.list.get(element.get_name());
match found {
Some(_) => (),
None => {
let name = element.get_name().to_string();
for alias in element.get_aliases().iter() {
self.aliases.insert(alias.clone(), name.clone());
}
self.list.insert(name.clone(), Rc::new(element));
}
}
}
pub fn add_alias(&mut self, alias: String, for_element: &'a T) {
let element = self.aliases.get(&alias);
match element {
Some(x) => panic!(
"Repeated alias {} for {} and {}",
alias,
for_element.get_name(),
x
),
None => {
self.aliases
.insert(alias, for_element.get_name().to_string());
}
}
()
}
pub fn element_in_list(&self, element: &T) -> bool {
match self.aliases.get(element.get_name()) {
None => false,
Some(_) => true,
}
}
pub fn get(&self, index: &str) -> Result<&Rc<T>, LedgerError> {
match self.list.get(index) {
None => match self.aliases.get(index) {
None => Err(LedgerError::AliasNotInList(format!(
"{} {:?} not found",
std::any::type_name::<T>(),
index
))),
Some(x) => Ok(self.list.get(x).unwrap()),
},
Some(x) => Ok(x),
}
}
pub fn iter(&self) -> Iter<'_, String, Rc<T>> {
self.list.iter()
}
pub fn values(&self) -> Values<'_, String, Rc<T>> {
self.list.values()
}
pub fn len(&self) -> usize {
self.list.len()
}
pub fn len_alias(&self) -> usize {
self.aliases.len() + self.len()
}
}
impl<T: Clone> List<T> {
pub fn append(&mut self, other: &List<T>) {
self.list.extend(other.to_owned().list.into_iter());
self.aliases.extend(other.to_owned().aliases.into_iter());
}
}