Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/third_party/rust/hyper-util/src/client/pool/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 5 kB image not shown  

Quelle  map.rs

  Sprache: Rust
 

//! Map pool utilities
//!
//! The map isn't a typical `Service`, but rather stand-alone type that can map
//! requests to a key and  service factory. This is because the service is more
//! of a router, and cannot determine which inner service to check for
//! backpressure since it's not know until the request is made.
//!
//! The map implementation allows customization of extracting a key, and how to
//! construct a MakeService for that key.
//!
//! # Example
//!
//! ```rust,ignore
//! # async fn run() {
//! # use hyper_util::client::pool;
//! # let req = http::Request::new(());
//! # let some_http1_connector = || {
//! #     tower::service::service_fn(|_req| async { Ok::<_, &'static str>(()) })
//! # };
//! let mut map = pool::map::Map::builder()
//!     .keys(|uri| (uri.scheme().clone(), uri.authority().clone()))
//!     .values(|_uri| {
//!         some_http1_connector()
//!     })
//!     .build();
//!
//! let resp = map.service(req.uri()).call(req).await;
//! # }
//! ```

use std::collections::HashMap;

// expose the documentation
#[cfg(docsrs)]
pub use self::builder::Builder;

/// A map caching `MakeService`s per key.
///
/// Create one with the [`Map::builder()`].
pub struct Map<T, Req>
where
    T: target::Target<Req>,
{
    map: HashMap<T::Key, T::Service>,
    targeter: T,
}

// impl Map

impl Map<builder::StartHere, builder::StartHere> {
    /// Create a [`Builder`] to configure a new `Map`.
    pub fn builder<Dst>() -> builder::Builder<Dst, builder::WantsKeyer, builder::WantsServiceMaker>
    {
        builder::Builder::new()
    }
}

impl<T, Req> Map<T, Req>
where
    T: target::Target<Req>,
{
    fn new(targeter: T) -> Self {
        Map {
            map: HashMap::new(),
            targeter,
        }
    }
}

impl<T, Req> Map<T, Req>
where
    T: target::Target<Req>,
    T::Key: Eq + std::hash::Hash,
{
    /// Get a service after extracting the key from `req`.
    pub fn service(&mut self, req: &Req) -> &mut T::Service {
        let key = self.targeter.key(req);
        self.map
            .entry(key)
            .or_insert_with(|| self.targeter.service(req))
    }

    /// Retains only the services specified by the predicate.
    pub fn retain<F>(&mut self, predicate: F)
    where
        F: FnMut(&T::Key, &mut T::Service) -> bool,
    {
        self.map.retain(predicate);
    }

    /// Clears the map, removing all key-value pairs.
    pub fn clear(&mut self) {
        self.map.clear();
    }
}

// sealed and unnameable for now
mod target {
    pub trait Target<Dst> {
        type Key;
        type Service;

        fn key(&self, dst: &Dst) -> Self::Key;
        fn service(&self, dst: &Dst) -> Self::Service;
    }
}

// sealed and unnameable for now
mod builder {
    use std::marker::PhantomData;

    /// A builder to configure a `Map`.
    ///
    /// # Unnameable
    ///
    /// This type is normally unnameable, forbidding naming of the type within
    /// code. The type is exposed in the documentation to show which methods
    /// can be publicly called.
    pub struct Builder<Dst, K, S> {
        _dst: PhantomData<fn(Dst)>,
        keys: K,
        svcs: S,
    }

    pub struct WantsKeyer;
    pub struct WantsServiceMaker;

    pub enum StartHere {}

    pub struct Built<K, S> {
        keys: K,
        svcs: S,
    }

    impl<Dst> Builder<Dst, WantsKeyer, WantsServiceMaker> {
        pub(superfn new() -> Self {
            Builder {
                _dst: PhantomData,
                keys: WantsKeyer,
                svcs: WantsServiceMaker,
            }
        }
    }

    impl<Dst, S> Builder<Dst, WantsKeyer, S> {
        /// Provide a closure that extracts a pool key for the destination.
        pub fn keys<K, KK>(self, keyer: K) -> Builder<Dst, K, S>
        where
            K: Fn(&Dst) -> KK,
        {
            Builder {
                _dst: PhantomData,
                keys: keyer,
                svcs: self.svcs,
            }
        }
    }

    impl<Dst, K> Builder<Dst, K, WantsServiceMaker> {
        /// Provide a closure to create a new `MakeService` for the destination.
        pub fn values<S, SS>(self, svcs: S) -> Builder<Dst, K, S>
        where
            S: Fn(&Dst) -> SS,
        {
            Builder {
                _dst: PhantomData,
                keys: self.keys,
                svcs,
            }
        }
    }

    impl<Dst, K, S> Builder<Dst, K, S>
    where
        Built<K, S>: super::target::Target<Dst>,
        <Built<K, S> as super::target::Target<Dst>>::Key: Eq + std::hash::Hash,
    {
        /// Build the `Map` pool.
        pub fn build(self) -> super::Map<Built<K, S>, Dst> {
            super::Map::new(Built {
                keys: self.keys,
                svcs: self.svcs,
            })
        }
    }

    impl super::target::Target<StartHere> for StartHere {
        type Key = StartHere;
        type Service = StartHere;

        fn key(&self, _: &StartHere) -> Self::Key {
            match *self {}
        }

        fn service(&self, _: &StartHere) -> Self::Service {
            match *self {}
        }
    }

    impl<K, KK, S, SS, Dst> super::target::Target<Dst> for Built<K, S>
    where
        K: Fn(&Dst) -> KK,
        S: Fn(&Dst) -> SS,
        KK: Eq + std::hash::Hash,
    {
        type Key = KK;
        type Service = SS;

        fn key(&self, dst: &Dst) -> Self::Key {
            (self.keys)(dst)
        }

        fn service(&self, dst: &Dst) -> Self::Service {
            (self.svcs)(dst)
        }
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn smoke() {
        let mut pool = super::Map::builder().keys(|_| "a").values(|_| "b").build();
        pool.service(&"hello");
    }
}

Messung V0.5 in Prozent
C=86 H=100 G=93

¤ Dauer der Verarbeitung: 0.5 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.