mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-29 15:51:20 +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"
|
||||
checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0"
|
||||
|
||||
[[package]]
|
||||
name = "dissimilar"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc4b29f4b9bb94bf267d57269fd0706d343a160937108e9619fe380645428abb"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.6.1"
|
||||
|
@ -1371,6 +1377,12 @@ version = "0.23.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce"
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.2.7"
|
||||
|
@ -1887,12 +1899,23 @@ dependencies = [
|
|||
"activitystreams",
|
||||
"activitystreams-ext",
|
||||
"async-trait",
|
||||
"lemmy_apub_lib_derive",
|
||||
"lemmy_utils",
|
||||
"lemmy_websocket",
|
||||
"serde",
|
||||
"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]]
|
||||
name = "lemmy_apub_receive"
|
||||
version = "0.1.0"
|
||||
|
@ -3652,6 +3675,15 @@ dependencies = [
|
|||
"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]]
|
||||
name = "tower-service"
|
||||
version = "0.3.1"
|
||||
|
@ -3735,6 +3767,21 @@ version = "0.2.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "twoway"
|
||||
version = "0.2.1"
|
||||
|
|
|
@ -15,6 +15,7 @@ members = [
|
|||
"crates/api_crud",
|
||||
"crates/api_common",
|
||||
"crates/apub_lib",
|
||||
"crates/apub_lib_derive",
|
||||
"crates/apub",
|
||||
"crates/apub_receive",
|
||||
"crates/utils",
|
||||
|
|
|
@ -6,6 +6,7 @@ edition = "2018"
|
|||
[dependencies]
|
||||
lemmy_utils = { path = "../utils" }
|
||||
lemmy_websocket = { path = "../websocket" }
|
||||
lemmy_apub_lib_derive = { path = "../apub_lib_derive" }
|
||||
activitystreams = "0.7.0-alpha.11"
|
||||
activitystreams-ext = "0.1.0-alpha.2"
|
||||
serde = { version = "1.0.123", features = ["derive"] }
|
||||
|
|
|
@ -4,6 +4,7 @@ use activitystreams::{
|
|||
primitives::OneOrMany,
|
||||
unparsed::Unparsed,
|
||||
};
|
||||
pub use lemmy_apub_lib_derive::*;
|
||||
use lemmy_utils::LemmyError;
|
||||
use lemmy_websocket::LemmyContext;
|
||||
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 post;
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ActivityHandlerNew)]
|
||||
#[serde(untagged)]
|
||||
enum Ac {
|
||||
CreatePost(CreatePost),
|
||||
|
@ -38,42 +38,6 @@ enum Ac {
|
|||
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(
|
||||
request: HttpRequest,
|
||||
mut body: web::Payload,
|
||||
|
|
Loading…
Reference in a new issue