rust ZY#rustc 1.98.1 (48a229cea 2026-09-01)Á‰m6GÞ­n6ÇèÆ2-64f5f36fb0927694ÁûÊÆÍRLñ.åSÛAúwjL-df1bddb45adbe94bÁ«ª1Úë• ¢›ºXÝÓrŽ*-1ad4f876c768bda9Á±ò‰<å%Z‰>¸64‡ËV`-2d2ab9fb0fe1def5Á»ÄóG Øg{ë(3íi«F×-06449a08aaab5e30Árustc_std_workspace_coreÁ€û{ù`ä"Ei¥€ÞÏ%G-cb0d4d77988d81b5Áó"Æ)ΉÉðÛÕpEÍ—E-3ec41d3a5a80a4a4Á miniz_oxideÁÐ8°ø‚ðbž Lƨ°J-e44eaef1807e5fc0Áadler2Á9lí©yA6P/D$UBŸ-dca52f01a59c33e7Á hashbrownÁ™¸ÈXó®÷ …ùý{e-143c77bb957d9940Árustc_std_workspace_allocÁð…¨À �¶÷Üúò·_z%í-145a318e0772276cÁ std_detectÁK(ƒ0ì*ãÛ8²D?-f99feda5ce9e492aÁrustc_demangleÁµ%jŽeårVŠÕÓ•-cfd0ab54bb33760eÁcfg_ifÁÍ}λ—©ŒÕž§C•×o-360da4ba13154744Á addr2lineÁ‹c²ŽúY\ÈGÞö÷ö--09755979c57b7e64ÁgimliÁ¢±QÄÍ`ª§DÞåù¬y-9a1fede77fbbf2f0ÁobjectÁö‚F λâËvú.zËí-7ff85ea729a864ffÁmemchrÁž˜]²1<õ¶=U�ý�Où-0e3477fb2664a277Á  ÿŽ—jl‹®¾To–K™G-549498e8b2e4d924Á‰ServiceÁRequestÁResponseÁErrorÁFutureÁ poll_readyÁÛ'aÁ�ó��œ©Û�ó��œ©Û 8 8 8 888888888 Å�óŸŸ BoxÁ£ó‹¤ô‹ljô²ßk#�ÅFÅFÆFGlobalÁ Ä› +ÉÑó Ÿ DÚe¼Úe ƒ Š *îetãe÷eüƒetÙ´Û´Ü´ËÝ´óÞ´ß´¸±Ýæó}rÑ÷ÀœÜÄœ¯ÅœóƜǜ€Èœó‘¥_¿´Òw ƒ Š Ôµe  ƒ L‘e �…�…lŸ…wakerÁ‰… … local_wakerÁ‰…¡…extÁ‰…¢…_markerÁ‰…£…_marker2Á‰…8íœ}©œeªŸ¨cxÁ!½ ÊD¹f´¹fç ƒ Š ,<ÇflÂfÕfüýeX ƒ Š L¥f¨L…fŠ <�fªrequestÁ&Z¦¦DåhÀÀUniqueÁ¿ µÃ‹µ´]8"»Oÿ× ®®«°¿ ”3¯f*²Û�× ‹  × ›¼åhC × ‰ Æùhtîh ûh‚iüŽhtÙ´Û´Ü´ËÝ´óÞ´ß´¸±Ýæó}rÑ÷ÀœÜÄœ¯ÅœóƜǜ€Èœó‘¥_¿´Òw’ × ‰ ÔÀh – Lœh·§h × Æà£$-ä1ÿ‚SDÄiߣ à+´ÄiÝ × ‰ V<ÒilÍi ÙiàiüˆiX × ‰ L°iõL�i‰ <›iŠ¹à£ )£-aœµ ‰œ4ο´l<æ�…»$ïÙ´üâiüº30 Definition of the core `Service` trait to TowerÁî�üòJG The [`Service`] trait provides the necessary abstractions for definingÁü½LI request / response clients and servers. It is simple but powerful and isÁüŠ1. used as the foundation for the rest of Tower.Á‰‚œƒ¿´l‚�…»�Ù´ÈËΜÁÅLÚ¹¼«®ÔÂRü÷>; An asynchronous function from a `Request` to a `Response`.Á¶�üºIF The `Service` trait is a simplified interface making it easy to writeÁü„JG network applications in a modular and reusable way, decoupled from theÁüÏGD underlying protocol. It is one of Tower's fundamental abstractions.Á—�„› # FunctionalÁ¬�ü°FC A `Service` is a function of a `Request`. It immediately returns aÁü÷C@ `Future` representing the eventual completion of processing theÁü»HE request. The actual request processing may happen at any time in theÁü„KH future, on any thread or executor. The processing may depend on callingÁüÐNK other services. At some point in the future, the processing will complete,ÁüŸ 96 and the `Future` will resolve to a response or error.ÁÙ �üÝ PM At a high level, the `Service::call` function represents an RPC request. TheÁü® 0- `Service` value can be a server or a client.Áß �dã # ServerÁð �üô LI An RPC server *implements* the `Service` trait. Requests received by theÁüÁ RO server over the network are deserialized and then passed as an argument to theÁü” FC server value. The returned response is sent back over the network.ÁÛ �üß HE As an example, here is how an HTTP request is processed by a server:Á¨ �\¬  ```rustÁĸ  # use std::pin::Pin;ÁüÑ %" # use std::task::{Poll, Context};Áô÷  # use std::future::Future;Áü–! # use tower_service::Service;Áü¸.+ use http::{Request, Response, StatusCode};Áç�´ë struct HelloWorld;Á‚�ü†30 impl Service>> for HelloWorld {Áüº*' type Response = Response>;Áüå! type Error = http::Error;Áü‡YV type Future = Pin>>>;Áá�üåYV fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll> {Áü¿ Poll::Ready(Ok(()))ÁLß }Áé�üíC@ fn call(&mut self, req: Request>) -> Self::Future {Áô± // create the bodyÁüÐ1. let body: Vec = "hello, world!\n"ÁÜ‚ .as_bytes()Áäž .to_owned();Áü»'$ // Create the HTTP responseÁüã*' let resp = Response::builder()ÁüŽ'$ .status(StatusCode::OK)Áܶ .body(body)ÁüÒ=: .expect("Unable to create `http::Response`");Á��ü”-* // create a response in a future.Áì let fut = async {ÁÄà Ok(resp)Átù };Áˆ�üŒ96 // Return the response as an immediate futureÁÌÆ Box::pin(fut)ÁLà +,ê }Á<ð ```Áø�dü # ClientÁ‰�ü�JG A client consumes a service by using a `Service` value. The client mayÁüØMJ issue requests by invoking `call` and passing the request as an argument.Áü¦EB It then receives the response by waiting for the returned future.Áì�üð?< As an example, here is how a Redis request would be issued:Á°�”´ ```rust,ignoreÁüÇ%" let client = redis::Client::new()Áüí30 .connect("127.0.0.1:6379".parse().unwrap())Á”¡ .unwrap();Á´�ü¸OL let resp = client.call(Cmd::set("foo", "this is the value of foo")).await?;Áˆ�üŒ%" // Wait for the future to resolveÁü²+( println!("Redis response: {:?}", resp);Á<Þã1æ�Äê # Middleware / LayerÁƒ�ü‡KH More often than not, all the pieces needed for writing robust, scalableÁüÓKH network applications are the same no matter the underlying protocol. ByÁüŸMJ unifying the API for both clients and servers in a protocol agnostic way,ÁüíEB it is possible to write middleware that provide these pieces in aÁŒ³ reusable way.ÁÅ�üÉ  Take timeouts as an example:Áê�\îä%üú use tower_service::Service;ÁÜš use tower_layer::Layer;Áܶ use futures::FutureExt;ÁäÒ use std::future::Future;Áüï# use std::task::{Context, Poll};Áä“  use std::time::Duration;Á´°  use std::pin::Pin;ÁŒÇ  use std::fmt;ÁÔÙ  use std::error::Error;Áô �üø ;8 // Our timeout service, which wraps another service andÁü´!-* // adds a timeout to its response future.ÁÜâ! pub struct Timeout {ÁŒþ! inner: T,ÁÔ�" timeout: Duration,Á,«"Õ1±"�ĵ" impl Timeout {ÁüÎ"EB pub const fn new(inner: T, timeout: Duration) -> Timeout {Á¬”# Timeout {Á´ª# inner,Á¼Á# timeoutÁlÙ# }ÁLç# +,ñ#Õ1÷#�üû#;8 // The error returned if processing a request timed outÁ¤·$ #[derive(Debug)]Á¼Ì$ pub struct Expired;Áä$�üè$# impl fmt::Display for Expired {ÁüŒ%B? fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {ÁüÏ%  write!(f, "expired")ÁLð% +,ú%Õ1€&�ì„& impl Error for Expired {}Á¢&�ü¦&HE // We can implement `Service` for `Timeout` if `T` is a `Service`Áüï&41 impl Service for TimeoutÁL¤' whereÁä®' T: Service,ÁÜË' T::Future: 'static,Áüç'?< T::Error: Into> + 'static,Áì§( T::Response: 'static,Á,Å( {ÁüË(TQ // `Timeout` doesn't modify the response type, so we use `T`'s response typeÁü )$! type Response = T::Response;ÁüÅ)XU // Errors may be either `Expired` if the timeout expired, or the inner service'sÁüž*eb // `Error` type. Therefore, we return a boxed `dyn Error + Send + Sync` trait object to eraseÁä„+ // the error's type.Áü¡+2/ type Error = Box;ÁüÔ+Y¦)®,�ü²,Y•*üŒ-JG // Our timeout service is ready if the inner service is ready.Áü×-\Y // This is how backpressure can be propagated through a tree of nested services.Áü´.85 self.inner.poll_ready(cx).map_err(Into::into)ÁLí. +÷.�üû.:7 fn call(&mut self, req: Request) -> Self::Future {Áü¶/B? // Create a future that completes after `self.timeout`Áüù/;8 let timeout = tokio::time::sleep(self.timeout);Áµ0�ü¹0TQ // Call the inner service and get a future that resolves to the responseÁüŽ1+( let fut = self.inner.call(req);Áº1�ü¾1`] // Wrap those two futures in another future that completes when either one completesÁtŸ2 //Áü®2VS // If the inner service is too slow the `sleep` future will complete firstÁü…3[X // And an error will be returned and `fut` will be dropped and not polled againÁtá3ŒRüð3;8 // We have to box the errors so the types matchÁü¬4  let f = async move {ÁüÍ4  tokio::select! {Áüî4" res = fut => {Áü‘552 res.map_err(|err| err.into())Á´Ç5 },ÁüÞ5$! _ = timeout => {Áüƒ6NK Err(Box::new(Expired) as Box)Á´Ò6øUŒé6 }Átû6Á0Š7�¼Ž7 Box::pin(f)ÁL¦7 +,°7Õ1¶7�üº71. // A layer for wrapping services in `Timeout`Áüì7&# pub struct TimeoutLayer(Duration);Á“8�¼—8 impl TimeoutLayer {Áü¯830 pub const fn new(delay: Duration) -> Self {Áüã8 TimeoutLayer(delay)ÁLƒ9 +,�9Õ1“9�ü—9'$ impl Layer for TimeoutLayer {Áü¿9" type Service = Timeout;Áâ9�üæ930 fn layer(&self, service: S) -> Timeout {Áüš:)& Timeout::new(service, self.0)ÁLÄ: +,Î:Õ1<Ô:ã1Ü:�üà:NK The above timeout implementation is decoupled from the underlying protocolÁü¯;MJ and is also decoupled from client or server concerns. In other words, theÁüý;IF same timeout middleware could be used in either a client or a server.ÁÇ<�”Ë< # BackpressureÁÞ<�üâGD that the service is ready to receive the request before calling it.ÁÓ>�ü×>LI `Service` provides a mechanism by which the caller is able to coordinateÁü¤?PM readiness. `Service::poll_ready` returns `Ready` if the service expects thatÁüõ?$! it is able to process a request.Áš@�üž@,) # Be careful when cloning inner servicesÁË@�üÏ@`] Services are permitted to panic if `call` is invoked without obtaining `Poll::Ready(Ok(()))`Áü°A`] from `poll_ready`. You should therefore be careful when cloning services for example to moveÁü‘B_\ them into boxed futures. Even though the original service is ready, the clone might not be.ÁñB�üõB96 Therefore this kind of code is wrong and might panic:Á¯C�\³Cä%Ä¿Cø%üØC%š&ôþCÈ&ü�D!ð&,¿D #Á¼ÅD struct Wrapper {ÁŒÝD inner: S,Á,ïDÕ1õD�üùD(% impl Service for WrapperÁL¢EÒFü¬E(% S: Service + Clone + 'static,ÁœÕE R: 'static,Á,éEœHüïE$! type Response = S::Response;Áô”F type Error = S::Error;Áü³FY¦)�G�ü‘GY•*üëG%" self.inner.poll_ready(cx)ÁL‘H +›H�üŸH41 fn call(&mut self, req: R) -> Self::Future {ÁüÔH/, let mut inner = self.inner.clone();Áü„I! Box::pin(async move {Áü¦I?< // `inner` might not be ready since its a cloneÁüæI%" inner.call(req).awaitÁtŒJ })ÁL›J +,¥JÕ1<«Jã1³J�ü·JTQ You should instead use [`std::mem::replace`] to take the service that was ready:ÁŒK�\�Kä%ÄœKø%üµK%š&ôÛKÈ&üúK!ð&,œL˜g¼¢L¦gŒºLÆg,ÌLÕ1ÒL�üÖL(ùgLÿLÒFü‰M(·hœ²Mèh,ÆMœHüÌM$‘iôñM¾iü�NY¦)êN�üîNY•*üÈO%ŒjLîO +øO�üüO4Ójü±P+( let clone = self.inner.clone();ÁüÝP.+ // take the service that was readyÁüŒQFC let mut inner = std::mem::replace(&mut self.inner, clone);ÁüÓQ!ÊküõQ%¾lt›RìlLªR +,´RÕ1<ºRã1<ÌRóÿÆüÂR‡þƉ <ÔRìs*ìs/ þÆ ôs‰ t‹S¶tþÆ ôs‰ \ÇSÖtþÆ ôs‰ üûSB¿´þtüˆT4À´þtÀœÜÄœ¯ÅœóƜǜ€Èœó‘¥_¿´Òw¾tÞtü�T,öt‘us¢u l‹SüãR# Responses given by the service.ÁD�STÇSüŸS# Errors produced by the service.Á,ÌSüûSAôØS The future response value.Á4€Tü‰^PüÃTOL Returns `Poll::Ready(Ok(()))` when the service is able to process requests.Á—U�üŸUPM If the service is at capacity, then `Poll::Pending` is returned and the taskÁüôUFC is notified when the service becomes ready again. This function isÁü¿VKH expected to be called while on a task. Generally, this can be done withÁü�W-* a simple `futures::future::poll_fn` call.ÁÁW�üÉW[X If `Poll::Ready(Err(_))` is returned, the service is no longer able to service requestsÁü©X74 and the caller should discard the service instance.ÁåX�üíXWT Once `poll_ready` returns `Poll::Ready(Ok(()))`, a request may be dispatched to theÁüÉYJG service using `call`. Until a request is dispatched, repeated calls toÁü˜ZSP `poll_ready` must return either `Poll::Ready(Ok(()))` or `Poll::Ready(Err(_))`.ÁðZ�üøZYV Note that `poll_ready` may reserve shared resources that are consumed in a subsequentÁüÖ[\Y invocation of `call`. Thus, it is critical for implementations to not assume that `call`Áü·\[X will always be invoked and to ensure that such resources are released if the service isÁü—]ZW dropped before `call` is invoked or the future returned by `call` is dropped before itÁtö] is polled.ÁTŒ^ ! ôs  �…�…lŸ…Î ‰… …á ‰…¡…ú ‰…¢…‹‰…£… ‰…8íœ}©!Ù´Û´Ü´ËÝ´óÞ´ß´¸±Ýæó}rÑ÷ÀœÜÄœ¯ÅœóƜǜ€Èœó‘¥_¿´Òw’ÞtBÿ —^ ôs‰ $œ^ä¢^ü–c1üß^?< Process the request and return the response asynchronously.Á£_�ü«_?< This function is expected to be callable off task. As such,Áüï_>; implementations should take care to not call `poll_ready`.Á²`�üº`HE Before dispatching a request, `poll_ready` must be called and returnÁÔ‡a `Poll::Ready(Ok(()))`.Á¦a�d®a # PanicsÁ¿a�üÇaGD Implementations are permitted to panic if `call` is invoked withoutÁü“b63 obtaining `Poll::Ready(Ok(()))` from `poll_ready`.Á/üÎbC3futures do nothing unless you `.await` or poll themÁ$™c" "ôs‰ þtBÿ žc ôs‰ $£creqÁ©cüËcWÅ�óþƃ ÔcþÆŠ <×cƒ Š „Œdƒ ÅŸdý      Ðc[]Z\l©dD®d ƒ Š TÊd,Ïd•\åd4êdçüƒeLT†e#$% #ý  $�…�…lŸ…Î ‰… …á ‰…¡…ú ‰…¢…‹‰…£… ‰…8íœ}©%þ Bÿ ‘e Ń Š $–eäGüýe1$€f& &ý Š çBÿ …f Ń Š $Šf£üÙfT�óÿÆ× 4¦g€t<áf× ‰ „“g–       ÞfFHl´gD¹g × ‰ TÕg,Úgâ\ðg4õgåüŽhLT‘h'() '–  (�…�…lŸ…Î ‰… …á ‰…¡…ú ‰…¢…‹‰…£… ‰…8íœ}©)ËBÿ œh × ‰ $¡hä üˆi1$‹i* *– ‰ åBÿ �i × ‰ $•i£ S¹ ¦^¹³^¹¤¹Á¹  e¹­e¹o¹³¹ «h¹¸h¹g¹ åstd::memÁstd::mem::replaceÁ ô劓‰—“Š“ô‰å‰—“¿´…ù öÌí÷±¯²ýÆþÆÿ ÈÇ€#…#ˆ#‹#Î!Ñ!Ö!¦£¬©ÔPŽQ—PŽPÄQµì6"å6‚Åam¼"‚}jrQœ?Æüîa’Í,f „éÎMJøÒ$†Ì@«ßs9¯Qššž{9V(fˆª9�ÏëeXjø²„ÖoØLP]ŸÐ fé3!»Dø¦YüYƒt™â¤¤PP$Z†ÁÙ‹.‡d4,ù?‚_ Dlª1÷ )¿Áa‹À˜îbf”NÃ\ �ß`G6ˆþ¬.Û}Ý}ámŒ3öîL_í^l÷7<ÉÔ7)€Ä$J-~þÝíÆ»eœàì&QFÆýö”—˜©¿n¡çÓî¯ò>Ì„z¥/-;/ƒ†’ÿ»¤æm<ñ}Ê6W“׳‡ié•5óZ‘¡VétX 3;‡aòöñ:‘44á ` E$ ²:ô:7;t; BÐD†E§E¾EÖE»F!G¯GÐGçGÿGÝH× ª9¯9@EoG   Ö I9ã:%;b;¬@…DŠE«EÂEîEÓF³GÔGëGHõH¡ ! ' * 1 5 ; A Ÿ:®:ð:2;o;BËD`EfEuE‚E£EºEÑE¶FG�GžG«GÌGãGúGØH7I=IDIKIQIWI^IeIkIpIwI~I$ . 8 > E9¢:ß:!;^;”@mDdEhEwE†E§E¾EÖE»F“G G¯GÐGçGÿGÝH:IAIHINITI[IbIhImItI{I€Ii9«:ì:.;k;èA«DýDpEE“E´EËE”FúFCG›G¨G¼GÝGôG¼HIJ9¥:ä:&;c;ÜAŸDÒDjEyE‹E¬EÃEˆFîF#G•G¢G´GÕGìG°HIìA¯D>E—E¸EÏE˜FþFmGÀGáGøGÀHI­@†DïEÔFHöH¯@ˆDòE×FHøH˜@qDÚE¿FHáHù�9­:rE�E�GªGŸ†HR „FP K …GQ L öA¹D¨FGÊH)I�9Ô C9ÐD!GÃÆÍÑÕÙÝáïý %6=AJQX_fmt{†�”›¢©°¶¼ÂÈÎÔÚàæìò´9Ô9ô9–:—:EEIEMEQEUEtGxG|G€G„GM O Q S ƒIïI˜:YEˆG¹¹¹¹Ü "å6‚ÅašøZÃ`*”S¶RºRÞRÎRõRðODHT +@·ÞúGrà=Gü$"å6‚ÅaÍ,f „éÎMP$Z†ÁÙ‹ ì&QFÆýö”A\œFQU‡*÷7<ÉÔ7)P]ŸÐ fé3 €Ä$J-~þNÃ\ �ß`ˆª9�ÏëeX` QŠN‚(JøÒ$†Ìié•5óZjø²„ÖoØL}Ý}ámŒ3Ê6W“׳‡QI,þ™èm˜)‚_ Dlª1`Ì„z÷ )¿Áa‹~ÿ0ÿ&ÿEJCÿ0ÿ,ÿAfÿÿ-&CLÿÿÿÿÿOxÿ(p,ÿÿiÿÿIsI>2gÿÿ38ÿ(=E~ÿ0ÿ&ÿEJCÿ0ÿ,Y/root/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tower-service-0.3.3/src/lib.rsÁN/root/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tower-service-0.3.3ÁY/root/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tower-service-0.3.3/src/lib.rsÁ _ÓøU³Š ÁYTa»°ãiãi† #64KM2 ?JKHGDILO:Q1 MSGI &"/4+"ZZ D2(+(>.:  KNF@&4P&,LLNF! $<.F <$C! I5 @U%Yf3ZZK]9 ;C<U,aW\+VV>>>]>>04>>>]0+V>]ƒ½ rust-end-file