Implement to_value for sql::Value ()

`sql::Value` is an integral part of `surrealdb`. It's the internal type used by our storage layer. Because of this, we do a lot of converting between this type and native Rust types. Currently this conversion is done through `JSON` using the `serde_json` crate because we do not have our own custom data format implementation. This works because `SQL` is a superset of `JSON`.  This, however, means that this conversion is lossy and can cause surprises in some cases. For example expecting record IDs to be deserialized into a `String` instead of its corresponding Rust native type.

This change implements a custom data format around `sql::Value` and introduces a `to_value` function that facilitates that conversion.
This commit is contained in:
Rushmore Mushambi 2023-03-30 12:41:44 +02:00 committed by GitHub
parent 86f768e996
commit 3e80aa9914
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
143 changed files with 9130 additions and 291 deletions

View file

@ -27,7 +27,7 @@ jobs:
- name: Run cargo test
run: |
(&>/dev/null cargo run -- start --log trace --user root --pass root memory &)
(&>/dev/null cargo run --no-default-features -F storage-mem -- start --log trace --user root --pass root memory &)
cargo test --workspace --features protocol-ws,protocol-http,kv-rocksdb
lint:

View file

@ -24,7 +24,7 @@ jobs:
- name: Run cargo test
run: |
(&>/dev/null cargo run -- start --log trace --user root --pass root memory &)
(&>/dev/null cargo run --no-default-features -F storage-mem -- start --log trace --user root --pass root memory &)
cargo test --workspace --features protocol-ws,protocol-http,kv-rocksdb
lint:

View file

