fix(apb): proper feature gating, dict->unstructured

This commit is contained in:
əlemi 2024-04-06 18:04:14 +02:00
parent 24d547e93a
commit 101de0cc08
Signed by: alemi
GPG key ID: A4895B84D311642C
15 changed files with 205 additions and 185 deletions

View file

@ -9,15 +9,16 @@ edition = "2021"
[dependencies] [dependencies]
chrono = { version = "0.4", features = ["serde"] } chrono = { version = "0.4", features = ["serde"] }
thiserror = "1.0" thiserror = "1"
serde_json = { version = "1.0", optional = true } paste = "1.0"
reqwest = { version = "0.12", features = ["json"], optional = true } tracing = "0.1"
paste = "1.0.14" serde_json = { version = "1", optional = true }
sea-orm = { version = "0.12", optional = true } sea-orm = { version = "0.12", optional = true }
tracing = "0.1.40" reqwest = { version = "0.12", features = ["json"], optional = true }
[features] [features]
default = ["fetch", "dict", "orm"] default = []
fetch = ["dep:reqwest"] orm = ["dep:sea-orm"]
dict = ["dep:serde_json"] fetch = ["dep:reqwest"]
orm = ["dep:sea-orm"] unstructured = ["dep:serde_json"]
# TODO eventually also make a structured base?

View file

