Device macro to generate stateful and publish variants of device specific poll inputs.

This commit is contained in:
Zachary Sunforge
2023-06-20 18:17:11 -07:00
parent 8557ed19fd
commit 996bc66431

View File

@ -3,10 +3,11 @@ use quote::quote;
use std::ops::Deref; use std::ops::Deref;
use syn::__private::Span; use syn::__private::Span;
use syn::punctuated::Punctuated; use syn::punctuated::Punctuated;
use syn::token::{Colon, PathSep, Plus}; use syn::token::{Colon, Comma, PathSep, Plus};
use syn::{ use syn::{
parse_macro_input, parse_quote, Data, DeriveInput, Expr, GenericParam, Ident, Lit, Meta, Path, parse_macro_input, parse_quote, parse_quote_spanned, Data, DeriveInput, Expr, GenericParam,
PathSegment, Token, TraitBound, TraitBoundModifier, TypeParam, TypeParamBound, Generics, Ident, Lit, Meta, Path, PathSegment, Token, TraitBound, TraitBoundModifier,
TypeParam, TypeParamBound,
}; };
// Struct name: Ads1256PollStateful, Ads1256PollPublish, Ads1256PollStatePub // Struct name: Ads1256PollStateful, Ads1256PollPublish, Ads1256PollStatePub
@ -126,19 +127,37 @@ pub fn poll_variant_macro(input: TokenStream) -> TokenStream {
let (publ_impl_generics, publ_type_generics, publ_where_clause) = let (publ_impl_generics, publ_type_generics, publ_where_clause) =
&publish_generics.split_for_impl(); &publish_generics.split_for_impl();
let stateful_ident = Ident::new(format!("{ident}Stateful").deref(), ident.span()); let pubsub_error_path: Path = parse_quote!(embassy_sync::pubsub::Error);
let publish_ident = Ident::new(format!("{ident}Publish").deref(), ident.span()); let pubsub_sub_path: Path = parse_quote!(embassy_sync::pubsub::Subscriber);
let state_pub_ident = Ident::new(format!("{ident}StatePub").deref(), ident.span());
let stateful_variant_ident = Ident::new(format!("{ident}Stateful").deref(), ident.span());
let publish_variant_ident = Ident::new(format!("{ident}Publish").deref(), ident.span());
let state_pub_variant_ident = Ident::new(format!("{ident}StatePub").deref(), ident.span());
let poll_path: Path = parse_quote!(physical_node::transducer::input::Poll);
let stateful_path: Path = parse_quote!(physical_node::transducer::Stateful);
let publish_path: Path = parse_quote!(physical_node::transducer::Publish);
let expanded = quote! { let expanded = quote! {
// ----- Stateful struct ---------------------------------- // ----- Stateful struct ----------------------------------
#vis struct #stateful_ident #og_generics #og_where_clause { #vis struct #stateful_variant_ident #og_generics #og_where_clause {
pub poll: #ident #og_type_generics, pub poll: #ident #og_type_generics,
pub state: physical_node::transducer::State<#value_type_ident>, pub state: physical_node::transducer::State<#value_type_ident>,
} }
// ----- Stateful impls ---------------------------------- // ----- Stateful impls ----------------------------------
impl #og_impl_generics physical_node::transducer::Stateful for #stateful_ident #og_type_generics #og_where_clause { impl #og_impl_generics #poll_path for #stateful_variant_ident #og_type_generics #og_where_clause {
type Value = #value_type_ident;
#[inline(always)]
async fn poll(&self) -> Self::Value {
let value = self.poll.poll().await;
self.state.update(value);
value
}
}
impl #og_impl_generics #stateful_path for #stateful_variant_ident #og_type_generics #og_where_clause {
type Value = #value_type_ident; type Value = #value_type_ident;
#[inline(always)] #[inline(always)]
@ -152,25 +171,37 @@ pub fn poll_variant_macro(input: TokenStream) -> TokenStream {
} }
} }
impl #og_impl_generics physical_node::transducer::input::Poll for #stateful_ident #og_type_generics #og_where_clause {
type Value = #value_type_ident;
#[inline(always)]
async fn poll(&self) -> Self::Value {
let value = self.poll.poll().await;
self.state.update(value);
value
}
}
// ----- Publish struct ---------------------------------- // ----- Publish struct ----------------------------------
//#[cfg(feature = "embassy-sync")] //#[cfg(feature = "embassy-sync")]
#vis struct #publish_ident #publish_generics #publ_where_clause { #vis struct #publish_variant_ident #publish_generics #publ_where_clause {
pub poll: #ident #og_type_generics, pub poll: #ident #og_type_generics,
pub publisher: physical_node::transducer::Publisher<#value_type_ident, #mutex_t_ident, #capacity_ident, #num_subs_ident>, pub publisher: physical_node::transducer::Publisher<#value_type_ident, #mutex_t_ident, #capacity_ident, #num_subs_ident>,
} }
// ----- Publish impl ---------------------------------- // ----- Publish impl ----------------------------------
//#[cfg(feature = "embassy-sync")]
impl #publ_impl_generics #poll_path for #publish_variant_ident #publ_type_generics #publ_where_clause {
type Value = #value_type_ident;
#[inline(always)]
async fn poll(&self) -> Self::Value {
let value = self.poll.poll().await;
self.publisher.update(value);
value
}
}
impl #publ_impl_generics #publish_path<#capacity_ident, #num_subs_ident> for #publish_variant_ident #publ_type_generics #publ_where_clause {
type Value = #value_type_ident;
type Mutex = #mutex_t_ident;
#[inline(always)]
fn subscribe(
&self,
) -> Result<#pubsub_sub_path<Self::Mutex, Self::Value, #capacity_ident, #num_subs_ident, 0>, #pubsub_error_path> {
self.publisher.subscribe()
}
}
// ----- StatePub struct ---------------------------------- // ----- StatePub struct ----------------------------------