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}