change expand into a partial expand to remove resolver dependency
This commit is contained in:
parent
271eba8d7b
commit
1e7c59c5a4
|
@ -321,6 +321,7 @@ dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"axum",
|
"axum",
|
||||||
"base-62",
|
"base-62",
|
||||||
|
"flabk-derive",
|
||||||
"handlebars",
|
"handlebars",
|
||||||
"jsonwebtoken",
|
"jsonwebtoken",
|
||||||
"mime_guess",
|
"mime_guess",
|
||||||
|
@ -335,6 +336,16 @@ dependencies = [
|
||||||
"tower-cookies",
|
"tower-cookies",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flabk-derive"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://sectorinf.com/emilis/flabk-derive#d5647801bb9fe24edcb1165c900ce5f3d7f24cee"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
|
|
|
@ -31,6 +31,7 @@ serde_json = "1.0.85"
|
||||||
tokio = { version = "1", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
tokio-postgres = { version = "0.7.7", features = ["with-serde_json-1"] }
|
tokio-postgres = { version = "0.7.7", features = ["with-serde_json-1"] }
|
||||||
tower-cookies = "0.7.0"
|
tower-cookies = "0.7.0"
|
||||||
|
flabk-derive = { git = "https://sectorinf.com/emilis/flabk-derive" }
|
||||||
|
|
||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
serde = { git = "https://sectorinf.com/emilis/serde" }
|
serde = { git = "https://sectorinf.com/emilis/serde" }
|
||||||
|
|
|
@ -1,13 +1,21 @@
|
||||||
|
use super::serde_ext::IriPartial;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
pub const CONTEXT_ID: &str = "https://www.w3.org/ns/activitystreams";
|
pub const CONTEXT_ID: &str = "https://www.w3.org/ns/activitystreams";
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, Deserialize)]
|
#[derive(Default, Debug, Clone, Deserialize)]
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
|
pub id: Option<String>,
|
||||||
#[serde(rename = "@context")]
|
#[serde(rename = "@context")]
|
||||||
pub ctx: ContextMap,
|
pub ctx: ContextMap,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl IriPartial for Context {
|
||||||
|
fn set_id(&mut self, new_id: &str) {
|
||||||
|
self.id = Some(new_id.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, Deserialize)]
|
#[derive(Default, Debug, Clone, Deserialize)]
|
||||||
#[serde(rename_all = "PascalCase")]
|
#[serde(rename_all = "PascalCase")]
|
||||||
pub struct ContextMap {
|
pub struct ContextMap {
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use flabk_derive::IRI;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_ext::IriPartial;
|
||||||
|
|
||||||
use self::{
|
use self::{
|
||||||
context::Context,
|
context::Context,
|
||||||
note::Note,
|
note::Note,
|
||||||
resolve::ResolveError,
|
resolve::ResolveError,
|
||||||
serde_ext::{expand, pull_single_into_vec},
|
serde_ext::{expand_partial, pull_single_into_vec},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub mod context;
|
pub mod context;
|
||||||
|
@ -54,17 +56,18 @@ pub struct ActivityLD {
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Activity {
|
pub struct Activity {
|
||||||
#[serde(rename = "@context")]
|
// #[serde(rename = "@context")]
|
||||||
#[serde(deserialize_with = "expand")]
|
// #[serde(deserialize_with = "expand_partial")]
|
||||||
pub ap_context: Context,
|
// pub ap_context: Context,
|
||||||
pub id: String,
|
pub id: String,
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
pub kind: ActivityKind,
|
pub kind: ActivityKind,
|
||||||
|
#[serde(deserialize_with = "expand_partial")]
|
||||||
pub attributed_to: Actor,
|
pub attributed_to: Actor,
|
||||||
pub content: Option<String>,
|
pub content: Option<String>,
|
||||||
// pub context: Option<String>,
|
pub context: Option<String>,
|
||||||
#[serde(deserialize_with = "expand")]
|
#[serde(deserialize_with = "pull_single_into_vec")]
|
||||||
pub to: Context,
|
pub to: Vec<String>,
|
||||||
pub url: Option<String>,
|
pub url: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +92,7 @@ pub struct ObjectLD {
|
||||||
|
|
||||||
pub enum ActorType {}
|
pub enum ActorType {}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize, IRI, Default)]
|
||||||
pub struct Actor {
|
pub struct Actor {
|
||||||
id: String,
|
id: String,
|
||||||
}
|
}
|
||||||
|
@ -110,7 +113,6 @@ pub async fn test() {
|
||||||
}"#;
|
}"#;
|
||||||
|
|
||||||
let obj = serde_json::from_str::<Activity>(obj).unwrap();
|
let obj = serde_json::from_str::<Activity>(obj).unwrap();
|
||||||
println!("to: {:#?}", &obj.to);
|
|
||||||
println!();
|
println!();
|
||||||
println!("{:#?}", obj);
|
println!("{:#?}", obj);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,25 @@
|
||||||
use super::resolve::Resolver;
|
|
||||||
use std::{fmt, marker::PhantomData};
|
use std::{fmt, marker::PhantomData};
|
||||||
|
|
||||||
use serde::{de::Visitor, Deserialize, Deserializer};
|
use serde::{de::Visitor, Deserialize, Deserializer};
|
||||||
|
|
||||||
// Allows a value that's a string to be expanded into an object AND the serialization of that object itself
|
pub trait IriPartial: Default {
|
||||||
// TODO: deserializing the actual object isnt supported atm LOL
|
fn set_id(&mut self, new_id: &str);
|
||||||
pub(super) fn expand<'de, D, Out>(deserializer: D) -> Result<Out, D::Error>
|
}
|
||||||
|
|
||||||
|
// 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>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
Out: for<'dt> serde::Deserialize<'dt>,
|
Out: for<'dt> serde::Deserialize<'dt> + IriPartial,
|
||||||
{
|
{
|
||||||
let resolver = Resolver::new();
|
|
||||||
struct ResolveVisitor<Out> {
|
struct ResolveVisitor<Out> {
|
||||||
resolver: Resolver,
|
|
||||||
_type: PhantomData<Out>,
|
_type: PhantomData<Out>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, Out> Visitor<'de> for ResolveVisitor<Out>
|
impl<'de, Out> Visitor<'de> for ResolveVisitor<Out>
|
||||||
where
|
where
|
||||||
Out: for<'dt> serde::Deserialize<'dt>,
|
Out: for<'dt> serde::Deserialize<'dt> + IriPartial,
|
||||||
{
|
{
|
||||||
type Value = Out;
|
type Value = Out;
|
||||||
|
|
||||||
|
@ -30,18 +31,9 @@ where
|
||||||
where
|
where
|
||||||
E: serde::de::Error,
|
E: serde::de::Error,
|
||||||
{
|
{
|
||||||
tokio::runtime::Runtime::new()
|
let mut out = Out::default();
|
||||||
.unwrap()
|
out.set_id(value);
|
||||||
.block_on(self.resolver.resolve_into::<Out>(value.to_string()))
|
Ok(out)
|
||||||
.map_err(|e| {
|
|
||||||
let name = std::any::type_name::<Out>();
|
|
||||||
serde::de::Error::invalid_value(
|
|
||||||
serde::de::Unexpected::Other(
|
|
||||||
format!("failed resolving iri [{}]: {}", value, e.0).as_str(),
|
|
||||||
),
|
|
||||||
&name,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_seq<S>(self, visitor: S) -> Result<Self::Value, S::Error>
|
fn visit_seq<S>(self, visitor: S) -> Result<Self::Value, S::Error>
|
||||||
|
@ -52,10 +44,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let resolve_visitor = ResolveVisitor {
|
let resolve_visitor = ResolveVisitor { _type: PhantomData };
|
||||||
resolver: resolver,
|
|
||||||
_type: PhantomData,
|
|
||||||
};
|
|
||||||
deserializer.deserialize_map_string(resolve_visitor, |des| Out::deserialize(des))
|
deserializer.deserialize_map_string(resolve_visitor, |des| Out::deserialize(des))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,28 +88,38 @@ where
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use flabk_derive::IRI;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use super::expand;
|
use crate::astreams::serde_ext::IriPartial;
|
||||||
|
|
||||||
|
use super::expand_partial;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn expand_context_from_iri() {
|
fn expand_partial_populates_iri_from_string() {
|
||||||
|
#[derive(Deserialize, IRI, Default)]
|
||||||
|
struct Context {
|
||||||
|
pub id: String,
|
||||||
|
pub context: bool,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct WithContext {
|
struct WithContext {
|
||||||
#[serde(deserialize_with = "expand")]
|
#[serde(deserialize_with = "expand_partial")]
|
||||||
pub context: super::super::context::Context,
|
pub context: Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
const JSONLD_INPUT: &str = r#"{"context": "https://www.w3.org/ns/activitystreams"}"#;
|
const JSONLD_INPUT: &str = r#"{"context": "https://www.w3.org/ns/activitystreams"}"#;
|
||||||
let result =
|
let result =
|
||||||
serde_json::from_str::<WithContext>(JSONLD_INPUT).expect("deserializing with expand");
|
serde_json::from_str::<WithContext>(JSONLD_INPUT).expect("deserializing with expand");
|
||||||
|
|
||||||
assert!(result.context.ctx.xsd == "http://www.w3.org/2001/XMLSchema#")
|
assert!(result.context.id == "https://www.w3.org/ns/activitystreams");
|
||||||
|
assert!(result.context.context == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn expand_when_json_isnt_iri_but_the_object_itself() {
|
fn expand_partial_expands_into_object_fully() {
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize, IRI, Default)]
|
||||||
struct Expanded {
|
struct Expanded {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
pub truth: bool,
|
pub truth: bool,
|
||||||
|
@ -128,7 +127,7 @@ mod tests {
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct Expandable {
|
struct Expandable {
|
||||||
#[serde(deserialize_with = "expand")]
|
#[serde(deserialize_with = "expand_partial")]
|
||||||
pub expansive: Expanded,
|
pub expansive: Expanded,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue