diff --git a/Cargo.lock b/Cargo.lock index c8939a6..189db6a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,9 +10,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bytes" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" [[package]] name = "cfg-if" @@ -28,9 +28,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "futures" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" +checksum = "13e2792b0ff0340399d58445b88fd9770e3489eff258a4cbc1523418f12abf84" dependencies = [ "futures-channel", "futures-core", @@ -43,9 +43,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5" dependencies = [ "futures-core", "futures-sink", @@ -53,15 +53,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" +checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608" [[package]] name = "futures-executor" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" +checksum = "e8de0a35a6ab97ec8869e32a2473f4b1324459e14c29275d14b10cb1fd19b50e" dependencies = [ "futures-core", "futures-task", @@ -70,15 +70,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" +checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531" [[package]] name = "futures-macro" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" +checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70" dependencies = [ "proc-macro2", "quote", @@ -87,21 +87,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" +checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364" [[package]] name = "futures-task" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" +checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366" [[package]] name = "futures-util" -version = "0.3.25" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1" dependencies = [ "futures-channel", "futures-core", @@ -149,7 +149,7 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "motore" -version = "0.3.0" +version = "0.3.1" dependencies = [ "futures", "http", @@ -171,9 +171,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" [[package]] name = "pin-project" @@ -209,9 +209,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "proc-macro2" -version = "1.0.49" +version = "1.0.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" +checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" dependencies = [ "unicode-ident", ] @@ -247,9 +247,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.24.2" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a12a59981d9e3c38d216785b0c37399f6e415e8d0712047620f189371b0bb" +checksum = "c8e00990ebabbe4c14c08aca901caed183ecd5c09562a12c824bb53d3c3fd3af" dependencies = [ "autocfg", "pin-project-lite", @@ -335,42 +335,42 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" [[package]] name = "windows_aarch64_msvc" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" [[package]] name = "windows_i686_gnu" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" [[package]] name = "windows_i686_msvc" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" [[package]] name = "windows_x86_64_gnu" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" [[package]] name = "windows_x86_64_msvc" -version = "0.42.0" +version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" diff --git a/motore/Cargo.toml b/motore/Cargo.toml index 85d164b..fce964c 100644 --- a/motore/Cargo.toml +++ b/motore/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "motore" -version = "0.3.0" +version = "0.3.1" edition = "2021" description = """ Motore is a library of modular and reusable components for building robust diff --git a/motore/src/service/mod.rs b/motore/src/service/mod.rs index bb64c37..c5b7c9f 100644 --- a/motore/src/service/mod.rs +++ b/motore/src/service/mod.rs @@ -118,16 +118,85 @@ pub trait UnaryService { fn call(&self, req: Request) -> Self::Future<'_>; } +/// A [`Send`] + [`Sync`] boxed [`Service`]. +/// +/// [`BoxService`] turns a service into a trait object, allowing the +/// response future type to be dynamic, and allowing the service to be cloned. +pub struct BoxService { + raw: *mut (), + vtable: ServiceVtable, +} + +impl BoxService { + /// Create a new `BoxService`. + pub fn new(s: S) -> Self + where + S: Service + Send + Sync + 'static, + T: 'static, + for<'cx> S::Future<'cx>: Send, + { + let raw = Box::into_raw(Box::new(s)) as *mut (); + BoxService { + raw, + vtable: ServiceVtable { + call: call::, + drop: drop::, + }, + } + } +} + +impl Drop for BoxService { + fn drop(&mut self) { + unsafe { (self.vtable.drop)(self.raw) }; + } +} + +impl fmt::Debug for BoxService { + fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { + fmt.debug_struct("BoxService").finish() + } +} + +impl Service for BoxService { + type Response = U; + + type Error = E; + + type Future<'cx> = BoxFuture<'cx, Result> + where + Self: 'cx; + + fn call<'cx, 's>(&'s self, cx: &'cx mut Cx, req: T) -> Self::Future<'cx> + where + 's: 'cx, + { + unsafe { (self.vtable.call)(self.raw, cx, req) } + } +} + +/// # Safety +/// +/// The contained `Service` must be `Send` and `Sync` required by the bounds of `new` and `clone`. +unsafe impl Send for BoxService {} + +unsafe impl Sync for BoxService {} + +struct ServiceVtable { + call: unsafe fn(raw: *mut (), cx: &mut Cx, req: T) -> BoxFuture<'_, Result>, + drop: unsafe fn(raw: *mut ()), +} + /// A [`Clone`] + [`Send`] + [`Sync`] boxed [`Service`]. /// /// [`BoxCloneService`] turns a service into a trait object, allowing the /// response future type to be dynamic, and allowing the service to be cloned. /// -/// This is similar to [`BoxService`](super::BoxService) except the resulting +/// This is similar to [`BoxService`](BoxService) except the resulting /// service implements [`Clone`]. pub struct BoxCloneService { raw: *mut (), - vtable: ServiceVtable, + vtable: CloneServiceVtable, } impl BoxCloneService { @@ -141,7 +210,7 @@ impl BoxCloneService { let raw = Box::into_raw(Box::new(s)) as *mut (); BoxCloneService { raw, - vtable: ServiceVtable { + vtable: CloneServiceVtable { call: call::, clone: clone::, drop: drop::, @@ -192,7 +261,7 @@ unsafe impl Send for BoxCloneService {} unsafe impl Sync for BoxCloneService {} -struct ServiceVtable { +struct CloneServiceVtable { call: unsafe fn(raw: *mut (), cx: &mut Cx, req: T) -> BoxFuture<'_, Result>, clone: unsafe fn(raw: *mut ()) -> BoxCloneService, drop: unsafe fn(raw: *mut ()), diff --git a/motore/src/service/service_fn.rs b/motore/src/service/service_fn.rs index 3af2fb6..60cb840 100644 --- a/motore/src/service/service_fn.rs +++ b/motore/src/service/service_fn.rs @@ -112,7 +112,7 @@ mod tests { struct MotoreContext; async fn handle(cx: &mut MotoreContext, request: String) -> Result { - println!("{:?}, {:?}", cx, request); + println!("{cx:?}, {request:?}"); Ok::<_, Infallible>(request.to_uppercase()) } @@ -121,7 +121,7 @@ mod tests { assert_eq!( "ServiceFn { f: motore::service::service_fn::tests::debug_impl_ok::handle }" .to_string(), - format!("{:?}", uppercase_service), + format!("{uppercase_service:?}"), ); } }