bitsy_core/
lib.rs

1pub mod database;
2pub mod task;
3pub mod utils;
4
5pub use crate::database::{Database, DatabaseKey};
6pub use async_std::sync::{Arc, Mutex};
7pub use bitsy_utils::type_id;
8pub use bytes::Bytes;
9pub use nom::AsBytes;
10use serde::{Deserialize, Serialize};
11pub use serde_json::Value;
12use std::{
13    collections::HashMap,
14    hash::{Hash, Hasher},
15};
16use thiserror::Error;
17pub use url::Url;
18
19// pub type Extractor = fn(&Input) -> BitsyResult<Field>;
20pub struct Input(pub Bytes);
21
22impl Input {
23    pub fn new(s: &'static str) -> Self {
24        Self(Bytes::from(s.as_bytes()))
25    }
26}
27
28pub type BitsyResult<T> = Result<T, BitsyError>;
29
30pub mod prelude {
31    pub use super::{
32        task::Task, type_id, utils::values_to_bytes, Arc, AsBytes, BitsyResult, Bytes,
33        Database, DatabaseKey, Extractor, Extractors, Field, FieldMetadata, FieldType,
34        Input, Key, KeyType, Metadata, Mutex, Url, Value,
35    };
36}
37
38impl AsRef<str> for Input {
39    fn as_ref(&self) -> &str {
40        std::str::from_utf8(self.0.as_bytes()).expect("Bad input.")
41    }
42}
43
44impl From<&'static str> for Input {
45    fn from(value: &'static str) -> Self {
46        Self::new(value)
47    }
48}
49
50pub trait AsValue {
51    fn as_value(&self) -> Bytes;
52}
53
54impl AsValue for bool {
55    fn as_value(&self) -> Bytes {
56        match self {
57            true => Bytes::from("1"),
58            false => Bytes::from("0"),
59        }
60    }
61}
62
63impl AsValue for u64 {
64    fn as_value(&self) -> Bytes {
65        Bytes::from(u64::to_le_bytes(*self).to_vec())
66    }
67}
68
69impl AsValue for &'static str {
70    fn as_value(&self) -> Bytes {
71        Bytes::from(self.to_string())
72    }
73}
74
75#[derive(Debug, Error)]
76pub enum BitsyError {
77    #[error("ParseError: {0:#?}")]
78    ParseError(#[from] url::ParseError),
79    #[error("BincodeError: {0:#?}")]
80    BincodeError(#[from] bincode::Error),
81    #[error("Utf8Error: {0:#?}")]
82    Utf8Error(#[from] std::str::Utf8Error),
83}
84
85#[derive(Debug, Serialize, Deserialize, Default, Clone, Eq)]
86pub struct ValueMap {
87    items: HashMap<usize, Bytes>,
88}
89
90impl ValueMap {
91    pub fn from_values(v: Vec<Bytes>) -> Self {
92        Self {
93            items: HashMap::from_iter(
94                v.iter().map(|v| (type_id(v.as_bytes()), v.clone())),
95            ),
96        }
97    }
98}
99
100impl Hash for ValueMap {
101    fn hash<H: Hasher>(&self, state: &mut H) {
102        for (k, v) in self.items.iter() {
103            k.hash(state);
104            v.hash(state);
105        }
106    }
107}
108
109impl PartialEq for ValueMap {
110    fn eq(&self, other: &Self) -> bool {
111        for k in self.items.keys() {
112            if other.items.contains_key(k) {
113                return true;
114            }
115        }
116        false
117    }
118}
119
120pub enum KeyType {
121    Compressed,
122    Decompressed,
123}
124
125pub enum FieldType {
126    Compressed,
127    Decompressed,
128}
129
130#[derive(Debug, Serialize, Deserialize, Default, Clone, Eq, PartialEq, Hash)]
131pub struct FieldMetadata {
132    name: String,
133    key: String,
134    value_map: ValueMap,
135    type_id: usize,
136    description: String,
137}
138
139impl FieldMetadata {
140    pub fn new(name: &str, key: &str, values: Vec<Bytes>, description: &str) -> Self {
141        Self {
142            name: name.to_string(),
143            key: key.to_string(),
144            value_map: ValueMap::from_values(values),
145            type_id: type_id(key),
146            description: description.to_string(),
147        }
148    }
149}
150
151#[derive(Debug, Serialize, Deserialize, Default, Clone, Eq)]
152pub struct KeyMetadata {
153    field_meta: HashMap<String, FieldMetadata>,
154    type_id: usize,
155}
156
157impl Hash for KeyMetadata {
158    fn hash<H: Hasher>(&self, state: &mut H) {
159        self.type_id.hash(state);
160        for (k, v) in self.field_meta.iter() {
161            k.hash(state);
162            v.hash(state);
163        }
164    }
165}
166
167impl PartialEq for KeyMetadata {
168    fn eq(&self, other: &Self) -> bool {
169        self.type_id == other.type_id
170    }
171}
172
173impl KeyMetadata {
174    pub fn new() -> Self {
175        Self {
176            type_id: 0,
177            field_meta: HashMap::default(),
178        }
179    }
180
181    pub fn as_bytes(&self) -> BitsyResult<Bytes> {
182        Ok(Bytes::from(bincode::serialize(&self)?))
183    }
184
185    pub fn field(&mut self, f: FieldMetadata) -> &mut Self {
186        self.field_meta.insert(f.name.clone(), f);
187        self
188    }
189
190    pub fn build(&self) -> Self {
191        self.clone()
192    }
193
194    pub fn with_key_code(meta: Self, type_id: usize) -> Self {
195        Self {
196            field_meta: meta.field_meta,
197            type_id,
198        }
199    }
200}
201
202#[derive(Debug, Default, Serialize, Deserialize, Clone, Eq, PartialEq, Hash)]
203pub struct Field {
204    pub type_id: usize,
205    pub field_name: String,
206    pub value: Bytes,
207}
208
209impl Field {
210    pub fn new(field_name: &str, value: Bytes) -> Self {
211        Self {
212            type_id: type_id(field_name),
213            field_name: field_name.to_string(),
214            value,
215        }
216    }
217}
218
219pub trait Key {
220    const NAME: &'static str;
221    const TYPE_ID: usize;
222
223    type Item;
224    type Metadata;
225
226    fn build(&self) -> Self;
227    fn field(&mut self, f: Self::Item) -> &mut Self;
228    fn flatten(&self) -> Bytes;
229    fn get_metadata(&self) -> Self::Metadata;
230    fn metadata(&mut self, meta: KeyMetadata) -> &mut Self;
231    fn builder() -> Self;
232    fn type_id(&self) -> usize;
233    fn name(&self) -> &'static str;
234}
235
236pub struct Extractor {
237    #[allow(unused)]
238    key: String,
239    func: fn(&Input) -> BitsyResult<Field>,
240}
241
242impl Default for Extractor {
243    fn default() -> Self {
244        fn default_func(_input: &Input) -> BitsyResult<Field> {
245            Ok(Field::default())
246        }
247
248        Self {
249            key: String::default(),
250            func: default_func,
251        }
252    }
253}
254
255impl Extractor {
256    pub fn new(key: &str, func: fn(&Input) -> BitsyResult<Field>) -> Self {
257        Self {
258            key: key.to_string(),
259            func,
260        }
261    }
262
263    pub fn call(&self, input: &Input) -> BitsyResult<Field> {
264        (self.func)(input)
265    }
266}
267
268#[derive(Default)]
269pub struct Extractors {
270    pub items: HashMap<String, Extractor>,
271}
272
273impl Extractors {
274    pub fn new() -> Self {
275        Self {
276            items: HashMap::default(),
277        }
278    }
279
280    pub fn add(&mut self, key: &str, value: fn(&Input) -> BitsyResult<Field>) {
281        self.items
282            .insert(key.to_string(), Extractor::new(key, value));
283    }
284}
285
286#[derive(Default)]
287pub struct Metadata {
288    items: HashMap<usize, KeyMetadata>,
289}
290
291impl Metadata {
292    pub fn new() -> Self {
293        Self {
294            items: HashMap::default(),
295        }
296    }
297
298    pub fn insert(&mut self, ty_id: usize, meta: KeyMetadata) {
299        self.items.insert(ty_id, meta);
300    }
301
302    pub fn get(&self, ty_id: &usize) -> &KeyMetadata {
303        self.items.get(ty_id).unwrap()
304    }
305}