pogo_masterfile/
masterfile.rs1use std::collections::HashMap;
6
7use pogo_masterfile_types::MasterfileEntry;
8
9use crate::GroupIndexes;
10use crate::error::Result;
11
12#[cfg(feature = "async")]
13use crate::builder::MasterfileBuilder;
14
15pub struct Masterfile {
16 pub(crate) entries: Vec<MasterfileEntry>,
17 pub(crate) by_id: HashMap<String, usize>,
18 pub(crate) groups: GroupIndexes,
19}
20
21impl Masterfile {
22 #[cfg(feature = "async")]
25 pub fn builder() -> MasterfileBuilder {
26 MasterfileBuilder::new()
27 }
28
29 #[cfg(feature = "async")]
31 pub async fn from_remote() -> Result<Self> {
32 Self::builder().fetch().await
33 }
34
35 pub fn from_json(json: &str) -> Result<Self> {
37 let entries = pogo_masterfile_types::parse_masterfile(json)?;
38 Ok(Self::from_entries(entries))
39 }
40
41 pub fn from_entries(entries: Vec<MasterfileEntry>) -> Self {
43 let by_id = entries
44 .iter()
45 .enumerate()
46 .map(|(i, e)| (e.template_id().to_string(), i))
47 .collect();
48 let groups = GroupIndexes::build(&entries);
49 Self {
50 entries,
51 by_id,
52 groups,
53 }
54 }
55
56 pub fn get_entry(&self, id: &str) -> Option<&MasterfileEntry> {
59 let &idx = self.by_id.get(id)?;
60 self.entries.get(idx)
61 }
62
63 pub fn has(&self, id: &str) -> bool {
64 self.by_id.contains_key(id)
65 }
66
67 pub fn entries(&self) -> &[MasterfileEntry] {
70 &self.entries
71 }
72
73 pub fn len(&self) -> usize {
74 self.entries.len()
75 }
76
77 pub fn is_empty(&self) -> bool {
78 self.entries.is_empty()
79 }
80
81 pub fn iter(&self) -> std::slice::Iter<'_, MasterfileEntry> {
82 self.entries.iter()
83 }
84
85 pub fn template_ids(&self) -> impl Iterator<Item = &str> + '_ {
86 self.entries.iter().map(MasterfileEntry::template_id)
87 }
88
89 #[cfg(feature = "async")]
92 pub async fn refresh(&mut self) -> Result<()> {
93 let fresh = Self::from_remote().await?;
94 *self = fresh;
95 Ok(())
96 }
97
98 pub fn update(&mut self, entries: Vec<MasterfileEntry>) {
99 *self = Self::from_entries(entries);
100 }
101}
102
103impl<'a> IntoIterator for &'a Masterfile {
105 type Item = &'a MasterfileEntry;
106 type IntoIter = std::slice::Iter<'a, MasterfileEntry>;
107 fn into_iter(self) -> Self::IntoIter {
108 self.iter()
109 }
110}