mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-26 06:11:26 +00:00
implement a (very bad) derive macro for activityhandler
This commit is contained in:
parent
3d2e19f3c3
commit
9af57acfe5
7 changed files with 168 additions and 37 deletions
47
Cargo.lock
generated
47
Cargo.lock
generated
|
@ -1069,6 +1069,12 @@ version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
|
checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dissimilar"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fc4b29f4b9bb94bf267d57269fd0706d343a160937108e9619fe380645428abb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.6.1"
|
version = "1.6.1"
|
||||||
|
@ -1371,6 +1377,12 @@ version = "0.23.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce"
|
checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "glob"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "h2"
|
name = "h2"
|
||||||
version = "0.2.7"
|
version = "0.2.7"
|
||||||
|
@ -1887,12 +1899,23 @@ dependencies = [
|
||||||
"activitystreams",
|
"activitystreams",
|
||||||
"activitystreams-ext",
|
"activitystreams-ext",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
"lemmy_apub_lib_derive",
|
||||||
"lemmy_utils",
|
"lemmy_utils",
|
||||||
"lemmy_websocket",
|
"lemmy_websocket",
|
||||||
"serde",
|
"serde",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lemmy_apub_lib_derive"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2 1.0.24",
|
||||||
|
"quote 1.0.8",
|
||||||
|
"syn 1.0.60",
|
||||||
|
"trybuild",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lemmy_apub_receive"
|
name = "lemmy_apub_receive"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -3652,6 +3675,15 @@ dependencies = [
|
||||||
"tokio 0.2.25",
|
"tokio 0.2.25",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.5.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower-service"
|
name = "tower-service"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
|
@ -3735,6 +3767,21 @@ version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
|
checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "trybuild"
|
||||||
|
version = "1.0.42"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1768998d9a3b179411618e377dbb134c58a88cda284b0aa71c42c40660127d46"
|
||||||
|
dependencies = [
|
||||||
|
"dissimilar",
|
||||||
|
"glob",
|
||||||
|
"lazy_static",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"termcolor",
|
||||||
|
"toml",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "twoway"
|
name = "twoway"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
|
|
|
@ -15,6 +15,7 @@ members = [
|
||||||
"crates/api_crud",
|
"crates/api_crud",
|
||||||
"crates/api_common",
|
"crates/api_common",
|
||||||
"crates/apub_lib",
|
"crates/apub_lib",
|
||||||
|
"crates/apub_lib_derive",
|
||||||
"crates/apub",
|
"crates/apub",
|
||||||
"crates/apub_receive",
|
"crates/apub_receive",
|
||||||
"crates/utils",
|
"crates/utils",
|
||||||
|
|
|
@ -6,6 +6,7 @@ edition = "2018"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
lemmy_utils = { path = "../utils" }
|
lemmy_utils = { path = "../utils" }
|
||||||
lemmy_websocket = { path = "../websocket" }
|
lemmy_websocket = { path = "../websocket" }
|
||||||
|
lemmy_apub_lib_derive = { path = "../apub_lib_derive" }
|
||||||
activitystreams = "0.7.0-alpha.11"
|
activitystreams = "0.7.0-alpha.11"
|
||||||
activitystreams-ext = "0.1.0-alpha.2"
|
activitystreams-ext = "0.1.0-alpha.2"
|
||||||
serde = { version = "1.0.123", features = ["derive"] }
|
serde = { version = "1.0.123", features = ["derive"] }
|
||||||
|
|
|
@ -4,6 +4,7 @@ use activitystreams::{
|
||||||
primitives::OneOrMany,
|
primitives::OneOrMany,
|
||||||
unparsed::Unparsed,
|
unparsed::Unparsed,
|
||||||
};
|
};
|
||||||
|
pub use lemmy_apub_lib_derive::*;
|
||||||
use lemmy_utils::LemmyError;
|
use lemmy_utils::LemmyError;
|
||||||
use lemmy_websocket::LemmyContext;
|
use lemmy_websocket::LemmyContext;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
15
crates/apub_lib_derive/Cargo.toml
Normal file
15
crates/apub_lib_derive/Cargo.toml
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
[package]
|
||||||
|
name = "lemmy_apub_lib_derive"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
proc-macro = true
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
trybuild = { version = "1.0", features = ["diff"] }
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
proc-macro2 = "1.0"
|
||||||
|
syn = "1.0"
|
||||||
|
quote = "1.0"
|
102
crates/apub_lib_derive/src/lib.rs
Normal file
102
crates/apub_lib_derive/src/lib.rs
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
use proc_macro2::TokenStream;
|
||||||
|
use quote::quote;
|
||||||
|
use syn::{parse_macro_input, Data, DeriveInput};
|
||||||
|
|
||||||
|
#[proc_macro_derive(ActivityHandlerNew)]
|
||||||
|
pub fn derive_activity_handler(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||||
|
// Parse the input tokens into a syntax tree.
|
||||||
|
let input = parse_macro_input!(input as DeriveInput);
|
||||||
|
|
||||||
|
// Used in the quasi-quotation below as `#name`.
|
||||||
|
let name = input.ident;
|
||||||
|
|
||||||
|
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
|
||||||
|
|
||||||
|
let input_enum = if let Data::Enum(d) = input.data {
|
||||||
|
d
|
||||||
|
} else {
|
||||||
|
unimplemented!()
|
||||||
|
};
|
||||||
|
|
||||||
|
let impl_verify = input_enum
|
||||||
|
.variants
|
||||||
|
.iter()
|
||||||
|
.map(|variant| variant_impl_verify(&name, variant));
|
||||||
|
let impl_receive = input_enum
|
||||||
|
.variants
|
||||||
|
.iter()
|
||||||
|
.map(|variant| variant_impl_receive(&name, variant));
|
||||||
|
let impl_common = input_enum
|
||||||
|
.variants
|
||||||
|
.iter()
|
||||||
|
.map(|variant| variant_impl_common(&name, variant));
|
||||||
|
|
||||||
|
// The generated impl.
|
||||||
|
let expanded = quote! {
|
||||||
|
#[async_trait::async_trait(?Send)]
|
||||||
|
impl #impl_generics lemmy_apub_lib::ActivityHandlerNew for #name #ty_generics #where_clause {
|
||||||
|
async fn verify(
|
||||||
|
&self,
|
||||||
|
context: &LemmyContext,
|
||||||
|
request_counter: &mut i32,
|
||||||
|
) -> Result<(), LemmyError> {
|
||||||
|
match self {
|
||||||
|
#(#impl_verify)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async fn receive(
|
||||||
|
&self,
|
||||||
|
context: &LemmyContext,
|
||||||
|
request_counter: &mut i32,
|
||||||
|
) -> Result<(), LemmyError> {
|
||||||
|
match self {
|
||||||
|
#(#impl_receive)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn common(&self) -> &ActivityCommonFields {
|
||||||
|
match self {
|
||||||
|
#(#impl_common)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Hand the output tokens back to the compiler.
|
||||||
|
proc_macro::TokenStream::from(expanded)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn variant_impl_common(name: &syn::Ident, variant: &syn::Variant) -> TokenStream {
|
||||||
|
let id = &variant.ident;
|
||||||
|
match &variant.fields {
|
||||||
|
syn::Fields::Unnamed(_) => {
|
||||||
|
quote! {
|
||||||
|
#name::#id(a) => a.common(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn variant_impl_verify(name: &syn::Ident, variant: &syn::Variant) -> TokenStream {
|
||||||
|
let id = &variant.ident;
|
||||||
|
match &variant.fields {
|
||||||
|
syn::Fields::Unnamed(_) => {
|
||||||
|
quote! {
|
||||||
|
#name::#id(a) => a.verify(context, request_counter).await,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn variant_impl_receive(name: &syn::Ident, variant: &syn::Variant) -> TokenStream {
|
||||||
|
let id = &variant.ident;
|
||||||
|
match &variant.fields {
|
||||||
|
syn::Fields::Unnamed(_) => {
|
||||||
|
quote! {
|
||||||
|
#name::#id(a) => a.receive(context, request_counter).await,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unimplemented!(),
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,7 +30,7 @@ pub mod inbox_enums;
|
||||||
pub mod person;
|
pub mod person;
|
||||||
pub mod post;
|
pub mod post;
|
||||||
|
|
||||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ActivityHandlerNew)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
enum Ac {
|
enum Ac {
|
||||||
CreatePost(CreatePost),
|
CreatePost(CreatePost),
|
||||||
|
@ -38,42 +38,6 @@ enum Ac {
|
||||||
AcceptFollowCommunity(AcceptFollowCommunity),
|
AcceptFollowCommunity(AcceptFollowCommunity),
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: write a derive trait which creates this
|
|
||||||
#[async_trait::async_trait(?Send)]
|
|
||||||
impl ActivityHandlerNew for Ac {
|
|
||||||
async fn verify(
|
|
||||||
&self,
|
|
||||||
context: &LemmyContext,
|
|
||||||
request_counter: &mut i32,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
match self {
|
|
||||||
Ac::CreatePost(a) => a.verify(context, request_counter).await,
|
|
||||||
Ac::LikePost(a) => a.verify(context, request_counter).await,
|
|
||||||
Ac::AcceptFollowCommunity(a) => a.verify(context, request_counter).await,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn receive(
|
|
||||||
&self,
|
|
||||||
context: &LemmyContext,
|
|
||||||
request_counter: &mut i32,
|
|
||||||
) -> Result<(), LemmyError> {
|
|
||||||
match self {
|
|
||||||
Ac::CreatePost(a) => a.receive(context, request_counter).await,
|
|
||||||
Ac::LikePost(a) => a.receive(context, request_counter).await,
|
|
||||||
Ac::AcceptFollowCommunity(a) => a.receive(context, request_counter).await,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn common(&self) -> &ActivityCommonFields {
|
|
||||||
match self {
|
|
||||||
Ac::CreatePost(a) => a.common(),
|
|
||||||
Ac::LikePost(a) => a.common(),
|
|
||||||
Ac::AcceptFollowCommunity(a) => a.common(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn shared_inbox(
|
pub async fn shared_inbox(
|
||||||
request: HttpRequest,
|
request: HttpRequest,
|
||||||
mut body: web::Payload,
|
mut body: web::Payload,
|
||||||
|
|
Loading…
Reference in a new issue