radish_database/
container.rs

1/* Copyright (c) 2020 Dmitry Shatilov <shatilov dot diman at gmail dot com>
2 * 
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU Affero General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * GNU Affero General Public License for more details.
12
13 * You should have received a copy of the GNU Affero General Public License
14 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
15 */
16
17use std::sync::Arc;
18use std::collections::VecDeque;
19
20use tokio::sync::Mutex;
21use indexmap::{IndexSet, IndexMap};
22
23type Key = super::Key;
24type Value = super::Value;
25
26#[derive(Debug)]
27pub struct ContainerImpl<Inner> {
28	pub inner: Inner,
29	pub expiration_time: Option<std::time::SystemTime>,
30}
31impl<Inner: Default> ContainerImpl<Inner> {
32	pub fn new() -> Self {
33		Self {
34			inner: Inner::default(),
35			expiration_time: None,
36		}
37	}
38}
39
40#[derive(Debug)]
41pub enum Container {
42	Set(ContainerImpl<IndexSet<Value>>),
43	List(ContainerImpl<VecDeque<Value>>),
44	Hash(ContainerImpl<IndexMap<Value, Value>>),
45	Strings(ContainerImpl<Vec<u8>>),
46}
47pub type ContainerPtr = Arc<Mutex<Container>>;
48pub type Containers = IndexMap<Key, ContainerPtr>;
49pub type ContainersPtr = Arc<Mutex<Containers>>;
50
51
52impl super::Storage {
53
54	pub fn extract(arg: Option<Value>) -> Result<Value, String> {
55		match arg {
56			Some(arg) => Ok(arg),
57			None => Err(format!("Not enough arguments")),
58		}
59	}
60
61	pub fn extract_buffer(arg: Option<Value>) -> Result<Vec<u8>, String> {
62		match Self::extract(arg)? {
63			Value::Buffer(k) => Ok(k),
64			_ => Err(format!("Unexpected buffer type")),
65		}
66	}
67
68	pub fn extract_string(arg: Option<Value>) -> Result<String, String> {
69		match String::from_utf8(Self::extract_buffer(arg)?) {
70			Ok(s) => Ok(s),
71			Err(err) => Err(format!("Failed to extract string: {}", err)),
72		}
73	}
74
75	pub fn extract_key(arg: Option<Value>) -> Result<Key, String> {
76		match Self::extract(arg)? {
77			Value::Buffer(k) => Ok(k),
78			_ => Err(format!("Unexpected key type")),
79		}
80	}
81
82	pub fn extract_integer(arg: Option<Value>) -> Result<i64, String> {
83		match Self::extract(arg)? {
84			Value::Integer(i) => Ok(i),
85			_ => Err(format!("{}", "Unexpected index type")),
86		}
87	}
88
89	pub fn extract_unsigned_integer(arg: Option<Value>) -> Result<u64, String> {
90		match Self::extract(arg)? {
91			Value::Integer(i) => Ok(i as u64),
92			_ => Err(format!("{}", "Unexpected index type")),
93		}
94	}
95
96	pub fn extract_float(arg: Option<Value>) -> Result<f64, String> {
97		match Self::extract(arg)? {
98			Value::Float(n) => Ok(f64::from_bits(n)),
99			_ => Err(format!("{}", "Unexpected index type")),
100		}
101	}
102
103	pub fn extract_index(arg: Option<Value>) -> Result<usize, String> {
104		match Self::extract(arg)? {
105			Value::Integer(i) => num::cast(i).ok_or(format!("Index is out of range: [0; {}]", usize::max_value())),
106			_ => Err(format!("{}", "Unexpected index type")),
107		}
108	}
109
110	pub fn extract_bit(arg: Option<Value>) -> Result<bool, String> {
111		match Self::extract(arg)? {
112			Value::Bool(b) => Ok(b),
113			Value::Integer(i) => match i {
114				0 => Ok(false),
115				1 => Ok(true),
116				_ => Err(format!("Unexpected bit value")),
117			},
118			_ => Err(format!("Unexpected bit type")),
119		}
120	}
121}
122