Skip to content

Commit

Permalink
wip: works w/ lifetimes & extend
Browse files Browse the repository at this point in the history
  • Loading branch information
vobradovich committed Nov 22, 2024
1 parent a196c25 commit 6f91e6b
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 554 deletions.
47 changes: 36 additions & 11 deletions rs/macros/core/src/service/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.

//! Supporting functions and structures for the `gservice` macro.
#![allow(unused_variables)] // temporary
use crate::{
sails_paths,
shared::{self, Func},
Expand All @@ -30,7 +30,7 @@ use proc_macro_error::abort;
use quote::{format_ident, quote};
use std::collections::BTreeMap;
use syn::{
parse_quote, punctuated::Punctuated, spanned::Spanned, token::Comma, Ident, ImplItemFn,
parse_quote, punctuated::Punctuated, spanned::Spanned, token::Comma, Ident, ImplItemFn, Index,
ItemImpl, Lifetime, Path, Type, Visibility,
};

Expand Down Expand Up @@ -367,39 +367,64 @@ fn generate_gservice(args: TokenStream, service_impl: ItemImpl) -> TokenStream {
quote! {}
};

let mut base_expo_types = Vec::with_capacity(service_args.base_types().len());
let mut base_types_funcs = Vec::with_capacity(service_args.base_types().len());
let mut base_types_impl = Vec::with_capacity(service_args.base_types().len());
let mut base_exposure_instantiation = Vec::with_capacity(service_args.base_types().len());
// let mut invocation_dispatches = Vec::with_capacity(service_handlers.len());
let single_base_type = service_args.base_types().len() == 1;
service_args.base_types().iter()
.enumerate()
.for_each(|(idx, base_type)| {
let as_base_ident = Ident::new(&format!("as_base_{}", idx), Span::call_site());
let as_base_ident = format_ident!("as_base_{}", idx);
let base_idx = Index::from(idx);

base_expo_types.push(quote! {
#sails_path::gstd::services::ServiceExposure< #base_type, () >
});

base_types_funcs.push(quote!{
fn #as_base_ident (&self) -> &< #base_type as #sails_path::gstd::services::Service>::Exposure;
fn #as_base_ident (&self) -> & #sails_path::gstd::services::ServiceExposure< #base_type, () >;
});

let extend_ref = if single_base_type {
quote! { &self.extend }
} else {
quote! { &self.extend.#base_idx }
};

base_types_impl.push(quote!{
fn #as_base_ident (&self) -> &< #base_type as #sails_path::gstd::services::Service>::Exposure {
&self.extend.#idx
fn #as_base_ident (&self) -> & #sails_path::gstd::services::ServiceExposure< #base_type, () > {
#extend_ref
}
});

base_exposure_instantiation.push(quote!(
< #base_type as Clone>::clone(AsRef::< #base_type >::as_ref( #inner_ident )).expose( #message_id_ident , #route_ident ),
< #base_type as Clone>::clone(AsRef::< #base_type >::as_ref( &self )).expose( #message_id_ident , #route_ident )
));
});

let base_type = if single_base_type {
let single_type = &base_expo_types[0];
quote! { #single_type }
} else {
quote! { ( #( #base_expo_types ),* ) }
};
let base_inst: TokenStream = quote! { ( #( #base_exposure_instantiation ),* ) };

quote!(
#service_impl

pub trait #trait_ident #trait_lifetimes {
#( #trait_funcs )*

#( #base_types_funcs )*
}

impl #generics #trait_ident #trait_lifetimes for #sails_path::gstd::services::ServiceExposure< #exposure_args, () > #service_type_constraints {
impl #generics #trait_ident #trait_lifetimes for #sails_path::gstd::services::ServiceExposure< #service_type_path, #base_type > #service_type_constraints {
#( #trait_funcs_impl )*

#( #base_types_impl )*
}

impl #generics #sails_path::gstd::services::ServiceHandle for #service_type_path #service_type_constraints {
Expand All @@ -414,11 +439,11 @@ fn generate_gservice(args: TokenStream, service_impl: ItemImpl) -> TokenStream {
}

impl #generics #sails_path::gstd::services::Service for #service_type_path #service_type_constraints {
type Exposure = #sails_path::gstd::services::ServiceExposure< #exposure_args, () >;
type Extend = ();
type Exposure = #sails_path::gstd::services::ServiceExposure< #service_type_path, #base_type >;
type Extend = #base_type;

fn expose(self, #message_id_ident : #sails_path::MessageId, #route_ident : &'static [u8]) -> Self::Exposure {
let extend = ();
let extend = #base_inst;
Self::Exposure::new(#message_id_ident, #route_ident, self, extend)
}
}
Expand Down
44 changes: 40 additions & 4 deletions rs/macros/core/tests/snapshots/gservice__works_with_extends.snap
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,35 @@ impl SomeService {
}
pub trait SomeServiceImplTrait {
fn do_this(&mut self) -> u32;
fn as_base_0(
&self,
) -> &sails_rs::gstd::services::ServiceExposure<ExtendedService1, ()>;
fn as_base_1(
&self,
) -> &sails_rs::gstd::services::ServiceExposure<ExtendedService2, ()>;
}
impl SomeServiceImplTrait
for sails_rs::gstd::services::ServiceExposure<SomeService, ()> {
for sails_rs::gstd::services::ServiceExposure<
SomeService,
(
sails_rs::gstd::services::ServiceExposure<ExtendedService1, ()>,
sails_rs::gstd::services::ServiceExposure<ExtendedService2, ()>,
),
> {
fn do_this(&mut self) -> u32 {
let exposure_scope = sails_rs::gstd::services::ExposureCallScope::new2(self);
self.inner.do_this()
}
fn as_base_0(
&self,
) -> &sails_rs::gstd::services::ServiceExposure<ExtendedService1, ()> {
&self.extend.0
}
fn as_base_1(
&self,
) -> &sails_rs::gstd::services::ServiceExposure<ExtendedService2, ()> {
&self.extend.1
}
}
impl sails_rs::gstd::services::ServiceHandle for SomeService {
async fn try_handle(&mut self, input: &[u8]) -> Option<(Vec<u8>, u128)> {
Expand All @@ -36,14 +58,28 @@ impl sails_rs::gstd::services::ServiceHandle for SomeService {
}
}
impl sails_rs::gstd::services::Service for SomeService {
type Exposure = sails_rs::gstd::services::ServiceExposure<SomeService, ()>;
type Extend = ();
type Exposure = sails_rs::gstd::services::ServiceExposure<
SomeService,
(
sails_rs::gstd::services::ServiceExposure<ExtendedService1, ()>,
sails_rs::gstd::services::ServiceExposure<ExtendedService2, ()>,
),
>;
type Extend = (
sails_rs::gstd::services::ServiceExposure<ExtendedService1, ()>,
sails_rs::gstd::services::ServiceExposure<ExtendedService2, ()>,
);
fn expose(
self,
message_id: sails_rs::MessageId,
route: &'static [u8],
) -> Self::Exposure {
let extend = ();
let extend = (
<ExtendedService1 as Clone>::clone(AsRef::<ExtendedService1>::as_ref(&self))
.expose(message_id, route),
<ExtendedService2 as Clone>::clone(AsRef::<ExtendedService2>::as_ref(&self))
.expose(message_id, route),
);
Self::Exposure::new(message_id, route, self, extend)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,15 @@ impl<'a> ExtendedLifetime<'a> {
pub trait ExtendedLifetimeImplTrait<'a> {
fn extended_name(&self) -> String;
fn name(&self) -> String;
fn as_base_0(
&self,
) -> &sails_rs::gstd::services::ServiceExposure<base::BaseLifetime<'a>, ()>;
}
impl<'a> ExtendedLifetimeImplTrait<'a>
for sails_rs::gstd::services::ServiceExposure<'a, ExtendedLifetime<'a>, ()> {
for sails_rs::gstd::services::ServiceExposure<
ExtendedLifetime<'a>,
sails_rs::gstd::services::ServiceExposure<base::BaseLifetime<'a>, ()>,
> {
fn extended_name(&self) -> String {
let exposure_scope = sails_rs::gstd::services::ExposureCallScope::new2(self);
self.inner.extended_name()
Expand All @@ -24,6 +30,11 @@ for sails_rs::gstd::services::ServiceExposure<'a, ExtendedLifetime<'a>, ()> {
let exposure_scope = sails_rs::gstd::services::ExposureCallScope::new2(self);
self.inner.name()
}
fn as_base_0(
&self,
) -> &sails_rs::gstd::services::ServiceExposure<base::BaseLifetime<'a>, ()> {
&self.extend
}
}
impl<'a> sails_rs::gstd::services::ServiceHandle for ExtendedLifetime<'a> {
async fn try_handle(&mut self, input: &[u8]) -> Option<(Vec<u8>, u128)> {
Expand Down Expand Up @@ -54,17 +65,19 @@ impl<'a> sails_rs::gstd::services::ServiceHandle for ExtendedLifetime<'a> {
}
impl<'a> sails_rs::gstd::services::Service for ExtendedLifetime<'a> {
type Exposure = sails_rs::gstd::services::ServiceExposure<
'a,
ExtendedLifetime<'a>,
(),
sails_rs::gstd::services::ServiceExposure<base::BaseLifetime<'a>, ()>,
>;
type Extend = ();
type Extend = sails_rs::gstd::services::ServiceExposure<base::BaseLifetime<'a>, ()>;
fn expose(
self,
message_id: sails_rs::MessageId,
route: &'static [u8],
) -> Self::Exposure {
let extend = ();
let extend = (<base::BaseLifetime<
'a,
> as Clone>::clone(AsRef::<base::BaseLifetime<'a>>::as_ref(&self))
.expose(message_id, route));
Self::Exposure::new(message_id, route, self, extend)
}
}
Expand Down
Loading

0 comments on commit 6f91e6b

Please sign in to comment.