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]
chrono = { version = "0.4", features = ["serde"] }
thiserror = "1.0"
serde_json = { version = "1.0", optional = true }
reqwest = { version = "0.12", features = ["json"], optional = true }
paste = "1.0.14"
thiserror = "1"
paste = "1.0"
tracing = "0.1"
serde_json = { version = "1", optional = true }
sea-orm = { version = "0.12", optional = true }
tracing = "0.1.40"
reqwest = { version = "0.12", features = ["json"], optional = true }
[features]
default = ["fetch", "dict", "orm"]
fetch = ["dep:reqwest"]
dict = ["dep:serde_json"]
default = []
orm = ["dep:sea-orm"]
fetch = ["dep:reqwest"]
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 {
;
Object(ObjectType),
@ -30,12 +30,14 @@ impl Base for String {
}
}
#[cfg(feature = "unstructured")]
impl Base for serde_json::Value {
getter! { id -> &str }
getter! { base_type -> type BaseType }
crate::getter! { id -> &str }
crate::getter! { base_type -> type BaseType }
}
#[cfg(feature = "unstructured")]
impl BaseMut for serde_json::Value {
setter! { id -> &str }
setter! { base_type -> type BaseType }
crate::setter! { id -> &str }
crate::setter! { base_type -> type BaseType }
}

View file

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

View file

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

View file

