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
19pub 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}