Skip to main content

moonpool_core/
providers.rs

1//! Provider bundle trait for simplified type parameters.
2//!
3//! This module provides a unified [`Providers`] trait that bundles all four
4//! provider types into a single type parameter, eliminating type parameter
5//! explosion in downstream code.
6//!
7//! ## Motivation
8//!
9//! Without bundling, code must carry four separate type parameters:
10//!
11//! ```text
12//! struct MyStruct<N, T, TP, R>
13//! where
14//!     N: NetworkProvider + Clone + 'static,
15//!     T: TimeProvider + Clone + 'static,
16//!     TP: TaskProvider + Clone + 'static,
17//!     R: RandomProvider + Clone + 'static,
18//! ```
19//!
20//! With bundling, this simplifies to:
21//!
22//! ```text
23//! struct MyStruct<P: Providers>
24//! ```
25//!
26//! ## Usage
27//!
28//! ```rust,ignore
29//! use moonpool_core::{Providers, TokioProviders};
30//!
31//! let providers = TokioProviders::new();
32//! let time_now = providers.time().now();
33//! ```
34
35use crate::{
36    NetworkProvider, RandomProvider, TaskProvider, TimeProvider, TokioNetworkProvider,
37    TokioRandomProvider, TokioTaskProvider, TokioTimeProvider,
38};
39
40/// Bundle of all provider types for a runtime environment.
41///
42/// This trait consolidates the four provider types ([`NetworkProvider`],
43/// [`TimeProvider`], [`TaskProvider`], [`RandomProvider`]) into a single
44/// bundle, reducing type parameter explosion and repetitive where clauses.
45///
46/// ## Implementations
47///
48/// - [`TokioProviders`]: Production providers using real Tokio runtime
49/// - `SimProviders` (in moonpool-sim): Simulation providers for deterministic testing
50///
51/// ## Design
52///
53/// The trait uses associated types to preserve type information at compile time
54/// without runtime dispatch. Accessor methods provide convenient access to
55/// individual providers while maintaining the bundle.
56pub trait Providers: Clone + 'static {
57    /// Network provider type for TCP connections and listeners.
58    type Network: NetworkProvider + Clone + 'static;
59
60    /// Time provider type for sleep, timeout, and time queries.
61    type Time: TimeProvider + Clone + 'static;
62
63    /// Task provider type for spawning local tasks.
64    type Task: TaskProvider + Clone + 'static;
65
66    /// Random provider type for deterministic or real randomness.
67    type Random: RandomProvider + Clone + 'static;
68
69    /// Get the network provider instance.
70    fn network(&self) -> &Self::Network;
71
72    /// Get the time provider instance.
73    fn time(&self) -> &Self::Time;
74
75    /// Get the task provider instance.
76    fn task(&self) -> &Self::Task;
77
78    /// Get the random provider instance.
79    fn random(&self) -> &Self::Random;
80}
81
82/// Production providers using Tokio runtime.
83///
84/// This struct bundles all four Tokio-based providers into a single
85/// instance that implements [`Providers`].
86///
87/// ## Example
88///
89/// ```rust,ignore
90/// use moonpool_core::{Providers, TokioProviders};
91///
92/// let providers = TokioProviders::new();
93///
94/// // Access individual providers
95/// let network = providers.network();
96/// let time = providers.time();
97/// let task = providers.task();
98/// let random = providers.random();
99/// ```
100#[derive(Clone)]
101pub struct TokioProviders {
102    network: TokioNetworkProvider,
103    time: TokioTimeProvider,
104    task: TokioTaskProvider,
105    random: TokioRandomProvider,
106}
107
108impl TokioProviders {
109    /// Create a new production providers bundle.
110    ///
111    /// Initializes all four Tokio-based providers with their default
112    /// configurations.
113    pub fn new() -> Self {
114        Self {
115            network: TokioNetworkProvider::new(),
116            time: TokioTimeProvider::new(),
117            task: TokioTaskProvider,
118            random: TokioRandomProvider::new(),
119        }
120    }
121}
122
123impl Default for TokioProviders {
124    fn default() -> Self {
125        Self::new()
126    }
127}
128
129impl Providers for TokioProviders {
130    type Network = TokioNetworkProvider;
131    type Time = TokioTimeProvider;
132    type Task = TokioTaskProvider;
133    type Random = TokioRandomProvider;
134
135    fn network(&self) -> &Self::Network {
136        &self.network
137    }
138
139    fn time(&self) -> &Self::Time {
140        &self.time
141    }
142
143    fn task(&self) -> &Self::Task {
144        &self.task
145    }
146
147    fn random(&self) -> &Self::Random {
148        &self.random
149    }
150}