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
99
100
101
use crate::types::{Feed, Media, Post};
use crate::{Record, TypedValue, UntypedRecord};
use std::any::Any;
use std::collections::HashMap;
#[derive(Debug, Default)]
pub struct RecordMap {
records: HashMap<&'static str, HashMap<String, Box<dyn Any + Send>>>,
}
impl RecordMap {
pub fn from_untyped(records: Vec<UntypedRecord>) -> anyhow::Result<Self> {
let mut this = RecordMap::default();
this.insert_untyped_bulk(records)?;
Ok(this)
}
pub fn insert_untyped_bulk(&mut self, records: Vec<UntypedRecord>) -> anyhow::Result<()> {
for record in records.into_iter() {
match record.typ() {
Media::NAME => self.insert_untyped::<Media>(record)?,
Post::NAME => self.insert_untyped::<Post>(record)?,
Feed::NAME => self.insert_untyped::<Feed>(record)?,
_ => {}
}
}
Ok(())
}
pub fn insert_untyped<T: TypedValue>(&mut self, record: UntypedRecord) -> anyhow::Result<()> {
let record = record.into_typed::<T>()?;
self.insert(record);
Ok(())
}
pub fn insert<T: TypedValue>(&mut self, record: Record<T>) {
let entry = self.records.entry(T::NAME).or_insert_with(HashMap::new);
entry.insert(record.id().to_string(), Box::new(record));
}
pub fn get<T: TypedValue>(&self, id: &str) -> Option<&Record<T>> {
self.records
.get(T::NAME)
.and_then(|m| m.get(id))
.map(|boxed_record| boxed_record.downcast_ref().unwrap())
}
pub fn get_all<T: TypedValue>(&self) -> Option<impl Iterator<Item = &Record<T>>> {
if let Some(records) = self.records.get(T::NAME) {
let iter = records
.values()
.map(|boxed_record| boxed_record.downcast_ref::<Record<T>>().unwrap());
Some(iter)
} else {
None
}
}
pub fn into_iter<T: TypedValue>(&mut self) -> Option<impl Iterator<Item = Record<T>>> {
if let Some(records) = self.records.remove(T::NAME) {
let iter = records
.into_iter()
.map(|(_, boxed_record)| *boxed_record.downcast::<Record<T>>().unwrap());
Some(iter)
} else {
None
}
}
pub fn into_vec<T: TypedValue>(&mut self) -> Vec<Record<T>> {
let iter = self.into_iter();
iter.map(|iter| iter.collect()).unwrap_or_default()
}
pub fn into_hashmap<T: TypedValue>(&mut self) -> HashMap<String, Record<T>> {
self.into_vec::<T>()
.into_iter()
.map(|r| (r.guid().to_string(), r))
.collect()
}
pub fn get_mut<T: TypedValue>(&mut self, id: &str) -> Option<&mut Record<T>> {
self.records
.get_mut(T::NAME)
.and_then(|m| m.get_mut(id))
.map(|boxed_record| boxed_record.downcast_mut().unwrap())
}
}