ap-relay 0.3.129

A simple activitypub relay
mod actor;
mod followers;
mod following;
mod healthz;
mod host_meta;
mod inbox;
mod index;
mod media;
mod nodeinfo;
mod outbox;
mod statics;
mod webfinger;

pub(crate) use self::{
    actor::route as actor,
    followers::route as followers,
    following::route as following,
    healthz::route as healthz,
    host_meta::route as host_meta,
    inbox::route as inbox,
    index::route as index,
    media::route as media,
    nodeinfo::{route as nodeinfo, well_known as nodeinfo_meta},
    outbox::route as outbox,
    statics::route as statics,
    webfinger::resolve as webfinger,
};

use activitystreams::iri_string::types::IriString;
use actix_web::HttpResponse;
use serde::ser::Serialize;

#[derive(Default, serde::Serialize)]
enum ActivityStreamsContext {
    #[default]
    #[serde(rename = "https://www.w3.org/ns/activitystreams")]
    ActivityStreams,
}

#[derive(Default, serde::Serialize)]
enum OrderedCollectionType {
    #[default]
    #[serde(rename = "OrderedCollection")]
    OrderedCollection,
}

#[derive(Default, serde::Serialize)]
enum OrderedCollectionPageType {
    #[default]
    #[serde(rename = "OrderedCollection")]
    OrderedCollectionPage,
}

#[derive(serde::Serialize)]
#[serde(rename = "camelCase")]
pub(crate) struct OrderedCollectionResponse {
    #[serde(rename = "@context")]
    context: ActivityStreamsContext,
    id: IriString,
    #[serde(rename = "type")]
    _type: OrderedCollectionType,
    total_items: usize,
    first: IriString,
}

#[derive(serde::Deserialize)]
pub(crate) struct PageQuery {
    page: u64,
}

#[derive(serde::Serialize)]
#[serde(rename = "camelCase")]
pub(crate) struct OrderedCollectionPageResponse {
    #[serde(rename = "@context")]
    context: ActivityStreamsContext,
    id: IriString,
    #[serde(rename = "type")]
    _type: OrderedCollectionPageType,
    total_items: usize,
    part_of: IriString,
    ordered_items: Vec<IriString>,
}

#[derive(serde::Serialize)]
#[serde(untagged)]
pub(crate) enum Either<L, R> {
    Left(L),
    Right(R),
}

type CollectionResponse = Either<OrderedCollectionResponse, OrderedCollectionPageResponse>;

static CONTENT_TYPE: &str = "application/activity+json";

fn ok<T>(item: T) -> HttpResponse
where
    T: Serialize,
{
    HttpResponse::Ok().content_type(CONTENT_TYPE).json(&item)
}

fn accepted<T>(item: T) -> HttpResponse
where
    T: Serialize,
{
    HttpResponse::Accepted()
        .content_type(CONTENT_TYPE)
        .json(&item)
}