use crate::types::{Document, FieldType, Value};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
mod base64_serde {
use base64::{Engine as _, engine::general_purpose};
use serde::{self, Deserialize, Deserializer, Serializer};
pub fn serialize<S>(bytes: &Vec<u8>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
if serializer.is_human_readable() {
let base64 = general_purpose::STANDARD.encode(bytes);
serializer.serialize_str(&base64)
} else {
serializer.serialize_bytes(bytes)
}
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
where
D: Deserializer<'de>,
{
if deserializer.is_human_readable() {
let base64 = <String>::deserialize(deserializer)?;
general_purpose::STANDARD
.decode(&base64)
.map_err(serde::de::Error::custom)
} else {
<Vec<u8>>::deserialize(deserializer)
}
}
}
#[derive(Serialize, Deserialize, Debug)]
pub enum Request {
Get(String),
Put(String, #[serde(with = "base64_serde")] Vec<u8>),
Delete(String),
NewCollection {
name: String,
fields: Vec<(String, FieldType, bool)>,
},
Insert {
collection: String,
data: HashMap<String, Value>,
},
GetDocument { collection: String, id: String },
Query(crate::query::SimpleQueryBuilder),
BeginTransaction,
CommitTransaction(u64),
RollbackTransaction(u64),
}
#[derive(Serialize, Deserialize, Debug)]
pub enum Response {
Success(#[serde(with = "base64_serde_option")] Option<Vec<u8>>),
Document(Option<Document>),
Documents(Vec<Document>),
Message(String),
TransactionId(u64),
Done,
Error(String),
}
mod base64_serde_option {
use base64::{Engine as _, engine::general_purpose};
use serde::{self, Deserialize, Deserializer, Serializer};
pub fn serialize<S>(bytes: &Option<Vec<u8>>, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match bytes {
Some(b) => super::base64_serde::serialize(b, serializer),
None => serializer.serialize_none(),
}
}
pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Vec<u8>>, D::Error>
where
D: Deserializer<'de>,
{
let opt: Option<Vec<u8>> = if deserializer.is_human_readable() {
let base64: Option<String> = Option::deserialize(deserializer)?;
match base64 {
Some(s) => Some(
general_purpose::STANDARD
.decode(&s)
.map_err(serde::de::Error::custom)?,
),
None => None,
}
} else {
Option::deserialize(deserializer)?
};
Ok(opt)
}
}