Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(macros): cleanup macros, add better error handling, dedup code, DX #472

Merged
merged 4 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions blueprints/examples/src/periodic_web_poller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ pub async fn web_poller(value: bool, client: reqwest::Client) -> Result<u8, Infa
}

// Maps a JSON response to a boolean value
async fn pre_process(event: serde_json::Value) -> Result<bool, gadget_sdk::Error> {
pub async fn pre_process(event: serde_json::Value) -> Result<bool, gadget_sdk::Error> {
gadget_sdk::info!("Running web_poller pre-processor on value: {event}");
let completed = event["completed"].as_bool().unwrap_or(false);
Ok(completed)
}

// Received the u8 value output from the job and performs any last post-processing
async fn post_process(job_output: u8) -> Result<(), gadget_sdk::Error> {
pub async fn post_process(job_output: u8) -> Result<(), gadget_sdk::Error> {
gadget_sdk::info!("Running web_poller post-processor on value: {job_output}");
if job_output == 1 {
Ok(())
Expand Down
2 changes: 2 additions & 0 deletions macros/blueprint-proc-macro-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ pub enum FieldType {
List(Box<FieldType>),
/// A Struct of items of type [`FieldType`].
Struct(String, Vec<(String, Box<FieldType>)>),
/// Tuple
Tuple(Vec<FieldType>),
Comment on lines +48 to +49
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be updated and added to the runtime, please open a PR on tangle or a task so we are aware of it.

CC @Serial-ATA to maybe support this into blueprint-serde.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// NOTE: Special types starts from 100
/// A special type for AccountId
AccountId,
Expand Down
2 changes: 1 addition & 1 deletion macros/blueprint-proc-macro/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ indexmap = { workspace = true }

[dev-dependencies]
trybuild = { workspace = true }
gadget-sdk = { path = "../../sdk", features = ["std"] }
gadget-sdk = { path = "../../sdk", features = ["std", "testing"] }
tracing = { workspace = true }
async-trait = { workspace = true }

Expand Down
60 changes: 9 additions & 51 deletions macros/blueprint-proc-macro/src/hooks.rs
Original file line number Diff line number Diff line change
@@ -1,42 +1,9 @@
use std::collections::BTreeMap;

use proc_macro::TokenStream;
use quote::quote;
use syn::ForeignItemFn;

pub(crate) fn registration_hook_impl(input: &ForeignItemFn) -> syn::Result<TokenStream> {
let syn::ReturnType::Default = &input.sig.output else {
return Err(syn::Error::new_spanned(
&input.sig.output,
"hooks does not return any value",
));
};

let mut param_types = BTreeMap::new();
for input in &input.sig.inputs {
if let syn::FnArg::Typed(arg) = input {
if let syn::Pat::Ident(pat_ident) = &*arg.pat {
let ident = &pat_ident.ident;
let ty = &*arg.ty;
let added = param_types.insert(ident.clone(), ty.clone());
if added.is_some() {
return Err(syn::Error::new_spanned(
ident,
"tried to add the same field twice",
));
}
}
}
}

let params = param_types
.values()
.map(crate::shared::type_to_field_type)
.collect::<syn::Result<Vec<_>>>()?;

let hook_params = serde_json::to_string(&params).map_err(|err| {
syn::Error::new_spanned(input, format!("failed to serialize hook: {err}"))
})?;
let hook_params = generate_hook_params(input)?;

let gen = quote! {
#[doc(hidden)]
Expand All @@ -48,30 +15,15 @@ pub(crate) fn registration_hook_impl(input: &ForeignItemFn) -> syn::Result<Token
Ok(gen.into())
}

pub(crate) fn request_hook_impl(input: &ForeignItemFn) -> syn::Result<TokenStream> {
fn generate_hook_params(input: &ForeignItemFn) -> syn::Result<String> {
let syn::ReturnType::Default = &input.sig.output else {
return Err(syn::Error::new_spanned(
&input.sig.output,
"hooks does not return any value",
));
};

let mut param_types = BTreeMap::new();
for input in &input.sig.inputs {
if let syn::FnArg::Typed(arg) = input {
if let syn::Pat::Ident(pat_ident) = &*arg.pat {
let ident = &pat_ident.ident;
let ty = &*arg.ty;
let added = param_types.insert(ident.clone(), ty.clone());
if added.is_some() {
return Err(syn::Error::new_spanned(
ident,
"tried to add the same field twice",
));
}
}
}
}
let param_types = crate::shared::param_types(&input.sig)?;

let params = param_types
.values()
Expand All @@ -82,6 +34,12 @@ pub(crate) fn request_hook_impl(input: &ForeignItemFn) -> syn::Result<TokenStrea
syn::Error::new_spanned(input, format!("failed to serialize hook: {err}"))
})?;

Ok(hook_params)
}

pub(crate) fn request_hook_impl(input: &ForeignItemFn) -> syn::Result<TokenStream> {
let hook_params = generate_hook_params(input)?;

let gen = quote! {
#[doc(hidden)]
#[doc = "The request hook parameters for the service"]
Expand Down
Loading
Loading