rustpub 0.1.4

An implementation of the Activitypub types
Documentation
use derive_builder::Builder;
use serde::{Deserialize, Serialize};

use crate::properties::*;

// TODO: make a proc_macro_derive to generate the enum type and From<XEnum> implementations for the core types

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
enum ObjectEnum {
    Brief(String),
    #[serde(rename_all = "camelCase")]
    Full {
        #[serde(skip_serializing_if = "ActivitypubProperty::is_none", default)]
        attachment: Attachment,
        #[serde(skip_serializing_if = "ActivitypubProperty::is_none", default)]
        attributed_to: AttributedTo,
        #[serde(skip_serializing_if = "ActivitypubProperty::is_none", default)]
        audience: Audience,
        #[serde(
            alias = "contentMap",
            skip_serializing_if = "ActivitypubProperty::is_none",
            default
        )]
        content: Content,
        #[serde(
            rename = "@context",
            skip_serializing_if = "ActivitypubProperty::is_none",
            default
        )]
        context: Context,
        #[serde(skip_serializing_if = "ActivitypubProperty::is_none", default)]
        generator: Generator,
        #[serde(skip_serializing_if = "ActivitypubProperty::is_none", default)]
        in_reply_to: InReplyTo,
        #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
        kind: Option<Kind>,
        #[serde(skip_serializing_if = "Option::is_none")]
        id: Option<Id>,
        #[serde(skip_serializing_if = "Option::is_none")]
        media_type: Option<MediaType>,
        #[serde(
            alias = "nameMap",
            skip_serializing_if = "ActivitypubProperty::is_none",
            default
        )]
        name: Name,
        #[serde(
            alias = "summaryMap",
            skip_serializing_if = "ActivitypubProperty::is_none",
            default
        )]
        summary: Summary,
        #[serde(skip_serializing_if = "ActivitypubProperty::is_none", default)]
        tag: Tag,
        #[serde(skip_serializing_if = "ActivitypubProperty::is_none", default)]
        url: Url,
        #[serde(skip_serializing_if = "Option::is_none")]
        inbox: Option<Inbox>,
        #[serde(skip_serializing_if = "Option::is_none")]
        outbox: Option<Inbox>,
    },
}

#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, Builder)]
#[serde(rename_all = "camelCase", from = "ObjectEnum")]
#[builder(default, setter(strip_option))]
pub struct Object {
    #[serde(skip_serializing_if = "ActivitypubProperty::is_none")]
    pub attachment: Attachment,
    #[serde(skip_serializing_if = "ActivitypubProperty::is_none")]
    pub attributed_to: AttributedTo,
    #[serde(skip_serializing_if = "ActivitypubProperty::is_none")]
    pub audience: Audience,
    #[serde(
        alias = "contentMap",
        skip_serializing_if = "ActivitypubProperty::is_none"
    )]
    pub content: Content,
    #[serde(
        rename = "@context",
        skip_serializing_if = "ActivitypubProperty::is_none"
    )]
    pub context: Context,
    #[serde(skip_serializing_if = "ActivitypubProperty::is_none")]
    pub generator: Generator,
    #[serde(skip_serializing_if = "ActivitypubProperty::is_none")]
    pub in_reply_to: InReplyTo,
    #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
    pub kind: Option<Kind>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub id: Option<Id>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub media_type: Option<MediaType>,
    #[serde(
        alias = "nameMap",
        skip_serializing_if = "ActivitypubProperty::is_none"
    )]
    pub name: Name,
    #[serde(
        alias = "summaryMap",
        skip_serializing_if = "ActivitypubProperty::is_none"
    )]
    pub summary: Summary,
    #[serde(skip_serializing_if = "ActivitypubProperty::is_none")]
    pub tag: Tag,
    #[serde(skip_serializing_if = "ActivitypubProperty::is_none")]
    pub url: Url,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub inbox: Option<Inbox>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub outbox: Option<Inbox>,
}

impl From<ObjectEnum> for Object {
    fn from(object_enum: ObjectEnum) -> Self {
        match object_enum {
            ObjectEnum::Brief(id) => ObjectBuilder::default().id(id).build().unwrap(),
            ObjectEnum::Full {
                attachment,
                attributed_to,
                audience,
                content,
                context,
                generator,
                in_reply_to,
                kind,
                id,
                media_type,
                name,
                summary,
                tag,
                url,
                inbox,
                outbox,
            } => Object {
                attachment,
                attributed_to,
                audience,
                content,
                context,
                generator,
                in_reply_to,
                kind,
                id,
                media_type,
                name,
                summary,
                tag,
                url,
                inbox,
                outbox,
            },
        }
    }
}

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
enum LinkEnum {
    Brief(String),
    Full {
        #[serde(skip_serializing_if = "Option::is_none")]
        href: Option<Href>,
        #[serde(skip_serializing_if = "Option::is_none")]
        media_type: Option<MediaType>,
        #[serde(
            alias = "nameMap",
            skip_serializing_if = "ActivitypubProperty::is_none",
            default
        )]
        name: Name,
    },
}

#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, Builder)]
#[serde(rename_all = "camelCase", from = "LinkEnum")]
#[builder(default, setter(strip_option))]
pub struct Link {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub href: Option<Href>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub media_type: Option<MediaType>,
    #[serde(
        alias = "nameMap",
        skip_serializing_if = "ActivitypubProperty::is_none"
    )]
    pub name: Name,
}

impl From<LinkEnum> for Link {
    fn from(link_enum: LinkEnum) -> Self {
        match link_enum {
            LinkEnum::Brief(href) => LinkBuilder::default().href(href).build().unwrap(),
            LinkEnum::Full {
                href,
                media_type,
                name,
            } => Link {
                href,
                media_type,
                name,
            },
        }
    }
}