asterix_parser/
asterix.rs1pub mod category;
2pub mod message;
3pub mod uap;
4pub mod uap_json;
5
6use std::collections::BTreeMap;
7use std::fs;
8use thiserror::Error;
9
10use self::category::{Category, CategoryIndex, CategoryKey};
11use self::uap::providers::Provider;
12use self::uap_json::errors::ParseError;
13use self::uap_json::loader::Loader;
14use self::uap_json::structures::{DataRecord, Edition};
15
16#[derive(Error, Debug)]
17pub enum ContextErrors {
18 #[error("Definition folder for UAPs could not be loaded")]
19 UAPDefinitionFolderCouldNotBeLoaded,
20 #[error("unknown error")]
21 Unknown,
22}
23
24pub struct DataBlock {
39 pub records: Vec<DataRecord>
40}
41
42type CategoryMap = BTreeMap<CategoryKey, Category>;
43type UapMap = BTreeMap<CategoryKey, DataRecord>;
44
45pub struct Context {
46 pub categories: CategoryMap,
48 pub uap_definitions: UapMap
49}
50
51impl Context {
52 const UAPS_FOLDER: &'static str = "./resources/uaps";
53
54 pub fn new() -> anyhow::Result<Context> {
55 let (categories, uap_defs) = Context::load()?;
56
57 Ok(Context {
58 categories: categories,
59 uap_definitions: uap_defs
60 })
61 }
62
63 fn find_uap_definition_files() -> anyhow::Result<Vec<String>> {
64 let uap_files = match fs::read_dir(Context::UAPS_FOLDER) {
65 Ok(read_dir) => {
66 let mut files = Vec::<String>::new();
67 for result in read_dir {
68 let path = match result {
69 Ok(dir_entry) => {
70 let filename =
71 match dir_entry.file_name().into_string() {
72 Ok(s) => s,
73 Err(_) => { return Err(ContextErrors::UAPDefinitionFolderCouldNotBeLoaded.into()); },
74 };
75
76 filename
77 },
78 Err(e) => { return Err(e.into()); },
79 };
80 files.push(path);
81 };
82 files
83 },
84 Err(e) => { return Err(e.into()); },
85 };
86
87 Ok(uap_files)
92 }
93
94 fn load() -> anyhow::Result<(CategoryMap, UapMap)> {
95 let mut categories = CategoryMap::new();
96 let mut uap_defs = UapMap::new();
97
98 let uap_files = Context::find_uap_definition_files()?;
99 for file in uap_files {
100 let filepath_and_name = format!("{}/{}", Context::UAPS_FOLDER, file);
101 let uap_definition = Loader::load(&filepath_and_name)?;
102 let category_index =
103 match CategoryIndex::from_u8(uap_definition.number) {
104 Some(i) => i,
105 None => { return Err(ParseError::OpenUapJsonDefinitionError.into()) }
106 };
107
108 let category =
109 Category::new(
110 CategoryKey {
111 index: category_index,
112 edition: uap_definition.edition.clone(),
113 provider: Provider::Standard
114 },
115 uap_definition.title.as_str());
116
117 categories.insert(category.key.clone(), category.clone());
118 uap_defs.insert(category.key, uap_definition);
119 }
120
121 Ok((categories, uap_defs))
122 }
123
124 pub fn find_definition(&self, category_key: CategoryKey) -> anyhow::Result<DataRecord> {
125 let mut uap_def_opt: Option<DataRecord> = None;
126
127 for uap in &self.uap_definitions {
128 if uap.0 == &category_key {
129 uap_def_opt = Some(uap.1.clone())
130 }
131 }
132
133 if uap_def_opt.is_none() {
134 return Err(ParseError::CategoryNotYetSupported {
135 category_code: format!("{}", category_key.index.as_string()),
136 edition: format!("{}.{}", category_key.edition.major, category_key.edition.minor),
137 provider: category_key.provider.as_ref().to_owned(),
138 }.into());
139 }
140
141 Ok(uap_def_opt.unwrap())
142 }
143
144 fn find_newest_edition_for_category(&self, cat_idx: &CategoryIndex) -> anyhow::Result<Edition> {
145 let uap_defs:&Vec<&CategoryKey> = &self.uap_definitions
146 .keys()
147 .into_iter()
148 .filter(|x| x.index == *cat_idx).collect::<Vec<&CategoryKey>>();
149
150 if uap_defs.is_empty() {
151 return Err(ParseError::CategoryUapDefinitionNotFound { category_code: cat_idx.as_string()}.into());
152 }
153
154 let uap_def = *uap_defs.into_iter().max().unwrap();
155
156 Ok(uap_def.edition.clone())
157 }
158
159
160}
161