Use custom serialization format

This commit is contained in:
Tobie Morgan Hitchcock 2023-03-31 23:36:07 +01:00
parent 1cb05c7b0a
commit 45094c76ce
16 changed files with 55 additions and 31 deletions

18
Cargo.lock generated
View file

@ -710,6 +710,17 @@ version = "3.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
[[package]]
name = "bung"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da8bcf29331f126c3b4f20a6698909d58004290723aac75e3eafab41ae3c2953"
dependencies = [
"byteorder",
"rmp",
"serde",
]
[[package]] [[package]]
name = "byteorder" name = "byteorder"
version = "1.4.3" version = "1.4.3"
@ -3769,6 +3780,7 @@ version = "1.0.0-beta.8"
dependencies = [ dependencies = [
"argon2", "argon2",
"base64 0.21.0", "base64 0.21.0",
"bung",
"bytes", "bytes",
"chrono", "chrono",
"clap", "clap",
@ -3815,6 +3827,7 @@ dependencies = [
"async-recursion", "async-recursion",
"bcrypt", "bcrypt",
"bigdecimal", "bigdecimal",
"bung",
"chrono", "chrono",
"dmp", "dmp",
"echodb", "echodb",
@ -3839,7 +3852,6 @@ dependencies = [
"rand 0.8.5", "rand 0.8.5",
"regex", "regex",
"reqwest", "reqwest",
"rmp-serde",
"rocksdb", "rocksdb",
"rquickjs", "rquickjs",
"rustls", "rustls",
@ -3870,9 +3882,9 @@ dependencies = [
[[package]] [[package]]
name = "surrealdb-derive" name = "surrealdb-derive"
version = "0.5.0" version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "552bb4f9eb49f493b14d79d989ea9ecb53ee8cee0aad529e289faca72fb78b14" checksum = "dfb39273220b1d4cd0936abb8d1e9ec0eb673e17044169cb4604345576b1e0ef"
dependencies = [ dependencies = [
"quote", "quote",
"syn 1.0.109", "syn 1.0.109",

View file

@ -27,6 +27,7 @@ codegen-units = 1
[dependencies] [dependencies]
argon2 = "0.5.0" argon2 = "0.5.0"
base64 = "0.21.0" base64 = "0.21.0"
bung = "0.1.0"
bytes = "1.4.0" bytes = "1.4.0"
chrono = { version = "0.4.24", features = ["serde"] } chrono = { version = "0.4.24", features = ["serde"] }
clap = { version = "3.2.23", features = ["env"] } clap = { version = "3.2.23", features = ["env"] }

View file

@ -56,9 +56,10 @@ ascii = { version = "0.3.2", package = "any_ascii" }
async-recursion = "1.0.4" async-recursion = "1.0.4"
bcrypt = "0.14.0" bcrypt = "0.14.0"
bigdecimal = { version = "0.3.0", features = ["serde", "string-only"] } bigdecimal = { version = "0.3.0", features = ["serde", "string-only"] }
bung = "0.1.0"
channel = { version = "1.8.0", package = "async-channel" } channel = { version = "1.8.0", package = "async-channel" }
chrono = { version = "0.4.24", features = ["serde"] } chrono = { version = "0.4.24", features = ["serde"] }
derive = { version = "0.5.0", package = "surrealdb-derive" } derive = { version = "0.6.0", package = "surrealdb-derive" }
dmp = "0.1.3" dmp = "0.1.3"
echodb = { version = "0.4.0", optional = true } echodb = { version = "0.4.0", optional = true }
executor = { version = "1.5.0", package = "async-executor" } executor = { version = "1.5.0", package = "async-executor" }
@ -74,7 +75,6 @@ js = { version = "0.1.7", package = "rquickjs", features = ["array-buffer", "bin
lexicmp = "0.1.0" lexicmp = "0.1.0"
log = "0.4.17" log = "0.4.17"
md-5 = "0.10.5" md-5 = "0.10.5"
msgpack = { version = "1.1.1", package = "rmp-serde" }
nanoid = "0.4.0" nanoid = "0.4.0"
native-tls = { version = "0.2.11", optional = true } native-tls = { version = "0.2.11", optional = true }
nom = { version = "7.1.3", features = ["alloc"] } nom = { version = "7.1.3", features = ["alloc"] }

View file

@ -104,7 +104,7 @@ impl Surreal<Client> {
pub(crate) fn default_headers() -> HeaderMap { pub(crate) fn default_headers() -> HeaderMap {
let mut headers = HeaderMap::new(); let mut headers = HeaderMap::new();
headers.insert(ACCEPT, HeaderValue::from_static("application/cork")); headers.insert(ACCEPT, HeaderValue::from_static("application/bung"));
headers headers
} }
@ -168,7 +168,7 @@ async fn submit_auth(request: RequestBuilder) -> Result<Value> {
let response = request.send().await?.error_for_status()?; let response = request.send().await?.error_for_status()?;
let bytes = response.bytes().await?; let bytes = response.bytes().await?;
let response: AuthResponse = let response: AuthResponse =
msgpack::from_slice(&bytes).map_err(|error| Error::ResponseFromBinary { bung::from_slice(&bytes).map_err(|error| Error::ResponseFromBinary {
binary: bytes.to_vec(), binary: bytes.to_vec(),
error, error,
})?; })?;
@ -180,7 +180,7 @@ async fn query(request: RequestBuilder) -> Result<QueryResponse> {
let response = request.send().await?.error_for_status()?; let response = request.send().await?.error_for_status()?;
let bytes = response.bytes().await?; let bytes = response.bytes().await?;
let responses: Vec<HttpQueryResponse> = let responses: Vec<HttpQueryResponse> =
msgpack::from_slice(&bytes).map_err(|error| Error::ResponseFromBinary { bung::from_slice(&bytes).map_err(|error| Error::ResponseFromBinary {
binary: bytes.to_vec(), binary: bytes.to_vec(),
error, error,
})?; })?;

View file

@ -422,7 +422,7 @@ impl Response {
trace!(target: LOG, "Received an unexpected text message; {text}"); trace!(target: LOG, "Received an unexpected text message; {text}");
Ok(None) Ok(None)
} }
Message::Binary(binary) => msgpack::from_slice(&binary).map(Some).map_err(|error| { Message::Binary(binary) => bung::from_slice(&binary).map(Some).map_err(|error| {
Error::ResponseFromBinary { Error::ResponseFromBinary {
binary, binary,
error, error,

View file

@ -405,7 +405,7 @@ impl Response {
trace!(target: LOG, "Received an unexpected text message; {text}"); trace!(target: LOG, "Received an unexpected text message; {text}");
Ok(None) Ok(None)
} }
Message::Binary(binary) => msgpack::from_slice(&binary).map(Some).map_err(|error| { Message::Binary(binary) => bung::from_slice(&binary).map(Some).map_err(|error| {
Error::ResponseFromBinary { Error::ResponseFromBinary {
binary, binary,
error, error,

View file

@ -98,7 +98,7 @@ pub enum Error {
#[error("Failed to deserialize a binary response: {error}")] #[error("Failed to deserialize a binary response: {error}")]
ResponseFromBinary { ResponseFromBinary {
binary: Vec<u8>, binary: Vec<u8>,
error: msgpack::decode::Error, error: bung::decode::Error,
}, },
/// Failed to serialize `sql::Value` to JSON string /// Failed to serialize `sql::Value` to JSON string

View file

@ -1,5 +1,5 @@
use crate::sql::idiom::Idiom; use crate::sql::idiom::Idiom;
use msgpack::encode::Error as SerdeError; use bung::encode::Error as SerdeError;
use serde::Serialize; use serde::Serialize;
use storekey::decode::Error as DecodeError; use storekey::decode::Error as DecodeError;
use storekey::encode::Error as EncodeError; use storekey::encode::Error as EncodeError;

View file

@ -1856,6 +1856,17 @@ mod tests {
assert_eq!(8, std::mem::size_of::<Box<crate::sql::expression::Expression>>()); assert_eq!(8, std::mem::size_of::<Box<crate::sql::expression::Expression>>());
} }
#[test]
fn check_serialize() {
assert_eq!(1, Value::None.to_vec().len());
assert_eq!(1, Value::Null.to_vec().len());
assert_eq!(1, Value::True.to_vec().len());
assert_eq!(1, Value::False.to_vec().len());
assert_eq!(7, Value::from("test").to_vec().len());
assert_eq!(17, Value::parse("{ hello: 'world' }").to_vec().len());
assert_eq!(24, Value::parse("{ compact: true, schema: 0 }").to_vec().len());
}
#[test] #[test]
fn serialize_deserialize() { fn serialize_deserialize() {
let val = Value::parse( let val = Value::parse(

View file

@ -45,7 +45,7 @@ async fn handler(
"application/cbor" => Ok(output::cbor(&res)), "application/cbor" => Ok(output::cbor(&res)),
"application/pack" => Ok(output::pack(&res)), "application/pack" => Ok(output::pack(&res)),
// Internal serialization // Internal serialization
"application/cork" => Ok(output::cork(&res)), "application/bung" => Ok(output::full(&res)),
// Return nothing // Return nothing
"application/octet-stream" => Ok(output::none()), "application/octet-stream" => Ok(output::none()),
// An incorrect content-type was requested // An incorrect content-type was requested

View file

@ -156,7 +156,7 @@ async fn select_all(
"application/cbor" => Ok(output::cbor(&res)), "application/cbor" => Ok(output::cbor(&res)),
"application/pack" => Ok(output::pack(&res)), "application/pack" => Ok(output::pack(&res)),
// Internal serialization // Internal serialization
"application/cork" => Ok(output::cork(&res)), "application/bung" => Ok(output::full(&res)),
// An incorrect content-type was requested // An incorrect content-type was requested
_ => Err(warp::reject::custom(Error::InvalidType)), _ => Err(warp::reject::custom(Error::InvalidType)),
}, },
@ -197,7 +197,7 @@ async fn create_all(
"application/cbor" => Ok(output::cbor(&res)), "application/cbor" => Ok(output::cbor(&res)),
"application/pack" => Ok(output::pack(&res)), "application/pack" => Ok(output::pack(&res)),
// Internal serialization // Internal serialization
"application/cork" => Ok(output::cork(&res)), "application/bung" => Ok(output::full(&res)),
// An incorrect content-type was requested // An incorrect content-type was requested
_ => Err(warp::reject::custom(Error::InvalidType)), _ => Err(warp::reject::custom(Error::InvalidType)),
}, },
@ -234,7 +234,7 @@ async fn delete_all(
"application/cbor" => Ok(output::cbor(&res)), "application/cbor" => Ok(output::cbor(&res)),
"application/pack" => Ok(output::pack(&res)), "application/pack" => Ok(output::pack(&res)),
// Internal serialization // Internal serialization
"application/cork" => Ok(output::cork(&res)), "application/bung" => Ok(output::full(&res)),
// An incorrect content-type was requested // An incorrect content-type was requested
_ => Err(warp::reject::custom(Error::InvalidType)), _ => Err(warp::reject::custom(Error::InvalidType)),
}, },
@ -277,7 +277,7 @@ async fn select_one(
"application/cbor" => Ok(output::cbor(&res)), "application/cbor" => Ok(output::cbor(&res)),
"application/pack" => Ok(output::pack(&res)), "application/pack" => Ok(output::pack(&res)),
// Internal serialization // Internal serialization
"application/cork" => Ok(output::cork(&res)), "application/bung" => Ok(output::full(&res)),
// An incorrect content-type was requested // An incorrect content-type was requested
_ => Err(warp::reject::custom(Error::InvalidType)), _ => Err(warp::reject::custom(Error::InvalidType)),
}, },
@ -325,7 +325,7 @@ async fn create_one(
"application/cbor" => Ok(output::cbor(&res)), "application/cbor" => Ok(output::cbor(&res)),
"application/pack" => Ok(output::pack(&res)), "application/pack" => Ok(output::pack(&res)),
// Internal serialization // Internal serialization
"application/cork" => Ok(output::cork(&res)), "application/bung" => Ok(output::full(&res)),
// An incorrect content-type was requested // An incorrect content-type was requested
_ => Err(warp::reject::custom(Error::InvalidType)), _ => Err(warp::reject::custom(Error::InvalidType)),
}, },
@ -376,7 +376,7 @@ async fn update_one(
"application/cbor" => Ok(output::cbor(&res)), "application/cbor" => Ok(output::cbor(&res)),
"application/pack" => Ok(output::pack(&res)), "application/pack" => Ok(output::pack(&res)),
// Internal serialization // Internal serialization
"application/cork" => Ok(output::cork(&res)), "application/bung" => Ok(output::full(&res)),
// An incorrect content-type was requested // An incorrect content-type was requested
_ => Err(warp::reject::custom(Error::InvalidType)), _ => Err(warp::reject::custom(Error::InvalidType)),
}, },
@ -427,7 +427,7 @@ async fn modify_one(
"application/cbor" => Ok(output::cbor(&res)), "application/cbor" => Ok(output::cbor(&res)),
"application/pack" => Ok(output::pack(&res)), "application/pack" => Ok(output::pack(&res)),
// Internal serialization // Internal serialization
"application/cork" => Ok(output::cork(&res)), "application/bung" => Ok(output::full(&res)),
// An incorrect content-type was requested // An incorrect content-type was requested
_ => Err(warp::reject::custom(Error::InvalidType)), _ => Err(warp::reject::custom(Error::InvalidType)),
}, },
@ -471,7 +471,7 @@ async fn delete_one(
"application/cbor" => Ok(output::cbor(&res)), "application/cbor" => Ok(output::cbor(&res)),
"application/pack" => Ok(output::pack(&res)), "application/pack" => Ok(output::pack(&res)),
// Internal serialization // Internal serialization
"application/cork" => Ok(output::cork(&res)), "application/bung" => Ok(output::full(&res)),
// An incorrect content-type was requested // An incorrect content-type was requested
_ => Err(warp::reject::custom(Error::InvalidType)), _ => Err(warp::reject::custom(Error::InvalidType)),
}, },

View file

@ -10,7 +10,7 @@ pub enum Output {
Json(Vec<u8>), // JSON Json(Vec<u8>), // JSON
Cbor(Vec<u8>), // CBOR Cbor(Vec<u8>), // CBOR
Pack(Vec<u8>), // MessagePack Pack(Vec<u8>), // MessagePack
Cork(Vec<u8>), // Full type serialization Full(Vec<u8>), // Full type serialization
} }
pub fn none() -> Output { pub fn none() -> Output {
@ -51,12 +51,12 @@ where
} }
} }
pub fn cork<T>(val: &T) -> Output pub fn full<T>(val: &T) -> Output
where where
T: Serialize, T: Serialize,
{ {
match serialize_internal(|| serde_pack::to_vec(val)) { match serialize_internal(|| bung::to_vec(val)) {
Ok(v) => Output::Cork(v), Ok(v) => Output::Full(v),
Err(_) => Output::Fail, Err(_) => Output::Fail,
} }
} }
@ -88,9 +88,9 @@ impl warp::Reply for Output {
res.headers_mut().insert(CONTENT_TYPE, con); res.headers_mut().insert(CONTENT_TYPE, con);
res res
} }
Output::Cork(v) => { Output::Full(v) => {
let mut res = warp::reply::Response::new(v.into()); let mut res = warp::reply::Response::new(v.into());
let con = HeaderValue::from_static("application/cork"); let con = HeaderValue::from_static("application/bung");
res.headers_mut().insert(CONTENT_TYPE, con); res.headers_mut().insert(CONTENT_TYPE, con);
res res
} }

View file

@ -64,7 +64,7 @@ async fn handler(
Some("application/cbor") => Ok(output::cbor(&Success::new(v))), Some("application/cbor") => Ok(output::cbor(&Success::new(v))),
Some("application/pack") => Ok(output::pack(&Success::new(v))), Some("application/pack") => Ok(output::pack(&Success::new(v))),
// Internal serialization // Internal serialization
Some("application/cork") => Ok(output::cork(&Success::new(v))), Some("application/bung") => Ok(output::full(&Success::new(v))),
// Text serialization // Text serialization
Some("text/plain") => Ok(output::text(v.unwrap_or_default())), Some("text/plain") => Ok(output::text(v.unwrap_or_default())),
// Return nothing // Return nothing

View file

@ -64,7 +64,7 @@ async fn handler(
Some("application/cbor") => Ok(output::cbor(&Success::new(v))), Some("application/cbor") => Ok(output::cbor(&Success::new(v))),
Some("application/pack") => Ok(output::pack(&Success::new(v))), Some("application/pack") => Ok(output::pack(&Success::new(v))),
// Internal serialization // Internal serialization
Some("application/cork") => Ok(output::cork(&Success::new(v))), Some("application/bung") => Ok(output::full(&Success::new(v))),
// Text serialization // Text serialization
Some("text/plain") => Ok(output::text(v.unwrap_or_default())), Some("text/plain") => Ok(output::text(v.unwrap_or_default())),
// Return nothing // Return nothing

View file

@ -58,7 +58,7 @@ async fn handler(
"application/cbor" => Ok(output::cbor(&res)), "application/cbor" => Ok(output::cbor(&res)),
"application/pack" => Ok(output::pack(&res)), "application/pack" => Ok(output::pack(&res)),
// Internal serialization // Internal serialization
"application/cork" => Ok(output::cork(&res)), "application/bung" => Ok(output::full(&res)),
// An incorrect content-type was requested // An incorrect content-type was requested
_ => Err(warp::reject::custom(Error::InvalidType)), _ => Err(warp::reject::custom(Error::InvalidType)),
}, },

View file

@ -49,7 +49,7 @@ impl<T: Serialize> Response<T> {
let _ = chn.send(res).await; let _ = chn.send(res).await;
} }
Output::Full => { Output::Full => {
let res = serialize_internal(|| serde_pack::to_vec(&self).unwrap()); let res = serialize_internal(|| bung::to_vec(&self).unwrap());
let res = Message::binary(res); let res = Message::binary(res);
let _ = chn.send(res).await; let _ = chn.send(res).await;
} }