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, StorageProvider, TaskProvider, TimeProvider,
37    TokioNetworkProvider, TokioRandomProvider, TokioStorageProvider, TokioTaskProvider,
38    TokioTimeProvider,
39};
40
41/// Bundle of all provider types for a runtime environment.
42///
43/// This trait consolidates the four provider types ([`NetworkProvider`],
44/// [`TimeProvider`], [`TaskProvider`], [`RandomProvider`]) into a single
45/// bundle, reducing type parameter explosion and repetitive where clauses.
46///
47/// ## Implementations
48///
49/// - [`TokioProviders`]: Production providers using real Tokio runtime
50/// - `SimProviders` (in moonpool-sim): Simulation providers for deterministic testing
51///
52/// ## Design
53///
54/// The trait uses associated types to preserve type information at compile time
55/// without runtime dispatch. Accessor methods provide convenient access to
56/// individual providers while maintaining the bundle.
57pub trait Providers: Clone + 'static {
58    /// Network provider type for TCP connections and listeners.
59    type Network: NetworkProvider + Clone + 'static;
60
61    /// Time provider type for sleep, timeout, and time queries.
62    type Time: TimeProvider + Clone + 'static;
63
64    /// Task provider type for spawning local tasks.
65    type Task: TaskProvider + Clone + 'static;
66
67    /// Random provider type for deterministic or real randomness.
68    type Random: RandomProvider + Clone + 'static;
69
70    /// Storage provider type for file I/O operations.
71    type Storage: StorageProvider + Clone + 'static;
72
73    /// Get the network provider instance.
74    fn network(&self) -> &Self::Network;
75
76    /// Get the time provider instance.
77    fn time(&self) -> &Self::Time;
78
79    /// Get the task provider instance.
80    fn task(&self) -> &Self::Task;
81
82    /// Get the random provider instance.
83    fn random(&self) -> &Self::Random;
84
85    /// Get the storage provider instance.
86    fn storage(&self) -> &Self::Storage;
87}
88
89/// Production providers using Tokio runtime.
90///
91/// This struct bundles all four Tokio-based providers into a single
92/// instance that implements [`Providers`].
93///
94/// ## Example
95///
96/// ```rust,ignore
97/// use moonpool_core::{Providers, TokioProviders};
98///
99/// let providers = TokioProviders::new();
100///
101/// // Access individual providers
102/// let network = providers.network();
103/// let time = providers.time();
104/// let task = providers.task();
105/// let random = providers.random();
106/// ```
107#[derive(Clone)]
108pub struct TokioProviders {
109    network: TokioNetworkProvider,
110    time: TokioTimeProvider,
111    task: TokioTaskProvider,
112    random: TokioRandomProvider,
113    storage: TokioStorageProvider,
114}
115
116impl TokioProviders {
117    /// Create a new production providers bundle.
118    ///
119    /// Initializes all four Tokio-based providers with their default
120    /// configurations.
121    pub fn new() -> Self {
122        Self {
123            network: TokioNetworkProvider::new(),
124            time: TokioTimeProvider::new(),
125            task: TokioTaskProvider,
126            random: TokioRandomProvider::new(),
127            storage: TokioStorageProvider::new(),
128        }
129    }
130}
131
132impl Default for TokioProviders {
133    fn default() -> Self {
134        Self::new()
135    }
136}
137
138impl Providers for TokioProviders {
139    type Network = TokioNetworkProvider;
140    type Time = TokioTimeProvider;
141    type Task = TokioTaskProvider;
142    type Random = TokioRandomProvider;
143
144    fn network(&self) -> &Self::Network {
145        &self.network
146    }
147
148    fn time(&self) -> &Self::Time {
149        &self.time
150    }
151
152    fn task(&self) -> &Self::Task {
153        &self.task
154    }
155
156    fn random(&self) -> &Self::Random {
157        &self.random
158    }
159
160    type Storage = TokioStorageProvider;
161
162    fn storage(&self) -> &Self::Storage {
163        &self.storage
164    }
165}