@ -44,6 +44,7 @@ use serde::{Deserialize, Serialize};
use serde_json::json;
use std::borrow::Cow;
use surrealdb::sql;
use surrealdb::sql::Thing;
use surrealdb::Surreal;
use surrealdb::engine::remote::ws::Ws;
use surrealdb::opt::auth::Root;
@ -57,7 +58,7 @@ struct Name {
#[derive(Serialize, Deserialize)]
struct Person {
#[serde(skip_serializing)]
id: Option<String>,
id: Option<Thing>,
title: Cow<'static, str>,
name: Name,
marketing: bool,
@ -107,7 +108,7 @@ async fn main() -> surrealdb::Result<()> {
})
.await?;
assert_eq!(jaime.id.unwrap(), "person:jaime");
assert_eq!(jaime.id.unwrap().to_string(), "person:jaime");
// Update a person record with a specific ID
jaime = db

View file

@ -2,12 +2,14 @@ use serde::Deserialize;
use serde::Serialize;
use surrealdb::engine::remote::ws::Ws;
use surrealdb::opt::auth::Root;
use surrealdb::sql::thing;
use surrealdb::sql::Thing;
use surrealdb::Surreal;
#[derive(Debug, Serialize, Deserialize)]
#[allow(dead_code)]
struct User {
id: String,
id: Thing,
name: String,
company: String,
}
@ -29,7 +31,7 @@ async fn main() -> surrealdb::Result<()> {
let mut results = db
.query(sql)
.bind(User {
id: "john".to_owned(),
id: thing("user:john")?,
name: "John Doe".to_owned(),
company: "ACME Corporation".to_owned(),
})

View file

@ -1,6 +1,7 @@
use serde::Deserialize;
use surrealdb::engine::remote::ws::Ws;
use surrealdb::opt::auth::Root;
use surrealdb::sql::Thing;
use surrealdb::Surreal;
const ACCOUNT: &str = "account";
@ -8,7 +9,7 @@ const ACCOUNT: &str = "account";
#[derive(Debug, Deserialize)]
#[allow(dead_code)]
struct Account {
id: String,
id: Thing,
balance: String,
}

View file

@ -203,7 +203,7 @@ impl Connection for Any {
Box::pin(async move {
let response = receiver.into_recv_async().await?;
match response? {
DbResponse::Other(value) => from_value(value),
DbResponse::Other(value) => from_value(value).map_err(Into::into),
DbResponse::Query(..) => unreachable!(),
}
})

View file

@ -158,7 +158,7 @@ impl Connection for Any {
Box::pin(async move {
let response = receiver.into_recv_async().await?;
match response? {
DbResponse::Other(value) => from_value(value),
DbResponse::Other(value) => from_value(value).map_err(Into::into),
DbResponse::Query(..) => unreachable!(),
}
})

View file

@ -91,7 +91,7 @@ impl Connection for Db {
Box::pin(async move {
let response = rx.into_recv_async().await?;
match response? {
DbResponse::Other(value) => from_value(value),
DbResponse::Other(value) => from_value(value).map_err(Into::into),
DbResponse::Query(..) => unreachable!(),
}
})

View file

@ -92,7 +92,7 @@ impl Connection for Db {
let response = rx.into_recv_async().await?;
trace!(target: LOG, "Response {response:?}");
match response? {
DbResponse::Other(value) => from_value(value),
DbResponse::Other(value) => from_value(value).map_err(Into::into),
DbResponse::Query(..) => unreachable!(),
}
})

View file

@ -17,13 +17,14 @@ use crate::api::engine::select_statement;
use crate::api::engine::update_statement;
use crate::api::err::Error;
use crate::api::method::query::QueryResult;
use crate::api::opt::from_json;
use crate::api::opt::from_value;
use crate::api::Connect;
use crate::api::Response as QueryResponse;
use crate::api::Result;
use crate::api::Surreal;
use crate::opt::IntoEndpoint;
use crate::sql;
use crate::sql::to_value;
use crate::sql::Array;
use crate::sql::Strand;
use crate::sql::Value;
@ -102,6 +103,7 @@ impl Surreal<Client> {
}
}
#[derive(Debug)]
enum Auth {
Basic {
user: String,
@ -153,17 +155,9 @@ async fn submit_auth(request: RequestBuilder) -> Result<Value> {
let response = request.send().await?.error_for_status()?;
let text = response.text().await?;
info!(target: LOG, "Response {text}");
let response: AuthResponse = match serde_json::from_str(&text) {
Ok(response) => response,
Err(error) => {
return Err(Error::FromJsonString {
string: text,
error: error.to_string(),
}
.into());
}
};
Ok(response.token.filter(|token| token != "NONE").into())
let value = sql::json(&text)?;
let response: AuthResponse = from_value(value)?;
Ok(response.token.into())
}
async fn query(request: RequestBuilder) -> Result<QueryResponse> {
@ -171,22 +165,14 @@ async fn query(request: RequestBuilder) -> Result<QueryResponse> {
let response = request.send().await?.error_for_status()?;
let text = response.text().await?;
info!(target: LOG, "Response {text}");
let responses: Vec<HttpQueryResponse> = match serde_json::from_str(&text) {
Ok(vec) => vec,
Err(error) => {
return Err(Error::FromJsonString {
string: text,
error: error.to_string(),
}
.into());
}
};
let value = sql::json(&text)?;
let responses: Vec<HttpQueryResponse> = from_value(value)?;
let mut map = IndexMap::<usize, QueryResult>::with_capacity(responses.len());
for (index, response) in responses.into_iter().enumerate() {
match response.status {
Status::Ok => {
if let Some(value) = response.result {
match from_json(value) {
match to_value(value)? {
Value::Array(Array(array)) => map.insert(index, Ok(array)),
Value::None | Value::Null => map.insert(index, Ok(vec![])),
value => map.insert(index, Ok(vec![value])),
@ -350,16 +336,7 @@ async fn router(
Method::Signin => {
let path = base_url.join(Method::Signin.as_str())?;
let credentials = match &mut params[..] {
[credentials] => match serde_json::to_string(credentials) {
Ok(json) => json,
Err(error) => {
return Err(Error::ToJsonString {
value: mem::take(credentials),
error: error.to_string(),
}
.into());
}
},
[credentials] => credentials.to_string(),
_ => unreachable!(),
};
let request = client.post(path).headers(headers.clone()).auth(auth).body(credentials);
@ -385,16 +362,7 @@ async fn router(
Method::Signup => {
let path = base_url.join(Method::Signup.as_str())?;
let credentials = match &mut params[..] {
[credentials] => match serde_json::to_string(credentials) {
Ok(json) => json,
Err(error) => {
return Err(Error::ToJsonString {
value: mem::take(credentials),
error: error.to_string(),
}
.into());
}
},
[credentials] => credentials.to_string(),
_ => unreachable!(),
};
let request = client.post(path).headers(headers.clone()).auth(auth).body(credentials);

View file

@ -116,7 +116,7 @@ impl Connection for Client {
let response = rx.into_recv_async().await?;
trace!(target: LOG, "Response {response:?}");
match response? {
DbResponse::Other(value) => from_value(value),
DbResponse::Other(value) => from_value(value).map_err(Into::into),
DbResponse::Query(..) => unreachable!(),
}
})

View file

@ -100,7 +100,7 @@ impl Connection for Client {
let response = rx.into_recv_async().await?;
trace!(target: LOG, "Response {response:?}");
match response? {
DbResponse::Other(value) => from_value(value),
DbResponse::Other(value) => from_value(value).map_err(Into::into),
DbResponse::Query(..) => unreachable!(),
}
})

View file

@ -172,7 +172,7 @@ impl Connection for Client {
Box::pin(async move {
let response = rx.into_recv_async().await?;
match response? {
DbResponse::Other(value) => from_value(value),
DbResponse::Other(value) => from_value(value).map_err(Into::into),
DbResponse::Query(..) => unreachable!(),
}
})

View file

@ -126,7 +126,7 @@ impl Connection for Client {
Box::pin(async move {
let response = rx.into_recv_async().await?;
match response? {
DbResponse::Other(value) => from_value(value),
DbResponse::Other(value) => from_value(value).map_err(Into::into),
DbResponse::Query(..) => unreachable!(),
}
})

View file

@ -1,15 +1,14 @@
use crate::api::conn::Method;
use crate::api::conn::Param;
use crate::api::conn::Router;
use crate::api::opt::from_json;
use crate::api::opt::Range;
use crate::api::opt::Resource;
use crate::api::Connection;
use crate::api::Result;
use crate::sql::to_value;
use crate::sql::Id;
use serde::de::DeserializeOwned;
use serde::Serialize;
use serde_json::json;
use std::future::Future;
use std::future::IntoFuture;
use std::marker::PhantomData;
@ -39,8 +38,8 @@ where
Some(range) => resource.with_range(range)?,
None => resource.into(),
};
let content = json!(self.content);
let param = Param::new(vec![param, from_json(content)]);
let content = to_value(self.content)?;
let param = Param::new(vec![param, content]);
Ok((self.router?, self.method, param))
}
}

View file

@ -1,15 +1,14 @@
use crate::api::conn::Method;
use crate::api::conn::Param;
use crate::api::conn::Router;
use crate::api::opt::from_json;
use crate::api::opt::Range;
use crate::api::opt::Resource;
use crate::api::Connection;
use crate::api::Result;
use crate::sql::to_value;
use crate::sql::Id;
use serde::de::DeserializeOwned;
use serde::Serialize;
use serde_json::json;
use std::future::Future;
use std::future::IntoFuture;
use std::marker::PhantomData;
@ -36,8 +35,8 @@ where
Some(range) => resource.with_range(range)?,
None => resource.into(),
};
let content = json!(self.content);
let param = Param::new(vec![param, from_json(content)]);
let content = to_value(self.content)?;
let param = Param::new(vec![param, content]);
Ok((self.router?, Method::Merge, param))
}
}

View file

@ -67,16 +67,15 @@ use crate::api::opt;
use crate::api::opt::auth;
use crate::api::opt::auth::Credentials;
use crate::api::opt::auth::Jwt;
use crate::api::opt::from_json;
use crate::api::opt::IntoEndpoint;
use crate::api::Connect;
use crate::api::Connection;
use crate::api::ExtractRouter;
use crate::api::Surreal;
use crate::sql::to_value;
use crate::sql::Uuid;
use once_cell::sync::OnceCell;
use serde::Serialize;
use serde_json::json;
use std::marker::PhantomData;
use std::path::Path;
@ -300,7 +299,7 @@ where
Set {
router: self.router.extract(),
key: key.into(),
value: Ok(from_json(json!(value))),
value: to_value(value).map_err(Into::into),
}
}
@ -402,7 +401,7 @@ where
pub fn signup<R>(&self, credentials: impl Credentials<auth::Signup, R>) -> Signup<C, R> {
Signup {
router: self.router.extract(),
credentials: Ok(from_json(json!(credentials))),
credentials: to_value(credentials).map_err(Into::into),
response_type: PhantomData,
}
}
@ -525,7 +524,7 @@ where
pub fn signin<R>(&self, credentials: impl Credentials<auth::Signin, R>) -> Signin<C, R> {
Signin {
router: self.router.extract(),
credentials: Ok(from_json(json!(credentials))),
credentials: to_value(credentials).map_err(Into::into),
response_type: PhantomData,
}
}

View file

@ -14,6 +14,7 @@ use std::future::Future;
use std::future::IntoFuture;
use std::marker::PhantomData;
use std::pin::Pin;
use std::result::Result as StdResult;
/// A patch future
#[derive(Debug)]
@ -21,7 +22,7 @@ pub struct Patch<'r, C: Connection, R> {
pub(super) router: Result<&'r Router<C>>,
pub(super) resource: Result<Resource>,
pub(super) range: Option<Range<Id>>,
pub(super) patches: Vec<Value>,
pub(super) patches: Vec<StdResult<Value, crate::err::Error>>,
pub(super) response_type: PhantomData<R>,
}
@ -51,7 +52,11 @@ where
Some(range) => resource.with_range(range)?,
None => resource.into(),
};
let patches = Value::Array(Array(self.patches));
let mut patches = Vec::with_capacity(self.patches.len());
for result in self.patches {
patches.push(result?);
}
let patches = Value::Array(Array(patches));
let mut conn = Client::new(Method::Patch);
conn.execute(self.router?, Param::new(vec![param, patches])).await
})

View file

@ -3,10 +3,10 @@ use crate::api::conn::Param;
use crate::api::conn::Router;
use crate::api::err::Error;
use crate::api::opt;
use crate::api::opt::from_json;
use crate::api::Connection;
use crate::api::Result;
use crate::sql;
use crate::sql::to_value;
use crate::sql::Array;
use crate::sql::Object;
use crate::sql::Statement;
@ -16,7 +16,6 @@ use crate::sql::Value;
use indexmap::IndexMap;
use serde::de::DeserializeOwned;
use serde::Serialize;
use serde_json::json;
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::future::Future;
@ -106,18 +105,24 @@ where
/// ```
pub fn bind(mut self, bindings: impl Serialize) -> Self {
if let Ok(current) = &mut self.bindings {
let mut bindings = from_json(json!(bindings));
if let Value::Array(Array(array)) = &mut bindings {
if let [Value::Strand(Strand(key)), value] = &mut array[..] {
let mut map = BTreeMap::new();
map.insert(mem::take(key), mem::take(value));
bindings = map.into();
match to_value(bindings) {
Ok(mut bindings) => {
if let Value::Array(Array(array)) = &mut bindings {
if let [Value::Strand(Strand(key)), value] = &mut array[..] {
let mut map = BTreeMap::new();
map.insert(mem::take(key), mem::take(value));
bindings = map.into();
}
}
match &mut bindings {
Value::Object(Object(map)) => current.append(map),
_ => {
self.bindings = Err(Error::InvalidBindings(bindings).into());
}
}
}
}
match &mut bindings {
Value::Object(Object(map)) => current.append(map),
_ => {
self.bindings = Err(Error::InvalidBindings(bindings).into());
Err(error) => {
self.bindings = Err(error.into());
}
}
}
@ -394,14 +399,15 @@ mod tests {
let summary = Summary {
title: "Lorem Ipsum".to_owned(),
};
let value = to_value(summary.clone()).unwrap();
let mut response = Response(to_map(vec![Ok(vec![from_json(json!(summary.clone()))])]));
let mut response = Response(to_map(vec![Ok(vec![value.clone()])]));
let Some(title): Option<String> = response.take("title").unwrap() else {
panic!("title not found");
};
assert_eq!(title, summary.title);
let mut response = Response(to_map(vec![Ok(vec![from_json(json!(summary.clone()))])]));
let mut response = Response(to_map(vec![Ok(vec![value])]));
let vec: Vec<String> = response.take("title").unwrap();
assert_eq!(vec, vec![summary.title]);
@ -409,8 +415,9 @@ mod tests {
title: "Lorem Ipsum".to_owned(),
body: "Lorem Ipsum Lorem Ipsum".to_owned(),
};
let value = to_value(article.clone()).unwrap();
let mut response = Response(to_map(vec![Ok(vec![from_json(json!(article.clone()))])]));
let mut response = Response(to_map(vec![Ok(vec![value.clone()])]));
let Some(title): Option<String> = response.take("title").unwrap() else {
panic!("title not found");
};
@ -420,7 +427,7 @@ mod tests {
};
assert_eq!(body, article.body);
let mut response = Response(to_map(vec![Ok(vec![from_json(json!(article.clone()))])]));
let mut response = Response(to_map(vec![Ok(vec![value])]));
let vec: Vec<String> = response.take("title").unwrap();
assert_eq!(vec, vec![article.title]);
}

View file

@ -123,7 +123,7 @@ impl Connection for Client {
Box::pin(async move {
let result = rx.into_recv_async().await.unwrap();
match result.unwrap() {
DbResponse::Other(value) => from_value(value),
DbResponse::Other(value) => from_value(value).map_err(Into::into),
DbResponse::Query(..) => unreachable!(),
}
})

View file

@ -1,16 +1,15 @@
use super::types::Credentials;
use super::types::Root;
use super::types::User;
use crate::api::conn::DbResponse;
use crate::api::conn::Method;
use crate::api::conn::Route;
use crate::api::opt::from_json;
use crate::api::opt::from_value;
use crate::api::Response as QueryResponse;
use crate::sql::to_value;
use crate::sql::Array;
use crate::sql::Value;
use flume::Receiver;
use futures::StreamExt;
use serde_json::json;
use std::mem;
pub(super) fn mock(route_rx: Receiver<Option<Route>>) {
@ -51,15 +50,12 @@ pub(super) fn mock(route_rx: Receiver<Option<Route>>) {
_ => unreachable!(),
},
Method::Signup | Method::Signin => match &mut params[..] {
[credentials] => {
let credentials: Credentials = from_value(mem::take(credentials)).unwrap();
match credentials {
Credentials::Root {
..
} => Ok(DbResponse::Other(Value::None)),
_ => Ok(DbResponse::Other("jwt".to_owned().into())),
}
}
[credentials] => match from_value(mem::take(credentials)) {
Ok(Root {
..
}) => Ok(DbResponse::Other(Value::None)),
_ => Ok(DbResponse::Other("jwt".to_owned().into())),
},
_ => unreachable!(),
},
Method::Set => match &params[..] {
@ -71,12 +67,12 @@ pub(super) fn mock(route_rx: Receiver<Option<Route>>) {
_ => unreachable!(),
},
Method::Create => match &params[..] {
[_] => Ok(DbResponse::Other(from_json(json!(User::default())))),
[_] => Ok(DbResponse::Other(to_value(User::default()).unwrap())),
[_, user] => Ok(DbResponse::Other(user.clone())),
_ => unreachable!(),
},
Method::Select => match &params[..] {
[Value::Thing(..)] => Ok(DbResponse::Other(from_json(json!(User::default())))),
[Value::Thing(..)] => Ok(DbResponse::Other(to_value(User::default()).unwrap())),
[Value::Table(..) | Value::Array(..) | Value::Range(..)] => {
Ok(DbResponse::Other(Value::Array(Array(Vec::new()))))
}
@ -84,7 +80,7 @@ pub(super) fn mock(route_rx: Receiver<Option<Route>>) {
},
Method::Update | Method::Merge | Method::Patch => match &params[..] {
[Value::Thing(..)] | [Value::Thing(..), _] => {
Ok(DbResponse::Other(from_json(json!(User::default()))))
Ok(DbResponse::Other(to_value(User::default()).unwrap()))
}
[Value::Table(..) | Value::Array(..) | Value::Range(..)]
| [Value::Table(..) | Value::Array(..) | Value::Range(..), _] => {

View file

@ -10,28 +10,10 @@ pub struct User {
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(untagged)]
pub enum Credentials {
Database {
ns: String,
db: String,
user: String,
pass: String,
},
Namespace {
ns: String,
user: String,
pass: String,
},
Root {
user: String,
pass: String,
},
Scope {
ns: String,
db: String,
sc: String,
},
#[serde(deny_unknown_fields)]
pub struct Root {
user: String,
pass: String,
}
#[derive(Debug, Serialize, Deserialize)]

View file

@ -9,14 +9,14 @@ mod strict;
mod tls;
use crate::api::err::Error;
use crate::api::Result;
use crate::sql;
use crate::sql::serde::serialize_internal;
use crate::sql::to_value;
use crate::sql::Thing;
use crate::sql::Value;
use dmp::Diff;
use serde::de::DeserializeOwned;
use serde::Serialize;
use serde_json::json;
use serde_json::Map;
use serde_json::Value as JsonValue;
pub use endpoint::*;
@ -59,7 +59,7 @@ enum InnerOp<'a, T> {
///
/// [JSON Patch]: https://jsonpatch.com/
#[derive(Debug)]
pub struct PatchOp(pub(crate) Value);
pub struct PatchOp(pub(crate) Result<Value, crate::err::Error>);
impl PatchOp {
/// Adds a value to an object or inserts it into an array.
@ -80,11 +80,10 @@ impl PatchOp {
where
T: Serialize,
{
let value = from_json(json!(InnerOp::Add {
Self(to_value(InnerOp::Add {
path,
value
}));
Self(value)
value,
}))
}
/// Removes a value from an object or array.
@ -107,10 +106,9 @@ impl PatchOp {
/// ```
#[must_use]
pub fn remove(path: &str) -> Self {
let value = from_json(json!(UnitOp::Remove {
path
}));
Self(value)
Self(to_value(UnitOp::Remove {
path,
}))
}
/// Replaces a value.
@ -129,53 +127,143 @@ impl PatchOp {
where
T: Serialize,
{
let value = from_json(json!(InnerOp::Replace {
Self(to_value(InnerOp::Replace {
path,
value
}));
Self(value)
value,
}))
}
/// Changes a value
#[must_use]
pub fn change(path: &str, diff: Diff) -> Self {
let value = from_json(json!(UnitOp::Change {
Self(to_value(UnitOp::Change {
path,
value: diff.text,
}));
Self(value)
}))
}
}
fn into_json(value: Value) -> serde_json::Result<JsonValue> {
use crate::sql;
use crate::sql::Number;
use serde_json::Error;
#[derive(Serialize)]
struct Array(Vec<JsonValue>);
impl TryFrom<sql::Array> for Array {
type Error = Error;
fn try_from(arr: sql::Array) -> Result<Self, Self::Error> {
let mut vec = Vec::with_capacity(arr.0.len());
for value in arr.0 {
vec.push(into_json(value)?);
}
Ok(Self(vec))
}
}
#[derive(Serialize)]
struct Object(Map<String, JsonValue>);
impl TryFrom<sql::Object> for Object {
type Error = Error;
fn try_from(obj: sql::Object) -> Result<Self, Self::Error> {
let mut map = Map::with_capacity(obj.0.len());
for (key, value) in obj.0 {
map.insert(key.to_owned(), into_json(value)?);
}
Ok(Self(map))
}
}
#[derive(Serialize)]
enum Id {
Number(i64),
String(String),
Array(Array),
Object(Object),
}
impl TryFrom<sql::Id> for Id {
type Error = Error;
fn try_from(id: sql::Id) -> Result<Self, Self::Error> {
use sql::Id::*;
Ok(match id {
Number(n) => Id::Number(n),
String(s) => Id::String(s),
Array(arr) => Id::Array(arr.try_into()?),
Object(obj) => Id::Object(obj.try_into()?),
})
}
}
#[derive(Serialize)]
struct Thing {
tb: String,
id: Id,
}
impl TryFrom<sql::Thing> for Thing {
type Error = Error;
fn try_from(thing: sql::Thing) -> Result<Self, Self::Error> {
Ok(Self {
tb: thing.tb,
id: thing.id.try_into()?,
})
}
}
match value {
Value::None | Value::Null => Ok(JsonValue::Null),
Value::False => Ok(false.into()),
Value::True => Ok(true.into()),
Value::Number(Number::Int(n)) => Ok(n.into()),
Value::Number(Number::Float(n)) => Ok(n.into()),
Value::Number(Number::Decimal(n)) => serde_json::to_value(n),
Value::Strand(strand) => Ok(strand.0.into()),
Value::Duration(d) => serde_json::to_value(d),
Value::Datetime(d) => serde_json::to_value(d),
Value::Uuid(uuid) => serde_json::to_value(uuid),
Value::Array(arr) => Ok(JsonValue::Array(Array::try_from(arr)?.0)),
Value::Object(obj) => Ok(JsonValue::Object(Object::try_from(obj)?.0)),
Value::Geometry(geometry) => serde_json::to_value(geometry),
Value::Param(param) => serde_json::to_value(param),
Value::Idiom(idiom) => serde_json::to_value(idiom),
Value::Table(table) => serde_json::to_value(table),
Value::Thing(thing) => serde_json::to_value(thing),
Value::Model(model) => serde_json::to_value(model),
Value::Regex(regex) => serde_json::to_value(regex),
Value::Block(block) => serde_json::to_value(block),
Value::Range(range) => serde_json::to_value(range),
Value::Edges(edges) => serde_json::to_value(edges),
Value::Future(future) => serde_json::to_value(future),
Value::Constant(constant) => serde_json::to_value(constant),
Value::Function(function) => serde_json::to_value(function),
Value::Subquery(subquery) => serde_json::to_value(subquery),
Value::Expression(expression) => serde_json::to_value(expression),
}
}
/// Deserializes a value `T` from `SurrealDB` [`Value`]
pub(crate) fn from_value<T>(value: sql::Value) -> Result<T>
pub(crate) fn from_value<T>(value: Value) -> Result<T, Error>
where
T: DeserializeOwned,
{
let bytes = match msgpack::to_vec(&value) {
Ok(bytes) => bytes,
let json = match serialize_internal(|| into_json(value.clone())) {
Ok(json) => json,
Err(error) => {
return Err(Error::FromValue {
value,
error: error.to_string(),
}
.into());
})
}
};
match msgpack::from_slice(&bytes) {
Ok(response) => Ok(response),
Err(error) => Err(Error::FromValue {
value,
error: error.to_string(),
}
.into()),
}
}
pub(crate) fn from_json(json: JsonValue) -> sql::Value {
match sql::json(&json.to_string()) {
Ok(value) => value,
// It shouldn't get to this as `JsonValue` will always produce valid JSON
Err(_) => unreachable!(),
}
serde_json::from_value(json).map_err(|error| Error::FromValue {
value,
error: error.to_string(),
})
}

View file

@ -206,7 +206,7 @@ where
[] => Ok(None),
[value] => {
let value = mem::take(value);
from_value(value)
from_value(value).map_err(Into::into)
}
_ => Err(Error::LossyTake(QueryResponse(mem::take(map))).into()),
};
@ -257,7 +257,7 @@ where
let Some(value) = object.remove(key) else {
return Ok(None);
};
from_value(value)
from_value(value).map_err(Into::into)
}
_ => Ok(None),
}
@ -275,7 +275,7 @@ where
return Ok(vec![]);
}
};
from_value(vec.into())
from_value(vec.into()).map_err(Into::into)
}
}
@ -306,7 +306,7 @@ where
}
}
}
from_value(vec.into())
from_value(vec.into()).map_err(Into::into)
}
}

View file

@ -4,6 +4,8 @@ use serde::ser::SerializeStruct;
use serde::Serialize;
use std::time::Duration;
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Response";
/// The return value when running a query set on the database.
#[derive(Debug)]
pub struct Response {
@ -29,14 +31,14 @@ impl Serialize for Response {
{
match &self.result {
Ok(v) => {
let mut val = serializer.serialize_struct("Response", 3)?;
let mut val = serializer.serialize_struct(TOKEN, 3)?;
val.serialize_field("time", self.speed().as_str())?;
val.serialize_field("status", "OK")?;
val.serialize_field("result", v)?;
val.end()
}
Err(e) => {
let mut val = serializer.serialize_struct("Response", 3)?;
let mut val = serializer.serialize_struct(TOKEN, 3)?;
val.serialize_field("time", self.speed().as_str())?;
val.serialize_field("status", "ERR")?;
val.serialize_field("detail", e)?;

View file

@ -21,6 +21,8 @@ use std::ops;
use std::ops::Deref;
use std::ops::DerefMut;
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Array";
#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Deserialize, Hash)]
pub struct Array(pub Vec<Value>);
@ -163,9 +165,9 @@ impl Serialize for Array {
S: serde::Serializer,
{
if is_internal_serialization() {
serializer.serialize_newtype_struct("Array", &self.0)
serializer.serialize_newtype_struct(TOKEN, &self.0)
} else {
serializer.serialize_some(&self.0)
serializer.serialize_some(&self.to_string())
}
}
}

View file

@ -7,6 +7,7 @@ use crate::sql::comment::{comment, mightbespace};
use crate::sql::common::colons;
use crate::sql::error::IResult;
use crate::sql::fmt::{is_pretty, pretty_indent, Fmt, Pretty};
use crate::sql::serde::is_internal_serialization;
use crate::sql::statements::create::{create, CreateStatement};
use crate::sql::statements::delete::{delete, DeleteStatement};
use crate::sql::statements::ifelse::{ifelse, IfelseStatement};
@ -28,7 +29,9 @@ use std::cmp::Ordering;
use std::fmt::{self, Display, Formatter, Write};
use std::ops::Deref;
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Block";
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Deserialize, Hash)]
pub struct Block(pub Vec<Entry>);
impl Deref for Block {
@ -154,6 +157,19 @@ impl Display for Block {
}
}
impl Serialize for Block {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if is_internal_serialization() {
serializer.serialize_newtype_struct(TOKEN, &self.0)
} else {
serializer.serialize_none()
}
}
}
pub fn block(i: &str) -> IResult<&str, Block> {
let (i, _) = char('{')(i)?;
let (i, _) = mightbespace(i)?;

View file

@ -12,6 +12,8 @@ use nom::combinator::map;
use serde::{Deserialize, Serialize};
use std::fmt;
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Constant";
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Deserialize, Store, Hash)]
pub enum Constant {
MathE,
@ -101,25 +103,25 @@ impl Serialize for Constant {
{
if is_internal_serialization() {
match self {
Self::MathE => s.serialize_unit_variant("Constant", 0, "MathE"),
Self::MathFrac1Pi => s.serialize_unit_variant("Constant", 1, "MathFrac1Pi"),
Self::MathFrac1Sqrt2 => s.serialize_unit_variant("Constant", 2, "MathFrac1Sqrt2"),
Self::MathFrac2Pi => s.serialize_unit_variant("Constant", 3, "MathFrac2Pi"),
Self::MathFrac2SqrtPi => s.serialize_unit_variant("Constant", 4, "MathFrac2SqrtPi"),
Self::MathFracPi2 => s.serialize_unit_variant("Constant", 5, "MathFracPi2"),
Self::MathFracPi3 => s.serialize_unit_variant("Constant", 6, "MathFracPi3"),
Self::MathFracPi4 => s.serialize_unit_variant("Constant", 7, "MathFracPi4"),
Self::MathFracPi6 => s.serialize_unit_variant("Constant", 8, "MathFracPi6"),
Self::MathFracPi8 => s.serialize_unit_variant("Constant", 9, "MathFracPi8"),
Self::MathLn10 => s.serialize_unit_variant("Constant", 10, "MathLn10"),
Self::MathLn2 => s.serialize_unit_variant("Constant", 11, "MathLn2"),
Self::MathLog102 => s.serialize_unit_variant("Constant", 12, "MathLog102"),
Self::MathLog10E => s.serialize_unit_variant("Constant", 13, "MathLog10E"),
Self::MathLog210 => s.serialize_unit_variant("Constant", 14, "MathLog210"),
Self::MathLog2E => s.serialize_unit_variant("Constant", 15, "MathLog2E"),
Self::MathPi => s.serialize_unit_variant("Constant", 16, "MathPi"),
Self::MathSqrt2 => s.serialize_unit_variant("Constant", 17, "MathSqrt2"),
Self::MathTau => s.serialize_unit_variant("Constant", 18, "MathTau"),
Self::MathE => s.serialize_unit_variant(TOKEN, 0, "MathE"),
Self::MathFrac1Pi => s.serialize_unit_variant(TOKEN, 1, "MathFrac1Pi"),
Self::MathFrac1Sqrt2 => s.serialize_unit_variant(TOKEN, 2, "MathFrac1Sqrt2"),
Self::MathFrac2Pi => s.serialize_unit_variant(TOKEN, 3, "MathFrac2Pi"),
Self::MathFrac2SqrtPi => s.serialize_unit_variant(TOKEN, 4, "MathFrac2SqrtPi"),
Self::MathFracPi2 => s.serialize_unit_variant(TOKEN, 5, "MathFracPi2"),
Self::MathFracPi3 => s.serialize_unit_variant(TOKEN, 6, "MathFracPi3"),
Self::MathFracPi4 => s.serialize_unit_variant(TOKEN, 7, "MathFracPi4"),
Self::MathFracPi6 => s.serialize_unit_variant(TOKEN, 8, "MathFracPi6"),
Self::MathFracPi8 => s.serialize_unit_variant(TOKEN, 9, "MathFracPi8"),
Self::MathLn10 => s.serialize_unit_variant(TOKEN, 10, "MathLn10"),
Self::MathLn2 => s.serialize_unit_variant(TOKEN, 11, "MathLn2"),
Self::MathLog102 => s.serialize_unit_variant(TOKEN, 12, "MathLog102"),
Self::MathLog10E => s.serialize_unit_variant(TOKEN, 13, "MathLog10E"),
Self::MathLog210 => s.serialize_unit_variant(TOKEN, 14, "MathLog210"),
Self::MathLog2E => s.serialize_unit_variant(TOKEN, 15, "MathLog2E"),
Self::MathPi => s.serialize_unit_variant(TOKEN, 16, "MathPi"),
Self::MathSqrt2 => s.serialize_unit_variant(TOKEN, 17, "MathSqrt2"),
Self::MathTau => s.serialize_unit_variant(TOKEN, 18, "MathTau"),
}
} else {
match self {

View file

@ -17,6 +17,8 @@ use std::ops;
use std::ops::Deref;
use std::str;
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Datetime";
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Deserialize, Hash)]
pub struct Datetime(pub DateTime<Utc>);
@ -73,9 +75,9 @@ impl Serialize for Datetime {
S: serde::Serializer,
{
if is_internal_serialization() {
serializer.serialize_newtype_struct("Datetime", &self.0)
serializer.serialize_newtype_struct(TOKEN, &self.0)
} else {
serializer.serialize_some(&self.0)
serializer.serialize_some(&self.to_string())
}
}
}

View file

@ -21,6 +21,8 @@ static SECONDS_PER_HOUR: u64 = 60 * SECONDS_PER_MINUTE;
static SECONDS_PER_MINUTE: u64 = 60;
static NANOSECONDS_PER_MILLISECOND: u32 = 1000000;
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Duration";
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Deserialize, Hash)]
pub struct Duration(pub time::Duration);
@ -161,7 +163,7 @@ impl Serialize for Duration {
S: serde::Serializer,
{
if is_internal_serialization() {
serializer.serialize_newtype_struct("Duration", &self.0)
serializer.serialize_newtype_struct(TOKEN, &self.0)
} else {
serializer.serialize_some(&self.to_string())
}

View file

@ -1,15 +1,19 @@
use crate::sql::comment::mightbespace;
use crate::sql::dir::{dir, Dir};
use crate::sql::error::IResult;
use crate::sql::serde::is_internal_serialization;
use crate::sql::table::{table, tables, Tables};
use crate::sql::thing::{thing, Thing};
use nom::branch::alt;
use nom::character::complete::char;
use nom::combinator::map;
use serde::ser::SerializeStruct;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Edges";
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Deserialize, Hash)]
pub struct Edges {
pub dir: Dir,
pub from: Thing,
@ -26,6 +30,23 @@ impl fmt::Display for Edges {
}
}
impl Serialize for Edges {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if is_internal_serialization() {
let mut val = serializer.serialize_struct(TOKEN, 3)?;
val.serialize_field("dir", &self.dir)?;
val.serialize_field("from", &self.from)?;
val.serialize_field("what", &self.what)?;
val.end()
} else {
serializer.serialize_none()
}
}
}
pub fn edges(i: &str) -> IResult<&str, Edges> {
let (i, from) = thing(i)?;
let (i, dir) = dir(i)?;

View file

@ -5,12 +5,16 @@ use crate::err::Error;
use crate::fnc;
use crate::sql::error::IResult;
use crate::sql::operator::{operator, Operator};
use crate::sql::serde::is_internal_serialization;
use crate::sql::value::{single, value, Value};
use serde::ser::SerializeStruct;
use serde::{Deserialize, Serialize};
use std::fmt;
use std::str;
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Expression";
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Deserialize, Hash)]
pub struct Expression {
pub l: Value,
pub o: Operator,
@ -135,6 +139,23 @@ impl fmt::Display for Expression {
}
}
impl Serialize for Expression {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if is_internal_serialization() {
let mut val = serializer.serialize_struct(TOKEN, 3)?;
val.serialize_field("l", &self.l)?;
val.serialize_field("o", &self.o)?;
val.serialize_field("r", &self.r)?;
val.end()
} else {
serializer.serialize_none()
}
}
}
pub fn expression(i: &str) -> IResult<&str, Expression> {
let (i, l) = single(i)?;
let (i, o) = operator(i)?;

View file

@ -10,6 +10,7 @@ use crate::sql::error::IResult;
use crate::sql::fmt::Fmt;
use crate::sql::idiom::Idiom;
use crate::sql::script::{script as func, Script};
use crate::sql::serde::is_internal_serialization;
use crate::sql::value::{single, value, Value};
use async_recursion::async_recursion;
use futures::future::try_join_all;
@ -18,11 +19,14 @@ use nom::bytes::complete::tag;
use nom::bytes::complete::take_while1;
use nom::character::complete::char;
use nom::multi::separated_list0;
use serde::ser::SerializeTupleVariant;
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
use std::fmt;
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Function";
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Hash)]
pub enum Function {
Cast(String, Value),
Normal(String, Vec<Value>),
@ -216,6 +220,47 @@ impl fmt::Display for Function {
}
}
impl Serialize for Function {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if is_internal_serialization() {
match self {
Self::Cast(s, e) => {
let mut serializer = serializer.serialize_tuple_variant(TOKEN, 0, "Cast", 2)?;
serializer.serialize_field(s)?;
serializer.serialize_field(e)?;
serializer.end()
}
Self::Normal(s, e) => {
let mut serializer =
serializer.serialize_tuple_variant(TOKEN, 1, "Normal", 2)?;
serializer.serialize_field(s)?;
serializer.serialize_field(e)?;
serializer.end()
}
Self::Custom(s, e) => {
let mut serializer =
serializer.serialize_tuple_variant(TOKEN, 2, "Custom", 2)?;
serializer.serialize_field(s)?;
serializer.serialize_field(e)?;
serializer.end()
}
Self::Script(s, e) => {
let mut serializer =
serializer.serialize_tuple_variant(TOKEN, 3, "Script", 2)?;
serializer.serialize_field(s)?;
serializer.serialize_field(e)?;
serializer.end()
}
}
} else {
serializer.serialize_none()
}
}
}
pub fn function(i: &str) -> IResult<&str, Function> {
alt((normal, custom, script, cast))(i)
}

View file

@ -5,13 +5,16 @@ use crate::err::Error;
use crate::sql::block::{block, Block};
use crate::sql::comment::mightbespace;
use crate::sql::error::IResult;
use crate::sql::serde::is_internal_serialization;
use crate::sql::value::Value;
use nom::bytes::complete::tag;
use nom::character::complete::char;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Future";
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Deserialize, Hash)]
pub struct Future(pub Block);
impl From<Value> for Future {
@ -44,6 +47,19 @@ impl fmt::Display for Future {
}
}
impl Serialize for Future {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if is_internal_serialization() {
serializer.serialize_newtype_struct(TOKEN, &self.0)
} else {
serializer.serialize_none()
}
}
}
pub fn future(i: &str) -> IResult<&str, Future> {
let (i, _) = char('<')(i)?;
let (i, _) = tag("future")(i)?;

View file

@ -24,6 +24,8 @@ use std::cmp::Ordering;
use std::iter::{once, FromIterator};
use std::{fmt, hash};
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Geometry";
const SINGLE: char = '\'';
const DOUBLE: char = '\"';
@ -471,15 +473,13 @@ impl Serialize for Geometry {
{
if is_internal_serialization() {
match self {
Self::Point(v) => s.serialize_newtype_variant("Geometry", 0, "Point", v),
Self::Line(v) => s.serialize_newtype_variant("Geometry", 1, "Line", v),
Self::Polygon(v) => s.serialize_newtype_variant("Geometry", 2, "Polygon", v),
Self::MultiPoint(v) => s.serialize_newtype_variant("Geometry", 3, "MultiPoint", v),
Self::MultiLine(v) => s.serialize_newtype_variant("Geometry", 4, "MultiLine", v),
Self::MultiPolygon(v) => {
s.serialize_newtype_variant("Geometry", 5, "MultiPolygon", v)
}
Self::Collection(v) => s.serialize_newtype_variant("Geometry", 6, "Collection", v),
Self::Point(v) => s.serialize_newtype_variant(TOKEN, 0, "Point", v),
Self::Line(v) => s.serialize_newtype_variant(TOKEN, 1, "Line", v),
Self::Polygon(v) => s.serialize_newtype_variant(TOKEN, 2, "Polygon", v),
Self::MultiPoint(v) => s.serialize_newtype_variant(TOKEN, 3, "MultiPoint", v),
Self::MultiLine(v) => s.serialize_newtype_variant(TOKEN, 4, "MultiLine", v),
Self::MultiPolygon(v) => s.serialize_newtype_variant(TOKEN, 5, "MultiPolygon", v),
Self::Collection(v) => s.serialize_newtype_variant(TOKEN, 6, "Collection", v),
}
} else {
match self {

View file

@ -20,7 +20,7 @@ use serde::{Deserialize, Serialize};
use std::fmt::{self, Display, Formatter};
use ulid::Ulid;
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize, Hash)]
pub enum Id {
Number(i64),
String(String),

View file

@ -8,6 +8,7 @@ use crate::sql::fmt::{fmt_separated_by, Fmt};
use crate::sql::part::Next;
use crate::sql::part::{all, field, first, graph, index, last, part, thing, Part};
use crate::sql::paths::{ID, IN, OUT};
use crate::sql::serde::is_internal_serialization;
use crate::sql::value::Value;
use md5::Digest;
use md5::Md5;
@ -19,6 +20,8 @@ use std::fmt::{self, Display, Formatter};
use std::ops::Deref;
use std::str;
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Idiom";
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
pub struct Idioms(pub Vec<Idiom>);
@ -40,7 +43,7 @@ pub fn locals(i: &str) -> IResult<&str, Idioms> {
Ok((i, Idioms(v)))
}
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Deserialize, Hash)]
pub struct Idiom(pub Vec<Part>);
impl Deref for Idiom {
@ -162,6 +165,19 @@ impl fmt::Display for Idiom {
}
}
impl Serialize for Idiom {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if is_internal_serialization() {
serializer.serialize_newtype_struct(TOKEN, &self.0)
} else {
serializer.serialize_none()
}
}
}
/// Used in a DEFINE FIELD and DEFINE INDEX clauses
pub fn local(i: &str) -> IResult<&str, Idiom> {
let (i, p) = first(i)?;

View file

@ -129,3 +129,5 @@ pub use self::value::Value;
pub use self::value::Values;
pub use self::version::Version;
pub use self::view::View;
pub(crate) use self::value::serde::to_value;

View file

@ -3,12 +3,16 @@ use crate::sql::error::IResult;
use crate::sql::escape::escape_ident;
use crate::sql::id::Id;
use crate::sql::ident::ident_raw;
use crate::sql::serde::is_internal_serialization;
use crate::sql::thing::Thing;
use nom::branch::alt;
use nom::character::complete::char;
use serde::ser::SerializeTupleVariant;
use serde::{Deserialize, Serialize};
use std::fmt;
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Model";
pub struct IntoIter {
model: Model,
index: u64,
@ -44,7 +48,7 @@ impl Iterator for IntoIter {
}
}
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Deserialize, Hash)]
pub enum Model {
Count(String, u64),
Range(String, u64, u64),
@ -74,6 +78,35 @@ impl fmt::Display for Model {
}
}
impl Serialize for Model {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if is_internal_serialization() {
match self {
Self::Count(tb, c) => {
let mut serializer =
serializer.serialize_tuple_variant(TOKEN, 0, "Count", 2)?;
serializer.serialize_field(tb)?;
serializer.serialize_field(c)?;
serializer.end()
}
Self::Range(tb, b, e) => {
let mut serializer =
serializer.serialize_tuple_variant(TOKEN, 1, "Range", 3)?;
serializer.serialize_field(tb)?;
serializer.serialize_field(b)?;
serializer.serialize_field(e)?;
serializer.end()
}
}
} else {
serializer.serialize_none()
}
}
}
pub fn model(i: &str) -> IResult<&str, Model> {
alt((model_count, model_range))(i)
}

