feat(apb): allow upcasting from object

basically now object.as_actor() or object.as_collection() returns an
option which is full with a self ref only if the type is correct, so
that we can assume flexible json behavior from anything implementing our
apb traits, and we don't need to rely anymore on knowing the underlying
type
also little import refactor
This commit is contained in:
əlemi 2024-04-29 20:01:39 +02:00
parent f6ba30a43f
commit a3cf7a17e8
Signed by: alemi
GPG key ID: A4895B84D311642C
3 changed files with 52 additions and 19 deletions

View file

@ -3,7 +3,7 @@
pub enum Node<T : super::Base> {
Array(std::collections::VecDeque<T>), // TODO would be cool to make it Box<[T]> so that Node is just a ptr
Object(Box<T>),
Link(Box<dyn super::Link + Sync + Send>), // TODO feature flag to toggle these maybe?
Link(Box<dyn crate::Link + Sync + Send>), // TODO feature flag to toggle these maybe?
Empty,
}

View file

@ -1,6 +1,4 @@
use crate::Node;
use crate::{Object, ObjectMut, PublicKey};
use crate::{Node, Object, ObjectMut};
crate::strenum! {
pub enum ActorType {
@ -13,7 +11,7 @@ crate::strenum! {
}
pub trait Actor : Object {
type PublicKey : PublicKey;
type PublicKey : crate::PublicKey;
fn actor_type(&self) -> Option<ActorType> { None }
fn preferred_username(&self) -> Option<&str> { None }
@ -30,7 +28,7 @@ pub trait Actor : Object {
}
pub trait ActorMut : ObjectMut {
type PublicKey : PublicKey;
type PublicKey : crate::PublicKey;
fn set_actor_type(self, val: Option<ActorType>) -> Self;
fn set_preferred_username(self, val: Option<&str>) -> Self;

View file

@ -7,12 +7,12 @@ pub mod place;
pub mod profile;
pub mod relationship;
use crate::{Base, BaseMut, Link, Node};
use crate::{Base, BaseMut, Node};
use actor::{Actor, ActorType};
use document::{Document, DocumentType};
use actor::ActorType;
use document::DocumentType;
use activity::ActivityType;
use collection::{Collection, CollectionType};
use collection::CollectionType;
crate::strenum! {
pub enum ObjectType {
@ -33,11 +33,12 @@ crate::strenum! {
}
pub trait Object : Base {
type Link : Link;
type Actor : Actor;
type Link : crate::Link;
type Actor : crate::Actor;
type Object : Object;
type Collection : Collection;
type Document : Document;
type Collection : crate::Collection;
type Document : crate::Document;
type Activity : crate::Activity;
fn object_type(&self) -> Option<ObjectType> { None }
fn attachment(&self) -> Node<Self::Object> { Node::Empty }
@ -69,14 +70,19 @@ pub trait Object : Base {
// TODO i really need this but it isn't part of AP!
fn sensitive(&self) -> Option<bool> { None }
fn as_activity(&self) -> Option<&Self::Activity> { None }
fn as_actor(&self) -> Option<&Self::Actor> { None }
fn as_collection(&self) -> Option<&Self::Collection> { None }
fn as_document(&self) -> Option<&Self::Document> { None }
}
pub trait ObjectMut : BaseMut {
type Link : Link;
type Actor : Actor;
type Link : crate::Link;
type Actor : crate::Actor;
type Object : Object;
type Collection : Collection;
type Document : Document;
type Collection : crate::Collection;
type Document : crate::Document;
fn set_object_type(self, val: Option<ObjectType>) -> Self;
fn set_attachment(self, val: Node<Self::Object>) -> Self;
@ -116,7 +122,8 @@ impl Object for serde_json::Value {
type Object = serde_json::Value;
type Document = serde_json::Value;
type Collection = serde_json::Value;
type Activity = serde_json::Value;
crate::getter! { object_type -> type ObjectType }
crate::getter! { attachment -> node <Self as Object>::Object }
crate::getter! { attributed_to::attributedTo -> node Self::Actor }
@ -156,6 +163,34 @@ impl Object for serde_json::Value {
}
}
}
fn as_activity(&self) -> Option<&Self::Activity> {
match self.object_type() {
Some(ObjectType::Activity(_)) => Some(self),
_ => None,
}
}
fn as_actor(&self) -> Option<&Self::Actor> {
match self.object_type() {
Some(ObjectType::Actor(_)) => Some(self),
_ => None,
}
}
fn as_collection(&self) -> Option<&Self::Collection> {
match self.object_type() {
Some(ObjectType::Collection(_)) => Some(self),
_ => None,
}
}
fn as_document(&self) -> Option<&Self::Document> {
match self.object_type() {
Some(ObjectType::Document(_)) => Some(self),
_ => None,
}
}
}
#[cfg(feature = "unstructured")]