mirror of https://github.com/LemmyNet/lemmy.git
Allow single item for to, cc, and @context
parent
be951a76c8
commit
cfda9b73dd
|
@ -8,6 +8,7 @@ static CONTEXT: Lazy<Vec<serde_json::Value>> = Lazy::new(|| {
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub(crate) struct WithContext<T> {
|
pub(crate) struct WithContext<T> {
|
||||||
#[serde(rename = "@context")]
|
#[serde(rename = "@context")]
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
context: Vec<serde_json::Value>,
|
context: Vec<serde_json::Value>,
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
inner: T,
|
inner: T,
|
||||||
|
|
|
@ -3,6 +3,7 @@ use anyhow::{anyhow, Context};
|
||||||
use lemmy_api_common::blocking;
|
use lemmy_api_common::blocking;
|
||||||
use lemmy_db_schema::{newtypes::DbUrl, source::activity::Activity, DbPool};
|
use lemmy_db_schema::{newtypes::DbUrl, source::activity::Activity, DbPool};
|
||||||
use lemmy_utils::{location_info, settings::structs::Settings, LemmyError};
|
use lemmy_utils::{location_info, settings::structs::Settings, LemmyError};
|
||||||
|
use serde::{Deserialize, Deserializer};
|
||||||
use std::net::IpAddr;
|
use std::net::IpAddr;
|
||||||
use url::{ParseError, Url};
|
use url::{ParseError, Url};
|
||||||
|
|
||||||
|
@ -85,6 +86,25 @@ pub(crate) fn check_is_apub_id_valid(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn deserialize_one_or_many<'de, T, D>(deserializer: D) -> Result<Vec<T>, D::Error>
|
||||||
|
where
|
||||||
|
T: Deserialize<'de>,
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
enum OneOrMany<T> {
|
||||||
|
One(T),
|
||||||
|
Many(Vec<T>),
|
||||||
|
}
|
||||||
|
|
||||||
|
let result: OneOrMany<T> = Deserialize::deserialize(deserializer)?;
|
||||||
|
Ok(match result {
|
||||||
|
OneOrMany::Many(list) => list,
|
||||||
|
OneOrMany::One(value) => vec![value],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub enum EndpointType {
|
pub enum EndpointType {
|
||||||
Community,
|
Community,
|
||||||
Person,
|
Person,
|
||||||
|
|
|
@ -8,9 +8,11 @@ use url::Url;
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct AddMod {
|
pub struct AddMod {
|
||||||
pub(crate) actor: ObjectId<ApubPerson>,
|
pub(crate) actor: ObjectId<ApubPerson>,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) to: Vec<Url>,
|
pub(crate) to: Vec<Url>,
|
||||||
pub(crate) object: ObjectId<ApubPerson>,
|
pub(crate) object: ObjectId<ApubPerson>,
|
||||||
pub(crate) target: Url,
|
pub(crate) target: Url,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) cc: Vec<Url>,
|
pub(crate) cc: Vec<Url>,
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
pub(crate) kind: AddType,
|
pub(crate) kind: AddType,
|
||||||
|
|
|
@ -12,8 +12,10 @@ use url::Url;
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct AnnounceActivity {
|
pub struct AnnounceActivity {
|
||||||
pub(crate) actor: ObjectId<ApubCommunity>,
|
pub(crate) actor: ObjectId<ApubCommunity>,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) to: Vec<Url>,
|
pub(crate) to: Vec<Url>,
|
||||||
pub(crate) object: AnnouncableActivities,
|
pub(crate) object: AnnouncableActivities,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) cc: Vec<Url>,
|
pub(crate) cc: Vec<Url>,
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
pub(crate) kind: AnnounceType,
|
pub(crate) kind: AnnounceType,
|
||||||
|
|
|
@ -11,8 +11,10 @@ use url::Url;
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct BlockUserFromCommunity {
|
pub struct BlockUserFromCommunity {
|
||||||
pub(crate) actor: ObjectId<ApubPerson>,
|
pub(crate) actor: ObjectId<ApubPerson>,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) to: Vec<Url>,
|
pub(crate) to: Vec<Url>,
|
||||||
pub(crate) object: ObjectId<ApubPerson>,
|
pub(crate) object: ObjectId<ApubPerson>,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) cc: Vec<Url>,
|
pub(crate) cc: Vec<Url>,
|
||||||
pub(crate) target: ObjectId<ApubCommunity>,
|
pub(crate) target: ObjectId<ApubCommunity>,
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
|
|
|
@ -8,8 +8,10 @@ use url::Url;
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct RemoveMod {
|
pub struct RemoveMod {
|
||||||
pub(crate) actor: ObjectId<ApubPerson>,
|
pub(crate) actor: ObjectId<ApubPerson>,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) to: Vec<Url>,
|
pub(crate) to: Vec<Url>,
|
||||||
pub(crate) object: ObjectId<ApubPerson>,
|
pub(crate) object: ObjectId<ApubPerson>,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) cc: Vec<Url>,
|
pub(crate) cc: Vec<Url>,
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
pub(crate) kind: RemoveType,
|
pub(crate) kind: RemoveType,
|
||||||
|
|
|
@ -11,8 +11,10 @@ use url::Url;
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct UndoBlockUserFromCommunity {
|
pub struct UndoBlockUserFromCommunity {
|
||||||
pub(crate) actor: ObjectId<ApubPerson>,
|
pub(crate) actor: ObjectId<ApubPerson>,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) to: Vec<Url>,
|
pub(crate) to: Vec<Url>,
|
||||||
pub(crate) object: BlockUserFromCommunity,
|
pub(crate) object: BlockUserFromCommunity,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) cc: Vec<Url>,
|
pub(crate) cc: Vec<Url>,
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
pub(crate) kind: UndoType,
|
pub(crate) kind: UndoType,
|
||||||
|
|
|
@ -13,9 +13,11 @@ use url::Url;
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct UpdateCommunity {
|
pub struct UpdateCommunity {
|
||||||
pub(crate) actor: ObjectId<ApubPerson>,
|
pub(crate) actor: ObjectId<ApubPerson>,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) to: Vec<Url>,
|
pub(crate) to: Vec<Url>,
|
||||||
// TODO: would be nice to use a separate struct here, which only contains the fields updated here
|
// TODO: would be nice to use a separate struct here, which only contains the fields updated here
|
||||||
pub(crate) object: Box<Group>,
|
pub(crate) object: Box<Group>,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) cc: Vec<Url>,
|
pub(crate) cc: Vec<Url>,
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
pub(crate) kind: UpdateType,
|
pub(crate) kind: UpdateType,
|
||||||
|
|
|
@ -11,8 +11,10 @@ use url::Url;
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct CreateOrUpdateComment {
|
pub struct CreateOrUpdateComment {
|
||||||
pub(crate) actor: ObjectId<ApubPerson>,
|
pub(crate) actor: ObjectId<ApubPerson>,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) to: Vec<Url>,
|
pub(crate) to: Vec<Url>,
|
||||||
pub(crate) object: Note,
|
pub(crate) object: Note,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) cc: Vec<Url>,
|
pub(crate) cc: Vec<Url>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub(crate) tag: Vec<Mention>,
|
pub(crate) tag: Vec<Mention>,
|
||||||
|
|
|
@ -10,8 +10,10 @@ use url::Url;
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct CreateOrUpdatePost {
|
pub struct CreateOrUpdatePost {
|
||||||
pub(crate) actor: ObjectId<ApubPerson>,
|
pub(crate) actor: ObjectId<ApubPerson>,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) to: Vec<Url>,
|
pub(crate) to: Vec<Url>,
|
||||||
pub(crate) object: Page,
|
pub(crate) object: Page,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) cc: Vec<Url>,
|
pub(crate) cc: Vec<Url>,
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
pub(crate) kind: CreateOrUpdateType,
|
pub(crate) kind: CreateOrUpdateType,
|
||||||
|
|
|
@ -13,6 +13,7 @@ use url::Url;
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Delete {
|
pub struct Delete {
|
||||||
pub(crate) actor: ObjectId<ApubPerson>,
|
pub(crate) actor: ObjectId<ApubPerson>,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) to: Vec<Url>,
|
pub(crate) to: Vec<Url>,
|
||||||
pub(crate) object: Tombstone,
|
pub(crate) object: Tombstone,
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
|
|
|
@ -11,8 +11,10 @@ use url::Url;
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct UndoDelete {
|
pub struct UndoDelete {
|
||||||
pub(crate) actor: ObjectId<ApubPerson>,
|
pub(crate) actor: ObjectId<ApubPerson>,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) to: Vec<Url>,
|
pub(crate) to: Vec<Url>,
|
||||||
pub(crate) object: Delete,
|
pub(crate) object: Delete,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) cc: Vec<Url>,
|
pub(crate) cc: Vec<Url>,
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
pub(crate) kind: UndoType,
|
pub(crate) kind: UndoType,
|
||||||
|
|
|
@ -11,8 +11,10 @@ use url::Url;
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct UndoVote {
|
pub struct UndoVote {
|
||||||
pub(crate) actor: ObjectId<ApubPerson>,
|
pub(crate) actor: ObjectId<ApubPerson>,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) to: Vec<Url>,
|
pub(crate) to: Vec<Url>,
|
||||||
pub(crate) object: Vote,
|
pub(crate) object: Vote,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) cc: Vec<Url>,
|
pub(crate) cc: Vec<Url>,
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
pub(crate) kind: UndoType,
|
pub(crate) kind: UndoType,
|
||||||
|
|
|
@ -15,8 +15,10 @@ use url::Url;
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct Vote {
|
pub struct Vote {
|
||||||
pub(crate) actor: ObjectId<ApubPerson>,
|
pub(crate) actor: ObjectId<ApubPerson>,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) to: Vec<Url>,
|
pub(crate) to: Vec<Url>,
|
||||||
pub(crate) object: ObjectId<PostOrComment>,
|
pub(crate) object: ObjectId<PostOrComment>,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) cc: Vec<Url>,
|
pub(crate) cc: Vec<Url>,
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
pub(crate) kind: VoteType,
|
pub(crate) kind: VoteType,
|
||||||
|
|
|
@ -23,8 +23,10 @@ pub struct Note {
|
||||||
pub(crate) r#type: NoteType,
|
pub(crate) r#type: NoteType,
|
||||||
pub(crate) id: ObjectId<ApubComment>,
|
pub(crate) id: ObjectId<ApubComment>,
|
||||||
pub(crate) attributed_to: ObjectId<ApubPerson>,
|
pub(crate) attributed_to: ObjectId<ApubPerson>,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) to: Vec<Url>,
|
pub(crate) to: Vec<Url>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) cc: Vec<Url>,
|
pub(crate) cc: Vec<Url>,
|
||||||
pub(crate) content: String,
|
pub(crate) content: String,
|
||||||
pub(crate) media_type: Option<MediaTypeHtml>,
|
pub(crate) media_type: Option<MediaTypeHtml>,
|
||||||
|
|
|
@ -24,8 +24,10 @@ pub struct Page {
|
||||||
pub(crate) r#type: PageType,
|
pub(crate) r#type: PageType,
|
||||||
pub(crate) id: ObjectId<ApubPost>,
|
pub(crate) id: ObjectId<ApubPost>,
|
||||||
pub(crate) attributed_to: ObjectId<ApubPerson>,
|
pub(crate) attributed_to: ObjectId<ApubPerson>,
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) to: Vec<Url>,
|
pub(crate) to: Vec<Url>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
#[serde(deserialize_with = "crate::deserialize_one_or_many")]
|
||||||
pub(crate) cc: Vec<Url>,
|
pub(crate) cc: Vec<Url>,
|
||||||
pub(crate) name: String,
|
pub(crate) name: String,
|
||||||
pub(crate) content: Option<String>,
|
pub(crate) content: Option<String>,
|
||||||
|
|
Loading…
Reference in New Issue