Implement to_value
for sql::Value
(#1659)
`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:
parent
86f768e996
commit
3e80aa9914
143 changed files with 9130 additions and 291 deletions
.github/workflows
lib
README.md
examples
src
api
engine
method
opt
dbs
sql
array.rsblock.rsconstant.rsdatetime.rsduration.rsedges.rsexpression.rsfunction.rsfuture.rsgeometry.rsid.rsidiom.rsmod.rsmodel.rsnumber.rsobject.rsparam.rsrange.rsregex.rsstrand.rssubquery.rstable.rsthing.rsuuid.rs
value
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
@ -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:
|
||||
|
|
2
.github/workflows/nightly.yml
vendored
2
.github/workflows/nightly.yml
vendored
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(),
|
||||
})
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
|
@ -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!(),
|
||||
}
|
||||
})
|
||||
|
|
|
@ -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!(),
|
||||
}
|
||||
})
|
||||
|
|
|
@ -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!(),
|
||||
}
|
||||
})
|
||||
|
|
|
@ -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!(),
|
||||
}
|
||||
})
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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!(),
|
||||
}
|
||||
})
|
||||
|
|
|
@ -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!(),
|
||||
}
|
||||
})
|
||||
|
|
|
@ -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!(),
|
||||
}
|
||||
})
|
||||
|
|
|
@ -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!(),
|
||||
}
|
||||
})
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
})
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
|
|
@ -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!(),
|
||||
}
|
||||
})
|
||||
|
|
|
@ -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 ¶ms[..] {
|
||||
|
@ -71,12 +67,12 @@ pub(super) fn mock(route_rx: Receiver<Option<Route>>) {
|
|||
_ => unreachable!(),
|
||||
},
|
||||
Method::Create => match ¶ms[..] {
|
||||
[_] => 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 ¶ms[..] {
|
||||
[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 ¶ms[..] {
|
||||
[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(..), _] => {
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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(),
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
pub use self::value::*;
|
||||
|
||||
pub(super) mod serde;
|
||||
|
||||
#[allow(clippy::module_inception)]
|
||||
mod value;
|
||||
|
||||
|
|
3
lib/src/sql/value/serde/mod.rs
Normal file
3
lib/src/sql/value/serde/mod.rs
Normal file
|
@ -0,0 +1,3 @@
|
|||
mod ser;
|
||||
|
||||
pub(crate) use ser::to_value;
|
145
lib/src/sql/value/serde/ser/block/entry/mod.rs
Normal file
145
lib/src/sql/value/serde/ser/block/entry/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
78
lib/src/sql/value/serde/ser/block/entry/vec.rs
Normal file
78
lib/src/sql/value/serde/ser/block/entry/vec.rs
Normal 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);
|
||||
}
|
||||
}
|
1
lib/src/sql/value/serde/ser/block/mod.rs
Normal file
1
lib/src/sql/value/serde/ser/block/mod.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub(super) mod entry;
|
1
lib/src/sql/value/serde/ser/cond/mod.rs
Normal file
1
lib/src/sql/value/serde/ser/cond/mod.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub(super) mod opt;
|
56
lib/src/sql/value/serde/ser/cond/opt.rs
Normal file
56
lib/src/sql/value/serde/ser/cond/opt.rs
Normal 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);
|
||||
}
|
||||
}
|
194
lib/src/sql/value/serde/ser/constant/mod.rs
Normal file
194
lib/src/sql/value/serde/ser/constant/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
408
lib/src/sql/value/serde/ser/data/mod.rs
Normal file
408
lib/src/sql/value/serde/ser/data/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
56
lib/src/sql/value/serde/ser/data/opt.rs
Normal file
56
lib/src/sql/value/serde/ser/data/opt.rs
Normal 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);
|
||||
}
|
||||
}
|
60
lib/src/sql/value/serde/ser/datetime/mod.rs
Normal file
60
lib/src/sql/value/serde/ser/datetime/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
46
lib/src/sql/value/serde/ser/decimal/mod.rs
Normal file
46
lib/src/sql/value/serde/ser/decimal/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
66
lib/src/sql/value/serde/ser/dir/mod.rs
Normal file
66
lib/src/sql/value/serde/ser/dir/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
97
lib/src/sql/value/serde/ser/duration/mod.rs
Normal file
97
lib/src/sql/value/serde/ser/duration/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
56
lib/src/sql/value/serde/ser/duration/opt.rs
Normal file
56
lib/src/sql/value/serde/ser/duration/opt.rs
Normal 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);
|
||||
}
|
||||
}
|
99
lib/src/sql/value/serde/ser/edges/mod.rs
Normal file
99
lib/src/sql/value/serde/ser/edges/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
104
lib/src/sql/value/serde/ser/expression/mod.rs
Normal file
104
lib/src/sql/value/serde/ser/expression/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
1
lib/src/sql/value/serde/ser/fetch/mod.rs
Normal file
1
lib/src/sql/value/serde/ser/fetch/mod.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub(super) mod vec;
|
81
lib/src/sql/value/serde/ser/fetch/vec/mod.rs
Normal file
81
lib/src/sql/value/serde/ser/fetch/vec/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
56
lib/src/sql/value/serde/ser/fetch/vec/opt.rs
Normal file
56
lib/src/sql/value/serde/ser/fetch/vec/opt.rs
Normal 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);
|
||||
}
|
||||
}
|
139
lib/src/sql/value/serde/ser/field/mod.rs
Normal file
139
lib/src/sql/value/serde/ser/field/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
78
lib/src/sql/value/serde/ser/field/vec.rs
Normal file
78
lib/src/sql/value/serde/ser/field/vec.rs
Normal 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);
|
||||
}
|
||||
}
|
91
lib/src/sql/value/serde/ser/fields/mod.rs
Normal file
91
lib/src/sql/value/serde/ser/fields/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
153
lib/src/sql/value/serde/ser/function/mod.rs
Normal file
153
lib/src/sql/value/serde/ser/function/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
99
lib/src/sql/value/serde/ser/geometry/coord/mod.rs
Normal file
99
lib/src/sql/value/serde/ser/geometry/coord/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
78
lib/src/sql/value/serde/ser/geometry/coord/vec.rs
Normal file
78
lib/src/sql/value/serde/ser/geometry/coord/vec.rs
Normal 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);
|
||||
}
|
||||
}
|
1
lib/src/sql/value/serde/ser/geometry/line_string/mod.rs
Normal file
1
lib/src/sql/value/serde/ser/geometry/line_string/mod.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub mod vec;
|
79
lib/src/sql/value/serde/ser/geometry/line_string/vec.rs
Normal file
79
lib/src/sql/value/serde/ser/geometry/line_string/vec.rs
Normal 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);
|
||||
}
|
||||
}
|
156
lib/src/sql/value/serde/ser/geometry/mod.rs
Normal file
156
lib/src/sql/value/serde/ser/geometry/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
1
lib/src/sql/value/serde/ser/geometry/point/mod.rs
Normal file
1
lib/src/sql/value/serde/ser/geometry/point/mod.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub mod vec;
|
78
lib/src/sql/value/serde/ser/geometry/point/vec.rs
Normal file
78
lib/src/sql/value/serde/ser/geometry/point/vec.rs
Normal 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);
|
||||
}
|
||||
}
|
88
lib/src/sql/value/serde/ser/geometry/polygon/mod.rs
Normal file
88
lib/src/sql/value/serde/ser/geometry/polygon/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
79
lib/src/sql/value/serde/ser/geometry/polygon/vec.rs
Normal file
79
lib/src/sql/value/serde/ser/geometry/polygon/vec.rs
Normal 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);
|
||||
}
|
||||
}
|
66
lib/src/sql/value/serde/ser/geometry/vec.rs
Normal file
66
lib/src/sql/value/serde/ser/geometry/vec.rs
Normal 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);
|
||||
}
|
||||
}
|
120
lib/src/sql/value/serde/ser/graph/mod.rs
Normal file
120
lib/src/sql/value/serde/ser/graph/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
1
lib/src/sql/value/serde/ser/group/mod.rs
Normal file
1
lib/src/sql/value/serde/ser/group/mod.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub(super) mod vec;
|
81
lib/src/sql/value/serde/ser/group/vec/mod.rs
Normal file
81
lib/src/sql/value/serde/ser/group/vec/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
56
lib/src/sql/value/serde/ser/group/vec/opt.rs
Normal file
56
lib/src/sql/value/serde/ser/group/vec/opt.rs
Normal 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);
|
||||
}
|
||||
}
|
85
lib/src/sql/value/serde/ser/id/mod.rs
Normal file
85
lib/src/sql/value/serde/ser/id/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
1
lib/src/sql/value/serde/ser/limit/mod.rs
Normal file
1
lib/src/sql/value/serde/ser/limit/mod.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub(super) mod opt;
|
56
lib/src/sql/value/serde/ser/limit/opt.rs
Normal file
56
lib/src/sql/value/serde/ser/limit/opt.rs
Normal 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);
|
||||
}
|
||||
}
|
480
lib/src/sql/value/serde/ser/mod.rs
Normal file
480
lib/src/sql/value/serde/ser/mod.rs
Normal 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()
|
||||
}
|
||||
}
|
116
lib/src/sql/value/serde/ser/model/mod.rs
Normal file
116
lib/src/sql/value/serde/ser/model/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
145
lib/src/sql/value/serde/ser/number/mod.rs
Normal file
145
lib/src/sql/value/serde/ser/number/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
330
lib/src/sql/value/serde/ser/operator/mod.rs
Normal file
330
lib/src/sql/value/serde/ser/operator/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
106
lib/src/sql/value/serde/ser/order/mod.rs
Normal file
106
lib/src/sql/value/serde/ser/order/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
80
lib/src/sql/value/serde/ser/order/vec/mod.rs
Normal file
80
lib/src/sql/value/serde/ser/order/vec/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
56
lib/src/sql/value/serde/ser/order/vec/opt.rs
Normal file
56
lib/src/sql/value/serde/ser/order/vec/opt.rs
Normal 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);
|
||||
}
|
||||
}
|
110
lib/src/sql/value/serde/ser/output/mod.rs
Normal file
110
lib/src/sql/value/serde/ser/output/mod.rs
Normal 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);
|
||||
}
|
||||
}
|
56
lib/src/sql/value/serde/ser/output/opt.rs
Normal file
56
lib/src/sql/value/serde/ser/output/opt.rs
Normal 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);
|
||||
}
|
||||
}
|
129
lib/src/sql/value/serde/ser/part/mod.rs
Normal file
129
lib/src/sql/value/serde/ser/part/mod.rs
Normal 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
Loading…
Reference in a new issue