alex_db_lib/
value_record.rs

1use crate::error::Error;
2use chrono::{DateTime, Utc};
3use lazy_static::lazy_static;
4use regex::Regex;
5use serde::{Deserialize, Serialize};
6use std::{collections::VecDeque, str::FromStr};
7use utoipa::ToSchema;
8use uuid::Uuid;
9use validator::Validate;
10
11lazy_static! {
12    static ref VALID_KEY: Regex = Regex::new(r"^[a-zA-Z0-9._~!$&'()*+,;=:@/?-]+$").unwrap();
13}
14
15#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize, ToSchema)]
16#[serde(untagged)]
17pub enum Value {
18    Array(VecDeque<Value>),
19    Boolean(bool),
20    Integer(i64),
21    String(String),
22}
23
24impl FromStr for Value {
25    type Err = Error;
26
27    fn from_str(s: &str) -> Result<Self, Self::Err> {
28        let mut destination_value = match s.parse::<bool>() {
29            Err(_) => None,
30            Ok(value) => Some(Value::Boolean(value)),
31        };
32
33        if destination_value.is_none() {
34            destination_value = match s.parse::<i64>() {
35                Err(_) => None,
36                Ok(value) => Some(Value::Integer(value)),
37            };
38        }
39
40        if destination_value.is_none() {
41            let splitted_arguments = s.split("::").into_iter().collect::<Vec<&str>>();
42            if splitted_arguments.len() > 1 {
43                let mut splitted_argument_values = VecDeque::new();
44                for splitted_argument in splitted_arguments {
45                    let splitted_argument_value = Self::from_str(splitted_argument)?;
46                    splitted_argument_values.push_back(splitted_argument_value);
47                }
48                destination_value = Some(Value::Array(splitted_argument_values));
49            }
50        }
51
52        if destination_value.is_none() {
53            destination_value = Some(Value::String(s.to_string()));
54        }
55
56        let value = destination_value.ok_or(Error::ValueParse)?;
57
58        Ok(value)
59    }
60}
61
62#[derive(Clone, Debug, Deserialize, Serialize, ToSchema, Validate)]
63pub struct ValueAppend {
64    pub append: Value,
65}
66
67#[derive(Clone, Debug, Deserialize, Serialize, ToSchema, Validate)]
68pub struct ValueDecrement {
69    pub decrement: Option<i64>,
70}
71
72#[derive(Clone, Debug, Deserialize, Serialize, ToSchema, Validate)]
73pub struct ValueIncrement {
74    pub increment: Option<i64>,
75}
76
77#[derive(Clone, Debug, Deserialize, Serialize, ToSchema, Validate)]
78pub struct ValuePost {
79    #[validate(regex = "VALID_KEY")]
80    pub key: String,
81    pub ttl: Option<i64>,
82    pub value: Value,
83}
84
85#[derive(Clone, Debug, Deserialize, Serialize, ToSchema, Validate)]
86pub struct ValuePopBack {
87    pub pop_back: Option<usize>,
88}
89
90#[derive(Clone, Debug, Deserialize, Serialize, ToSchema, Validate)]
91pub struct ValuePopFront {
92    pub pop_front: Option<usize>,
93}
94
95#[derive(Clone, Debug, Deserialize, Serialize, ToSchema, Validate)]
96pub struct ValuePrepend {
97    pub prepend: Value,
98}
99
100#[derive(Clone, Debug, Deserialize, Serialize, ToSchema, Validate)]
101pub struct ValuePut {
102    pub ttl: Option<i64>,
103    pub value: Value,
104}
105
106#[derive(Clone, Debug, Deserialize, Serialize)]
107pub struct ValueRecord {
108    pub id: Uuid,
109    pub key: String,
110    pub value: Value,
111    pub created_at: DateTime<Utc>,
112    pub delete_at: Option<DateTime<Utc>>,
113    pub updated_at: DateTime<Utc>,
114}
115
116impl ValueRecord {
117    pub fn new(
118        id: Uuid,
119        key: &str,
120        value: &Value,
121        created_at: DateTime<Utc>,
122        delete_at: Option<DateTime<Utc>>,
123        updated_at: DateTime<Utc>,
124    ) -> Self {
125        Self {
126            id,
127            key: key.into(),
128            value: value.clone(),
129            created_at,
130            delete_at,
131            updated_at,
132        }
133    }
134}
135
136#[derive(Clone, Debug, Deserialize, Serialize, ToSchema)]
137pub struct ValueResponse {
138    pub key: String,
139    pub value: Value,
140}
141
142impl From<ValueRecord> for ValueResponse {
143    fn from(db_record: ValueRecord) -> Self {
144        ValueResponse {
145            key: db_record.key,
146            value: db_record.value,
147        }
148    }
149}