move to basic suggested deserialization for string/map

This commit is contained in:
emilis 2022-12-14 23:23:35 +00:00
parent 1e7c59c5a4
commit 62c4946dfb
6 changed files with 38 additions and 41 deletions

13
Cargo.lock generated
View File

@ -339,7 +339,7 @@ dependencies = [
[[package]]
name = "flabk-derive"
version = "0.1.0"
source = "git+https://sectorinf.com/emilis/flabk-derive#d5647801bb9fe24edcb1165c900ce5f3d7f24cee"
source = "git+https://sectorinf.com/emilis/flabk-derive#396181b0201da8bc8ea2fa73d9fbe21f1c4a2b20"
dependencies = [
"proc-macro2",
"quote",
@ -1289,7 +1289,8 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.147"
source = "git+https://sectorinf.com/emilis/serde#adabf4f770d7d0e2f5554720b27c2d73a168f9cc"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
dependencies = [
"serde_derive",
]
@ -1297,7 +1298,8 @@ dependencies = [
[[package]]
name = "serde_derive"
version = "1.0.147"
source = "git+https://sectorinf.com/emilis/serde#adabf4f770d7d0e2f5554720b27c2d73a168f9cc"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
dependencies = [
"proc-macro2",
"quote",
@ -1306,8 +1308,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.87"
source = "git+https://sectorinf.com/emilis/serde_json#18a1411b84b99082f0390775dd6607474aa7dd10"
version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
dependencies = [
"itoa",
"ryu",

View File

@ -32,7 +32,3 @@ tokio = { version = "1", features = ["full"] }
tokio-postgres = { version = "0.7.7", features = ["with-serde_json-1"] }
tower-cookies = "0.7.0"
flabk-derive = { git = "https://sectorinf.com/emilis/flabk-derive" }
[patch.crates-io]
serde = { git = "https://sectorinf.com/emilis/serde" }
serde_json = { git = "https://sectorinf.com/emilis/serde_json" }

2
rust-toolchain.toml Normal file
View File

@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"

View File

@ -1,4 +1,5 @@
use super::serde_ext::IriPartial;
use std::str::FromStr;
use serde::Deserialize;
pub const CONTEXT_ID: &str = "https://www.w3.org/ns/activitystreams";
@ -10,9 +11,13 @@ pub struct Context {
pub ctx: ContextMap,
}
impl IriPartial for Context {
fn set_id(&mut self, new_id: &str) {
self.id = Some(new_id.into());
impl FromStr for Context {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut ctx = Self::default();
ctx.id = Some(s.into());
Ok(ctx)
}
}

View File

@ -1,7 +1,6 @@
use async_trait::async_trait;
use flabk_derive::IRI;
use serde::{Deserialize, Serialize};
use serde_ext::IriPartial;
use self::{
context::Context,

View File

@ -1,51 +1,45 @@
use std::{fmt, marker::PhantomData};
use std::{convert::Infallible, fmt, marker::PhantomData, str::FromStr};
use serde::{de::Visitor, Deserialize, Deserializer};
pub trait IriPartial: Default {
fn set_id(&mut self, new_id: &str);
}
use serde::{
de::{self, MapAccess, Visitor},
Deserialize, Deserializer,
};
// Allows a value that's a string to be expanded into an object (move string into id property via From<IRI>)
// AND the serialization of that object itself
pub(super) fn expand_partial<'de, D, Out>(deserializer: D) -> Result<Out, D::Error>
pub fn expand_partial<'de, T, D>(deserializer: D) -> Result<T, D::Error>
where
T: Deserialize<'de> + FromStr<Err = ()>,
D: Deserializer<'de>,
Out: for<'dt> serde::Deserialize<'dt> + IriPartial,
{
struct ResolveVisitor<Out> {
_type: PhantomData<Out>,
}
struct BaseExpander<T>(PhantomData<fn() -> T>);
impl<'de, Out> Visitor<'de> for ResolveVisitor<Out>
impl<'de, T> Visitor<'de> for BaseExpander<T>
where
Out: for<'dt> serde::Deserialize<'dt> + IriPartial,
T: Deserialize<'de> + FromStr<Err = ()>,
{
type Value = Out;
type Value = T;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(std::any::type_name::<Out>())
formatter.write_str("string or map")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
fn visit_str<E>(self, value: &str) -> Result<T, E>
where
E: serde::de::Error,
E: de::Error,
{
let mut out = Out::default();
out.set_id(value);
Ok(out)
Ok(FromStr::from_str(value).unwrap())
}
fn visit_seq<S>(self, visitor: S) -> Result<Self::Value, S::Error>
fn visit_map<M>(self, map: M) -> Result<T, M::Error>
where
S: serde::de::SeqAccess<'de>,
M: MapAccess<'de>,
{
Deserialize::deserialize(serde::de::value::SeqAccessDeserializer::new(visitor))
Deserialize::deserialize(de::value::MapAccessDeserializer::new(map))
}
}
let resolve_visitor = ResolveVisitor { _type: PhantomData };
deserializer.deserialize_map_string(resolve_visitor, |des| Out::deserialize(des))
deserializer.deserialize_any(BaseExpander(PhantomData))
}
// Allows deserialization of a single item into a vector of that item
@ -91,8 +85,6 @@ mod tests {
use flabk_derive::IRI;
use serde::Deserialize;
use crate::astreams::serde_ext::IriPartial;
use super::expand_partial;
#[test]