View file

@ -19,6 +19,8 @@ use std::iter::Sum;
use std::ops;
use std::str::FromStr;
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Number";
#[derive(Clone, Debug, Deserialize)]
pub enum Number {
Int(i64),
@ -175,9 +177,9 @@ impl Serialize for Number {
{
if is_internal_serialization() {
match self {
Number::Int(v) => s.serialize_newtype_variant("Number", 0, "Int", v),
Number::Float(v) => s.serialize_newtype_variant("Number", 1, "Float", v),
Number::Decimal(v) => s.serialize_newtype_variant("Number", 2, "Decimal", v),
Number::Int(v) => s.serialize_newtype_variant(TOKEN, 0, "Int", v),
Number::Float(v) => s.serialize_newtype_variant(TOKEN, 1, "Float", v),
Number::Decimal(v) => s.serialize_newtype_variant(TOKEN, 2, "Decimal", v),
}
} else {
match self {

View file

@ -26,6 +26,8 @@ use std::fmt::{self, Display, Formatter, Write};
use std::ops::Deref;
use std::ops::DerefMut;
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Object";
#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Deserialize, Hash)]
pub struct Object(pub BTreeMap<String, Value>);
@ -170,7 +172,7 @@ impl Serialize for Object {
S: serde::Serializer,
{
if is_internal_serialization() {
serializer.serialize_newtype_struct("Object", &self.0)
serializer.serialize_newtype_struct(TOKEN, &self.0)
} else {
let mut map = serializer.serialize_map(Some(self.len()))?;
for (ref k, ref v) in &self.0 {

View file

@ -7,6 +7,7 @@ use crate::sql::idiom;
use crate::sql::idiom::Idiom;
use crate::sql::part::Next;
use crate::sql::part::Part;
use crate::sql::serde::is_internal_serialization;
use crate::sql::value::Value;
use nom::character::complete::char;
use serde::{Deserialize, Serialize};
@ -14,7 +15,9 @@ use std::fmt;
use std::ops::Deref;
use std::str;
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Param";
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Deserialize, Hash)]
pub struct Param(pub Idiom);
impl From<Idiom> for Param {
@ -96,6 +99,19 @@ impl fmt::Display for Param {
}
}
impl Serialize for Param {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if is_internal_serialization() {
serializer.serialize_newtype_struct(TOKEN, &self.0)
} else {
serializer.serialize_none()
}
}
}
pub fn param(i: &str) -> IResult<&str, Param> {
let (i, _) = char('$')(i)?;
let (i, v) = idiom::param(i)?;

View file

@ -5,6 +5,7 @@ use crate::err::Error;
use crate::sql::error::IResult;
use crate::sql::id::{id, Id};
use crate::sql::ident::ident_raw;
use crate::sql::serde::is_internal_serialization;
use crate::sql::value::Value;
use nom::branch::alt;
use nom::character::complete::char;
@ -12,12 +13,15 @@ use nom::combinator::map;
use nom::combinator::opt;
use nom::sequence::preceded;
use nom::sequence::terminated;
use serde::ser::SerializeStruct;
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
use std::fmt;
use std::ops::Bound;
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Range";
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Hash)]
pub struct Range {
pub tb: String,
pub beg: Bound<Id>,
@ -122,6 +126,23 @@ impl fmt::Display for Range {
}
}
impl Serialize for Range {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if is_internal_serialization() {
let mut val = serializer.serialize_struct(TOKEN, 3)?;
val.serialize_field("tb", &self.tb)?;
val.serialize_field("beg", &self.beg)?;
val.serialize_field("end", &self.end)?;
val.end()
} else {
serializer.serialize_none()
}
}
}
pub fn range(i: &str) -> IResult<&str, Range> {
let (i, tb) = ident_raw(i)?;
let (i, _) = char(':')(i)?;

View file

@ -1,4 +1,5 @@
use crate::sql::error::IResult;
use crate::sql::serde::is_internal_serialization;
use nom::bytes::complete::escaped;
use nom::bytes::complete::is_not;
use nom::character::complete::anychar;
@ -8,8 +9,10 @@ use std::fmt;
use std::ops::Deref;
use std::str;
#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
pub struct Regex(String);
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Regex";
#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Deserialize, Hash)]
pub struct Regex(pub(super) String);
impl From<&str> for Regex {
fn from(r: &str) -> Self {
@ -36,6 +39,19 @@ impl Regex {
}
}
impl Serialize for Regex {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if is_internal_serialization() {
serializer.serialize_newtype_struct(TOKEN, &self.0)
} else {
serializer.serialize_none()
}
}
}
pub fn regex(i: &str) -> IResult<&str, Regex> {
let (i, _) = char('/')(i)?;
let (i, v) = escaped(is_not("\\/"), '\\', anychar)(i)?;

View file

@ -15,6 +15,8 @@ use std::ops;
use std::ops::Deref;
use std::str;
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Strand";
const SINGLE: char = '\'';
const SINGLE_ESC: &str = r#"\'"#;
@ -78,9 +80,9 @@ impl Serialize for Strand {
S: serde::Serializer,
{
if is_internal_serialization() {
serializer.serialize_newtype_struct("Strand", &self.0)
serializer.serialize_newtype_struct(TOKEN, &self.0)
} else {
serializer.serialize_some(&self.0)
serializer.serialize_some(&self.to_string())
}
}
}

View file

@ -5,6 +5,7 @@ use crate::err::Error;
use crate::sql::comment::mightbespace;
use crate::sql::ending::subquery as ending;
use crate::sql::error::IResult;
use crate::sql::serde::is_internal_serialization;
use crate::sql::statements::create::{create, CreateStatement};
use crate::sql::statements::delete::{delete, DeleteStatement};
use crate::sql::statements::ifelse::{ifelse, IfelseStatement};
@ -21,7 +22,9 @@ use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
use std::fmt::{self, Display, Formatter};
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash)]
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Subquery";
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Hash)]
pub enum Subquery {
Value(Value),
Ifelse(IfelseStatement),
@ -222,6 +225,29 @@ impl Display for Subquery {
}
}
impl Serialize for Subquery {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if is_internal_serialization() {
match self {
Self::Value(v) => serializer.serialize_newtype_variant(TOKEN, 0, "Value", v),
Self::Ifelse(v) => serializer.serialize_newtype_variant(TOKEN, 1, "Ifelse", v),
Self::Output(v) => serializer.serialize_newtype_variant(TOKEN, 2, "Output", v),
Self::Select(v) => serializer.serialize_newtype_variant(TOKEN, 3, "Select", v),
Self::Create(v) => serializer.serialize_newtype_variant(TOKEN, 4, "Create", v),
Self::Update(v) => serializer.serialize_newtype_variant(TOKEN, 5, "Update", v),
Self::Delete(v) => serializer.serialize_newtype_variant(TOKEN, 6, "Delete", v),
Self::Relate(v) => serializer.serialize_newtype_variant(TOKEN, 7, "Relate", v),
Self::Insert(v) => serializer.serialize_newtype_variant(TOKEN, 8, "Insert", v),
}
} else {
serializer.serialize_none()
}
}
}
pub fn subquery(i: &str) -> IResult<&str, Subquery> {
alt((subquery_ifelse, subquery_other, subquery_value))(i)
}

View file

@ -4,6 +4,7 @@ use crate::sql::escape::escape_ident;
use crate::sql::fmt::Fmt;
use crate::sql::id::Id;
use crate::sql::ident::{ident_raw, Ident};
use crate::sql::serde::is_internal_serialization;
use crate::sql::thing::Thing;
use nom::multi::separated_list1;
use serde::{Deserialize, Serialize};
@ -11,6 +12,8 @@ use std::fmt::{self, Display, Formatter};
use std::ops::Deref;
use std::str;
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Table";
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
pub struct Tables(pub Vec<Table>);
@ -38,7 +41,7 @@ pub fn tables(i: &str) -> IResult<&str, Tables> {
Ok((i, Tables(v)))
}
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Serialize, Deserialize, Hash)]
#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Deserialize, Hash)]
pub struct Table(pub String);
impl From<String> for Table {
@ -81,6 +84,19 @@ impl Display for Table {
}
}
impl Serialize for Table {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
if is_internal_serialization() {
serializer.serialize_newtype_struct(TOKEN, &self.0)
} else {
serializer.serialize_none()
}
}
}
pub fn table(i: &str) -> IResult<&str, Table> {
let (i, v) = ident_raw(i)?;
Ok((i, Table(v)))

View file

@ -18,7 +18,9 @@ use serde::ser::SerializeStruct;
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Deserialize, Store, Hash)]
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Thing";
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Deserialize, Store, Hash)]
pub struct Thing {
pub tb: String,
pub id: Id,
@ -79,7 +81,7 @@ impl Serialize for Thing {
S: serde::Serializer,
{
if is_internal_serialization() {
let mut val = serializer.serialize_struct("Thing", 2)?;
let mut val = serializer.serialize_struct(TOKEN, 2)?;
val.serialize_field("tb", &self.tb)?;
val.serialize_field("id", &self.id)?;
val.end()

View file

@ -13,6 +13,8 @@ use std::fmt::{self, Display, Formatter};
use std::ops::Deref;
use std::str;
pub(crate) const TOKEN: &str = "$surrealdb::private::sql::Uuid";
#[derive(Clone, Debug, Default, Eq, Ord, PartialEq, PartialOrd, Deserialize, Hash)]
pub struct Uuid(pub uuid::Uuid);
@ -86,9 +88,9 @@ impl Serialize for Uuid {
S: serde::Serializer,
{
if is_internal_serialization() {
serializer.serialize_newtype_struct("Uuid", &self.0)
serializer.serialize_newtype_struct(TOKEN, &self.0)
} else {
serializer.serialize_some(&self.0)
serializer.serialize_some(&self.to_string())
}
}
}

View file

@ -1,5 +1,7 @@
pub use self::value::*;
pub(super) mod serde;
#[allow(clippy::module_inception)]
mod value;

View file

@ -0,0 +1,3 @@
mod ser;
pub(crate) use ser::to_value;

View file

@ -0,0 +1,145 @@
pub mod vec;
use crate::err::Error;
use crate::sql::block::Entry;
use crate::sql::value::serde::ser;
use serde::ser::Error as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub(super) struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Entry;
type Error = Error;
type SerializeSeq = Impossible<Entry, Error>;
type SerializeTuple = Impossible<Entry, Error>;
type SerializeTupleStruct = Impossible<Entry, Error>;
type SerializeTupleVariant = Impossible<Entry, Error>;
type SerializeMap = Impossible<Entry, Error>;
type SerializeStruct = Impossible<Entry, Error>;
type SerializeStructVariant = Impossible<Entry, Error>;
const EXPECTED: &'static str = "an enum `Entry`";
#[inline]
fn serialize_newtype_variant<T>(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<Self::Ok, Error>
where
T: ?Sized + Serialize,
{
match variant {
"Value" => Ok(Entry::Value(value.serialize(ser::value::Serializer.wrap())?)),
"Set" => Ok(Entry::Set(value.serialize(ser::statement::set::Serializer.wrap())?)),
"Ifelse" => {
Ok(Entry::Ifelse(value.serialize(ser::statement::ifelse::Serializer.wrap())?))
}
"Select" => {
Ok(Entry::Select(value.serialize(ser::statement::select::Serializer.wrap())?))
}
"Create" => {
Ok(Entry::Create(value.serialize(ser::statement::create::Serializer.wrap())?))
}
"Update" => {
Ok(Entry::Update(value.serialize(ser::statement::update::Serializer.wrap())?))
}
"Delete" => {
Ok(Entry::Delete(value.serialize(ser::statement::delete::Serializer.wrap())?))
}
"Relate" => {
Ok(Entry::Relate(value.serialize(ser::statement::relate::Serializer.wrap())?))
}
"Insert" => {
Ok(Entry::Insert(value.serialize(ser::statement::insert::Serializer.wrap())?))
}
"Output" => {
Ok(Entry::Output(value.serialize(ser::statement::output::Serializer.wrap())?))
}
variant => Err(Error::custom(format!("unexpected variant `{name}::{variant}`"))),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use ser::Serializer as _;
use serde::Serialize;
#[test]
fn value() {
let entry = Entry::Value(Default::default());
let serialized = serialize_internal(|| entry.serialize(Serializer.wrap())).unwrap();
assert_eq!(entry, serialized);
}
#[test]
fn set() {
let entry = Entry::Set(Default::default());
let serialized = serialize_internal(|| entry.serialize(Serializer.wrap())).unwrap();
assert_eq!(entry, serialized);
}
#[test]
fn ifelse() {
let entry = Entry::Ifelse(Default::default());
let serialized = serialize_internal(|| entry.serialize(Serializer.wrap())).unwrap();
assert_eq!(entry, serialized);
}
#[test]
fn select() {
let entry = Entry::Select(Default::default());
let serialized = serialize_internal(|| entry.serialize(Serializer.wrap())).unwrap();
assert_eq!(entry, serialized);
}
#[test]
fn create() {
let entry = Entry::Create(Default::default());
let serialized = serialize_internal(|| entry.serialize(Serializer.wrap())).unwrap();
assert_eq!(entry, serialized);
}
#[test]
fn update() {
let entry = Entry::Update(Default::default());
let serialized = serialize_internal(|| entry.serialize(Serializer.wrap())).unwrap();
assert_eq!(entry, serialized);
}
#[test]
fn delete() {
let entry = Entry::Delete(Default::default());
let serialized = serialize_internal(|| entry.serialize(Serializer.wrap())).unwrap();
assert_eq!(entry, serialized);
}
#[test]
fn relate() {
let entry = Entry::Relate(Default::default());
let serialized = serialize_internal(|| entry.serialize(Serializer.wrap())).unwrap();
assert_eq!(entry, serialized);
}
#[test]
fn insert() {
let entry = Entry::Insert(Default::default());
let serialized = serialize_internal(|| entry.serialize(Serializer.wrap())).unwrap();
assert_eq!(entry, serialized);
}
#[test]
fn output() {
let entry = Entry::Output(Default::default());
let serialized = serialize_internal(|| entry.serialize(Serializer.wrap())).unwrap();
assert_eq!(entry, serialized);
}
}

View file

@ -0,0 +1,78 @@
use crate::err::Error;
use crate::sql::block::Entry;
use crate::sql::value::serde::ser;
use ser::Serializer as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Vec<Entry>;
type Error = Error;
type SerializeSeq = SerializeEntryVec;
type SerializeTuple = Impossible<Vec<Entry>, Error>;
type SerializeTupleStruct = Impossible<Vec<Entry>, Error>;
type SerializeTupleVariant = Impossible<Vec<Entry>, Error>;
type SerializeMap = Impossible<Vec<Entry>, Error>;
type SerializeStruct = Impossible<Vec<Entry>, Error>;
type SerializeStructVariant = Impossible<Vec<Entry>, Error>;
const EXPECTED: &'static str = "a `Vec<Entry>`";
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Error> {
Ok(SerializeEntryVec(Vec::with_capacity(len.unwrap_or_default())))
}
#[inline]
fn serialize_newtype_struct<T>(
self,
_name: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
value.serialize(self.wrap())
}
}
pub struct SerializeEntryVec(Vec<Entry>);
impl serde::ser::SerializeSeq for SerializeEntryVec {
type Ok = Vec<Entry>;
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
self.0.push(value.serialize(super::Serializer.wrap())?);
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(self.0)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
#[test]
fn empty() {
let vec: Vec<Entry> = Vec::new();
let serialized = serialize_internal(|| vec.serialize(Serializer.wrap())).unwrap();
assert_eq!(vec, serialized);
}
#[test]
fn vec() {
let vec = vec![Entry::Value(Default::default())];
let serialized = serialize_internal(|| vec.serialize(Serializer.wrap())).unwrap();
assert_eq!(vec, serialized);
}
}

View file

@ -0,0 +1 @@
pub(super) mod entry;

View file

@ -0,0 +1 @@
pub(super) mod opt;

View file

@ -0,0 +1,56 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Cond;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Option<Cond>;
type Error = Error;
type SerializeSeq = Impossible<Option<Cond>, Error>;
type SerializeTuple = Impossible<Option<Cond>, Error>;
type SerializeTupleStruct = Impossible<Option<Cond>, Error>;
type SerializeTupleVariant = Impossible<Option<Cond>, Error>;
type SerializeMap = Impossible<Option<Cond>, Error>;
type SerializeStruct = Impossible<Option<Cond>, Error>;
type SerializeStructVariant = Impossible<Option<Cond>, Error>;
const EXPECTED: &'static str = "an `Option<Cond>`";
#[inline]
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
Ok(None)
}
#[inline]
fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
Ok(Some(Cond(value.serialize(ser::value::Serializer.wrap())?)))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use ser::Serializer as _;
#[test]
fn none() {
let option: Option<Cond> = None;
let serialized = serialize_internal(|| option.serialize(Serializer.wrap())).unwrap();
assert_eq!(option, serialized);
}
#[test]
fn some() {
let option = Some(Cond::default());
let serialized = serialize_internal(|| option.serialize(Serializer.wrap())).unwrap();
assert_eq!(option, serialized);
}
}

View file

@ -0,0 +1,194 @@
use crate::err::Error;
use crate::sql::constant::Constant;
use crate::sql::value::serde::ser;
use serde::ser::Error as _;
use serde::ser::Impossible;
pub(super) struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Constant;
type Error = Error;
type SerializeSeq = Impossible<Constant, Error>;
type SerializeTuple = Impossible<Constant, Error>;
type SerializeTupleStruct = Impossible<Constant, Error>;
type SerializeTupleVariant = Impossible<Constant, Error>;
type SerializeMap = Impossible<Constant, Error>;
type SerializeStruct = Impossible<Constant, Error>;
type SerializeStructVariant = Impossible<Constant, Error>;
const EXPECTED: &'static str = "an enum `Constant`";
#[inline]
fn serialize_unit_variant(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<Self::Ok, Error> {
match variant {
"MathE" => Ok(Constant::MathE),
"MathFrac1Pi" => Ok(Constant::MathFrac1Pi),
"MathFrac1Sqrt2" => Ok(Constant::MathFrac1Sqrt2),
"MathFrac2Pi" => Ok(Constant::MathFrac2Pi),
"MathFrac2SqrtPi" => Ok(Constant::MathFrac2SqrtPi),
"MathFracPi2" => Ok(Constant::MathFracPi2),
"MathFracPi3" => Ok(Constant::MathFracPi3),
"MathFracPi4" => Ok(Constant::MathFracPi4),
"MathFracPi6" => Ok(Constant::MathFracPi6),
"MathFracPi8" => Ok(Constant::MathFracPi8),
"MathLn10" => Ok(Constant::MathLn10),
"MathLn2" => Ok(Constant::MathLn2),
"MathLog102" => Ok(Constant::MathLog102),
"MathLog10E" => Ok(Constant::MathLog10E),
"MathLog210" => Ok(Constant::MathLog210),
"MathLog2E" => Ok(Constant::MathLog2E),
"MathPi" => Ok(Constant::MathPi),
"MathSqrt2" => Ok(Constant::MathSqrt2),
"MathTau" => Ok(Constant::MathTau),
variant => Err(Error::custom(format!("unknown variant `{name}::{variant}`"))),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use ser::Serializer as _;
use serde::Serialize;
#[test]
fn math_e() {
let constant = Constant::MathE;
let serialized = serialize_internal(|| constant.serialize(Serializer.wrap())).unwrap();
assert_eq!(constant, serialized);
}
#[test]
fn math_frac_1pi() {
let constant = Constant::MathFrac1Pi;
let serialized = serialize_internal(|| constant.serialize(Serializer.wrap())).unwrap();
assert_eq!(constant, serialized);
}
#[test]
fn math_frac_1sqrt2() {
let constant = Constant::MathFrac1Sqrt2;
let serialized = serialize_internal(|| constant.serialize(Serializer.wrap())).unwrap();
assert_eq!(constant, serialized);
}
#[test]
fn math_frac_2pi() {
let constant = Constant::MathFrac2Pi;
let serialized = serialize_internal(|| constant.serialize(Serializer.wrap())).unwrap();
assert_eq!(constant, serialized);
}
#[test]
fn math_frac_2sqrt_pi() {
let constant = Constant::MathFrac2SqrtPi;
let serialized = serialize_internal(|| constant.serialize(Serializer.wrap())).unwrap();
assert_eq!(constant, serialized);
}
#[test]
fn math_frac_pi2() {
let constant = Constant::MathFracPi2;
let serialized = serialize_internal(|| constant.serialize(Serializer.wrap())).unwrap();
assert_eq!(constant, serialized);
}
#[test]
fn math_frac_pi3() {
let constant = Constant::MathFracPi3;
let serialized = serialize_internal(|| constant.serialize(Serializer.wrap())).unwrap();
assert_eq!(constant, serialized);
}
#[test]
fn math_frac_pi4() {
let constant = Constant::MathFracPi4;
let serialized = serialize_internal(|| constant.serialize(Serializer.wrap())).unwrap();
assert_eq!(constant, serialized);
}
#[test]
fn math_frac_pi6() {
let constant = Constant::MathFracPi6;
let serialized = serialize_internal(|| constant.serialize(Serializer.wrap())).unwrap();
assert_eq!(constant, serialized);
}
#[test]
fn math_frac_pi8() {
let constant = Constant::MathFracPi8;
let serialized = serialize_internal(|| constant.serialize(Serializer.wrap())).unwrap();
assert_eq!(constant, serialized);
}
#[test]
fn math_ln10() {
let constant = Constant::MathLn10;
let serialized = serialize_internal(|| constant.serialize(Serializer.wrap())).unwrap();
assert_eq!(constant, serialized);
}
#[test]
fn math_ln2() {
let constant = Constant::MathLn2;
let serialized = serialize_internal(|| constant.serialize(Serializer.wrap())).unwrap();
assert_eq!(constant, serialized);
}
#[test]
fn math_log102() {
let constant = Constant::MathLog102;
let serialized = serialize_internal(|| constant.serialize(Serializer.wrap())).unwrap();
assert_eq!(constant, serialized);
}
#[test]
fn math_log10_e() {
let constant = Constant::MathLog10E;
let serialized = serialize_internal(|| constant.serialize(Serializer.wrap())).unwrap();
assert_eq!(constant, serialized);
}
#[test]
fn math_log210() {
let constant = Constant::MathLog210;
let serialized = serialize_internal(|| constant.serialize(Serializer.wrap())).unwrap();
assert_eq!(constant, serialized);
}
#[test]
fn math_log2_e() {
let constant = Constant::MathLog2E;
let serialized = serialize_internal(|| constant.serialize(Serializer.wrap())).unwrap();
assert_eq!(constant, serialized);
}
#[test]
fn math_pi() {
let constant = Constant::MathPi;
let serialized = serialize_internal(|| constant.serialize(Serializer.wrap())).unwrap();
assert_eq!(constant, serialized);
}
#[test]
fn math_sqrt2() {
let constant = Constant::MathSqrt2;
let serialized = serialize_internal(|| constant.serialize(Serializer.wrap())).unwrap();
assert_eq!(constant, serialized);
}
#[test]
fn math_tau() {
let constant = Constant::MathTau;
let serialized = serialize_internal(|| constant.serialize(Serializer.wrap())).unwrap();
assert_eq!(constant, serialized);
}
}

View file

@ -0,0 +1,408 @@
pub(super) mod opt;
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Data;
use crate::sql::Idiom;
use crate::sql::Operator;
use crate::sql::Value;
use ser::Serializer as _;
use serde::ser::Error as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub(super) struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Data;
type Error = Error;
type SerializeSeq = Impossible<Data, Error>;
type SerializeTuple = Impossible<Data, Error>;
type SerializeTupleStruct = Impossible<Data, Error>;
type SerializeTupleVariant = Impossible<Data, Error>;
type SerializeMap = Impossible<Data, Error>;
type SerializeStruct = Impossible<Data, Error>;
type SerializeStructVariant = Impossible<Data, Error>;
const EXPECTED: &'static str = "an enum `Data`";
#[inline]
fn serialize_unit_variant(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<Self::Ok, Error> {
match variant {
"EmptyExpression" => Ok(Data::EmptyExpression),
variant => Err(Error::custom(format!("unexpected unit variant `{name}::{variant}`"))),
}
}
#[inline]
fn serialize_newtype_variant<T>(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<Self::Ok, Error>
where
T: ?Sized + Serialize,
{
match variant {
"SetExpression" => {
Ok(Data::SetExpression(value.serialize(IdiomOperatorValueVecSerializer.wrap())?))
}
"PatchExpression" => {
Ok(Data::PatchExpression(value.serialize(ser::value::Serializer.wrap())?))
}
"MergeExpression" => {
Ok(Data::MergeExpression(value.serialize(ser::value::Serializer.wrap())?))
}
"ReplaceExpression" => {
Ok(Data::ReplaceExpression(value.serialize(ser::value::Serializer.wrap())?))
}
"ContentExpression" => {
Ok(Data::ContentExpression(value.serialize(ser::value::Serializer.wrap())?))
}
"SingleExpression" => {
Ok(Data::SingleExpression(value.serialize(ser::value::Serializer.wrap())?))
}
"ValuesExpression" => {
Ok(Data::ValuesExpression(value.serialize(IdiomValueVecVecSerializer.wrap())?))
}
"UpdateExpression" => {
Ok(Data::UpdateExpression(value.serialize(IdiomOperatorValueVecSerializer.wrap())?))
}
variant => {
Err(Error::custom(format!("unexpected newtype variant `{name}::{variant}`")))
}
}
}
}
type IdiomOperatorValueTuple = (Idiom, Operator, Value);
struct IdiomOperatorValueVecSerializer;
impl ser::Serializer for IdiomOperatorValueVecSerializer {
type Ok = Vec<IdiomOperatorValueTuple>;
type Error = Error;
type SerializeSeq = SerializeIdiomOperatorValueVec;
type SerializeTuple = Impossible<Vec<IdiomOperatorValueTuple>, Error>;
type SerializeTupleStruct = Impossible<Vec<IdiomOperatorValueTuple>, Error>;
type SerializeTupleVariant = Impossible<Vec<IdiomOperatorValueTuple>, Error>;
type SerializeMap = Impossible<Vec<IdiomOperatorValueTuple>, Error>;
type SerializeStruct = Impossible<Vec<IdiomOperatorValueTuple>, Error>;
type SerializeStructVariant = Impossible<Vec<IdiomOperatorValueTuple>, Error>;
const EXPECTED: &'static str = "an `(Idiom, Operator, Value)`";
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Error> {
Ok(SerializeIdiomOperatorValueVec(Vec::with_capacity(len.unwrap_or_default())))
}
}
struct SerializeIdiomOperatorValueVec(Vec<IdiomOperatorValueTuple>);
impl serde::ser::SerializeSeq for SerializeIdiomOperatorValueVec {
type Ok = Vec<IdiomOperatorValueTuple>;
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
self.0.push(value.serialize(IdiomOperatorValueTupleSerializer.wrap())?);
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(self.0)
}
}
struct IdiomOperatorValueTupleSerializer;
impl ser::Serializer for IdiomOperatorValueTupleSerializer {
type Ok = IdiomOperatorValueTuple;
type Error = Error;
type SerializeSeq = Impossible<IdiomOperatorValueTuple, Error>;
type SerializeTuple = SerializeIdiomOperatorValueTuple;
type SerializeTupleStruct = Impossible<IdiomOperatorValueTuple, Error>;
type SerializeTupleVariant = Impossible<IdiomOperatorValueTuple, Error>;
type SerializeMap = Impossible<IdiomOperatorValueTuple, Error>;
type SerializeStruct = Impossible<IdiomOperatorValueTuple, Error>;
type SerializeStructVariant = Impossible<IdiomOperatorValueTuple, Error>;
const EXPECTED: &'static str = "an `(Idiom, Operator, Value)`";
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
Ok(SerializeIdiomOperatorValueTuple::default())
}
}
#[derive(Default)]
struct SerializeIdiomOperatorValueTuple {
index: usize,
idiom: Option<Idiom>,
operator: Option<Operator>,
value: Option<Value>,
}
impl serde::ser::SerializeTuple for SerializeIdiomOperatorValueTuple {
type Ok = IdiomOperatorValueTuple;
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
match self.index {
0 => {
self.idiom = Some(Idiom(value.serialize(ser::part::vec::Serializer.wrap())?));
}
1 => {
self.operator = Some(value.serialize(ser::operator::Serializer.wrap())?);
}
2 => {
self.value = Some(value.serialize(ser::value::Serializer.wrap())?);
}
index => {
return Err(Error::custom(format!(
"unexpected tuple index `{index}` for `(Idiom, Operator, Value)`"
)));
}
}
self.index += 1;
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
match (self.idiom, self.operator, self.value) {
(Some(idiom), Some(operator), Some(value)) => Ok((idiom, operator, value)),
_ => Err(Error::custom("`(Idiom, Operator, Value)` missing required value(s)")),
}
}
}
type IdiomValueTuple = (Idiom, Value);
struct IdiomValueVecVecSerializer;
impl ser::Serializer for IdiomValueVecVecSerializer {
type Ok = Vec<Vec<IdiomValueTuple>>;
type Error = Error;
type SerializeSeq = SerializeIdiomValueVecVec;
type SerializeTuple = Impossible<Vec<Vec<IdiomValueTuple>>, Error>;
type SerializeTupleStruct = Impossible<Vec<Vec<IdiomValueTuple>>, Error>;
type SerializeTupleVariant = Impossible<Vec<Vec<IdiomValueTuple>>, Error>;
type SerializeMap = Impossible<Vec<Vec<IdiomValueTuple>>, Error>;
type SerializeStruct = Impossible<Vec<Vec<IdiomValueTuple>>, Error>;
type SerializeStructVariant = Impossible<Vec<Vec<IdiomValueTuple>>, Error>;
const EXPECTED: &'static str = "a `Vec<Vec<(Idiom, Value)>>`";
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Error> {
Ok(SerializeIdiomValueVecVec(Vec::with_capacity(len.unwrap_or_default())))
}
}
struct SerializeIdiomValueVecVec(Vec<Vec<IdiomValueTuple>>);
impl serde::ser::SerializeSeq for SerializeIdiomValueVecVec {
type Ok = Vec<Vec<IdiomValueTuple>>;
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
self.0.push(value.serialize(IdiomValueVecSerializer.wrap())?);
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(self.0)
}
}
struct IdiomValueVecSerializer;
impl ser::Serializer for IdiomValueVecSerializer {
type Ok = Vec<IdiomValueTuple>;
type Error = Error;
type SerializeSeq = SerializeIdiomValueVec;
type SerializeTuple = Impossible<Vec<IdiomValueTuple>, Error>;
type SerializeTupleStruct = Impossible<Vec<IdiomValueTuple>, Error>;
type SerializeTupleVariant = Impossible<Vec<IdiomValueTuple>, Error>;
type SerializeMap = Impossible<Vec<IdiomValueTuple>, Error>;
type SerializeStruct = Impossible<Vec<IdiomValueTuple>, Error>;
type SerializeStructVariant = Impossible<Vec<IdiomValueTuple>, Error>;
const EXPECTED: &'static str = "a `Vec<(Idiom, Value)>`";
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Error> {
Ok(SerializeIdiomValueVec(Vec::with_capacity(len.unwrap_or_default())))
}
}
struct SerializeIdiomValueVec(Vec<IdiomValueTuple>);
impl serde::ser::SerializeSeq for SerializeIdiomValueVec {
type Ok = Vec<IdiomValueTuple>;
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
self.0.push(value.serialize(IdiomValueTupleSerializer.wrap())?);
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(self.0)
}
}
struct IdiomValueTupleSerializer;
impl ser::Serializer for IdiomValueTupleSerializer {
type Ok = IdiomValueTuple;
type Error = Error;
type SerializeSeq = Impossible<IdiomValueTuple, Error>;
type SerializeTuple = SerializeIdiomValueTuple;
type SerializeTupleStruct = Impossible<IdiomValueTuple, Error>;
type SerializeTupleVariant = Impossible<IdiomValueTuple, Error>;
type SerializeMap = Impossible<IdiomValueTuple, Error>;
type SerializeStruct = Impossible<IdiomValueTuple, Error>;
type SerializeStructVariant = Impossible<IdiomValueTuple, Error>;
const EXPECTED: &'static str = "an `(Idiom, Value)`";
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
Ok(SerializeIdiomValueTuple::default())
}
}
#[derive(Default)]
struct SerializeIdiomValueTuple {
index: usize,
idiom: Option<Idiom>,
value: Option<Value>,
}
impl serde::ser::SerializeTuple for SerializeIdiomValueTuple {
type Ok = IdiomValueTuple;
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
match self.index {
0 => {
self.idiom = Some(Idiom(value.serialize(ser::part::vec::Serializer.wrap())?));
}
1 => {
self.value = Some(value.serialize(ser::value::Serializer.wrap())?);
}
index => {
return Err(Error::custom(format!(
"unexpected tuple index `{index}` for `(Idiom, Value)`"
)));
}
}
self.index += 1;
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
match (self.idiom, self.value) {
(Some(idiom), Some(value)) => Ok((idiom, value)),
_ => Err(Error::custom("`(Idiom, Value)` missing required value(s)")),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
#[test]
fn empty_expression() {
let data = Data::EmptyExpression;
let serialized = serialize_internal(|| data.serialize(Serializer.wrap())).unwrap();
assert_eq!(data, serialized);
}
#[test]
fn set_expression() {
let data =
Data::SetExpression(vec![(Default::default(), Default::default(), Default::default())]);
let serialized = serialize_internal(|| data.serialize(Serializer.wrap())).unwrap();
assert_eq!(data, serialized);
}
#[test]
fn patch_expression() {
let data = Data::PatchExpression(Default::default());
let serialized = serialize_internal(|| data.serialize(Serializer.wrap())).unwrap();
assert_eq!(data, serialized);
}
#[test]
fn merge_expression() {
let data = Data::MergeExpression(Default::default());
let serialized = serialize_internal(|| data.serialize(Serializer.wrap())).unwrap();
assert_eq!(data, serialized);
}
#[test]
fn replace_expression() {
let data = Data::ReplaceExpression(Default::default());
let serialized = serialize_internal(|| data.serialize(Serializer.wrap())).unwrap();
assert_eq!(data, serialized);
}
#[test]
fn content_expression() {
let data = Data::ContentExpression(Default::default());
let serialized = serialize_internal(|| data.serialize(Serializer.wrap())).unwrap();
assert_eq!(data, serialized);
}
#[test]
fn single_expression() {
let data = Data::SingleExpression(Default::default());
let serialized = serialize_internal(|| data.serialize(Serializer.wrap())).unwrap();
assert_eq!(data, serialized);
}
#[test]
fn values_expression() {
let data = Data::ValuesExpression(vec![vec![(Default::default(), Default::default())]]);
let serialized = serialize_internal(|| data.serialize(Serializer.wrap())).unwrap();
assert_eq!(data, serialized);
}
#[test]
fn update_expression() {
let data = Data::UpdateExpression(vec![(
Default::default(),
Default::default(),
Default::default(),
)]);
let serialized = serialize_internal(|| data.serialize(Serializer.wrap())).unwrap();
assert_eq!(data, serialized);
}
}

View file

@ -0,0 +1,56 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Data;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Option<Data>;
type Error = Error;
type SerializeSeq = Impossible<Option<Data>, Error>;
type SerializeTuple = Impossible<Option<Data>, Error>;
type SerializeTupleStruct = Impossible<Option<Data>, Error>;
type SerializeTupleVariant = Impossible<Option<Data>, Error>;
type SerializeMap = Impossible<Option<Data>, Error>;
type SerializeStruct = Impossible<Option<Data>, Error>;
type SerializeStructVariant = Impossible<Option<Data>, Error>;
const EXPECTED: &'static str = "an `Option<Data>`";
#[inline]
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
Ok(None)
}
#[inline]
fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
Ok(Some(value.serialize(super::Serializer.wrap())?))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use ser::Serializer as _;
#[test]
fn none() {
let option: Option<Data> = None;
let serialized = serialize_internal(|| option.serialize(Serializer.wrap())).unwrap();
assert_eq!(option, serialized);
}
#[test]
fn some() {
let option = Some(Data::default());
let serialized = serialize_internal(|| option.serialize(Serializer.wrap())).unwrap();
assert_eq!(option, serialized);
}
}

