Skip to content

Commit

Permalink
tmp: entrait 0.7
Browse files Browse the repository at this point in the history
  • Loading branch information
audunhalland committed Mar 27, 2024
1 parent 1cc1061 commit 03d2a9b
Show file tree
Hide file tree
Showing 30 changed files with 212 additions and 794 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ jobs:
- uses: actions/checkout@v3
- uses: taiki-e/install-action@cargo-hack
- name: Test feature powerset
run: cargo hack --feature-powerset --exclude-features "default use-associated-futures nightly-tests" --exclude-no-default-features test
run: cargo hack --feature-powerset --exclude-features "default nightly-tests" --exclude-no-default-features test
- name: Test workspace
run: cargo test --workspace --features "boxed-futures"
run: cargo test --workspace --features "unimock"
- name: Doctest
run: cargo test --doc --features "unimock use-boxed-futures"
run: cargo test --doc --features "unimock"
- name: Clippy
run: cargo clippy --features "unimock use-boxed-futures" -- -D warnings
run: cargo clippy --features "unimock" -- -D warnings
- name: Build examples
run: cargo build --all

Expand Down
12 changes: 5 additions & 7 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[package]
name = "entrait"
version = "0.6.0"
version = "0.7.0-dev"
authors = ["Audun Halland <audun.halland@pm.me>"]
edition = "2021"
rust-version = "1.60"
rust-version = "1.75"
license = "MIT"
description = "Loosely coupled Rust application design made easy"
repository = "https://github.com/audunhalland/entrait/"
Expand All @@ -13,22 +13,20 @@ categories = ["rust-patterns", "development-tools::testing"]
[features]
default = []
unimock = ["dep:unimock"]
use-boxed-futures = ["boxed-futures"]
use-associated-futures = []
boxed-futures = ["dep:async-trait"]
nightly-tests = []

[dependencies]
entrait_macros = { path = "entrait_macros", version = "0.6.0" }
entrait_macros = { path = "entrait_macros", version = "0.7.0-dev" }
implementation = "0.1"
async-trait = { version = "0.1", optional = true }
unimock = { version = "0.6", optional = true }
unimock = { version = "0.6.2", optional = true }

[dev-dependencies]
tokio = { version = "1", features = ["macros", "rt"] }
feignhttp = "0.5"
mockall = "0.11"
tracing = "0.1"
async-trait = "0.1"

[lib]
# do not run doctest by default with `cargo hack`. They are tested with a separate `cargo test --doc` run.
Expand Down
2 changes: 1 addition & 1 deletion entrait_macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "entrait_macros"
version = "0.6.0"
version = "0.7.0-dev"
authors = ["Audun Halland <audun.halland@pm.me>"]
edition = "2021"
rust-version = "1.60"
Expand Down
56 changes: 10 additions & 46 deletions entrait_macros/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::analyze_generics::TraitFn;
use crate::generics::{self, TraitIndirection};
use crate::idents::CrateIdents;
use crate::input::FnInputMode;
use crate::opt::{AsyncStrategy, MockApiIdent, Opts, SpanOpt};
use crate::opt::{MockApiIdent, Opts};
use crate::token_util::{comma_sep, push_tokens};

use proc_macro2::{Span, TokenStream};
Expand Down Expand Up @@ -229,58 +229,22 @@ impl ToTokens for MockallAutomockParams {
}
}

pub fn opt_async_trait_attr<'s, 'o>(
opts: &'s Opts,
crate_idents: &'s CrateIdents,
trait_fns: impl Iterator<Item = &'o TraitFn>,
) -> Option<impl ToTokens + 's> {
match (
opts.async_strategy(),
generics::has_any_async(trait_fns.map(|trait_fn| trait_fn.sig())),
) {
(SpanOpt(AsyncStrategy::BoxFuture, span), true) => Some(Attr(AsyncTraitParams {
crate_idents,
use_static: false,
span,
})),
(SpanOpt(AsyncStrategy::AssociatedFuture, span), true) => Some(Attr(AsyncTraitParams {
crate_idents,
use_static: true,
span,
})),
_ => None,
}
}

pub struct AsyncTraitParams<'a> {
pub crate_idents: &'a CrateIdents,
pub use_static: bool,
pub span: Span,
}

