From b01fffa861255971c0aabc43658491e77c214dbd Mon Sep 17 00:00:00 2001 From: llehtahw Date: Sat, 30 Mar 2024 12:15:07 +0800 Subject: [PATCH] Add tuple-proc (#7) --- Cargo.lock | 444 +++++++++++++++++++++++++++++++++++++++++++++- Cargo.toml | 6 +- procs/src/lib.rs | 6 +- src/lib.rs | 4 + src/tuple_proc.rs | 288 ++++++++++++++++++++++++++++++ 5 files changed, 737 insertions(+), 11 deletions(-) create mode 100644 src/tuple_proc.rs diff --git a/Cargo.lock b/Cargo.lock index d55ebef..a8f8ebf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,11 +2,201 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "autocfg" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" + +[[package]] +name = "backtrace" +version = "0.3.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bytes" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" + +[[package]] +name = "cc" +version = "1.0.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + [[package]] name = "proc-macro2" -version = "1.0.71" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] @@ -22,33 +212,273 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "statecs" -version = "0.1.0" +version = "0.2.0" dependencies = [ "procs", + "tokio", + "tokio-test", ] [[package]] name = "syn" -version = "2.0.43" +version = "2.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53" +checksum = "11a6ae1e52eb25aab8f3fb9fca13be982a373b8f1157ca14b897a825ba4a2d35" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "tokio" +version = "1.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-stream" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-test" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2468baabc3311435b55dd935f702f42cd1b8abb7e754fb7dfb16bd36aa88f9f7" +dependencies = [ + "async-stream", + "bytes", + "futures-core", + "tokio", + "tokio-stream", +] + [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.4", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +dependencies = [ + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" diff --git a/Cargo.toml b/Cargo.toml index cd51198..c17eb42 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,14 @@ workspace = { members = ["procs"] } [package] name = "statecs" -version = "0.2.0" +version = "0.3.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] procs = { path = "procs" } + +[dev-dependencies] +tokio-test = "0.4.4" +tokio = { version = "1", features = ["full"] } \ No newline at end of file diff --git a/procs/src/lib.rs b/procs/src/lib.rs index 1bf21f3..5f13689 100644 --- a/procs/src/lib.rs +++ b/procs/src/lib.rs @@ -368,7 +368,7 @@ pub fn system_wrap(_attr: TokenStream, item: TokenStream) -> TokenStream { .into_iter() .map(|x| (x.id, (x.inputs, x.outputs))) .collect::>(); - if let Some(mut func) = syn::parse::(item.clone()).ok() { + if let Ok(mut func) = syn::parse::(item.clone()) { func.sig = transoform_impl_fnarg_to_generics(func.sig); expand_transition_type_generics(&mut func.sig, Some(&mut func.block), &map); @@ -377,7 +377,7 @@ pub fn system_wrap(_attr: TokenStream, item: TokenStream) -> TokenStream { #func }; TokenStream::from(expanded) - } else if let Some(trait_item) = syn::parse::(item.clone()).ok() { + } else if let Ok(trait_item) = syn::parse::(item.clone()) { let mut func = match trait_item { syn::TraitItem::Fn(func) => func, _ => panic!("Not supported trait item"), @@ -385,7 +385,7 @@ pub fn system_wrap(_attr: TokenStream, item: TokenStream) -> TokenStream { func.sig = transoform_impl_fnarg_to_generics(func.sig); expand_transition_type_generics(&mut func.sig, func.default.as_mut(), &map); TokenStream::from(quote! {#func}) - } else if let Some(impl_item) = syn::parse::(item.clone()).ok() { + } else if let Ok(impl_item) = syn::parse::(item.clone()) { let mut func = match impl_item { syn::ImplItem::Fn(func) => func, _ => panic!("Not supported trait item"), diff --git a/src/lib.rs b/src/lib.rs index 1130372..d6677a5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ pub(crate) mod component; pub(crate) mod entity; pub(crate) mod system; +pub(crate) mod tuple_proc; pub mod prelude { pub use crate::component::{ComponentGet, ComponentPut}; @@ -10,6 +11,9 @@ pub mod prelude { pub use crate::put; pub use crate::take; + + pub use crate::tuple_proc::{IntoTupleProcessor, TupleProcessFn}; + pub use crate::{cascade, cascade_option}; } pub use prelude::*; diff --git a/src/tuple_proc.rs b/src/tuple_proc.rs new file mode 100644 index 0000000..a41e9e7 --- /dev/null +++ b/src/tuple_proc.rs @@ -0,0 +1,288 @@ +use crate::apply_tuple; +use crate::ComponentGet; +use crate::TupleMerge; +use std::{future::Future, marker::PhantomData}; + +use procs::system_wrap; + +use crate::TupleExtend; + +pub trait IntoTupleProcessor { + type IType; + type OType; + type TupleProcessorType; + fn into_tuple_processor(self) -> Self::TupleProcessorType; +} + +#[macro_export] +macro_rules! cascade { + ($val:expr => $expr:expr) => { + $expr.into_tuple_processor().cascade($val) + }; +} + +#[macro_export] +macro_rules! cascade_option { + ($val:expr => $expr:expr) => { + $expr.into_tuple_processor().cascade_option($val) + }; +} + +#[macro_export] +macro_rules! cascade_result { + ($val:expr => $expr:expr) => { + $expr.into_tuple_processor().cascade_result($val) + }; +} + +#[macro_export] +macro_rules! cascade_async { + ($val:expr => $expr:expr) => { + $expr.into_tuple_processor().cascade_fut($val) + }; +} + +#[macro_export] +macro_rules! cascade_option_async { + ($val:expr => $expr:expr) => { + $expr.into_tuple_processor().cascade_option_fut($val) + }; +} + +#[macro_export] +macro_rules! cascade_result_async { + ($val:expr => $expr:expr) => { + $expr.into_tuple_processor().cascade_result_fut($val) + }; +} + +#[cfg(test)] +mod tests { + use crate::*; + use tokio::test; + #[test] + async fn test_basics() { + // cascade + fn test_cascade(a: i32) -> (i32,) { + (a + 1,) + } + assert_eq!((234i32,), cascade!((233i32,) => test_cascade)); + // option + fn test_option(a: i32) -> Option<(u32,)> { + if a > 0 { + Some((a as u32,)) + } else { + None + } + } + assert_eq!( + Some((1u32, 0i8, 2i16)), + cascade_option!((0i8, 1i32, 2i16) => test_option) + ); + // result + fn test_result(a: i32, b: u32) -> Result<(i32,), u32> { + if a as u32 > b { + Ok((a,)) + } else { + Err(b) + } + } + assert_eq!( + Err(666u32), + cascade_result!((666u32, 233i32, "string".to_string()) => test_result) + ); + assert_eq!( + Ok((666i32, "string".to_string())), + cascade_result!((233u32, 666i32, "string".to_string()) => test_result) + ); + } + #[test] + async fn test_fut() { + // cascade + async fn test_cascade(a: i32) -> (i32,) { + (a + 1,) + } + assert_eq!((234i32,), cascade_async!((233i32,) => test_cascade).await); + // option + async fn test_option(a: i32) -> Option<(u32,)> { + if a > 0 { + Some((a as u32,)) + } else { + None + } + } + assert_eq!( + Some((1u32, 0i8, 2i16)), + cascade_option_async!((0i8, 1i32, 2i16) => test_option).await + ); + // result + async fn test_result(a: i32, b: u32) -> Result<(i32,), u32> { + if a as u32 > b { + Ok((a,)) + } else { + Err(b) + } + } + assert_eq!( + Err(666u32), + cascade_result_async!((666u32, 233i32, "string".to_string()) => test_result).await + ); + assert_eq!( + Ok((666i32, "string".to_string())), + cascade_result_async!((233u32, 666i32, "string".to_string()) => test_result).await + ); + } +} + +pub struct TupleProcessFn(F, PhantomData); + +macro_rules! impl_tuple_proc { + (($($ids:ident),*$(,)?)) => { + #[allow(non_snake_case)] + impl IntoTupleProcessor<($($ids,)*), OType> for F + where + F: Fn($($ids,)*) -> OType, + { + type IType = ($($ids,)*); + + type OType = OType; + type TupleProcessorType = TupleProcessFn; + + fn into_tuple_processor(self) -> Self::TupleProcessorType { + TupleProcessFn(self, Default::default()) + } + } + #[allow(non_snake_case)] + impl<_F, OType, $($ids,)*> TupleProcessFn<_F, (($($ids,)*), OType)> + where + _F: Fn($($ids,)*) -> OType, + OType: TupleExtend, + { + #[system_wrap( + _E: ($($ids,)*) + )] + pub fn operate<_E>(&self, e: _E) -> (OType, outof![_E]) { + let (r, b) = _E!(e => |($($ids,)*)| self.0($($ids,)*) => NoMerge); + (r, b.merge(())) + } + #[system_wrap( + _E: ($($ids,)*) + )] + pub fn cascade<_E>(&self, e: _E) -> ::AfterMerge + where + outof![_E]: TupleMerge, + { + let (r, b) = _E!(e => |($($ids,)*)| self.0($($ids,)*) => NoMerge); + b.merge(()).merge(r) + } + } + #[allow(non_snake_case)] + impl TupleProcessFn)> + where + F: Fn($($ids,)*) -> Option, + { + #[system_wrap( + E: ($($ids,)*) + )] + pub fn cascade_option(&self, e: E) -> Option<::AfterMerge> + where + outof![E]: TupleMerge, + OType: TupleExtend, + { + let (r, b) = E!(e => |($($ids,)*)| self.0($($ids,)*) => NoMerge); + r.map(|r| b.merge(()).merge(r)) + } + } + #[allow(non_snake_case)] + impl TupleProcessFn)> + where + F: Fn($($ids,)*) -> Result, + { + #[system_wrap( + E: ($($ids,)*) + )] + pub fn cascade_result( + &self, + e: E, + ) -> Result<::AfterMerge, ErrType> + where + outof![E]: TupleMerge, + OType: TupleExtend, + { + let (r, b) = E!(e => |($($ids,)*)| self.0($($ids,)*) => NoMerge); + r.map(|r| b.merge(()).merge(r)) + } + } + #[allow(non_snake_case)] + impl TupleProcessFn + where + F: Fn($($ids,)*) -> Fut, + Fut: Future, + OType: TupleExtend, + { + #[system_wrap( + E: ($($ids,)*) + )] + pub async fn operate_fut(self, e: E) -> (OType, outof![E]) { + let (r, b) = E!(e => |($($ids,)*)| self.0($($ids,)*) => NoMerge); + (r.await, b.merge(())) + } + #[system_wrap( + E: ($($ids,)*) + )] + pub async fn cascade_fut(self, e: E) -> ::AfterMerge + where + outof![E]: TupleMerge, + { + let (r, b) = E!(e => |($($ids,)*)| self.0($($ids,)*) => NoMerge); + b.merge(()).merge(r.await) + } + } + #[allow(non_snake_case)] + impl TupleProcessFn + where + F: Fn($($ids,)*) -> Fut, + Fut: Future>, + { + #[system_wrap( + E: ($($ids,)*) + )] + pub async fn cascade_option_fut( + self, + e: E, + ) -> Option<::AfterMerge> + where + outof![E]: TupleMerge, + OType: TupleExtend, + { + let (r, b) = E!(e => |($($ids,)*)| self.0($($ids,)*) => NoMerge); + r.await.map(|r| b.merge(()).merge(r)) + } + } + #[allow(non_snake_case)] + impl TupleProcessFn + where + F: Fn($($ids,)*) -> Fut, + Fut: Future>, + { + #[system_wrap( + E: ($($ids,)*) + )] + pub async fn cascade_result_fut( + self, + e: E, + ) -> Result<::AfterMerge, ErrType> + where + outof![E]: TupleMerge, + OType: TupleExtend, + { + let (r, b) = E!(e => |($($ids,)*)| self.0($($ids,)*) => NoMerge); + r.await.map(|r| b.merge(()).merge(r)) + } + } + }; +} +apply_tuple!( + impl_tuple_proc, + (A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16) +);