View file

@ -0,0 +1,60 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use chrono::offset::Utc;
use chrono::DateTime;
use serde::ser::Error as _;
use serde::ser::Impossible;
use serde::Serialize;
use std::fmt::Display;
pub(super) struct Serializer;
impl ser::Serializer for Serializer {
type Ok = DateTime<Utc>;
type Error = Error;
type SerializeSeq = Impossible<DateTime<Utc>, Error>;
type SerializeTuple = Impossible<DateTime<Utc>, Error>;
type SerializeTupleStruct = Impossible<DateTime<Utc>, Error>;
type SerializeTupleVariant = Impossible<DateTime<Utc>, Error>;
type SerializeMap = Impossible<DateTime<Utc>, Error>;
type SerializeStruct = Impossible<DateTime<Utc>, Error>;
type SerializeStructVariant = Impossible<DateTime<Utc>, Error>;
const EXPECTED: &'static str = "a struct `DateTime<Utc>`";
#[inline]
fn collect_str<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
where
T: Display,
{
value.to_string().parse().map_err(Error::custom)
}
#[inline]
fn serialize_newtype_struct<T>(
self,
_name: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
value.serialize(self.wrap())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use ser::Serializer as _;
use serde::Serialize;
#[test]
fn now() {
let dt = Utc::now();
let serialized = serialize_internal(|| dt.serialize(Serializer.wrap())).unwrap();
assert_eq!(dt, serialized);
}
}

View file

@ -0,0 +1,46 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use bigdecimal::BigDecimal;
use serde::ser::Error as _;
use serde::ser::Impossible;
use std::fmt::Display;
pub(super) struct Serializer;
impl ser::Serializer for Serializer {
type Ok = BigDecimal;
type Error = Error;
type SerializeSeq = Impossible<BigDecimal, Error>;
type SerializeTuple = Impossible<BigDecimal, Error>;
type SerializeTupleStruct = Impossible<BigDecimal, Error>;
type SerializeTupleVariant = Impossible<BigDecimal, Error>;
type SerializeMap = Impossible<BigDecimal, Error>;
type SerializeStruct = Impossible<BigDecimal, Error>;
type SerializeStructVariant = Impossible<BigDecimal, Error>;
const EXPECTED: &'static str = "a struct `BigDecimal`";
#[inline]
fn collect_str<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
where
T: Display,
{
value.to_string().parse::<BigDecimal>().map_err(Error::custom)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use ser::Serializer as _;
use serde::Serialize;
#[test]
fn from_i32() {
let decimal = BigDecimal::from(25);
let serialized = serialize_internal(|| decimal.serialize(Serializer.wrap())).unwrap();
assert_eq!(decimal, serialized);
}
}

View file

@ -0,0 +1,66 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Dir;
use serde::ser::Error as _;
use serde::ser::Impossible;
pub(super) struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Dir;
type Error = Error;
type SerializeSeq = Impossible<Dir, Error>;
type SerializeTuple = Impossible<Dir, Error>;
type SerializeTupleStruct = Impossible<Dir, Error>;
type SerializeTupleVariant = Impossible<Dir, Error>;
type SerializeMap = Impossible<Dir, Error>;
type SerializeStruct = Impossible<Dir, Error>;
type SerializeStructVariant = Impossible<Dir, Error>;
const EXPECTED: &'static str = "an enum `Dir`";
#[inline]
fn serialize_unit_variant(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<Self::Ok, Error> {
match variant {
"In" => Ok(Dir::In),
"Out" => Ok(Dir::Out),
"Both" => Ok(Dir::Both),
variant => Err(Error::custom(format!("unexpected unit variant `{name}::{variant}`"))),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use ser::Serializer as _;
use serde::Serialize;
#[test]
fn r#in() {
let dir = Dir::In;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn out() {
let dir = Dir::Out;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn both() {
let dir = Dir::Both;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
}

View file

@ -0,0 +1,97 @@
pub(super) mod opt;
use crate::err::Error;
use crate::sql::value::serde::ser;
use ser::Serializer as _;
use serde::ser::Error as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
use std::time::Duration;
pub(super) struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Duration;
type Error = Error;
type SerializeSeq = Impossible<Duration, Error>;
type SerializeTuple = Impossible<Duration, Error>;
type SerializeTupleStruct = Impossible<Duration, Error>;
type SerializeTupleVariant = Impossible<Duration, Error>;
type SerializeMap = Impossible<Duration, Error>;
type SerializeStruct = SerializeDuration;
type SerializeStructVariant = Impossible<Duration, Error>;
const EXPECTED: &'static str = "a struct `Duration`";
#[inline]
fn serialize_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeStruct, Error> {
Ok(SerializeDuration::default())
}
#[inline]
fn serialize_newtype_struct<T>(
self,
_name: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
value.serialize(self.wrap())
}
}
#[derive(Default)]
pub(super) struct SerializeDuration {
secs: Option<u64>,
nanos: Option<u32>,
}
impl serde::ser::SerializeStruct for SerializeDuration {
type Ok = Duration;
type Error = Error;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Error>
where
T: ?Sized + Serialize,
{
match key {
"secs" => {
self.secs = Some(value.serialize(ser::primitive::u64::Serializer.wrap())?);
}
"nanos" => {
self.nanos = Some(value.serialize(ser::primitive::u32::Serializer.wrap())?);
}
key => {
return Err(Error::custom(format!("unexpected field `Duration::{key}`")));
}
}
Ok(())
}
fn end(self) -> Result<Self::Ok, Error> {
match (self.secs, self.nanos) {
(Some(secs), Some(nanos)) => Ok(Duration::new(secs, nanos)),
_ => Err(Error::custom("`Duration` missing required field(s)")),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use serde::Serialize;
#[test]
fn default() {
let duration = Duration::default();
let serialized = serialize_internal(|| duration.serialize(Serializer.wrap())).unwrap();
assert_eq!(duration, serialized);
}
}

View file

@ -0,0 +1,56 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use serde::ser::Impossible;
use serde::ser::Serialize;
use std::time::Duration;
pub struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Option<Duration>;
type Error = Error;
type SerializeSeq = Impossible<Option<Duration>, Error>;
type SerializeTuple = Impossible<Option<Duration>, Error>;
type SerializeTupleStruct = Impossible<Option<Duration>, Error>;
type SerializeTupleVariant = Impossible<Option<Duration>, Error>;
type SerializeMap = Impossible<Option<Duration>, Error>;
type SerializeStruct = Impossible<Option<Duration>, Error>;
type SerializeStructVariant = Impossible<Option<Duration>, Error>;
const EXPECTED: &'static str = "an `Option<Duration>`";
#[inline]
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
Ok(None)
}
#[inline]
fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
Ok(Some(value.serialize(super::Serializer.wrap())?))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use ser::Serializer as _;
#[test]
fn none() {
let option: Option<Duration> = None;
let serialized = serialize_internal(|| option.serialize(Serializer.wrap())).unwrap();
assert_eq!(option, serialized);
}
#[test]
fn some() {
let option = Some(Duration::default());
let serialized = serialize_internal(|| option.serialize(Serializer.wrap())).unwrap();
assert_eq!(option, serialized);
}
}

View file

@ -0,0 +1,99 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Dir;
use crate::sql::Edges;
use crate::sql::Tables;
use crate::sql::Thing;
use ser::Serializer as _;
use serde::ser::Error as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub(super) struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Edges;
type Error = Error;
type SerializeSeq = Impossible<Edges, Error>;
type SerializeTuple = Impossible<Edges, Error>;
type SerializeTupleStruct = Impossible<Edges, Error>;
type SerializeTupleVariant = Impossible<Edges, Error>;
type SerializeMap = Impossible<Edges, Error>;
type SerializeStruct = SerializeEdges;
type SerializeStructVariant = Impossible<Edges, Error>;
const EXPECTED: &'static str = "a struct `Edges`";
#[inline]
fn serialize_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeStruct, Error> {
Ok(SerializeEdges::default())
}
}
#[derive(Default)]
pub(super) struct SerializeEdges {
dir: Option<Dir>,
from: Option<Thing>,
what: Option<Tables>,
}
impl serde::ser::SerializeStruct for SerializeEdges {
type Ok = Edges;
type Error = Error;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Error>
where
T: ?Sized + Serialize,
{
match key {
"dir" => {
self.dir = Some(value.serialize(ser::dir::Serializer.wrap())?);
}
"from" => {
self.from = Some(value.serialize(ser::thing::Serializer.wrap())?);
}
"what" => {
self.what = Some(Tables(value.serialize(ser::table::vec::Serializer.wrap())?));
}
key => {
return Err(Error::custom(format!("unexpected field `Edges::{key}`")));
}
}
Ok(())
}
fn end(self) -> Result<Self::Ok, Error> {
match (self.dir, self.from, self.what) {
(Some(dir), Some(from), Some(what)) => Ok(Edges {
dir,
from,
what,
}),
_ => Err(Error::custom("`Edges` missing required field(s)")),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use crate::sql::thing;
use serde::Serialize;
#[test]
fn edges() {
let edges = Edges {
dir: Dir::Both,
from: thing("foo:bar").unwrap(),
what: Tables(Vec::new()),
};
let serialized = serialize_internal(|| edges.serialize(Serializer.wrap())).unwrap();
assert_eq!(edges, serialized);
}
}

View file

@ -0,0 +1,104 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Expression;
use crate::sql::Operator;
use crate::sql::Value;
use ser::Serializer as _;
use serde::ser::Error as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub(super) struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Expression;
type Error = Error;
type SerializeSeq = Impossible<Expression, Error>;
type SerializeTuple = Impossible<Expression, Error>;
type SerializeTupleStruct = Impossible<Expression, Error>;
type SerializeTupleVariant = Impossible<Expression, Error>;
type SerializeMap = Impossible<Expression, Error>;
type SerializeStruct = SerializeExpression;
type SerializeStructVariant = Impossible<Expression, Error>;
const EXPECTED: &'static str = "a struct `Expression`";
#[inline]
fn serialize_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeStruct, Error> {
Ok(SerializeExpression::default())
}
}
#[derive(Default)]
pub(super) struct SerializeExpression {
l: Option<Value>,
o: Option<Operator>,
r: Option<Value>,
}
impl serde::ser::SerializeStruct for SerializeExpression {
type Ok = Expression;
type Error = Error;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Error>
where
T: ?Sized + Serialize,
{
match key {
"l" => {
self.l = Some(value.serialize(ser::value::Serializer.wrap())?);
}
"o" => {
self.o = Some(value.serialize(ser::operator::Serializer.wrap())?);
}
"r" => {
self.r = Some(value.serialize(ser::value::Serializer.wrap())?);
}
key => {
return Err(Error::custom(format!("unexpected field `Expression::{key}`")));
}
}
Ok(())
}
fn end(self) -> Result<Self::Ok, Error> {
match (self.l, self.o, self.r) {
(Some(l), Some(o), Some(r)) => Ok(Expression {
l,
o,
r,
}),
_ => Err(Error::custom("`Expression` missing required field(s)")),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use serde::Serialize;
#[test]
fn default() {
let expression = Expression::default();
let serialized = serialize_internal(|| expression.serialize(Serializer.wrap())).unwrap();
assert_eq!(expression, serialized);
}
#[test]
fn foo_equals_bar() {
let expression = Expression {
l: "foo".into(),
o: Operator::Equal,
r: "Bar".into(),
};
let serialized = serialize_internal(|| expression.serialize(Serializer.wrap())).unwrap();
assert_eq!(expression, serialized);
}
}

View file

@ -0,0 +1 @@
pub(super) mod vec;

View file

@ -0,0 +1,81 @@
pub mod opt;
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Fetch;
use crate::sql::Idiom;
use ser::Serializer as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Vec<Fetch>;
type Error = Error;
type SerializeSeq = SerializeFetchVec;
type SerializeTuple = Impossible<Vec<Fetch>, Error>;
type SerializeTupleStruct = Impossible<Vec<Fetch>, Error>;
type SerializeTupleVariant = Impossible<Vec<Fetch>, Error>;
type SerializeMap = Impossible<Vec<Fetch>, Error>;
type SerializeStruct = Impossible<Vec<Fetch>, Error>;
type SerializeStructVariant = Impossible<Vec<Fetch>, Error>;
const EXPECTED: &'static str = "a `Vec<Fetch>`";
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Error> {
Ok(SerializeFetchVec(Vec::with_capacity(len.unwrap_or_default())))
}
#[inline]
fn serialize_newtype_struct<T>(
self,
_name: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
value.serialize(self.wrap())
}
}
pub struct SerializeFetchVec(Vec<Fetch>);
impl serde::ser::SerializeSeq for SerializeFetchVec {
type Ok = Vec<Fetch>;
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
self.0.push(Fetch(Idiom(value.serialize(ser::part::vec::Serializer.wrap())?)));
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(self.0)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
#[test]
fn empty() {
let vec: Vec<Fetch> = Vec::new();
let serialized = serialize_internal(|| vec.serialize(Serializer.wrap())).unwrap();
assert_eq!(vec, serialized);
}
#[test]
fn vec() {
let vec = vec![Fetch::default()];
let serialized = serialize_internal(|| vec.serialize(Serializer.wrap())).unwrap();
assert_eq!(vec, serialized);
}
}

View file

@ -0,0 +1,56 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Fetch;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Option<Vec<Fetch>>;
type Error = Error;
type SerializeSeq = Impossible<Option<Vec<Fetch>>, Error>;
type SerializeTuple = Impossible<Option<Vec<Fetch>>, Error>;
type SerializeTupleStruct = Impossible<Option<Vec<Fetch>>, Error>;
type SerializeTupleVariant = Impossible<Option<Vec<Fetch>>, Error>;
type SerializeMap = Impossible<Option<Vec<Fetch>>, Error>;
type SerializeStruct = Impossible<Option<Vec<Fetch>>, Error>;
type SerializeStructVariant = Impossible<Option<Vec<Fetch>>, Error>;
const EXPECTED: &'static str = "an `Option<Vec<Fetch>>`";
#[inline]
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
Ok(None)
}
#[inline]
fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
Ok(Some(value.serialize(super::Serializer.wrap())?))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use ser::Serializer as _;
#[test]
fn none() {
let option: Option<Vec<Fetch>> = None;
let serialized = serialize_internal(|| option.serialize(Serializer.wrap())).unwrap();
assert_eq!(option, serialized);
}
#[test]
fn some() {
let option = Some(vec![Fetch::default()]);
let serialized = serialize_internal(|| option.serialize(Serializer.wrap())).unwrap();
assert_eq!(option, serialized);
}
}

View file

@ -0,0 +1,139 @@
pub(super) mod vec;
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Field;
use crate::sql::Idiom;
use crate::sql::Value;
use ser::Serializer as _;
use serde::ser::Error as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub(super) struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Field;
type Error = Error;
type SerializeSeq = Impossible<Field, Error>;
type SerializeTuple = Impossible<Field, Error>;
type SerializeTupleStruct = Impossible<Field, Error>;
type SerializeTupleVariant = SerializeValueIdiomTuple;
type SerializeMap = Impossible<Field, Error>;
type SerializeStruct = Impossible<Field, Error>;
type SerializeStructVariant = Impossible<Field, Error>;
const EXPECTED: &'static str = "an enum `Field`";
#[inline]
fn serialize_unit_variant(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<Self::Ok, Error> {
match variant {
"All" => Ok(Field::All),
variant => Err(Error::custom(format!("unexpected unit variant `{name}::{variant}`"))),
}
}
#[inline]
fn serialize_newtype_variant<T>(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<Self::Ok, Error>
where
T: ?Sized + Serialize,
{
match variant {
"Alone" => Ok(Field::Alone(value.serialize(ser::value::Serializer.wrap())?)),
variant => {
Err(Error::custom(format!("unexpected newtype variant `{name}::{variant}`")))
}
}
}
fn serialize_tuple_variant(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> {
match variant {
"Alias" => Ok(SerializeValueIdiomTuple::default()),
variant => Err(Error::custom(format!("unexpected tuple variant `{name}::{variant}`"))),
}
}
}
#[derive(Default)]
pub(super) struct SerializeValueIdiomTuple {
index: usize,
value: Option<Value>,
idiom: Option<Idiom>,
}
impl serde::ser::SerializeTupleVariant for SerializeValueIdiomTuple {
type Ok = Field;
type Error = Error;
fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
match self.index {
0 => {
self.value = Some(value.serialize(ser::value::Serializer.wrap())?);
}
1 => {
self.idiom = Some(Idiom(value.serialize(ser::part::vec::Serializer.wrap())?));
}
index => {
return Err(Error::custom(format!("unexpected `Field::Alias` index `{index}`")));
}
}
self.index += 1;
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
match (self.value, self.idiom) {
(Some(value), Some(idiom)) => Ok(Field::Alias(value, idiom)),
_ => Err(Error::custom("`Field::Alias` missing required value(s)")),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use serde::Serialize;
#[test]
fn all() {
let field = Field::All;
let serialized = serialize_internal(|| field.serialize(Serializer.wrap())).unwrap();
assert_eq!(field, serialized);
}
#[test]
fn alone() {
let field = Field::Alone(Default::default());
let serialized = serialize_internal(|| field.serialize(Serializer.wrap())).unwrap();
assert_eq!(field, serialized);
}
#[test]
fn alias() {
let field = Field::Alias(Default::default(), Default::default());
let serialized = serialize_internal(|| field.serialize(Serializer.wrap())).unwrap();
assert_eq!(field, serialized);
}
}

View file

@ -0,0 +1,78 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Field;
use ser::Serializer as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Vec<Field>;
type Error = Error;
type SerializeSeq = SerializeFieldVec;
type SerializeTuple = Impossible<Vec<Field>, Error>;
type SerializeTupleStruct = Impossible<Vec<Field>, Error>;
type SerializeTupleVariant = Impossible<Vec<Field>, Error>;
type SerializeMap = Impossible<Vec<Field>, Error>;
type SerializeStruct = Impossible<Vec<Field>, Error>;
type SerializeStructVariant = Impossible<Vec<Field>, Error>;
const EXPECTED: &'static str = "a `Vec<Field>`";
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Error> {
Ok(SerializeFieldVec(Vec::with_capacity(len.unwrap_or_default())))
}
#[inline]
fn serialize_newtype_struct<T>(
self,
_name: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
value.serialize(self.wrap())
}
}
pub struct SerializeFieldVec(Vec<Field>);
impl serde::ser::SerializeSeq for SerializeFieldVec {
type Ok = Vec<Field>;
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
self.0.push(value.serialize(ser::field::Serializer.wrap())?);
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(self.0)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
#[test]
fn empty() {
let vec: Vec<Field> = Vec::new();
let serialized = serialize_internal(|| vec.serialize(Serializer.wrap())).unwrap();
assert_eq!(vec, serialized);
}
#[test]
fn vec() {
let vec = vec![Field::default()];
let serialized = serialize_internal(|| vec.serialize(Serializer.wrap())).unwrap();
assert_eq!(vec, serialized);
}
}

View file

@ -0,0 +1,91 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Field;
use crate::sql::Fields;
use ser::Serializer as _;
use serde::ser::Error as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub(super) struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Fields;
type Error = Error;
type SerializeSeq = Impossible<Fields, Error>;
type SerializeTuple = Impossible<Fields, Error>;
type SerializeTupleStruct = SerializeFields;
type SerializeTupleVariant = Impossible<Fields, Error>;
type SerializeMap = Impossible<Fields, Error>;
type SerializeStruct = Impossible<Fields, Error>;
type SerializeStructVariant = Impossible<Fields, Error>;
const EXPECTED: &'static str = "a struct `Fields`";
fn serialize_tuple_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleStruct, Error> {
Ok(SerializeFields::default())
}
}
#[derive(Default)]
pub(super) struct SerializeFields {
index: usize,
fields: Option<Vec<Field>>,
boolean: Option<bool>,
}
impl serde::ser::SerializeTupleStruct for SerializeFields {
type Ok = Fields;
type Error = Error;
fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
match self.index {
0 => {
self.fields = Some(value.serialize(ser::field::vec::Serializer.wrap())?);
}
1 => {
self.boolean = Some(value.serialize(ser::primitive::bool::Serializer.wrap())?);
}
index => {
return Err(Error::custom(format!("unexpected `Fields` index `{index}`")));
}
}
self.index += 1;
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
match (self.fields, self.boolean) {
(Some(fields), Some(boolean)) => Ok(Fields(fields, boolean)),
_ => Err(Error::custom("`Fields` missing required value(s)")),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
#[test]
fn default() {
let fields = Fields::default();
let serialized = serialize_internal(|| fields.serialize(Serializer.wrap())).unwrap();
assert_eq!(fields, serialized);
}
#[test]
fn all() {
let fields = Fields(vec![Field::All], true);
let serialized = serialize_internal(|| fields.serialize(Serializer.wrap())).unwrap();
assert_eq!(fields, serialized);
}
}

View file

@ -0,0 +1,153 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Function;
use crate::sql::Script;
use crate::sql::Value;
use ser::Serializer as _;
use serde::ser::Error as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub(super) struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Function;
type Error = Error;
type SerializeSeq = Impossible<Function, Error>;
type SerializeTuple = Impossible<Function, Error>;
type SerializeTupleStruct = Impossible<Function, Error>;
type SerializeTupleVariant = SerializeFunction;
type SerializeMap = Impossible<Function, Error>;
type SerializeStruct = Impossible<Function, Error>;
type SerializeStructVariant = Impossible<Function, Error>;
const EXPECTED: &'static str = "an enum `Function`";
fn serialize_tuple_variant(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> {
let inner = match variant {
"Cast" => Inner::Cast(None, None),
"Normal" => Inner::Normal(None, None),
"Custom" => Inner::Custom(None, None),
"Script" => Inner::Script(None, None),
variant => {
return Err(Error::custom(format!("unexpected tuple variant `{name}::{variant}`")));
}
};
Ok(SerializeFunction {
inner,
index: 0,
})
}
}
pub(super) struct SerializeFunction {
index: usize,
inner: Inner,
}
enum Inner {
Cast(Option<String>, Option<Value>),
Normal(Option<String>, Option<Vec<Value>>),
Custom(Option<String>, Option<Vec<Value>>),
Script(Option<Script>, Option<Vec<Value>>),
}
impl serde::ser::SerializeTupleVariant for SerializeFunction {
type Ok = Function;
type Error = Error;
fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
match (self.index, &mut self.inner) {
(
0,
Inner::Cast(ref mut var, _)
| Inner::Normal(ref mut var, _)
| Inner::Custom(ref mut var, _),
) => {
*var = Some(value.serialize(ser::string::Serializer.wrap())?);
}
(0, Inner::Script(ref mut var, _)) => {
*var = Some(Script(value.serialize(ser::string::Serializer.wrap())?));
}
(1, Inner::Cast(_, ref mut var)) => {
*var = Some(value.serialize(ser::value::Serializer.wrap())?);
}
(
1,
Inner::Normal(_, ref mut var)
| Inner::Custom(_, ref mut var)
| Inner::Script(_, ref mut var),
) => {
*var = Some(value.serialize(ser::value::vec::Serializer.wrap())?);
}
(index, inner) => {
let variant = match inner {
Inner::Cast(..) => "Cast",
Inner::Normal(..) => "Normal",
Inner::Custom(..) => "Custom",
Inner::Script(..) => "Script",
};
return Err(Error::custom(format!(
"unexpected `Function::{variant}` index `{index}`"
)));
}
}
self.index += 1;
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
match self.inner {
Inner::Cast(Some(one), Some(two)) => Ok(Function::Cast(one, two)),
Inner::Normal(Some(one), Some(two)) => Ok(Function::Normal(one, two)),
Inner::Custom(Some(one), Some(two)) => Ok(Function::Custom(one, two)),
Inner::Script(Some(one), Some(two)) => Ok(Function::Script(one, two)),
_ => Err(Error::custom("`Function` missing required value(s)")),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use serde::Serialize;
#[test]
fn cast() {
let function = Function::Cast(Default::default(), Default::default());
let serialized = serialize_internal(|| function.serialize(Serializer.wrap())).unwrap();
assert_eq!(function, serialized);
}
#[test]
fn normal() {
let function = Function::Normal(Default::default(), vec![Default::default()]);
let serialized = serialize_internal(|| function.serialize(Serializer.wrap())).unwrap();
assert_eq!(function, serialized);
}
#[test]
fn custom() {
let function = Function::Custom(Default::default(), vec![Default::default()]);
let serialized = serialize_internal(|| function.serialize(Serializer.wrap())).unwrap();
assert_eq!(function, serialized);
}
#[test]
fn script() {
let function = Function::Script(Default::default(), vec![Default::default()]);
let serialized = serialize_internal(|| function.serialize(Serializer.wrap())).unwrap();
assert_eq!(function, serialized);
}
}

View file

@ -0,0 +1,99 @@
pub mod vec;
use crate::err::Error;
use crate::sql::value::serde::ser;
use geo::Coord;
use ser::Serializer as _;
use serde::ser::Error as _;
use serde::ser::Impossible;
use serde::Serialize;
pub(super) struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Coord<f64>;
type Error = Error;
type SerializeSeq = Impossible<Coord<f64>, Error>;
type SerializeTuple = Impossible<Coord<f64>, Error>;
type SerializeTupleStruct = Impossible<Coord<f64>, Error>;
type SerializeTupleVariant = Impossible<Coord<f64>, Error>;
type SerializeMap = Impossible<Coord<f64>, Error>;
type SerializeStruct = SerializeCoord;
type SerializeStructVariant = Impossible<Coord<f64>, Error>;
const EXPECTED: &'static str = "a struct `Coord<f64>`";
#[inline]
fn serialize_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeStruct, Error> {
Ok(SerializeCoord::default())
}
#[inline]
fn serialize_newtype_struct<T>(
self,
_name: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
value.serialize(self.wrap())
}
}
#[derive(Default)]
pub(super) struct SerializeCoord {
x: Option<f64>,
y: Option<f64>,
}
impl serde::ser::SerializeStruct for SerializeCoord {
type Ok = Coord;
type Error = Error;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Error>
where
T: ?Sized + Serialize,
{
match key {
"x" => {
self.x = Some(value.serialize(ser::primitive::f64::Serializer.wrap())?);
}
"y" => {
self.y = Some(value.serialize(ser::primitive::f64::Serializer.wrap())?);
}
key => {
return Err(Error::custom(format!("unexpected field `Coord::{key}`")));
}
}
Ok(())
}
fn end(self) -> Result<Self::Ok, Error> {
match (self.x, self.y) {
(Some(x), Some(y)) => Ok(Coord {
x,
y,
}),
_ => Err(Error::custom("`Coord` missing required field(s)")),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
#[test]
fn default() {
let coord = Coord::default();
let serialized = serialize_internal(|| coord.serialize(Serializer.wrap())).unwrap();
assert_eq!(coord, serialized);
}
}

View file

@ -0,0 +1,78 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use geo::Coord;
use ser::Serializer as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Vec<Coord<f64>>;
type Error = Error;
type SerializeSeq = SerializeCoordVec;
type SerializeTuple = Impossible<Vec<Coord<f64>>, Error>;
type SerializeTupleStruct = Impossible<Vec<Coord<f64>>, Error>;
type SerializeTupleVariant = Impossible<Vec<Coord<f64>>, Error>;
type SerializeMap = Impossible<Vec<Coord<f64>>, Error>;
type SerializeStruct = Impossible<Vec<Coord<f64>>, Error>;
type SerializeStructVariant = Impossible<Vec<Coord<f64>>, Error>;
const EXPECTED: &'static str = "a `Vec<Coord<f64>>`";
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Error> {
Ok(SerializeCoordVec(Vec::with_capacity(len.unwrap_or_default())))
}
#[inline]
fn serialize_newtype_struct<T>(
self,
_name: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
value.serialize(self.wrap())
}
}
pub struct SerializeCoordVec(Vec<Coord<f64>>);
impl serde::ser::SerializeSeq for SerializeCoordVec {
type Ok = Vec<Coord<f64>>;
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
self.0.push(value.serialize(super::Serializer.wrap())?);
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(self.0)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
#[test]
fn empty() {
let vec: Vec<Coord<f64>> = Vec::new();
let serialized = serialize_internal(|| vec.serialize(Serializer.wrap())).unwrap();
assert_eq!(vec, serialized);
}
#[test]
fn vec() {
let vec = vec![Coord::default()];
let serialized = serialize_internal(|| vec.serialize(Serializer.wrap())).unwrap();
assert_eq!(vec, serialized);
}
}

View file

@ -0,0 +1 @@
pub mod vec;

View file

@ -0,0 +1,79 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use geo::LineString;
use ser::Serializer as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Vec<LineString<f64>>;
type Error = Error;
type SerializeSeq = SerializeLineStringVec;
type SerializeTuple = Impossible<Vec<LineString<f64>>, Error>;
type SerializeTupleStruct = Impossible<Vec<LineString<f64>>, Error>;
type SerializeTupleVariant = Impossible<Vec<LineString<f64>>, Error>;
type SerializeMap = Impossible<Vec<LineString<f64>>, Error>;
type SerializeStruct = Impossible<Vec<LineString<f64>>, Error>;
type SerializeStructVariant = Impossible<Vec<LineString<f64>>, Error>;
const EXPECTED: &'static str = "a `Vec<LineString<f64>>`";
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Error> {
Ok(SerializeLineStringVec(Vec::with_capacity(len.unwrap_or_default())))
}
#[inline]
fn serialize_newtype_struct<T>(
self,
_name: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
value.serialize(self.wrap())
}
}
pub struct SerializeLineStringVec(Vec<LineString<f64>>);
impl serde::ser::SerializeSeq for SerializeLineStringVec {
type Ok = Vec<LineString<f64>>;
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
self.0.push(LineString(value.serialize(ser::geometry::coord::vec::Serializer.wrap())?));
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(self.0)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use geo::Coord;
#[test]
fn empty() {
let vec: Vec<LineString<f64>> = Vec::new();
let serialized = serialize_internal(|| vec.serialize(Serializer.wrap())).unwrap();
assert_eq!(vec, serialized);
}
#[test]
fn vec() {
let vec = vec![LineString(vec![Coord::default()])];
let serialized = serialize_internal(|| vec.serialize(Serializer.wrap())).unwrap();
assert_eq!(vec, serialized);
}
}

View file

@ -0,0 +1,156 @@
pub(super) mod coord;
pub(super) mod line_string;
pub(super) mod point;
pub(super) mod polygon;
pub(super) mod vec;
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Geometry;
use geo::LineString;
use geo::MultiLineString;
use geo::MultiPoint;
use geo::MultiPolygon;
use geo::Point;
use serde::ser::Error as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub(super) struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Geometry;
type Error = Error;
type SerializeSeq = SerializeGeometryVec;
type SerializeTuple = Impossible<Geometry, Error>;
type SerializeTupleStruct = Impossible<Geometry, Error>;
type SerializeTupleVariant = Impossible<Geometry, Error>;
type SerializeMap = Impossible<Geometry, Error>;
type SerializeStruct = Impossible<Geometry, Error>;
type SerializeStructVariant = Impossible<Geometry, Error>;
const EXPECTED: &'static str = "an enum `Geometry`";
#[inline]
fn serialize_newtype_variant<T>(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<Self::Ok, Error>
where
T: ?Sized + Serialize,
{
match variant {
"Point" => Ok(Geometry::Point(Point(
value.serialize(ser::geometry::coord::Serializer.wrap())?,
))),
"Line" => Ok(Geometry::Line(LineString(
value.serialize(ser::geometry::coord::vec::Serializer.wrap())?,
))),
"Polygon" => {
Ok(Geometry::Polygon(value.serialize(ser::geometry::polygon::Serializer.wrap())?))
}
"MultiPoint" => Ok(Geometry::MultiPoint(MultiPoint(
value.serialize(ser::geometry::point::vec::Serializer.wrap())?,
))),
"MultiLine" => Ok(Geometry::MultiLine(MultiLineString(
value.serialize(ser::geometry::line_string::vec::Serializer.wrap())?,
))),
"MultiPolygon" => Ok(Geometry::MultiPolygon(MultiPolygon(
value.serialize(ser::geometry::polygon::vec::Serializer.wrap())?,
))),
"Collection" => {
Ok(Geometry::Collection(value.serialize(ser::geometry::vec::Serializer.wrap())?))
}
variant => {
Err(Error::custom(format!("unexpected newtype variant `{name}::{variant}`")))
}
}
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Error> {
let serialize_seq = vec::SerializeGeometryVec(Vec::with_capacity(len.unwrap_or_default()));
Ok(SerializeGeometryVec(serialize_seq))
}
}
pub(super) struct SerializeGeometryVec(vec::SerializeGeometryVec);
impl serde::ser::SerializeSeq for SerializeGeometryVec {
type Ok = Geometry;
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
self.0.serialize_element(value)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(Geometry::Collection(self.0.end()?))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use geo::Coord;
use geo::Polygon;
use ser::Serializer as _;
use serde::Serialize;
#[test]
fn point() {
let geometry = Geometry::Point(Default::default());
let serialized = serialize_internal(|| geometry.serialize(Serializer.wrap())).unwrap();
assert_eq!(geometry, serialized);
}
#[test]
fn line() {
let geometry = Geometry::Line(LineString(vec![Coord::default()]));
let serialized = serialize_internal(|| geometry.serialize(Serializer.wrap())).unwrap();
assert_eq!(geometry, serialized);
}
#[test]
fn polygon() {
let polygon = Polygon::new(LineString(Vec::new()), Vec::new());
let geometry = Geometry::Polygon(polygon);
let serialized = serialize_internal(|| geometry.serialize(Serializer.wrap())).unwrap();
assert_eq!(geometry, serialized);
}
#[test]
fn multi_point() {
let geometry = Geometry::MultiPoint(vec![(0., 0.), (1., 2.)].into());
let serialized = serialize_internal(|| geometry.serialize(Serializer.wrap())).unwrap();
assert_eq!(geometry, serialized);
}
#[test]
fn multi_line() {
let geometry = Geometry::MultiLine(MultiLineString::new(Vec::new()));
let serialized = serialize_internal(|| geometry.serialize(Serializer.wrap())).unwrap();
assert_eq!(geometry, serialized);
}
#[test]
fn multi_polygon() {
let geometry = Geometry::MultiPolygon(MultiPolygon::new(Vec::new()));
let serialized = serialize_internal(|| geometry.serialize(Serializer.wrap())).unwrap();
assert_eq!(geometry, serialized);
}
#[test]
fn collection() {
let geometry = Geometry::Collection(vec![Geometry::Point(Default::default())]);
let serialized = serialize_internal(|| geometry.serialize(Serializer.wrap())).unwrap();
assert_eq!(geometry, serialized);
}
}

View file

@ -0,0 +1 @@
pub mod vec;

View file

@ -0,0 +1,78 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use geo::Point;
use ser::Serializer as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Vec<Point<f64>>;
type Error = Error;
type SerializeSeq = SerializePointVec;
type SerializeTuple = Impossible<Vec<Point<f64>>, Error>;
type SerializeTupleStruct = Impossible<Vec<Point<f64>>, Error>;
type SerializeTupleVariant = Impossible<Vec<Point<f64>>, Error>;
type SerializeMap = Impossible<Vec<Point<f64>>, Error>;
type SerializeStruct = Impossible<Vec<Point<f64>>, Error>;
type SerializeStructVariant = Impossible<Vec<Point<f64>>, Error>;
const EXPECTED: &'static str = "a `Vec<Point<f64>>`";
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Error> {
Ok(SerializePointVec(Vec::with_capacity(len.unwrap_or_default())))
}
#[inline]
fn serialize_newtype_struct<T>(
self,
_name: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
value.serialize(self.wrap())
}
}
pub struct SerializePointVec(Vec<Point<f64>>);
impl serde::ser::SerializeSeq for SerializePointVec {
type Ok = Vec<Point<f64>>;
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
self.0.push(Point(value.serialize(ser::geometry::coord::Serializer.wrap())?));
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(self.0)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
#[test]
fn empty() {
let vec: Vec<Point<f64>> = Vec::new();
let serialized = serialize_internal(|| vec.serialize(Serializer.wrap())).unwrap();
assert_eq!(vec, serialized);
}
#[test]
fn vec() {
let vec = vec![Point::default()];
let serialized = serialize_internal(|| vec.serialize(Serializer.wrap())).unwrap();
assert_eq!(vec, serialized);
}
}

View file

@ -0,0 +1,88 @@
pub mod vec;
use crate::err::Error;
use crate::sql::value::serde::ser;
use geo::LineString;
use geo::Polygon;
use ser::Serializer as _;
use serde::ser::Error as _;
use serde::ser::Impossible;
use serde::Serialize;
pub(super) struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Polygon<f64>;
type Error = Error;
type SerializeSeq = Impossible<Polygon<f64>, Error>;
type SerializeTuple = Impossible<Polygon<f64>, Error>;
type SerializeTupleStruct = Impossible<Polygon<f64>, Error>;
type SerializeTupleVariant = Impossible<Polygon<f64>, Error>;
type SerializeMap = Impossible<Polygon<f64>, Error>;
type SerializeStruct = SerializePolygon;
type SerializeStructVariant = Impossible<Polygon<f64>, Error>;
const EXPECTED: &'static str = "a struct `Polygon<f64>`";
#[inline]
fn serialize_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeStruct, Error> {
Ok(SerializePolygon::default())
}
}
#[derive(Default)]
pub(super) struct SerializePolygon {
exterior: Option<LineString<f64>>,
interiors: Option<Vec<LineString<f64>>>,
}
impl serde::ser::SerializeStruct for SerializePolygon {
type Ok = Polygon<f64>;
type Error = Error;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Error>
where
T: ?Sized + Serialize,
{
match key {
"exterior" => {
self.exterior = Some(LineString(
value.serialize(ser::geometry::coord::vec::Serializer.wrap())?,
));
}
"interiors" => {
self.interiors =
Some(value.serialize(ser::geometry::line_string::vec::Serializer.wrap())?);
}
key => {
return Err(Error::custom(format!("unexpected field `Polygon::{key}`")));
}
}
Ok(())
}
fn end(self) -> Result<Self::Ok, Error> {
match (self.exterior, self.interiors) {
(Some(exterior), Some(interiors)) => Ok(Polygon::new(exterior, interiors)),
_ => Err(Error::custom("`Polygon` missing required field(s)")),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
#[test]
fn default() {
let polygon = Polygon::new(LineString(Vec::new()), Vec::new());
let serialized = serialize_internal(|| polygon.serialize(Serializer.wrap())).unwrap();
assert_eq!(polygon, serialized);
}
}

View file

@ -0,0 +1,79 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use geo::Polygon;
use ser::Serializer as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Vec<Polygon<f64>>;
type Error = Error;
type SerializeSeq = SerializePolygonVec;
type SerializeTuple = Impossible<Vec<Polygon<f64>>, Error>;
type SerializeTupleStruct = Impossible<Vec<Polygon<f64>>, Error>;
type SerializeTupleVariant = Impossible<Vec<Polygon<f64>>, Error>;
type SerializeMap = Impossible<Vec<Polygon<f64>>, Error>;
type SerializeStruct = Impossible<Vec<Polygon<f64>>, Error>;
type SerializeStructVariant = Impossible<Vec<Polygon<f64>>, Error>;
const EXPECTED: &'static str = "a `Vec<Polygon<f64>>`";
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Error> {
Ok(SerializePolygonVec(Vec::with_capacity(len.unwrap_or_default())))
}
#[inline]
fn serialize_newtype_struct<T>(
self,
_name: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
value.serialize(self.wrap())
}
}
pub struct SerializePolygonVec(Vec<Polygon<f64>>);
impl serde::ser::SerializeSeq for SerializePolygonVec {
type Ok = Vec<Polygon<f64>>;
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
self.0.push(value.serialize(super::Serializer.wrap())?);
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(self.0)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use geo::LineString;
#[test]
fn empty() {
let vec: Vec<Polygon<f64>> = Vec::new();
let serialized = serialize_internal(|| vec.serialize(Serializer.wrap())).unwrap();
assert_eq!(vec, serialized);
}
#[test]
fn vec() {
let vec = vec![Polygon::new(LineString(Vec::new()), Vec::new())];
let serialized = serialize_internal(|| vec.serialize(Serializer.wrap())).unwrap();
assert_eq!(vec, serialized);
}
}

View file

@ -0,0 +1,66 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Geometry;
use ser::Serializer as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Vec<Geometry>;
type Error = Error;
type SerializeSeq = SerializeGeometryVec;
type SerializeTuple = Impossible<Vec<Geometry>, Error>;
type SerializeTupleStruct = Impossible<Vec<Geometry>, Error>;
type SerializeTupleVariant = Impossible<Vec<Geometry>, Error>;
type SerializeMap = Impossible<Vec<Geometry>, Error>;
type SerializeStruct = Impossible<Vec<Geometry>, Error>;
type SerializeStructVariant = Impossible<Vec<Geometry>, Error>;
const EXPECTED: &'static str = "a `Vec<Geometry>`";
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Error> {
Ok(SerializeGeometryVec(Vec::with_capacity(len.unwrap_or_default())))
}
}
pub struct SerializeGeometryVec(pub(super) Vec<Geometry>);
impl serde::ser::SerializeSeq for SerializeGeometryVec {
type Ok = Vec<Geometry>;
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
self.0.push(value.serialize(ser::geometry::Serializer.wrap())?);
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(self.0)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
#[test]
fn empty() {
let vec: Vec<Geometry> = Vec::new();
let serialized = serialize_internal(|| vec.serialize(Serializer.wrap())).unwrap();
assert_eq!(vec, serialized);
}
#[test]
fn vec() {
let vec = vec![Geometry::Point(Default::default())];
let serialized = serialize_internal(|| vec.serialize(Serializer.wrap())).unwrap();
assert_eq!(vec, serialized);
}
}

View file

@ -0,0 +1,120 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Cond;
use crate::sql::Dir;
use crate::sql::Graph;
use crate::sql::Idiom;
use crate::sql::Tables;
use ser::Serializer as _;
use serde::ser::Error as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub(super) struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Graph;
type Error = Error;
type SerializeSeq = Impossible<Graph, Error>;
type SerializeTuple = Impossible<Graph, Error>;
type SerializeTupleStruct = Impossible<Graph, Error>;
type SerializeTupleVariant = Impossible<Graph, Error>;
type SerializeMap = Impossible<Graph, Error>;
type SerializeStruct = SerializeGraph;
type SerializeStructVariant = Impossible<Graph, Error>;
const EXPECTED: &'static str = "a struct `Graph`";
#[inline]
fn serialize_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeStruct, Error> {
Ok(SerializeGraph::default())
}
}
#[derive(Default)]
pub(super) struct SerializeGraph {
dir: Option<Dir>,
what: Option<Tables>,
cond: Option<Cond>,
alias: Option<Idiom>,
}
impl serde::ser::SerializeStruct for SerializeGraph {
type Ok = Graph;
type Error = Error;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Error>
where
T: ?Sized + Serialize,
{
match key {
"dir" => {
self.dir = Some(value.serialize(ser::dir::Serializer.wrap())?);
}
"what" => {
self.what = Some(Tables(value.serialize(ser::table::vec::Serializer.wrap())?));
}
"cond" => {
self.cond = value.serialize(ser::cond::opt::Serializer.wrap())?;
}
"alias" => {
self.alias = value.serialize(ser::part::vec::opt::Serializer.wrap())?.map(Idiom);
}
key => {
return Err(Error::custom(format!("unexpected field `Graph::{key}`")));
}
}
Ok(())
}
fn end(self) -> Result<Self::Ok, Error> {
match (self.dir, self.what) {
(Some(dir), Some(what)) => Ok(Graph {
dir,
what,
cond: self.cond,
alias: self.alias,
}),
_ => Err(Error::custom("`Graph` missing required field(s)")),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use serde::Serialize;
#[test]
fn default() {
let graph = Graph::default();
let serialized = serialize_internal(|| graph.serialize(Serializer.wrap())).unwrap();
assert_eq!(graph, serialized);
}
#[test]
fn with_cond() {
let graph = Graph {
cond: Some(Default::default()),
..Default::default()
};
let serialized = serialize_internal(|| graph.serialize(Serializer.wrap())).unwrap();
assert_eq!(graph, serialized);
}
#[test]
fn with_alias() {
let graph = Graph {
alias: Some(Default::default()),
..Default::default()
};
let serialized = serialize_internal(|| graph.serialize(Serializer.wrap())).unwrap();
assert_eq!(graph, serialized);
}
}

View file

@ -0,0 +1 @@
pub(super) mod vec;

View file

@ -0,0 +1,81 @@
pub mod opt;
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Group;
use crate::sql::Idiom;
use ser::Serializer as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Vec<Group>;
type Error = Error;
type SerializeSeq = SerializeGroupVec;
type SerializeTuple = Impossible<Vec<Group>, Error>;
type SerializeTupleStruct = Impossible<Vec<Group>, Error>;
type SerializeTupleVariant = Impossible<Vec<Group>, Error>;
type SerializeMap = Impossible<Vec<Group>, Error>;
type SerializeStruct = Impossible<Vec<Group>, Error>;
type SerializeStructVariant = Impossible<Vec<Group>, Error>;
const EXPECTED: &'static str = "a `Vec<Group>`";
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Error> {
Ok(SerializeGroupVec(Vec::with_capacity(len.unwrap_or_default())))
}
#[inline]
fn serialize_newtype_struct<T>(
self,
_name: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
value.serialize(self.wrap())
}
}
pub struct SerializeGroupVec(Vec<Group>);
impl serde::ser::SerializeSeq for SerializeGroupVec {
type Ok = Vec<Group>;
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
self.0.push(Group(Idiom(value.serialize(ser::part::vec::Serializer.wrap())?)));
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(self.0)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
#[test]
fn empty() {
let vec: Vec<Group> = Vec::new();
let serialized = serialize_internal(|| vec.serialize(Serializer.wrap())).unwrap();
assert_eq!(vec, serialized);
}
#[test]
fn vec() {
let vec = vec![Group::default()];
let serialized = serialize_internal(|| vec.serialize(Serializer.wrap())).unwrap();
assert_eq!(vec, serialized);
}
}

View file

@ -0,0 +1,56 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Group;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Option<Vec<Group>>;
type Error = Error;
type SerializeSeq = Impossible<Option<Vec<Group>>, Error>;
type SerializeTuple = Impossible<Option<Vec<Group>>, Error>;
type SerializeTupleStruct = Impossible<Option<Vec<Group>>, Error>;
type SerializeTupleVariant = Impossible<Option<Vec<Group>>, Error>;
type SerializeMap = Impossible<Option<Vec<Group>>, Error>;
type SerializeStruct = Impossible<Option<Vec<Group>>, Error>;
type SerializeStructVariant = Impossible<Option<Vec<Group>>, Error>;
const EXPECTED: &'static str = "an `Option<Vec<Group>>`";
#[inline]
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
Ok(None)
}
#[inline]
fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
Ok(Some(value.serialize(super::Serializer.wrap())?))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use ser::Serializer as _;
#[test]
fn none() {
let option: Option<Vec<Group>> = None;
let serialized = serialize_internal(|| option.serialize(Serializer.wrap())).unwrap();
assert_eq!(option, serialized);
}
#[test]
fn some() {
let option = Some(vec![Group::default()]);
let serialized = serialize_internal(|| option.serialize(Serializer.wrap())).unwrap();
assert_eq!(option, serialized);
}
}

View file

@ -0,0 +1,85 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Array;
use crate::sql::Id;
use crate::sql::Object;
use serde::ser::Error as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub(super) struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Id;
type Error = Error;
type SerializeSeq = Impossible<Id, Error>;
type SerializeTuple = Impossible<Id, Error>;
type SerializeTupleStruct = Impossible<Id, Error>;
type SerializeTupleVariant = Impossible<Id, Error>;
type SerializeMap = Impossible<Id, Error>;
type SerializeStruct = Impossible<Id, Error>;
type SerializeStructVariant = Impossible<Id, Error>;
const EXPECTED: &'static str = "an enum `Id`";
#[inline]
fn serialize_newtype_variant<T>(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<Self::Ok, Error>
where
T: ?Sized + Serialize,
{
match variant {
"Number" => Ok(Id::Number(value.serialize(ser::primitive::i64::Serializer.wrap())?)),
"String" => Ok(Id::String(value.serialize(ser::string::Serializer.wrap())?)),
"Array" => Ok(Id::Array(Array(value.serialize(ser::value::vec::Serializer.wrap())?))),
"Object" => {
Ok(Id::Object(Object(value.serialize(ser::value::map::Serializer.wrap())?)))
}
variant => {
Err(Error::custom(format!("unexpected newtype variant `{name}::{variant}`")))
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use ser::Serializer as _;
use serde::Serialize;
#[test]
fn number() {
let id = Id::Number(Default::default());
let serialized = serialize_internal(|| id.serialize(Serializer.wrap())).unwrap();
assert_eq!(id, serialized);
}
#[test]
fn string() {
let id = Id::String(Default::default());
let serialized = serialize_internal(|| id.serialize(Serializer.wrap())).unwrap();
assert_eq!(id, serialized);
}
#[test]
fn array() {
let id = Id::Array(Default::default());
let serialized = serialize_internal(|| id.serialize(Serializer.wrap())).unwrap();
assert_eq!(id, serialized);
}
#[test]
fn object() {
let id = Id::Object(Default::default());
let serialized = serialize_internal(|| id.serialize(Serializer.wrap())).unwrap();
assert_eq!(id, serialized);
}
}

View file

@ -0,0 +1 @@
pub(super) mod opt;

View file

@ -0,0 +1,56 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Limit;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Option<Limit>;
type Error = Error;
type SerializeSeq = Impossible<Option<Limit>, Error>;
type SerializeTuple = Impossible<Option<Limit>, Error>;
type SerializeTupleStruct = Impossible<Option<Limit>, Error>;
type SerializeTupleVariant = Impossible<Option<Limit>, Error>;
type SerializeMap = Impossible<Option<Limit>, Error>;
type SerializeStruct = Impossible<Option<Limit>, Error>;
type SerializeStructVariant = Impossible<Option<Limit>, Error>;
const EXPECTED: &'static str = "an `Option<Limit>`";
#[inline]
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
Ok(None)
}
#[inline]
fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
Ok(Some(Limit(value.serialize(ser::value::Serializer.wrap())?)))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use ser::Serializer as _;
#[test]
fn none() {
let option: Option<Limit> = None;
let serialized = serialize_internal(|| option.serialize(Serializer.wrap())).unwrap();
assert_eq!(option, serialized);
}
#[test]
fn some() {
let option = Some(Limit::default());
let serialized = serialize_internal(|| option.serialize(Serializer.wrap())).unwrap();
assert_eq!(option, serialized);
}
}

View file

@ -0,0 +1,480 @@
mod block;
mod cond;
mod constant;
mod data;
mod datetime;
mod decimal;
mod dir;
mod duration;
mod edges;
mod expression;
mod fetch;
mod field;
mod fields;
mod function;
mod geometry;
mod graph;
mod group;
mod id;
mod limit;
mod model;
mod number;
mod operator;
mod order;
mod output;
mod part;
mod primitive;
mod range;
mod split;
mod start;
mod statement;
mod string;
mod subquery;
mod table;
mod thing;
mod timeout;
mod uuid;
mod value;
mod version;
use serde::ser::Error;
use serde::ser::Serialize;
use serde::ser::SerializeMap;
use serde::ser::SerializeSeq;
use serde::ser::SerializeStruct;
use serde::ser::SerializeStructVariant;
use serde::ser::SerializeTuple;
use serde::ser::SerializeTupleStruct;
use serde::ser::SerializeTupleVariant;
use std::fmt::Display;
pub(crate) use value::to_value;
trait Serializer: Sized {
type Ok;
type Error: Error;
type SerializeSeq: SerializeSeq<Ok = Self::Ok, Error = Self::Error>;
type SerializeTuple: SerializeTuple<Ok = Self::Ok, Error = Self::Error>;
type SerializeTupleStruct: SerializeTupleStruct<Ok = Self::Ok, Error = Self::Error>;
type SerializeTupleVariant: SerializeTupleVariant<Ok = Self::Ok, Error = Self::Error>;
type SerializeMap: SerializeMap<Ok = Self::Ok, Error = Self::Error>;
type SerializeStruct: SerializeStruct<Ok = Self::Ok, Error = Self::Error>;
type SerializeStructVariant: SerializeStructVariant<Ok = Self::Ok, Error = Self::Error>;
const EXPECTED: &'static str;
fn unexpected(typ: &str, value: Option<impl Display>) -> Self::Error {
let message = match value {
Some(value) => format!("unexpected {typ} `{value}`, expected {}", Self::EXPECTED),
None => format!("unexpected {typ}, expected {}", Self::EXPECTED),
};
Self::Error::custom(message)
}
#[inline]
fn wrap(self) -> Wrapper<Self> {
Wrapper(self)
}
fn serialize_bool(self, value: bool) -> Result<Self::Ok, Self::Error> {
Err(Self::unexpected("bool", Some(value)))
}
fn serialize_i8(self, value: i8) -> Result<Self::Ok, Self::Error> {
Err(Self::unexpected("i8", Some(value)))
}
fn serialize_i16(self, value: i16) -> Result<Self::Ok, Self::Error> {
Err(Self::unexpected("i16", Some(value)))
}
fn serialize_i32(self, value: i32) -> Result<Self::Ok, Self::Error> {
Err(Self::unexpected("i32", Some(value)))
}
fn serialize_i64(self, value: i64) -> Result<Self::Ok, Self::Error> {
Err(Self::unexpected("i64", Some(value)))
}
fn serialize_i128(self, value: i128) -> Result<Self::Ok, Self::Error> {
Err(Self::unexpected("i128", Some(value)))
}
fn serialize_u8(self, value: u8) -> Result<Self::Ok, Self::Error> {
Err(Self::unexpected("u8", Some(value)))
}
fn serialize_u16(self, value: u16) -> Result<Self::Ok, Self::Error> {
Err(Self::unexpected("u16", Some(value)))
}
fn serialize_u32(self, value: u32) -> Result<Self::Ok, Self::Error> {
Err(Self::unexpected("u32", Some(value)))
}
fn serialize_u64(self, value: u64) -> Result<Self::Ok, Self::Error> {
Err(Self::unexpected("u64", Some(value)))
}
fn serialize_u128(self, value: u128) -> Result<Self::Ok, Self::Error> {
Err(Self::unexpected("u128", Some(value)))
}
fn serialize_f32(self, value: f32) -> Result<Self::Ok, Self::Error> {
Err(Self::unexpected("f32", Some(value)))
}
fn serialize_f64(self, value: f64) -> Result<Self::Ok, Self::Error> {
Err(Self::unexpected("f64", Some(value)))
}
fn serialize_char(self, value: char) -> Result<Self::Ok, Self::Error> {
Err(Self::unexpected("char", Some(value)))
}
fn serialize_str(self, _value: &str) -> Result<Self::Ok, Self::Error> {
Err(Self::unexpected("str", None::<String>))
}
fn serialize_bytes(self, _value: &[u8]) -> Result<Self::Ok, Self::Error> {
Err(Self::unexpected("bytes", None::<String>))
}
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
Err(Self::unexpected("unit", None::<String>))
}
fn serialize_unit_variant(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<Self::Ok, Self::Error> {
Err(Self::unexpected("unit variant", Some(format!("{name}::{variant}"))))
}
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
Err(Self::unexpected("unit struct", Some(name)))
}
fn serialize_newtype_variant<T>(
self,
name: &'static str,
_variant_index: u32,
_variant: &'static str,
_value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
Err(Self::unexpected("newtype variant", Some(name)))
}
fn serialize_newtype_struct<T>(
self,
name: &'static str,
_value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
Err(Self::unexpected("newtype struct", Some(name)))
}
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
Err(Self::unexpected("none", None::<String>))
}
fn serialize_some<T>(self, _value: &T) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
Err(Self::unexpected("some", None::<String>))
}
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
Err(Self::unexpected("sequence", None::<String>))
}
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
Err(Self::unexpected("tuple", None::<String>))
}
fn serialize_tuple_struct(
self,
name: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleStruct, Self::Error> {
Err(Self::unexpected("tuple struct", Some(name)))
}
fn serialize_tuple_variant(
self,
name: &'static str,
_variant_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> {
Err(Self::unexpected("tuple variant", Some(name)))
}
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
Err(Self::unexpected("map", None::<String>))
}
fn serialize_struct(
self,
name: &'static str,
_len: usize,
) -> Result<Self::SerializeStruct, Self::Error> {
Err(Self::unexpected("struct", Some(name)))
}
fn serialize_struct_variant(
self,
name: &'static str,
_variant_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeStructVariant, Self::Error> {
Err(Self::unexpected("struct variant", Some(name)))
}
fn collect_str<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
where
T: Display,
{
self.serialize_str(&value.to_string())
}
#[inline]
fn is_human_readable(&self) -> bool {
false
}
}
struct Wrapper<S: Serializer>(S);
impl<S> serde::ser::Serializer for Wrapper<S>
where
S: Serializer,
{
type Ok = S::Ok;
type Error = S::Error;
type SerializeSeq = S::SerializeSeq;
type SerializeTuple = S::SerializeTuple;
type SerializeTupleStruct = S::SerializeTupleStruct;
type SerializeTupleVariant = S::SerializeTupleVariant;
type SerializeMap = S::SerializeMap;
type SerializeStruct = S::SerializeStruct;
type SerializeStructVariant = S::SerializeStructVariant;
#[inline]
fn serialize_bool(self, value: bool) -> Result<Self::Ok, Self::Error> {
self.0.serialize_bool(value)
}
#[inline]
fn serialize_i8(self, value: i8) -> Result<Self::Ok, Self::Error> {
self.0.serialize_i8(value)
}
#[inline]
fn serialize_i16(self, value: i16) -> Result<Self::Ok, Self::Error> {
self.0.serialize_i16(value)
}
#[inline]
fn serialize_i32(self, value: i32) -> Result<Self::Ok, Self::Error> {
self.0.serialize_i32(value)
}
#[inline]
fn serialize_i64(self, value: i64) -> Result<Self::Ok, Self::Error> {
self.0.serialize_i64(value)
}
#[inline]
fn serialize_i128(self, value: i128) -> Result<Self::Ok, Self::Error> {
self.0.serialize_i128(value)
}
#[inline]
fn serialize_u8(self, value: u8) -> Result<Self::Ok, Self::Error> {
self.0.serialize_u8(value)
}
#[inline]
fn serialize_u16(self, value: u16) -> Result<Self::Ok, Self::Error> {
self.0.serialize_u16(value)
}
#[inline]
fn serialize_u32(self, value: u32) -> Result<Self::Ok, Self::Error> {
self.0.serialize_u32(value)
}
#[inline]
fn serialize_u64(self, value: u64) -> Result<Self::Ok, Self::Error> {
self.0.serialize_u64(value)
}
#[inline]
fn serialize_u128(self, value: u128) -> Result<Self::Ok, Self::Error> {
self.0.serialize_u128(value)
}
#[inline]
fn serialize_f32(self, value: f32) -> Result<Self::Ok, Self::Error> {
self.0.serialize_f32(value)
}
#[inline]
fn serialize_f64(self, value: f64) -> Result<Self::Ok, Self::Error> {
self.0.serialize_f64(value)
}
#[inline]
fn serialize_char(self, value: char) -> Result<Self::Ok, Self::Error> {
self.0.serialize_char(value)
}
#[inline]
fn serialize_str(self, value: &str) -> Result<Self::Ok, Self::Error> {
self.0.serialize_str(value)
}
#[inline]
fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok, Self::Error> {
self.0.serialize_bytes(value)
}
#[inline]
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
self.0.serialize_unit()
}
#[inline]
fn serialize_unit_variant(
self,
name: &'static str,
variant_index: u32,
variant: &'static str,
) -> Result<Self::Ok, Self::Error> {
self.0.serialize_unit_variant(name, variant_index, variant)
}
#[inline]
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
self.0.serialize_unit_struct(name)
}
#[inline]
fn serialize_newtype_variant<T>(
self,
name: &'static str,
variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
self.0.serialize_newtype_variant(name, variant_index, variant, value)
}
#[inline]
fn serialize_newtype_struct<T>(
self,
name: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
self.0.serialize_newtype_struct(name, value)
}
#[inline]
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
self.0.serialize_none()
}
#[inline]
fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
self.0.serialize_some(value)
}
#[inline]
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
self.0.serialize_seq(len)
}
#[inline]
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
self.0.serialize_tuple(len)
}
#[inline]
fn serialize_tuple_struct(
self,
name: &'static str,
len: usize,
) -> Result<Self::SerializeTupleStruct, Self::Error> {
self.0.serialize_tuple_struct(name, len)
}
#[inline]
fn serialize_tuple_variant(
self,
name: &'static str,
variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> {
self.0.serialize_tuple_variant(name, variant_index, variant, len)
}
#[inline]
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
self.0.serialize_map(len)
}
#[inline]
fn serialize_struct(
self,
name: &'static str,
len: usize,
) -> Result<Self::SerializeStruct, Self::Error> {
self.0.serialize_struct(name, len)
}
#[inline]
fn serialize_struct_variant(
self,
name: &'static str,
variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeStructVariant, Self::Error> {
self.0.serialize_struct_variant(name, variant_index, variant, len)
}
#[inline]
fn collect_str<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
where
T: Display,
{
self.0.collect_str(value)
}
#[inline]
fn is_human_readable(&self) -> bool {
self.0.is_human_readable()
}
}