impl<'a> ToTokens for AsyncTraitParams<'a> {
fn to_tokens(&self, stream: &mut TokenStream) {
let span = self.span;
if self.use_static {
push_tokens!(
stream,
syn::token::PathSep(span),
self.crate_idents.entrait,
syn::token::PathSep(span),
syn::Ident::new("static_async", span),
syn::token::PathSep(span),
syn::Ident::new("async_trait", span)
);
} else {
push_tokens!(
stream,
syn::token::PathSep(span),
self.crate_idents.entrait,
syn::token::PathSep(span),
syn::Ident::new("__async_trait", span),
syn::token::PathSep(span),
syn::Ident::new("async_trait", span)
);
}
push_tokens!(
stream,
syn::token::PathSep(span),
self.crate_idents.entrait,
syn::token::PathSep(span),
syn::Ident::new("__async_trait", span),
syn::token::PathSep(span),
syn::Ident::new("async_trait", span)
);
}
}
3 changes: 0 additions & 3 deletions entrait_macros/src/entrait_fn/input_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ impl Parse for EntraitFnAttr {
EntraitOpt::BoxFuture(opt) => {
async_strategy = Some(SpanOpt(AsyncStrategy::BoxFuture, opt.1))
}
EntraitOpt::AssociatedFuture(opt) => {
async_strategy = Some(SpanOpt(AsyncStrategy::AssociatedFuture, opt.1))
}
EntraitOpt::Export(opt) => export = Some(opt),
EntraitOpt::MockApi(ident) => mock_api = Some(ident),
EntraitOpt::Unimock(opt) => unimock = Some(opt),
Expand Down
25 changes: 14 additions & 11 deletions entrait_macros/src/entrait_fn/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::generics;
use crate::input::FnInputMode;
use crate::input::{InputFn, InputMod, ModItem};
use crate::signature;
use crate::sub_attributes::analyze_sub_attributes;
use crate::trait_codegen::Supertraits;
use crate::trait_codegen::TraitCodegen;
use input_attr::*;
Expand All @@ -33,22 +34,21 @@ pub fn entrait_for_single_fn(attr: &EntraitFnAttr, input_fn: InputFn) -> syn::Re
opts: &attr.opts,
}
.analyze(input_fn.input_sig(), &mut generics_analyzer)?];
let sub_attributes = analyze_sub_attributes(&input_fn.fn_attrs);

let trait_dependency_mode = detect_trait_dependency_mode(
&fn_input_mode,
&trait_fns,
&attr.crate_idents,
attr.trait_ident.span(),
)?;
let use_associated_future =
generics::detect_use_associated_future(&attr.opts, [&input_fn].into_iter());

let trait_generics = generics_analyzer.into_trait_generics();
let trait_def = TraitCodegen {
opts: &attr.opts,
crate_idents: &attr.crate_idents,
trait_indirection: generics::TraitIndirection::Plain,
trait_dependency_mode: &trait_dependency_mode,
sub_attributes: &sub_attributes,
}
.gen_trait_def(
&attr.trait_visibility,
Expand All @@ -58,6 +58,7 @@ pub fn entrait_for_single_fn(attr: &EntraitFnAttr, input_fn: InputFn) -> syn::Re
&trait_fns,
&fn_input_mode,
)?;

let impl_block = fn_delegation_codegen::FnDelegationCodegen {
opts: &attr.opts,
crate_idents: &attr.crate_idents,
Expand All @@ -67,7 +68,7 @@ pub fn entrait_for_single_fn(attr: &EntraitFnAttr, input_fn: InputFn) -> syn::Re
trait_generics: &trait_generics,
fn_input_mode: &fn_input_mode,
trait_dependency_mode: &trait_dependency_mode,
use_associated_future,
sub_attributes: &sub_attributes,
}
.gen_impl_block(&trait_fns);

Expand All @@ -79,11 +80,15 @@ pub fn entrait_for_single_fn(attr: &EntraitFnAttr, input_fn: InputFn) -> syn::Re
..
} = input_fn;

Ok(quote! {
let out = quote! {
#(#fn_attrs)* #fn_vis #fn_sig #fn_body
#trait_def
#impl_block
})
};

// println!("\n\nfn output: {out}");

Ok(out)
}