@ -1,6 +1,6 @@
use crate::{getter, setter, strenum, LinkType, ObjectType}; use crate::{LinkType, ObjectType};
strenum! { crate::strenum! {
pub enum BaseType { pub enum BaseType {
; ;
Object(ObjectType), Object(ObjectType),
@ -30,12 +30,14 @@ impl Base for String {
} }
} }
#[cfg(feature = "unstructured")]
impl Base for serde_json::Value { impl Base for serde_json::Value {
getter! { id -> &str } crate::getter! { id -> &str }
getter! { base_type -> type BaseType } crate::getter! { base_type -> type BaseType }
} }
#[cfg(feature = "unstructured")]
impl BaseMut for serde_json::Value { impl BaseMut for serde_json::Value {
setter! { id -> &str } crate::setter! { id -> &str }
setter! { base_type -> type BaseType } crate::setter! { base_type -> type BaseType }
} }

View file

@ -1,8 +1,5 @@
// TODO technically this is not part of ActivityStreams // TODO technically this is not part of ActivityStreams
use crate::{getter, setter};
pub trait PublicKey : super::Base { pub trait PublicKey : super::Base {
fn owner(&self) -> Option<&str> { None } fn owner(&self) -> Option<&str> { None }
fn public_key_pem(&self) -> &str; fn public_key_pem(&self) -> &str;
@ -13,16 +10,18 @@ pub trait PublicKeyMut : super::BaseMut {
fn set_public_key_pem(self, val: &str) -> Self; fn set_public_key_pem(self, val: &str) -> Self;
} }
#[cfg(feature = "unstructured")]
impl PublicKey for serde_json::Value { impl PublicKey for serde_json::Value {
getter! { owner -> &str } crate::getter! { owner -> &str }
fn public_key_pem(&self) -> &str { fn public_key_pem(&self) -> &str {
self.get("publicKeyPem").unwrap().as_str().unwrap() self.get("publicKeyPem").unwrap().as_str().unwrap()
} }
} }
#[cfg(feature = "unstructured")]
impl PublicKeyMut for serde_json::Value { impl PublicKeyMut for serde_json::Value {
setter! { owner -> &str } crate::setter! { owner -> &str }
fn set_public_key_pem(mut self, val: &str) -> Self { fn set_public_key_pem(mut self, val: &str) -> Self {
self.as_object_mut().unwrap().insert( self.as_object_mut().unwrap().insert(

View file

@ -1,6 +1,4 @@
use crate::{getter, setter, strenum}; crate::strenum! {
strenum! {
pub enum LinkType { pub enum LinkType {
Link, Link,
Mention; Mention;
@ -35,6 +33,7 @@ impl Link for String {
} }
} }
#[cfg(feature = "unstructured")]
impl Link for serde_json::Value { impl Link for serde_json::Value {
// TODO this can fail, but it should never do! // TODO this can fail, but it should never do!
fn href(&self) -> &str { fn href(&self) -> &str {
@ -51,15 +50,16 @@ impl Link for serde_json::Value {
} }
} }
getter! { rel -> &str } crate::getter! { rel -> &str }
getter! { link_media_type::mediaType -> &str } crate::getter! { link_media_type::mediaType -> &str }
getter! { link_name::name -> &str } crate::getter! { link_name::name -> &str }
getter! { hreflang -> &str } crate::getter! { hreflang -> &str }
getter! { height -> u64 } crate::getter! { height -> u64 }
getter! { width -> u64 } crate::getter! { width -> u64 }
getter! { link_preview::preview -> &str } crate::getter! { link_preview::preview -> &str }
} }
#[cfg(feature = "unstructured")]
impl LinkMut for serde_json::Value { impl LinkMut for serde_json::Value {
// TODO this can fail, but it should never do! // TODO this can fail, but it should never do!
fn set_href(mut self, href: &str) -> Self { fn set_href(mut self, href: &str) -> Self {
@ -76,11 +76,11 @@ impl LinkMut for serde_json::Value {
self self
} }
setter! { rel -> &str } crate::setter! { rel -> &str }
setter! { link_media_type::mediaType -> &str } crate::setter! { link_media_type::mediaType -> &str }
setter! { link_name::name -> &str } crate::setter! { link_name::name -> &str }
setter! { hreflang -> &str } crate::setter! { hreflang -> &str }
setter! { height -> u64 } crate::setter! { height -> u64 }
setter! { width -> u64 } crate::setter! { width -> u64 }
setter! { link_preview::preview -> &str } crate::setter! { link_preview::preview -> &str }
} }

View file

@ -1,15 +1,15 @@
use super::Node;
#[derive(Debug, thiserror::Error)] #[derive(Debug, thiserror::Error)]
#[error("invalid type value")] #[error("invalid type value")]
pub struct TypeValueError; pub struct TypeValueError;
#[cfg(feature = "orm")]
impl From<TypeValueError> for sea_orm::sea_query::ValueTypeErr { impl From<TypeValueError> for sea_orm::sea_query::ValueTypeErr {
fn from(_: TypeValueError) -> Self { fn from(_: TypeValueError) -> Self {
sea_orm::sea_query::ValueTypeErr sea_orm::sea_query::ValueTypeErr
} }
} }
#[cfg(feature = "orm")]
impl From<TypeValueError> for sea_orm::TryGetError { impl From<TypeValueError> for sea_orm::TryGetError {
fn from(_: TypeValueError) -> Self { fn from(_: TypeValueError) -> Self {
sea_orm::TryGetError::Null("value is not a valid type".into()) sea_orm::TryGetError::Null("value is not a valid type".into())
@ -54,12 +54,14 @@ macro_rules! strenum {
} }
} }
#[cfg(feature = "orm")]
impl From<$enum_name> for sea_orm::Value { impl From<$enum_name> for sea_orm::Value {
fn from(value: $enum_name) -> sea_orm::Value { fn from(value: $enum_name) -> sea_orm::Value {
sea_orm::Value::String(Some(Box::new(value.as_ref().to_string()))) sea_orm::Value::String(Some(Box::new(value.as_ref().to_string())))
} }
} }
#[cfg(feature = "orm")]
impl sea_orm::sea_query::ValueType for $enum_name { impl sea_orm::sea_query::ValueType for $enum_name {
fn try_from(v: sea_orm::Value) -> Result<Self, sea_orm::sea_query::ValueTypeErr> { fn try_from(v: sea_orm::Value) -> Result<Self, sea_orm::sea_query::ValueTypeErr> {
match v { match v {
@ -82,6 +84,7 @@ macro_rules! strenum {
} }
} }
#[cfg(feature = "orm")]
impl sea_orm::TryGetable for $enum_name { impl sea_orm::TryGetable for $enum_name {
fn try_get_by<I: sea_orm::ColIdx>(res: &sea_orm::prelude::QueryResult, index: I) -> Result<Self, sea_orm::TryGetError> { fn try_get_by<I: sea_orm::ColIdx>(res: &sea_orm::prelude::QueryResult, index: I) -> Result<Self, sea_orm::TryGetError> {
let x : String = res.try_get_by(index)?; let x : String = res.try_get_by(index)?;
@ -302,24 +305,25 @@ macro_rules! setter {
}; };
} }
pub fn set_maybe_node(obj: &mut serde_json::Value, key: &str, node: super::Node<serde_json::Value>) { #[cfg(feature = "unstructured")]
pub fn set_maybe_node(obj: &mut serde_json::Value, key: &str, node: crate::Node<serde_json::Value>) {
match node { match node {
super::Node::Object(x) => { crate::Node::Object(x) => {
set_maybe_value( set_maybe_value(
obj, key, Some(*x), obj, key, Some(*x),
); );
}, },
super::Node::Link(l) => { crate::Node::Link(l) => {
set_maybe_value( set_maybe_value(
obj, key, Some(serde_json::Value::String(l.href().to_string())), obj, key, Some(serde_json::Value::String(l.href().to_string())),
); );
}, },
super::Node::Array(_) => { crate::Node::Array(_) => {
set_maybe_value( set_maybe_value(
obj, key, Some(serde_json::Value::Array(node.into_iter().collect())), obj, key, Some(serde_json::Value::Array(node.into_iter().collect())),
); );
}, },
super::Node::Empty => { crate::Node::Empty => {
set_maybe_value( set_maybe_value(
obj, key, None, obj, key, None,
); );
@ -327,6 +331,7 @@ pub fn set_maybe_node(obj: &mut serde_json::Value, key: &str, node: super::Node<
} }
} }
#[cfg(feature = "unstructured")]
pub fn set_maybe_value(obj: &mut serde_json::Value, key: &str, value: Option<serde_json::Value>) { pub fn set_maybe_value(obj: &mut serde_json::Value, key: &str, value: Option<serde_json::Value>) {
if let Some(map) = obj.as_object_mut() { if let Some(map) = obj.as_object_mut() {
match value { match value {
@ -338,35 +343,37 @@ pub fn set_maybe_value(obj: &mut serde_json::Value, key: &str, value: Option<ser
} }
} }
#[cfg(feature = "unstructured")]
pub(crate) trait InsertValue { pub(crate) trait InsertValue {
fn insert_node(&mut self, k: &str, v: Node<serde_json::Value>); fn insert_node(&mut self, k: &str, v: crate::Node<serde_json::Value>);
fn insert_str(&mut self, k: &str, v: Option<&str>); fn insert_str(&mut self, k: &str, v: Option<&str>);
fn insert_float(&mut self, k: &str, f: Option<f64>); fn insert_float(&mut self, k: &str, f: Option<f64>);
fn insert_timestr(&mut self, k: &str, t: Option<chrono::DateTime<chrono::Utc>>); fn insert_timestr(&mut self, k: &str, t: Option<chrono::DateTime<chrono::Utc>>);
} }
#[cfg(feature = "unstructured")]
impl InsertValue for serde_json::Map<String, serde_json::Value> { impl InsertValue for serde_json::Map<String, serde_json::Value> {
fn insert_node(&mut self, k: &str, node: Node<serde_json::Value>) { fn insert_node(&mut self, k: &str, node: crate::Node<serde_json::Value>) {
match node { match node {
Node::Object(x) => { crate::Node::Object(x) => {
self.insert( self.insert(
k.to_string(), k.to_string(),
*x, *x,
); );
}, },
Node::Array(ref _arr) => { crate::Node::Array(ref _arr) => {
self.insert( self.insert(
k.to_string(), k.to_string(),
serde_json::Value::Array(node.into_iter().collect()), serde_json::Value::Array(node.into_iter().collect()),
); );
}, },
Node::Link(l) => { crate::Node::Link(l) => {
self.insert( self.insert(
k.to_string(), k.to_string(),
serde_json::Value::String(l.href().to_string()), serde_json::Value::String(l.href().to_string()),
); );
}, },
Node::Empty => {}, crate::Node::Empty => {},
}; };
} }

View file

@ -80,7 +80,7 @@ impl<T : super::Base> Node<T> {
} }
} }
#[cfg(feature = "dict")] #[cfg(feature = "unstructured")]
impl Node<serde_json::Value> { impl Node<serde_json::Value> {
pub fn link(uri: String) -> Self { pub fn link(uri: String) -> Self {
Node::Link(Box::new(uri)) Node::Link(Box::new(uri))
@ -133,7 +133,7 @@ impl Node<serde_json::Value> {
} }
} }
#[cfg(feature = "dict")] #[cfg(feature = "unstructured")]
impl From<Option<&str>> for Node<serde_json::Value> { impl From<Option<&str>> for Node<serde_json::Value> {
fn from(value: Option<&str>) -> Self { fn from(value: Option<&str>) -> Self {
match value { match value {
@ -143,14 +143,14 @@ impl From<Option<&str>> for Node<serde_json::Value> {
} }
} }
#[cfg(feature = "dict")] #[cfg(feature = "unstructured")]
impl From<&str> for Node<serde_json::Value> { impl From<&str> for Node<serde_json::Value> {
fn from(value: &str) -> Self { fn from(value: &str) -> Self {
Node::Link(Box::new(value.to_string())) Node::Link(Box::new(value.to_string()))
} }
} }
#[cfg(feature = "dict")] #[cfg(feature = "unstructured")]
impl From<serde_json::Value> for Node<serde_json::Value> { impl From<serde_json::Value> for Node<serde_json::Value> {
fn from(value: serde_json::Value) -> Self { fn from(value: serde_json::Value) -> Self {
match value { match value {

View file

@ -4,14 +4,14 @@ pub mod intransitive;
pub mod offer; pub mod offer;
pub mod reject; pub mod reject;
use crate::{Node, object::{Object, ObjectMut}, getter, setter, strenum}; use crate::{Node, object::{Object, ObjectMut}};
use accept::AcceptType; use accept::AcceptType;
use reject::RejectType; use reject::RejectType;
use offer::OfferType; use offer::OfferType;
use intransitive::IntransitiveActivityType; use intransitive::IntransitiveActivityType;
use ignore::IgnoreType; use ignore::IgnoreType;
strenum! { crate::strenum! {
pub enum ActivityType { pub enum ActivityType {
Activity, Activity,
Add, Add,
@ -60,22 +60,24 @@ pub trait ActivityMut : ObjectMut {
fn set_instrument(self, val: Node<Self::Object>) -> Self; fn set_instrument(self, val: Node<Self::Object>) -> Self;
} }
#[cfg(feature = "unstructured")]
impl Activity for serde_json::Value { impl Activity for serde_json::Value {
getter! { activity_type -> type ActivityType } crate::getter! { activity_type -> type ActivityType }
getter! { actor -> node Self::Actor } crate::getter! { actor -> node Self::Actor }
getter! { object -> node <Self as Object>::Object } crate::getter! { object -> node <Self as Object>::Object }
getter! { target -> node <Self as Object>::Object } crate::getter! { target -> node <Self as Object>::Object }
getter! { result -> node <Self as Object>::Object } crate::getter! { result -> node <Self as Object>::Object }
getter! { origin -> node <Self as Object>::Object } crate::getter! { origin -> node <Self as Object>::Object }
getter! { instrument -> node <Self as Object>::Object } crate::getter! { instrument -> node <Self as Object>::Object }
} }
#[cfg(feature = "unstructured")]
impl ActivityMut for serde_json::Value { impl ActivityMut for serde_json::Value {
setter! { activity_type -> type ActivityType } crate::setter! { activity_type -> type ActivityType }
setter! { actor -> node Self::Actor } crate::setter! { actor -> node Self::Actor }
setter! { object -> node <Self as Object>::Object } crate::setter! { object -> node <Self as Object>::Object }
setter! { target -> node <Self as Object>::Object } crate::setter! { target -> node <Self as Object>::Object }
setter! { result -> node <Self as Object>::Object } crate::setter! { result -> node <Self as Object>::Object }
setter! { origin -> node <Self as Object>::Object } crate::setter! { origin -> node <Self as Object>::Object }
setter! { instrument -> node <Self as Object>::Object } crate::setter! { instrument -> node <Self as Object>::Object }
} }

View file

@ -1,8 +1,8 @@
use crate::{Node, getter, setter, strenum}; use crate::Node;
use super::{Object, ObjectMut, super::key::PublicKey}; use super::{Object, ObjectMut, super::key::PublicKey};
strenum! { crate::strenum! {
pub enum ActorType { pub enum ActorType {
Application, Application,
Group, Group,
@ -18,12 +18,12 @@ pub trait Actor : Object {
fn preferred_username(&self) -> Option<&str> { None } fn preferred_username(&self) -> Option<&str> { None }
fn inbox(&self) -> Node<Self::Collection>; fn inbox(&self) -> Node<Self::Collection>;
fn outbox(&self) -> Node<Self::Collection>; fn outbox(&self) -> Node<Self::Collection>;
fn following(&self) -> Node<Self::Collection> { todo!() } fn following(&self) -> Node<Self::Collection> { Node::Empty }
fn followers(&self) -> Node<Self::Collection> { todo!() } fn followers(&self) -> Node<Self::Collection> { Node::Empty }
fn liked(&self) -> Node<Self::Collection> { todo!() } fn liked(&self) -> Node<Self::Collection> { Node::Empty }
fn streams(&self) -> Node<Self::Collection> { todo!() } fn streams(&self) -> Node<Self::Collection> { Node::Empty }
fn endpoints(&self) -> Option<serde_json::Map<String, String>> { None } fn endpoints(&self) -> Node<Self::Object> { Node::Empty }
fn public_key(&self) -> Node<Self::PublicKey> { todo!() } fn public_key(&self) -> Node<Self::PublicKey> { Node::Empty }
// idk about this? everyone has it but AP doesn't mention it // idk about this? everyone has it but AP doesn't mention it
fn discoverable(&self) -> Option<bool> { None } fn discoverable(&self) -> Option<bool> { None }
} }
@ -39,45 +39,47 @@ pub trait ActorMut : ObjectMut {
fn set_followers(self, val: Node<Self::Collection>) -> Self; fn set_followers(self, val: Node<Self::Collection>) -> Self;
fn set_liked(self, val: Node<Self::Collection>) -> Self; fn set_liked(self, val: Node<Self::Collection>) -> Self;
fn set_streams(self, val: Node<Self::Collection>) -> Self; fn set_streams(self, val: Node<Self::Collection>) -> Self;
fn set_endpoints(self, val: Option<serde_json::Map<String, String>>) -> Self; fn set_endpoints(self, val: Node<Self::Object>) -> Self; // TODO it's more complex than this!
fn set_public_key(self, val: Node<Self::PublicKey>) -> Self; fn set_public_key(self, val: Node<Self::PublicKey>) -> Self;
fn set_discoverable(self, val: Option<bool>) -> Self; fn set_discoverable(self, val: Option<bool>) -> Self;
} }
#[cfg(feature = "unstructured")]
impl Actor for serde_json::Value { impl Actor for serde_json::Value {
type PublicKey = serde_json::Value; type PublicKey = serde_json::Value;
getter! { actor_type -> type ActorType } crate::getter! { actor_type -> type ActorType }
getter! { preferred_username::preferredUsername -> &str } crate::getter! { preferred_username::preferredUsername -> &str }
getter! { inbox -> node Self::Collection } crate::getter! { inbox -> node Self::Collection }
getter! { outbox -> node Self::Collection } crate::getter! { outbox -> node Self::Collection }
getter! { following -> node Self::Collection } crate::getter! { following -> node Self::Collection }
getter! { followers -> node Self::Collection } crate::getter! { followers -> node Self::Collection }
getter! { liked -> node Self::Collection } crate::getter! { liked -> node Self::Collection }
getter! { streams -> node Self::Collection } crate::getter! { streams -> node Self::Collection }
getter! { public_key::publicKey -> node Self::PublicKey } crate::getter! { public_key::publicKey -> node Self::PublicKey }
getter! { discoverable -> bool } crate::getter! { discoverable -> bool }
fn endpoints(&self) -> Option<serde_json::Map<String, String>> { fn endpoints(&self) -> Node<<Self as Object>::Object> {
todo!() todo!()
} }
} }
#[cfg(feature = "unstructured")]
impl ActorMut for serde_json::Value { impl ActorMut for serde_json::Value {
type PublicKey = serde_json::Value; type PublicKey = serde_json::Value;
setter! { actor_type -> type ActorType } crate::setter! { actor_type -> type ActorType }
setter! { preferred_username::preferredUsername -> &str } crate::setter! { preferred_username::preferredUsername -> &str }
setter! { inbox -> node Self::Collection } crate::setter! { inbox -> node Self::Collection }
setter! { outbox -> node Self::Collection } crate::setter! { outbox -> node Self::Collection }
setter! { following -> node Self::Collection } crate::setter! { following -> node Self::Collection }
setter! { followers -> node Self::Collection } crate::setter! { followers -> node Self::Collection }
setter! { liked -> node Self::Collection } crate::setter! { liked -> node Self::Collection }
setter! { streams -> node Self::Collection } crate::setter! { streams -> node Self::Collection }
setter! { public_key::publicKey -> node Self::PublicKey } crate::setter! { public_key::publicKey -> node Self::PublicKey }
setter! { discoverable -> bool } crate::setter! { discoverable -> bool }
fn set_endpoints(mut self, _val: Option<serde_json::Map<String, String>>) -> Self { fn set_endpoints(mut self, _val: Node<<Self as Object>::Object>) -> Self {
self.as_object_mut().unwrap().insert("endpoints".to_string(), serde_json::Value::Object(serde_json::Map::default())); self.as_object_mut().unwrap().insert("endpoints".to_string(), serde_json::Value::Object(serde_json::Map::default()));
self self
} }

View file

@ -1,9 +1,9 @@
pub mod page; pub mod page;
pub use page::CollectionPage; pub use page::CollectionPage;
use crate::{Node, Object, object::ObjectMut, getter, setter, strenum}; use crate::{Node, Object, object::ObjectMut};
strenum! { crate::strenum! {
pub enum CollectionType { pub enum CollectionType {
Collection, Collection,
CollectionPage, CollectionPage,
@ -37,26 +37,28 @@ pub trait CollectionMut : ObjectMut {
fn set_ordered_items(self, val: Node<Self::Object>) -> Self; fn set_ordered_items(self, val: Node<Self::Object>) -> Self;
} }
#[cfg(feature = "unstructured")]
impl Collection for serde_json::Value { impl Collection for serde_json::Value {
type CollectionPage = serde_json::Value; type CollectionPage = serde_json::Value;
getter! { collection_type -> type CollectionType } crate::getter! { collection_type -> type CollectionType }
getter! { total_items::totalItems -> u64 } crate::getter! { total_items::totalItems -> u64 }
getter! { current -> node Self::CollectionPage } crate::getter! { current -> node Self::CollectionPage }
getter! { first -> node Self::CollectionPage } crate::getter! { first -> node Self::CollectionPage }
getter! { last -> node Self::CollectionPage } crate::getter! { last -> node Self::CollectionPage }
getter! { items -> node <Self as Object>::Object } crate::getter! { items -> node <Self as Object>::Object }
getter! { ordered_items::orderedItems -> node <Self as Object>::Object } crate::getter! { ordered_items::orderedItems -> node <Self as Object>::Object }
} }
#[cfg(feature = "unstructured")]
impl CollectionMut for serde_json::Value { impl CollectionMut for serde_json::Value {
type CollectionPage = serde_json::Value; type CollectionPage = serde_json::Value;
setter! { collection_type -> type CollectionType } crate::setter! { collection_type -> type CollectionType }
setter! { total_items::totalItems -> u64 } crate::setter! { total_items::totalItems -> u64 }
setter! { current -> node Self::CollectionPage } crate::setter! { current -> node Self::CollectionPage }
setter! { first -> node Self::CollectionPage } crate::setter! { first -> node Self::CollectionPage }
setter! { last -> node Self::CollectionPage } crate::setter! { last -> node Self::CollectionPage }
setter! { items -> node <Self as Object>::Object } crate::setter! { items -> node <Self as Object>::Object }
setter! { ordered_items::orderedItems -> node <Self as Object>::Object } crate::setter! { ordered_items::orderedItems -> node <Self as Object>::Object }
} }

View file

@ -1,4 +1,4 @@
use crate::{Node, getter, setter}; use crate::Node;
pub trait CollectionPage : super::Collection { pub trait CollectionPage : super::Collection {
fn part_of(&self) -> Node<Self::Collection> { Node::Empty } fn part_of(&self) -> Node<Self::Collection> { Node::Empty }
@ -12,14 +12,16 @@ pub trait CollectionPageMut : super::CollectionMut {
fn set_prev(self, val: Node<Self::CollectionPage>) -> Self; fn set_prev(self, val: Node<Self::CollectionPage>) -> Self;
} }
#[cfg(feature = "unstructured")]
impl CollectionPage for serde_json::Value { impl CollectionPage for serde_json::Value {
getter! { part_of::partOf -> node Self::Collection } crate::getter! { part_of::partOf -> node Self::Collection }
getter! { next -> node Self::CollectionPage } crate::getter! { next -> node Self::CollectionPage }
getter! { prev -> node Self::CollectionPage } crate::getter! { prev -> node Self::CollectionPage }
} }
#[cfg(feature = "unstructured")]
impl CollectionPageMut for serde_json::Value { impl CollectionPageMut for serde_json::Value {
setter! { part_of::partOf -> node Self::Collection } crate::setter! { part_of::partOf -> node Self::Collection }
setter! { next -> node Self::CollectionPage } crate::setter! { next -> node Self::CollectionPage }
setter! { prev -> node Self::CollectionPage } crate::setter! { prev -> node Self::CollectionPage }
} }

View file

@ -1,6 +1,4 @@
use crate::{getter, setter, strenum}; crate::strenum! {
strenum! {
pub enum DocumentType { pub enum DocumentType {
Document, Document,
Audio, Audio,
@ -19,10 +17,12 @@ pub trait DocumentMut : super::ObjectMut {
} }
#[cfg(feature = "unstructured")]
impl Document for serde_json::Value { impl Document for serde_json::Value {
getter! { document_type -> type DocumentType } crate::getter! { document_type -> type DocumentType }
} }
#[cfg(feature = "unstructured")]
impl DocumentMut for serde_json::Value { impl DocumentMut for serde_json::Value {
setter! { document_type -> type DocumentType } crate::setter! { document_type -> type DocumentType }
} }

View file

@ -7,8 +7,6 @@ pub mod place;
pub mod profile; pub mod profile;
pub mod relationship; pub mod relationship;
use crate::{getter, setter, strenum};
use super::{Base, BaseMut, Link, Node}; use super::{Base, BaseMut, Link, Node};
use actor::{Actor, ActorType}; use actor::{Actor, ActorType};
@ -16,7 +14,7 @@ use document::{Document, DocumentType};
use activity::ActivityType; use activity::ActivityType;
use collection::{Collection, CollectionType}; use collection::{Collection, CollectionType};
strenum! { crate::strenum! {
pub enum ObjectType { pub enum ObjectType {
Object, Object,
Article, Article,
@ -106,6 +104,7 @@ pub trait ObjectMut : BaseMut {
fn set_duration(self, val: Option<&str>) -> Self; // TODO how to parse xsd:duration ? fn set_duration(self, val: Option<&str>) -> Self; // TODO how to parse xsd:duration ?
} }
#[cfg(feature = "unstructured")]
impl Object for serde_json::Value { impl Object for serde_json::Value {
type Link = serde_json::Value; type Link = serde_json::Value;
type Actor = serde_json::Value; type Actor = serde_json::Value;
@ -113,32 +112,32 @@ impl Object for serde_json::Value {
type Document = serde_json::Value; type Document = serde_json::Value;
type Collection = serde_json::Value; type Collection = serde_json::Value;
getter! { object_type -> type ObjectType } crate::getter! { object_type -> type ObjectType }
getter! { attachment -> node <Self as Object>::Object } crate::getter! { attachment -> node <Self as Object>::Object }
getter! { attributed_to::attributedTo -> node Self::Actor } crate::getter! { attributed_to::attributedTo -> node Self::Actor }
getter! { audience -> node Self::Actor } crate::getter! { audience -> node Self::Actor }
getter! { content -> &str } crate::getter! { content -> &str }
getter! { name -> &str } crate::getter! { name -> &str }
getter! { end_time::endTime -> chrono::DateTime<chrono::Utc> } crate::getter! { end_time::endTime -> chrono::DateTime<chrono::Utc> }
getter! { generator -> node Self::Actor } crate::getter! { generator -> node Self::Actor }
getter! { icon -> node Self::Document } crate::getter! { icon -> node Self::Document }
getter! { image -> node Self::Document } crate::getter! { image -> node Self::Document }
getter! { in_reply_to::inReplyTo -> node <Self as Object>::Object } crate::getter! { in_reply_to::inReplyTo -> node <Self as Object>::Object }
getter! { location -> node <Self as Object>::Object } crate::getter! { location -> node <Self as Object>::Object }
getter! { preview -> node <Self as Object>::Object } crate::getter! { preview -> node <Self as Object>::Object }
getter! { published -> chrono::DateTime<chrono::Utc> } crate::getter! { published -> chrono::DateTime<chrono::Utc> }
getter! { replies -> node Self::Collection } crate::getter! { replies -> node Self::Collection }
getter! { start_time::startTime -> chrono::DateTime<chrono::Utc> } crate::getter! { start_time::startTime -> chrono::DateTime<chrono::Utc> }
getter! { summary -> &str } crate::getter! { summary -> &str }
getter! { tag -> node <Self as Object>::Object } crate::getter! { tag -> node <Self as Object>::Object }
getter! { updated -> chrono::DateTime<chrono::Utc> } crate::getter! { updated -> chrono::DateTime<chrono::Utc> }
getter! { to -> node Self::Link } crate::getter! { to -> node Self::Link }
getter! { bto -> node Self::Link } crate::getter! { bto -> node Self::Link }
getter! { cc -> node Self::Link } crate::getter! { cc -> node Self::Link }
getter! { bcc -> node Self::Link } crate::getter! { bcc -> node Self::Link }
getter! { media_type -> &str } crate::getter! { media_type -> &str }
getter! { duration -> &str } crate::getter! { duration -> &str }
getter! { url -> node Self::Link } crate::getter! { url -> node Self::Link }
// TODO Mastodon doesn't use a "context" field on the object but makes up a new one!! // TODO Mastodon doesn't use a "context" field on the object but makes up a new one!!
fn context(&self) -> Node<<Self as Object>::Object> { fn context(&self) -> Node<<Self as Object>::Object> {
@ -152,6 +151,7 @@ impl Object for serde_json::Value {
} }
} }
#[cfg(feature = "unstructured")]
impl ObjectMut for serde_json::Value { impl ObjectMut for serde_json::Value {
type Link = serde_json::Value; type Link = serde_json::Value;
type Actor = serde_json::Value; type Actor = serde_json::Value;
@ -159,32 +159,32 @@ impl ObjectMut for serde_json::Value {
type Document = serde_json::Value; type Document = serde_json::Value;
type Collection = serde_json::Value; type Collection = serde_json::Value;
setter! { object_type -> type ObjectType } crate::setter! { object_type -> type ObjectType }
setter! { attachment -> node <Self as Object>::Object } crate::setter! { attachment -> node <Self as Object>::Object }
setter! { attributed_to::attributedTo -> node Self::Actor } crate::setter! { attributed_to::attributedTo -> node Self::Actor }
setter! { audience -> node Self::Actor } crate::setter! { audience -> node Self::Actor }
setter! { content -> &str } crate::setter! { content -> &str }
setter! { name -> &str } crate::setter! { name -> &str }
setter! { end_time::endTime -> chrono::DateTime<chrono::Utc> } crate::setter! { end_time::endTime -> chrono::DateTime<chrono::Utc> }
setter! { generator -> node Self::Actor } crate::setter! { generator -> node Self::Actor }
setter! { icon -> node Self::Document } crate::setter! { icon -> node Self::Document }
setter! { image -> node Self::Document } crate::setter! { image -> node Self::Document }
setter! { in_reply_to::inReplyTo -> node <Self as Object>::Object } crate::setter! { in_reply_to::inReplyTo -> node <Self as Object>::Object }
setter! { location -> node <Self as Object>::Object } crate::setter! { location -> node <Self as Object>::Object }
setter! { preview -> node <Self as Object>::Object } crate::setter! { preview -> node <Self as Object>::Object }
setter! { published -> chrono::DateTime<chrono::Utc> } crate::setter! { published -> chrono::DateTime<chrono::Utc> }
setter! { replies -> node Self::Collection } crate::setter! { replies -> node Self::Collection }
setter! { start_time::startTime -> chrono::DateTime<chrono::Utc> } crate::setter! { start_time::startTime -> chrono::DateTime<chrono::Utc> }
setter! { summary -> &str } crate::setter! { summary -> &str }
setter! { tag -> node <Self as Object>::Object } crate::setter! { tag -> node <Self as Object>::Object }
setter! { updated -> chrono::DateTime<chrono::Utc> } crate::setter! { updated -> chrono::DateTime<chrono::Utc> }
setter! { to -> node Self::Link } crate::setter! { to -> node Self::Link }
setter! { bto -> node Self::Link} crate::setter! { bto -> node Self::Link}
setter! { cc -> node Self::Link } crate::setter! { cc -> node Self::Link }
setter! { bcc -> node Self::Link } crate::setter! { bcc -> node Self::Link }
setter! { media_type -> &str } crate::setter! { media_type -> &str }
setter! { duration -> &str } crate::setter! { duration -> &str }
setter! { url -> node Self::Link } crate::setter! { url -> node Self::Link }
// TODO Mastodon doesn't use a "context" field on the object but makes up a new one!! // TODO Mastodon doesn't use a "context" field on the object but makes up a new one!!
fn set_context(mut self, ctx: Node<<Self as Object>::Object>) -> Self { fn set_context(mut self, ctx: Node<<Self as Object>::Object>) -> Self {

View file

@ -1,8 +1,9 @@
pub trait Profile : super::Object { pub trait Profile : super::Object {
// not a Node because it's always embedded and one // not a Node because it's always embedded and one
fn describes(&self) -> Option<impl super::Object> { None::<serde_json::Value> } fn describes(&self) -> crate::Node<Self::Object> { crate::Node::Empty }
} }
#[cfg(feature = "unstructured")]
impl Profile for serde_json::Value { impl Profile for serde_json::Value {
} }

View file

@ -14,6 +14,7 @@ pub trait RelationshipMut : super::ObjectMut {
fn set_relationship_object(self, val: Node<Self::Object>) -> Self; fn set_relationship_object(self, val: Node<Self::Object>) -> Self;
} }
#[cfg(feature = "unstructured")]
impl Relationship for serde_json::Value { impl Relationship for serde_json::Value {
// ... TODO // ... TODO
} }

View file

@ -8,6 +8,7 @@ pub trait TombstoneMut : super::ObjectMut {
fn set_deleted(self, val: Option<chrono::DateTime<chrono::Utc>>) -> Self; fn set_deleted(self, val: Option<chrono::DateTime<chrono::Utc>>) -> Self;
} }
#[cfg(feature = "unstructured")]
impl Tombstone for serde_json::Value { impl Tombstone for serde_json::Value {
// ... TODO // ... TODO
} }