View file

@ -0,0 +1,116 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Model;
use ser::Serializer as _;
use serde::ser::Error as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub(super) struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Model;
type Error = Error;
type SerializeSeq = Impossible<Model, Error>;
type SerializeTuple = Impossible<Model, Error>;
type SerializeTupleStruct = Impossible<Model, Error>;
type SerializeTupleVariant = SerializeModel;
type SerializeMap = Impossible<Model, Error>;
type SerializeStruct = Impossible<Model, Error>;
type SerializeStructVariant = Impossible<Model, Error>;
const EXPECTED: &'static str = "an enum `Model`";
fn serialize_tuple_variant(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> {
let inner = match variant {
"Count" => Inner::Count(None, None),
"Range" => Inner::Range(None, None, None),
variant => {
return Err(Error::custom(format!("unexpected tuple variant `{name}::{variant}`")));
}
};
Ok(SerializeModel {
inner,
index: 0,
})
}
}
pub(super) struct SerializeModel {
index: usize,
inner: Inner,
}
enum Inner {
Count(Option<String>, Option<u64>),
Range(Option<String>, Option<u64>, Option<u64>),
}
impl serde::ser::SerializeTupleVariant for SerializeModel {
type Ok = Model;
type Error = Error;
fn serialize_field<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
match (self.index, &mut self.inner) {
(0, Inner::Count(ref mut var, _) | Inner::Range(ref mut var, ..)) => {
*var = Some(value.serialize(ser::string::Serializer.wrap())?);
}
(1, Inner::Count(_, ref mut var) | Inner::Range(_, ref mut var, _)) => {
*var = Some(value.serialize(ser::primitive::u64::Serializer.wrap())?);
}
(2, Inner::Range(.., ref mut var)) => {
*var = Some(value.serialize(ser::primitive::u64::Serializer.wrap())?);
}
(index, inner) => {
let variant = match inner {
Inner::Count(..) => "Count",
Inner::Range(..) => "Range",
};
return Err(Error::custom(format!(
"unexpected `Model::{variant}` index `{index}`"
)));
}
}
self.index += 1;
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
match self.inner {
Inner::Count(Some(one), Some(two)) => Ok(Model::Count(one, two)),
Inner::Range(Some(one), Some(two), Some(three)) => Ok(Model::Range(one, two, three)),
_ => Err(Error::custom("`Model` missing required value(s)")),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use serde::Serialize;
#[test]
fn count() {
let model = Model::Count(Default::default(), Default::default());
let serialized = serialize_internal(|| model.serialize(Serializer.wrap())).unwrap();
assert_eq!(model, serialized);
}
#[test]
fn range() {
let model = Model::Range(Default::default(), 1, 2);
let serialized = serialize_internal(|| model.serialize(Serializer.wrap())).unwrap();
assert_eq!(model, serialized);
}
}

View file

@ -0,0 +1,145 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Number;
use bigdecimal::BigDecimal;
use bigdecimal::FromPrimitive as _;
use serde::ser::Error as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub(super) struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Number;
type Error = Error;
type SerializeSeq = Impossible<Number, Error>;
type SerializeTuple = Impossible<Number, Error>;
type SerializeTupleStruct = Impossible<Number, Error>;
type SerializeTupleVariant = Impossible<Number, Error>;
type SerializeMap = Impossible<Number, Error>;
type SerializeStruct = Impossible<Number, Error>;
type SerializeStructVariant = Impossible<Number, Error>;
const EXPECTED: &'static str = "an enum `Number`";
#[inline]
fn serialize_i8(self, value: i8) -> Result<Self::Ok, Error> {
Ok(value.into())
}
#[inline]
fn serialize_i16(self, value: i16) -> Result<Self::Ok, Error> {
Ok(value.into())
}
#[inline]
fn serialize_i32(self, value: i32) -> Result<Self::Ok, Error> {
Ok(value.into())
}
#[inline]
fn serialize_i64(self, value: i64) -> Result<Self::Ok, Error> {
Ok(value.into())
}
fn serialize_i128(self, value: i128) -> Result<Self::Ok, Error> {
match BigDecimal::from_i128(value) {
Some(decimal) => Ok(decimal.into()),
None => Err(Error::TryFromError(value.to_string(), "BigDecimal")),
}
}
#[inline]
fn serialize_u8(self, value: u8) -> Result<Self::Ok, Error> {
Ok(value.into())
}
#[inline]
fn serialize_u16(self, value: u16) -> Result<Self::Ok, Error> {
Ok(value.into())
}
#[inline]
fn serialize_u32(self, value: u32) -> Result<Self::Ok, Error> {
Ok(value.into())
}
#[inline]
fn serialize_u64(self, value: u64) -> Result<Self::Ok, Error> {
Ok(value.into())
}
fn serialize_u128(self, value: u128) -> Result<Self::Ok, Error> {
match BigDecimal::from_u128(value) {
Some(decimal) => Ok(decimal.into()),
None => Err(Error::TryFromError(value.to_string(), "BigDecimal")),
}
}
#[inline]
fn serialize_f32(self, value: f32) -> Result<Self::Ok, Error> {
Ok(value.into())
}
#[inline]
fn serialize_f64(self, value: f64) -> Result<Self::Ok, Error> {
Ok(value.into())
}
#[inline]
fn serialize_str(self, value: &str) -> Result<Self::Ok, Error> {
let decimal = value.parse::<BigDecimal>().map_err(Error::custom)?;
Ok(decimal.into())
}
#[inline]
fn serialize_newtype_variant<T>(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<Self::Ok, Error>
where
T: ?Sized + Serialize,
{
match variant {
"Int" => Ok(Number::Int(value.serialize(ser::primitive::i64::Serializer.wrap())?)),
"Float" => Ok(Number::Float(value.serialize(ser::primitive::f64::Serializer.wrap())?)),
"Decimal" => Ok(Number::Decimal(value.serialize(ser::decimal::Serializer.wrap())?)),
variant => {
Err(Error::custom(format!("unexpected newtype variant `{name}::{variant}`")))
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use ser::Serializer as _;
use serde::Serialize;
#[test]
fn int() {
let number = Number::Int(Default::default());
let serialized = serialize_internal(|| number.serialize(Serializer.wrap())).unwrap();
assert_eq!(number, serialized);
}
#[test]
fn float() {
let number = Number::Float(Default::default());
let serialized = serialize_internal(|| number.serialize(Serializer.wrap())).unwrap();
assert_eq!(number, serialized);
}
#[test]
fn decimal() {
let number = Number::Decimal(Default::default());
let serialized = serialize_internal(|| number.serialize(Serializer.wrap())).unwrap();
assert_eq!(number, serialized);
}
}

View file

@ -0,0 +1,330 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Operator;
use serde::ser::Error as _;
use serde::ser::Impossible;
pub(super) struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Operator;
type Error = Error;
type SerializeSeq = Impossible<Operator, Error>;
type SerializeTuple = Impossible<Operator, Error>;
type SerializeTupleStruct = Impossible<Operator, Error>;
type SerializeTupleVariant = Impossible<Operator, Error>;
type SerializeMap = Impossible<Operator, Error>;
type SerializeStruct = Impossible<Operator, Error>;
type SerializeStructVariant = Impossible<Operator, Error>;
const EXPECTED: &'static str = "an enum `Operator`";
#[inline]
fn serialize_unit_variant(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<Self::Ok, Error> {
match variant {
"Or" => Ok(Operator::Or),
"And" => Ok(Operator::And),
"Tco" => Ok(Operator::Tco),
"Nco" => Ok(Operator::Nco),
"Add" => Ok(Operator::Add),
"Sub" => Ok(Operator::Sub),
"Mul" => Ok(Operator::Mul),
"Div" => Ok(Operator::Div),
"Pow" => Ok(Operator::Pow),
"Inc" => Ok(Operator::Inc),
"Dec" => Ok(Operator::Dec),
"Equal" => Ok(Operator::Equal),
"Exact" => Ok(Operator::Exact),
"NotEqual" => Ok(Operator::NotEqual),
"AllEqual" => Ok(Operator::AllEqual),
"AnyEqual" => Ok(Operator::AnyEqual),
"Like" => Ok(Operator::Like),
"NotLike" => Ok(Operator::NotLike),
"AllLike" => Ok(Operator::AllLike),
"AnyLike" => Ok(Operator::AnyLike),
"LessThan" => Ok(Operator::LessThan),
"LessThanOrEqual" => Ok(Operator::LessThanOrEqual),
"MoreThan" => Ok(Operator::MoreThan),
"MoreThanOrEqual" => Ok(Operator::MoreThanOrEqual),
"Contain" => Ok(Operator::Contain),
"NotContain" => Ok(Operator::NotContain),
"ContainAll" => Ok(Operator::ContainAll),
"ContainAny" => Ok(Operator::ContainAny),
"ContainNone" => Ok(Operator::ContainNone),
"Inside" => Ok(Operator::Inside),
"NotInside" => Ok(Operator::NotInside),
"AllInside" => Ok(Operator::AllInside),
"AnyInside" => Ok(Operator::AnyInside),
"NoneInside" => Ok(Operator::NoneInside),
"Outside" => Ok(Operator::Outside),
"Intersects" => Ok(Operator::Intersects),
variant => Err(Error::custom(format!("unexpected unit variant `{name}::{variant}`"))),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use ser::Serializer as _;
use serde::Serialize;
#[test]
fn or() {
let dir = Operator::Or;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn and() {
let dir = Operator::And;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn tco() {
let dir = Operator::Tco;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn nco() {
let dir = Operator::Nco;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn add() {
let dir = Operator::Add;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn sub() {
let dir = Operator::Sub;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn mul() {
let dir = Operator::Mul;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn div() {
let dir = Operator::Div;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn pow() {
let dir = Operator::Pow;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn inc() {
let dir = Operator::Inc;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn dec() {
let dir = Operator::Dec;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn equal() {
let dir = Operator::Equal;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn exact() {
let dir = Operator::Exact;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn not_equal() {
let dir = Operator::NotEqual;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn all_equal() {
let dir = Operator::AllEqual;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn any_equal() {
let dir = Operator::AnyEqual;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn like() {
let dir = Operator::Like;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn not_like() {
let dir = Operator::NotLike;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn all_like() {
let dir = Operator::AllLike;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn any_like() {
let dir = Operator::AnyLike;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn less_than() {
let dir = Operator::LessThan;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn less_than_or_equal() {
let dir = Operator::LessThanOrEqual;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn more_than() {
let dir = Operator::MoreThan;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn more_than_or_equal() {
let dir = Operator::MoreThanOrEqual;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn contain() {
let dir = Operator::Contain;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn not_contain() {
let dir = Operator::NotContain;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn contain_all() {
let dir = Operator::ContainAll;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn contain_any() {
let dir = Operator::ContainAny;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn contain_none() {
let dir = Operator::ContainNone;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn inside() {
let dir = Operator::Inside;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn not_inside() {
let dir = Operator::NotInside;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn all_inside() {
let dir = Operator::AllInside;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn any_inside() {
let dir = Operator::AnyInside;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn none_inside() {
let dir = Operator::NoneInside;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn outside() {
let dir = Operator::Outside;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
#[test]
fn intersects() {
let dir = Operator::Intersects;
let serialized = serialize_internal(|| dir.serialize(Serializer.wrap())).unwrap();
assert_eq!(dir, serialized);
}
}

View file

@ -0,0 +1,106 @@
pub(super) mod vec;
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Idiom;
use crate::sql::Order;
use ser::Serializer as _;
use serde::ser::Error as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub(super) struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Order;
type Error = Error;
type SerializeSeq = Impossible<Order, Error>;
type SerializeTuple = Impossible<Order, Error>;
type SerializeTupleStruct = Impossible<Order, Error>;
type SerializeTupleVariant = Impossible<Order, Error>;
type SerializeMap = Impossible<Order, Error>;
type SerializeStruct = SerializeOrder;
type SerializeStructVariant = Impossible<Order, Error>;
const EXPECTED: &'static str = "a struct `Order`";
#[inline]
fn serialize_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeStruct, Error> {
Ok(SerializeOrder::default())
}
}
#[derive(Default)]
pub(super) struct SerializeOrder {
order: Option<Idiom>,
random: Option<bool>,
collate: Option<bool>,
numeric: Option<bool>,
direction: Option<bool>,
}
impl serde::ser::SerializeStruct for SerializeOrder {
type Ok = Order;
type Error = Error;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Error>
where
T: ?Sized + Serialize,
{
match key {
"order" => {
self.order = Some(Idiom(value.serialize(ser::part::vec::Serializer.wrap())?));
}
"random" => {
self.random = Some(value.serialize(ser::primitive::bool::Serializer.wrap())?);
}
"collate" => {
self.collate = Some(value.serialize(ser::primitive::bool::Serializer.wrap())?);
}
"numeric" => {
self.numeric = Some(value.serialize(ser::primitive::bool::Serializer.wrap())?);
}
"direction" => {
self.direction = Some(value.serialize(ser::primitive::bool::Serializer.wrap())?);
}
key => {
return Err(Error::custom(format!("unexpected field `Order::{key}`")));
}
}
Ok(())
}
fn end(self) -> Result<Self::Ok, Error> {
match (self.order, self.random, self.collate, self.numeric, self.direction) {
(Some(order), Some(random), Some(collate), Some(numeric), Some(direction)) => {
Ok(Order {
order,
random,
collate,
numeric,
direction,
})
}
_ => Err(Error::custom("`Order` missing required field(s)")),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use serde::Serialize;
#[test]
fn default() {
let order = Order::default();
let serialized = serialize_internal(|| order.serialize(Serializer.wrap())).unwrap();
assert_eq!(order, serialized);
}
}

View file

@ -0,0 +1,80 @@
pub mod opt;
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Order;
use ser::Serializer as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Vec<Order>;
type Error = Error;
type SerializeSeq = SerializeOrderVec;
type SerializeTuple = Impossible<Vec<Order>, Error>;
type SerializeTupleStruct = Impossible<Vec<Order>, Error>;
type SerializeTupleVariant = Impossible<Vec<Order>, Error>;
type SerializeMap = Impossible<Vec<Order>, Error>;
type SerializeStruct = Impossible<Vec<Order>, Error>;
type SerializeStructVariant = Impossible<Vec<Order>, Error>;
const EXPECTED: &'static str = "a `Vec<Order>`";
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Error> {
Ok(SerializeOrderVec(Vec::with_capacity(len.unwrap_or_default())))
}
#[inline]
fn serialize_newtype_struct<T>(
self,
_name: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
value.serialize(self.wrap())
}
}
pub struct SerializeOrderVec(Vec<Order>);
impl serde::ser::SerializeSeq for SerializeOrderVec {
type Ok = Vec<Order>;
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize + ?Sized,
{
self.0.push(value.serialize(super::Serializer.wrap())?);
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(self.0)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
#[test]
fn empty() {
let vec: Vec<Order> = Vec::new();
let serialized = serialize_internal(|| vec.serialize(Serializer.wrap())).unwrap();
assert_eq!(vec, serialized);
}
#[test]
fn vec() {
let vec = vec![Order::default()];
let serialized = serialize_internal(|| vec.serialize(Serializer.wrap())).unwrap();
assert_eq!(vec, serialized);
}
}

View file

@ -0,0 +1,56 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Order;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Option<Vec<Order>>;
type Error = Error;
type SerializeSeq = Impossible<Option<Vec<Order>>, Error>;
type SerializeTuple = Impossible<Option<Vec<Order>>, Error>;
type SerializeTupleStruct = Impossible<Option<Vec<Order>>, Error>;
type SerializeTupleVariant = Impossible<Option<Vec<Order>>, Error>;
type SerializeMap = Impossible<Option<Vec<Order>>, Error>;
type SerializeStruct = Impossible<Option<Vec<Order>>, Error>;
type SerializeStructVariant = Impossible<Option<Vec<Order>>, Error>;
const EXPECTED: &'static str = "an `Option<Vec<Order>>`";
#[inline]
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
Ok(None)
}
#[inline]
fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
Ok(Some(value.serialize(super::Serializer.wrap())?))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use ser::Serializer as _;
#[test]
fn none() {
let option: Option<Vec<Order>> = None;
let serialized = serialize_internal(|| option.serialize(Serializer.wrap())).unwrap();
assert_eq!(option, serialized);
}
#[test]
fn some() {
let option = Some(vec![Order::default()]);
let serialized = serialize_internal(|| option.serialize(Serializer.wrap())).unwrap();
assert_eq!(option, serialized);
}
}

View file

@ -0,0 +1,110 @@
pub(super) mod opt;
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Output;
use serde::ser::Error as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub(super) struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Output;
type Error = Error;
type SerializeSeq = Impossible<Output, Error>;
type SerializeTuple = Impossible<Output, Error>;
type SerializeTupleStruct = Impossible<Output, Error>;
type SerializeTupleVariant = Impossible<Output, Error>;
type SerializeMap = Impossible<Output, Error>;
type SerializeStruct = Impossible<Output, Error>;
type SerializeStructVariant = Impossible<Output, Error>;
const EXPECTED: &'static str = "an enum `Output`";
fn serialize_unit_variant(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<Self::Ok, Error> {
match variant {
"None" => Ok(Output::None),
"Null" => Ok(Output::Null),
"Diff" => Ok(Output::Diff),
"After" => Ok(Output::After),
"Before" => Ok(Output::Before),
variant => Err(Error::custom(format!("unexpected unit variant `{name}::{variant}`"))),
}
}
#[inline]
fn serialize_newtype_variant<T>(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<Self::Ok, Error>
where
T: ?Sized + Serialize,
{
match variant {
"Fields" => Ok(Output::Fields(value.serialize(ser::fields::Serializer.wrap())?)),
variant => {
Err(Error::custom(format!("unexpected newtype variant `{name}::{variant}`")))
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use ser::Serializer as _;
use serde::Serialize;
#[test]
fn none() {
let output = Output::None;
let serialized = serialize_internal(|| output.serialize(Serializer.wrap())).unwrap();
assert_eq!(output, serialized);
}
#[test]
fn null() {
let output = Output::Null;
let serialized = serialize_internal(|| output.serialize(Serializer.wrap())).unwrap();
assert_eq!(output, serialized);
}
#[test]
fn diff() {
let output = Output::Diff;
let serialized = serialize_internal(|| output.serialize(Serializer.wrap())).unwrap();
assert_eq!(output, serialized);
}
#[test]
fn after() {
let output = Output::After;
let serialized = serialize_internal(|| output.serialize(Serializer.wrap())).unwrap();
assert_eq!(output, serialized);
}
#[test]
fn before() {
let output = Output::Before;
let serialized = serialize_internal(|| output.serialize(Serializer.wrap())).unwrap();
assert_eq!(output, serialized);
}
#[test]
fn fields() {
let output = Output::Fields(Default::default());
let serialized = serialize_internal(|| output.serialize(Serializer.wrap())).unwrap();
assert_eq!(output, serialized);
}
}

View file

@ -0,0 +1,56 @@
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Output;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Option<Output>;
type Error = Error;
type SerializeSeq = Impossible<Option<Output>, Error>;
type SerializeTuple = Impossible<Option<Output>, Error>;
type SerializeTupleStruct = Impossible<Option<Output>, Error>;
type SerializeTupleVariant = Impossible<Option<Output>, Error>;
type SerializeMap = Impossible<Option<Output>, Error>;
type SerializeStruct = Impossible<Option<Output>, Error>;
type SerializeStructVariant = Impossible<Option<Output>, Error>;
const EXPECTED: &'static str = "an `Option<Output>`";
#[inline]
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
Ok(None)
}
#[inline]
fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
where
T: ?Sized + Serialize,
{
Ok(Some(value.serialize(super::Serializer.wrap())?))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql::serde::serialize_internal;
use ser::Serializer as _;
#[test]
fn none() {
let option: Option<Output> = None;
let serialized = serialize_internal(|| option.serialize(Serializer.wrap())).unwrap();
assert_eq!(option, serialized);
}
#[test]
fn some() {
let option = Some(Output::default());
let serialized = serialize_internal(|| option.serialize(Serializer.wrap())).unwrap();
assert_eq!(option, serialized);
}
}

View file

@ -0,0 +1,129 @@
pub(super) mod vec;
use crate::err::Error;
use crate::sql::value::serde::ser;
use crate::sql::Ident;
use crate::sql::Part;
use serde::ser::Error as _;
use serde::ser::Impossible;
use serde::ser::Serialize;
pub(super) struct Serializer;
impl ser::Serializer for Serializer {
type Ok = Part;
type Error = Error;
type SerializeSeq = Impossible<Part, Error>;
type SerializeTuple = Impossible<Part, Error>;
type SerializeTupleStruct = Impossible<Part, Error>;
type SerializeTupleVariant = Impossible<Part, Error>;
type SerializeMap = Impossible<Part, Error>;
type SerializeStruct = Impossible<Part, Error>;
type SerializeStructVariant = Impossible<Part, Error>;
const EXPECTED: &'static str = "an enum `Part`";
#[inline]
fn serialize_unit_variant(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<Self::Ok, Error> {
match variant {
"All" => Ok(Part::All),
"Last" => Ok(Part::Last),
"First" => Ok(Part::First),
variant => Err(Error::custom(format!("unexpected unit variant `{name}::{variant}`"))),
}
}
#[inline]
fn serialize_newtype_variant<T>(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<Self::Ok, Error>
where
T: ?Sized + Serialize,
{
match variant {
"Field" => Ok(Part::Field(Ident(value.serialize(ser::string::Serializer.wrap())?))),
"Index" => Ok(Part::Index(value.serialize(ser::number::Serializer.wrap())?)),
"Where" => Ok(Part::Where(value.serialize(ser::value::Serializer.wrap())?)),
"Thing" => Ok(Part::Thing(value.serialize(ser::thing::Serializer.wrap())?)),
"Graph" => Ok(Part::Graph(value.serialize(ser::graph::Serializer.wrap())?)),
variant => {
Err(Error::custom(format!("unexpected newtype variant `{name}::{variant}`")))
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::sql;
use crate::sql::serde::serialize_internal;
use ser::Serializer as _;
use serde::Serialize;
#[test]
fn all() {
let part = Part::All;
let serialized = serialize_internal(|| part.serialize(Serializer.wrap())).unwrap();
assert_eq!(part, serialized);
}
#[test]
fn last() {
let part = Part::Last;
let serialized = serialize_internal(|| part.serialize(Serializer.wrap())).unwrap();
assert_eq!(part, serialized);
}
#[test]
fn first() {
let part = Part::First;
let serialized = serialize_internal(|| part.serialize(Serializer.wrap())).unwrap();
assert_eq!(part, serialized);
}
#[test]
fn field() {
let part = Part::Field(Default::default());
let serialized = serialize_internal(|| part.serialize(Serializer.wrap())).unwrap();
assert_eq!(part, serialized);
}
#[test]
fn index() {
let part = Part::Index(Default::default());
let serialized = serialize_internal(|| part.serialize(Serializer.wrap())).unwrap();
assert_eq!(part, serialized);
}
#[test]
fn r#where() {
let part = Part::Where(Default::default());
let serialized = serialize_internal(|| part.serialize(Serializer.wrap())).unwrap();
assert_eq!(part, serialized);
}
#[test]
fn thing() {
let part = Part::Thing(sql::thing("foo:bar").unwrap());
let serialized = serialize_internal(|| part.serialize(Serializer.wrap())).unwrap();
assert_eq!(part, serialized);
}
#[test]
fn graph() {
let part = Part::Graph(Default::default());
let serialized = serialize_internal(|| part.serialize(Serializer.wrap())).unwrap();
assert_eq!(part, serialized);
}
}

Some files were not shown because too many files have changed in this diff Show more