pub fn entrait_for_mod(attr: &EntraitFnAttr, input_mod: InputMod) -> syn::Result<TokenStream> {
Expand All @@ -103,24 +108,22 @@ pub fn entrait_for_mod(attr: &EntraitFnAttr, input_mod: InputMod) -> syn::Result
.analyze(input_fn.input_sig(), &mut generics_analyzer)
})
.collect::<syn::Result<Vec<_>>>()?;
let sub_attributes = analyze_sub_attributes(&input_mod.attrs);

let trait_dependency_mode = detect_trait_dependency_mode(
&fn_input_mode,
&trait_fns,
&attr.crate_idents,
attr.trait_ident.span(),
)?;
let use_associated_future = generics::detect_use_associated_future(
&attr.opts,
input_mod.items.iter().filter_map(ModItem::filter_pub_fn),
);

let trait_generics = generics_analyzer.into_trait_generics();
let trait_def = TraitCodegen {
opts: &attr.opts,
crate_idents: &attr.crate_idents,
trait_indirection: generics::TraitIndirection::Plain,
trait_dependency_mode: &trait_dependency_mode,
sub_attributes: &sub_attributes,
}
.gen_trait_def(
&attr.trait_visibility,
Expand All @@ -139,7 +142,7 @@ pub fn entrait_for_mod(attr: &EntraitFnAttr, input_mod: InputMod) -> syn::Result
trait_generics: &trait_generics,
fn_input_mode: &fn_input_mode,
trait_dependency_mode: &trait_dependency_mode,
use_associated_future,
sub_attributes: &sub_attributes,
}
.gen_impl_block(&trait_fns);

Expand Down
15 changes: 9 additions & 6 deletions entrait_macros/src/entrait_impl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use crate::input::InputImpl;
use crate::opt::AsyncStrategy;
use crate::opt::SpanOpt;
use crate::signature;
use crate::sub_attributes::analyze_sub_attributes;
use crate::sub_attributes::SubAttribute;

use quote::quote;
use syn::spanned::Spanned;
Expand Down Expand Up @@ -58,16 +60,13 @@ pub fn output_tokens_for_impl(
.analyze(input_fn.input_sig(), &mut generics_analyzer)
})
.collect::<syn::Result<Vec<_>>>()?;
let sub_attributes = analyze_sub_attributes(&attrs);

let trait_generics = generics_analyzer.into_trait_generics();

let fn_input_mode = crate::input::FnInputMode::ImplBlock(&self_ty);
let trait_dependency_mode =
detect_trait_dependency_mode(&fn_input_mode, &trait_fns, &attr.crate_idents, trait_span)?;
let use_associated_future = generics::detect_use_associated_future(
&attr.opts,
items.iter().filter_map(ImplItem::filter_fn),
);

let impl_indirection = match attr.impl_kind {
ImplKind::Static => generics::ImplIndirection::Static { ty: &self_ty },
Expand All @@ -83,12 +82,16 @@ pub fn output_tokens_for_impl(
trait_generics: &trait_generics,
fn_input_mode: &fn_input_mode,
trait_dependency_mode: &trait_dependency_mode,
use_associated_future,
sub_attributes: &sub_attributes,
}
.gen_impl_block(&trait_fns);

let inherent_sub_attrs = sub_attributes
.iter()
.filter(|sub_attr| !matches!(sub_attr, SubAttribute::AsyncTrait(_)));

Ok(quote! {
#(#attrs)*
#(#inherent_sub_attrs)*
#unsafety #impl_token #self_ty {
#(#items)*
}
Expand Down
3 changes: 0 additions & 3 deletions entrait_macros/src/entrait_trait/input_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ impl Parse for EntraitTraitAttr {
EntraitOpt::BoxFuture(opt) => {
async_strategy = Some(SpanOpt(AsyncStrategy::BoxFuture, opt.1))
}
EntraitOpt::AssociatedFuture(opt) => {
async_strategy = Some(SpanOpt(AsyncStrategy::AssociatedFuture, opt.1))
}
EntraitOpt::MockApi(ident) => mock_api = Some(ident),
EntraitOpt::Unimock(opt) => unimock = Some(opt),
EntraitOpt::Mockall(opt) => mockall = Some(opt),
Expand Down
Loading

0 comments on commit 03d2a9b

Please sign in to comment.