use crate::{
activity::{Activity, ActivityBox, IntransitiveActivity, IntransitiveActivityBox},
actor::{Actor, ActorBox},
collection::{Collection, CollectionBox, CollectionPage, CollectionPageBox},
link::{Link, LinkBox},
object::{Object, ObjectBox},
Base, BaseBox,
};
use std::{convert::TryFrom, fmt::Debug};
#[derive(Clone, Debug, Default)]
#[cfg_attr(feature = "derive", derive(serde::Deserialize, serde::Serialize))]
pub struct Ext<T, U> {
#[cfg_attr(feature = "derive", serde(flatten))]
pub base: T,
#[cfg_attr(feature = "derive", serde(flatten))]
pub extension: U,
}
pub trait Extension<T>
where
T: Base,
{
fn extends(self, base: T) -> Ext<T, Self>
where
Self: Sized,
{
Ext {
base,
extension: self,
}
}
}
pub trait Extensible<U> {
fn extend(self, extension: U) -> Ext<Self, U>
where
Self: Sized;
}
impl<T, U, V> AsRef<V> for Ext<T, U>
where
T: Base + AsRef<V>,
U: Extension<T> + Debug,
{
fn as_ref(&self) -> &V {
self.base.as_ref()
}
}
impl<T, U, V> AsMut<V> for Ext<T, U>
where
T: Base + AsMut<V>,
U: Extension<T> + Debug,
{
fn as_mut(&mut self) -> &mut V {
self.base.as_mut()
}
}
impl<T, U> TryFrom<Ext<T, U>> for BaseBox
where
T: Base + serde::ser::Serialize,
U: Extension<T> + serde::ser::Serialize + Debug,
{
type Error = std::io::Error;
fn try_from(e: Ext<T, U>) -> Result<Self, Self::Error> {
BaseBox::from_concrete(e)
}
}
impl<T, U> TryFrom<Ext<T, U>> for ObjectBox
where
T: Object + serde::ser::Serialize,
U: Extension<T> + serde::ser::Serialize + Debug,
{
type Error = std::io::Error;
fn try_from(e: Ext<T, U>) -> Result<Self, Self::Error> {
ObjectBox::from_concrete(e)
}
}
impl<T, U> TryFrom<Ext<T, U>> for LinkBox
where
T: Link + serde::ser::Serialize,
U: Extension<T> + serde::ser::Serialize + Debug,
{
type Error = std::io::Error;
fn try_from(e: Ext<T, U>) -> Result<Self, Self::Error> {
LinkBox::from_concrete(e)
}
}
impl<T, U> TryFrom<Ext<T, U>> for CollectionBox
where
T: Collection + serde::ser::Serialize,
U: Extension<T> + serde::ser::Serialize + Debug,
{
type Error = std::io::Error;
fn try_from(e: Ext<T, U>) -> Result<Self, Self::Error> {
CollectionBox::from_concrete(e)
}
}
impl<T, U> TryFrom<Ext<T, U>> for CollectionPageBox
where
T: CollectionPage + serde::ser::Serialize,
U: Extension<T> + serde::ser::Serialize + Debug,
{
type Error = std::io::Error;
fn try_from(e: Ext<T, U>) -> Result<Self, Self::Error> {
CollectionPageBox::from_concrete(e)
}
}
impl<T, U> TryFrom<Ext<T, U>> for ActivityBox
where
T: Activity + serde::ser::Serialize,
U: Extension<T> + serde::ser::Serialize + Debug,
{
type Error = std::io::Error;
fn try_from(e: Ext<T, U>) -> Result<Self, Self::Error> {
ActivityBox::from_concrete(e)
}
}
impl<T, U> TryFrom<Ext<T, U>> for IntransitiveActivityBox
where
T: IntransitiveActivity + serde::ser::Serialize,
U: Extension<T> + serde::ser::Serialize + Debug,
{
type Error = std::io::Error;
fn try_from(e: Ext<T, U>) -> Result<Self, Self::Error> {
IntransitiveActivityBox::from_concrete(e)
}
}
impl<T, U> TryFrom<Ext<T, U>> for ActorBox
where
T: Actor + serde::ser::Serialize,
U: Extension<T> + serde::ser::Serialize + Debug,
{
type Error = std::io::Error;
fn try_from(e: Ext<T, U>) -> Result<Self, Self::Error> {
ActorBox::from_concrete(e)
}
}
impl<T, U> Extensible<U> for T
where
T: crate::Base,
U: Extension<T>,
{
fn extend(self, item: U) -> Ext<Self, U> {
item.extends(self)
}
}
impl<T, U> Base for Ext<T, U>
where
T: Base,
U: Debug,
{
}
impl<T, U> Object for Ext<T, U>
where
T: Object,
U: Debug,
{
}
impl<T, U> Link for Ext<T, U>
where
T: Link,
U: Debug,
{
}
impl<T, U> Actor for Ext<T, U>
where
T: Actor,
U: Debug,
{
}
impl<T, U> Collection for Ext<T, U>
where
T: Collection,
U: Debug,
{
}
impl<T, U> CollectionPage for Ext<T, U>
where
T: CollectionPage,
U: Debug,
{
}
impl<T, U> Activity for Ext<T, U>
where
T: Activity,
U: Debug,
{
}
impl<T, U> IntransitiveActivity for Ext<T, U>
where
T: IntransitiveActivity,
U: Debug,
{
}