@ -1,15 +1,15 @@
use super::Node;
#[derive(Debug, thiserror::Error)]
#[error("invalid type value")]
pub struct TypeValueError;
#[cfg(feature = "orm")]
impl From<TypeValueError> for sea_orm::sea_query::ValueTypeErr {
fn from(_: TypeValueError) -> Self {
sea_orm::sea_query::ValueTypeErr
}
}
#[cfg(feature = "orm")]
impl From<TypeValueError> for sea_orm::TryGetError {
fn from(_: TypeValueError) -> Self {
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 {
fn from(value: $enum_name) -> sea_orm::Value {
sea_orm::Value::String(Some(Box::new(value.as_ref().to_string())))
}
}
#[cfg(feature = "orm")]
impl sea_orm::sea_query::ValueType for $enum_name {
fn try_from(v: sea_orm::Value) -> Result<Self, sea_orm::sea_query::ValueTypeErr> {
match v {
@ -82,6 +84,7 @@ macro_rules! strenum {
}
}
#[cfg(feature = "orm")]
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> {
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 {
super::Node::Object(x) => {
crate::Node::Object(x) => {
set_maybe_value(
obj, key, Some(*x),
);
},
super::Node::Link(l) => {
crate::Node::Link(l) => {
set_maybe_value(
obj, key, Some(serde_json::Value::String(l.href().to_string())),
);
},
super::Node::Array(_) => {
crate::Node::Array(_) => {
set_maybe_value(
obj, key, Some(serde_json::Value::Array(node.into_iter().collect())),
);
},
super::Node::Empty => {
crate::Node::Empty => {
set_maybe_value(
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>) {
if let Some(map) = obj.as_object_mut() {
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 {
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_float(&mut self, k: &str, f: Option<f64>);
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> {
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 {
Node::Object(x) => {
crate::Node::Object(x) => {
self.insert(
k.to_string(),
*x,
);
},
Node::Array(ref _arr) => {
crate::Node::Array(ref _arr) => {
self.insert(
k.to_string(),
serde_json::Value::Array(node.into_iter().collect()),
);
},
Node::Link(l) => {
crate::Node::Link(l) => {
self.insert(
k.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> {
pub fn link(uri: String) -> Self {
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> {
fn from(value: Option<&str>) -> Self {
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> {
fn from(value: &str) -> Self {
Node::Link(Box::new(value.to_string()))
}
}
#[cfg(feature = "dict")]
#[cfg(feature = "unstructured")]
impl From<serde_json::Value> for Node<serde_json::Value> {
fn from(value: serde_json::Value) -> Self {
match value {

View file

@ -4,14 +4,14 @@ pub mod intransitive;
pub mod offer;
pub mod reject;
use crate::{Node, object::{Object, ObjectMut}, getter, setter, strenum};
use crate::{Node, object::{Object, ObjectMut}};
use accept::AcceptType;
use reject::RejectType;
use offer::OfferType;
use intransitive::IntransitiveActivityType;
use ignore::IgnoreType;
strenum! {
crate::strenum! {
pub enum ActivityType {
Activity,
Add,
@ -60,22 +60,24 @@ pub trait ActivityMut : ObjectMut {
fn set_instrument(self, val: Node<Self::Object>) -> Self;
}
#[cfg(feature = "unstructured")]
impl Activity for serde_json::Value {
getter! { activity_type -> type ActivityType }
getter! { actor -> node Self::Actor }
getter! { object -> node <Self as Object>::Object }
getter! { target -> node <Self as Object>::Object }
getter! { result -> node <Self as Object>::Object }
getter! { origin -> node <Self as Object>::Object }
getter! { instrument -> node <Self as Object>::Object }
crate::getter! { activity_type -> type ActivityType }
crate::getter! { actor -> node Self::Actor }
crate::getter! { object -> node <Self as Object>::Object }
crate::getter! { target -> node <Self as Object>::Object }
crate::getter! { result -> node <Self as Object>::Object }
crate::getter! { origin -> node <Self as Object>::Object }
crate::getter! { instrument -> node <Self as Object>::Object }
}
#[cfg(feature = "unstructured")]
impl ActivityMut for serde_json::Value {
setter! { activity_type -> type ActivityType }
setter! { actor -> node Self::Actor }
setter! { object -> node <Self as Object>::Object }
setter! { target -> node <Self as Object>::Object }
setter! { result -> node <Self as Object>::Object }
setter! { origin -> node <Self as Object>::Object }
setter! { instrument -> node <Self as Object>::Object }
crate::setter! { activity_type -> type ActivityType }
crate::setter! { actor -> node Self::Actor }
crate::setter! { object -> node <Self as Object>::Object }
crate::setter! { target -> node <Self as Object>::Object }
crate::setter! { result -> node <Self as Object>::Object }
crate::setter! { origin -> 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};
strenum! {
crate::strenum! {
pub enum ActorType {
Application,
Group,
@ -18,12 +18,12 @@ pub trait Actor : Object {
fn preferred_username(&self) -> Option<&str> { None }
fn inbox(&self) -> Node<Self::Collection>;
fn outbox(&self) -> Node<Self::Collection>;
fn following(&self) -> Node<Self::Collection> { todo!() }
fn followers(&self) -> Node<Self::Collection> { todo!() }
fn liked(&self) -> Node<Self::Collection> { todo!() }
fn streams(&self) -> Node<Self::Collection> { todo!() }
fn endpoints(&self) -> Option<serde_json::Map<String, String>> { None }
fn public_key(&self) -> Node<Self::PublicKey> { todo!() }
fn following(&self) -> Node<Self::Collection> { Node::Empty }
fn followers(&self) -> Node<Self::Collection> { Node::Empty }
fn liked(&self) -> Node<Self::Collection> { Node::Empty }
fn streams(&self) -> Node<Self::Collection> { Node::Empty }
fn endpoints(&self) -> Node<Self::Object> { Node::Empty }
fn public_key(&self) -> Node<Self::PublicKey> { Node::Empty }
// idk about this? everyone has it but AP doesn't mention it
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_liked(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_discoverable(self, val: Option<bool>) -> Self;
}
#[cfg(feature = "unstructured")]
impl Actor for serde_json::Value {
type PublicKey = serde_json::Value;
getter! { actor_type -> type ActorType }
getter! { preferred_username::preferredUsername -> &str }
getter! { inbox -> node Self::Collection }
getter! { outbox -> node Self::Collection }
getter! { following -> node Self::Collection }
getter! { followers -> node Self::Collection }
getter! { liked -> node Self::Collection }
getter! { streams -> node Self::Collection }
getter! { public_key::publicKey -> node Self::PublicKey }
getter! { discoverable -> bool }
crate::getter! { actor_type -> type ActorType }
crate::getter! { preferred_username::preferredUsername -> &str }
crate::getter! { inbox -> node Self::Collection }
crate::getter! { outbox -> node Self::Collection }
crate::getter! { following -> node Self::Collection }
crate::getter! { followers -> node Self::Collection }
crate::getter! { liked -> node Self::Collection }
crate::getter! { streams -> node Self::Collection }
crate::getter! { public_key::publicKey -> node Self::PublicKey }
crate::getter! { discoverable -> bool }
fn endpoints(&self) -> Option<serde_json::Map<String, String>> {
fn endpoints(&self) -> Node<<Self as Object>::Object> {
todo!()
}
}
#[cfg(feature = "unstructured")]
impl ActorMut for serde_json::Value {
type PublicKey = serde_json::Value;
setter! { actor_type -> type ActorType }
setter! { preferred_username::preferredUsername -> &str }
setter! { inbox -> node Self::Collection }
setter! { outbox -> node Self::Collection }
setter! { following -> node Self::Collection }
setter! { followers -> node Self::Collection }
setter! { liked -> node Self::Collection }
setter! { streams -> node Self::Collection }
setter! { public_key::publicKey -> node Self::PublicKey }
setter! { discoverable -> bool }
crate::setter! { actor_type -> type ActorType }
crate::setter! { preferred_username::preferredUsername -> &str }
crate::setter! { inbox -> node Self::Collection }
crate::setter! { outbox -> node Self::Collection }
crate::setter! { following -> node Self::Collection }
crate::setter! { followers -> node Self::Collection }
crate::setter! { liked -> node Self::Collection }
crate::setter! { streams -> node Self::Collection }
crate::setter! { public_key::publicKey -> node Self::PublicKey }
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
}

View file

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

View file

@ -1,6 +1,4 @@
use crate::{getter, setter, strenum};
strenum! {
crate::strenum! {
pub enum DocumentType {
Document,
Audio,
@ -19,10 +17,12 @@ pub trait DocumentMut : super::ObjectMut {
}
#[cfg(feature = "unstructured")]
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 {
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 relationship;
use crate::{getter, setter, strenum};
use super::{Base, BaseMut, Link, Node};
use actor::{Actor, ActorType};
@ -16,7 +14,7 @@ use document::{Document, DocumentType};
use activity::ActivityType;
use collection::{Collection, CollectionType};
strenum! {
crate::strenum! {
pub enum ObjectType {
Object,
Article,
@ -106,6 +104,7 @@ pub trait ObjectMut : BaseMut {
fn set_duration(self, val: Option<&str>) -> Self; // TODO how to parse xsd:duration ?
}
#[cfg(feature = "unstructured")]
impl Object for serde_json::Value {
type Link = serde_json::Value;
type Actor = serde_json::Value;
@ -113,32 +112,32 @@ impl Object for serde_json::Value {
type Document = serde_json::Value;
type Collection = serde_json::Value;
getter! { object_type -> type ObjectType }
getter! { attachment -> node <Self as Object>::Object }
getter! { attributed_to::attributedTo -> node Self::Actor }
getter! { audience -> node Self::Actor }
getter! { content -> &str }
getter! { name -> &str }
getter! { end_time::endTime -> chrono::DateTime<chrono::Utc> }
getter! { generator -> node Self::Actor }
getter! { icon -> node Self::Document }
getter! { image -> node Self::Document }
getter! { in_reply_to::inReplyTo -> node <Self as Object>::Object }
getter! { location -> node <Self as Object>::Object }
getter! { preview -> node <Self as Object>::Object }
getter! { published -> chrono::DateTime<chrono::Utc> }
getter! { replies -> node Self::Collection }
getter! { start_time::startTime -> chrono::DateTime<chrono::Utc> }
getter! { summary -> &str }
getter! { tag -> node <Self as Object>::Object }
getter! { updated -> chrono::DateTime<chrono::Utc> }
getter! { to -> node Self::Link }
getter! { bto -> node Self::Link }
getter! { cc -> node Self::Link }
getter! { bcc -> node Self::Link }
getter! { media_type -> &str }
getter! { duration -> &str }
getter! { url -> node Self::Link }
crate::getter! { object_type -> type ObjectType }
crate::getter! { attachment -> node <Self as Object>::Object }
crate::getter! { attributed_to::attributedTo -> node Self::Actor }
crate::getter! { audience -> node Self::Actor }
crate::getter! { content -> &str }
crate::getter! { name -> &str }
crate::getter! { end_time::endTime -> chrono::DateTime<chrono::Utc> }
crate::getter! { generator -> node Self::Actor }
crate::getter! { icon -> node Self::Document }
crate::getter! { image -> node Self::Document }
crate::getter! { in_reply_to::inReplyTo -> node <Self as Object>::Object }
crate::getter! { location -> node <Self as Object>::Object }
crate::getter! { preview -> node <Self as Object>::Object }
crate::getter! { published -> chrono::DateTime<chrono::Utc> }
crate::getter! { replies -> node Self::Collection }
crate::getter! { start_time::startTime -> chrono::DateTime<chrono::Utc> }
crate::getter! { summary -> &str }
crate::getter! { tag -> node <Self as Object>::Object }
crate::getter! { updated -> chrono::DateTime<chrono::Utc> }
crate::getter! { to -> node Self::Link }
crate::getter! { bto -> node Self::Link }
crate::getter! { cc -> node Self::Link }
crate::getter! { bcc -> node Self::Link }
crate::getter! { media_type -> &str }
crate::getter! { duration -> &str }
crate::getter! { url -> node Self::Link }
// 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> {
@ -152,6 +151,7 @@ impl Object for serde_json::Value {
}
}
#[cfg(feature = "unstructured")]
impl ObjectMut for serde_json::Value {
type Link = serde_json::Value;
type Actor = serde_json::Value;
@ -159,32 +159,32 @@ impl ObjectMut for serde_json::Value {
type Document = serde_json::Value;
type Collection = serde_json::Value;
setter! { object_type -> type ObjectType }
setter! { attachment -> node <Self as Object>::Object }
setter! { attributed_to::attributedTo -> node Self::Actor }
setter! { audience -> node Self::Actor }
setter! { content -> &str }
setter! { name -> &str }
setter! { end_time::endTime -> chrono::DateTime<chrono::Utc> }
setter! { generator -> node Self::Actor }
setter! { icon -> node Self::Document }
setter! { image -> node Self::Document }
setter! { in_reply_to::inReplyTo -> node <Self as Object>::Object }
setter! { location -> node <Self as Object>::Object }
setter! { preview -> node <Self as Object>::Object }
setter! { published -> chrono::DateTime<chrono::Utc> }
setter! { replies -> node Self::Collection }
setter! { start_time::startTime -> chrono::DateTime<chrono::Utc> }
setter! { summary -> &str }
setter! { tag -> node <Self as Object>::Object }
setter! { updated -> chrono::DateTime<chrono::Utc> }
setter! { to -> node Self::Link }
setter! { bto -> node Self::Link}
setter! { cc -> node Self::Link }
setter! { bcc -> node Self::Link }
setter! { media_type -> &str }
setter! { duration -> &str }
setter! { url -> node Self::Link }
crate::setter! { object_type -> type ObjectType }
crate::setter! { attachment -> node <Self as Object>::Object }
crate::setter! { attributed_to::attributedTo -> node Self::Actor }
crate::setter! { audience -> node Self::Actor }
crate::setter! { content -> &str }
crate::setter! { name -> &str }
crate::setter! { end_time::endTime -> chrono::DateTime<chrono::Utc> }
crate::setter! { generator -> node Self::Actor }
crate::setter! { icon -> node Self::Document }
crate::setter! { image -> node Self::Document }
crate::setter! { in_reply_to::inReplyTo -> node <Self as Object>::Object }
crate::setter! { location -> node <Self as Object>::Object }
crate::setter! { preview -> node <Self as Object>::Object }
crate::setter! { published -> chrono::DateTime<chrono::Utc> }
crate::setter! { replies -> node Self::Collection }
crate::setter! { start_time::startTime -> chrono::DateTime<chrono::Utc> }
crate::setter! { summary -> &str }
crate::setter! { tag -> node <Self as Object>::Object }
crate::setter! { updated -> chrono::DateTime<chrono::Utc> }
crate::setter! { to -> node Self::Link }
crate::setter! { bto -> node Self::Link}
crate::setter! { cc -> node Self::Link }
crate::setter! { bcc -> node Self::Link }
crate::setter! { media_type -> &str }
crate::setter! { duration -> &str }
crate::setter! { url -> node Self::Link }
// 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 {

View file

@ -1,8 +1,9 @@
pub trait Profile : super::Object {
// 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 {
}

View file

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

View file

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