1
1
use core:: {
2
2
fmt,
3
3
future:: Future ,
4
+ marker:: PhantomData ,
4
5
ops:: { Deref , DerefMut } ,
5
6
pin:: Pin ,
6
7
} ;
@@ -10,7 +11,7 @@ use chain::Merge;
10
11
11
12
use crate :: { descriptor:: DescriptorError , ChangeSet , CreateParams , LoadParams , Wallet } ;
12
13
13
- /// Trait that persists [`Wallet `].
14
+ /// Trait that persists [`PersistedWallet `].
14
15
///
15
16
/// For an async version, use [`AsyncWalletPersister`].
16
17
///
@@ -50,7 +51,7 @@ pub trait WalletPersister {
50
51
51
52
type FutureResult < ' a , T , E > = Pin < Box < dyn Future < Output = Result < T , E > > + Send + ' a > > ;
52
53
53
- /// Async trait that persists [`Wallet `].
54
+ /// Async trait that persists [`PersistedWallet `].
54
55
///
55
56
/// For a blocking version, use [`WalletPersister`].
56
57
///
@@ -95,7 +96,7 @@ pub trait AsyncWalletPersister {
95
96
Self : ' a ;
96
97
}
97
98
98
- /// Represents a persisted wallet.
99
+ /// Represents a persisted wallet which persists into type `P` .
99
100
///
100
101
/// This is a light wrapper around [`Wallet`] that enforces some level of safety-checking when used
101
102
/// with a [`WalletPersister`] or [`AsyncWalletPersister`] implementation. Safety checks assume that
@@ -107,32 +108,36 @@ pub trait AsyncWalletPersister {
107
108
/// * Ensure there were no previously persisted wallet data before creating a fresh wallet and
108
109
/// persisting it.
109
110
/// * Only clear the staged changes of [`Wallet`] after persisting succeeds.
111
+ /// * Ensure the wallet is persisted to the same `P` type as when created/loaded. Note that this is
112
+ /// not completely fool-proof as you can have multiple instances of the same `P` type that are
113
+ /// connected to different databases.
110
114
#[ derive( Debug ) ]
111
- pub struct PersistedWallet ( pub ( crate ) Wallet ) ;
115
+ pub struct PersistedWallet < P > {
116
+ inner : Wallet ,
117
+ marker : PhantomData < P > ,
118
+ }
112
119
113
- impl Deref for PersistedWallet {
120
+ impl < P > Deref for PersistedWallet < P > {
114
121
type Target = Wallet ;
115
122
116
123
fn deref ( & self ) -> & Self :: Target {
117
- & self . 0
124
+ & self . inner
118
125
}
119
126
}
120
127
121
- impl DerefMut for PersistedWallet {
128
+ impl < P > DerefMut for PersistedWallet < P > {
122
129
fn deref_mut ( & mut self ) -> & mut Self :: Target {
123
- & mut self . 0
130
+ & mut self . inner
124
131
}
125
132
}
126
133
127
- impl PersistedWallet {
134
+ /// Methods when `P` is a [`WalletPersister`].
135
+ impl < P : WalletPersister > PersistedWallet < P > {
128
136
/// Create a new [`PersistedWallet`] with the given `persister` and `params`.
129
- pub fn create < P > (
137
+ pub fn create (
130
138
persister : & mut P ,
131
139
params : CreateParams ,
132
- ) -> Result < Self , CreateWithPersistError < P :: Error > >
133
- where
134
- P : WalletPersister ,
135
- {
140
+ ) -> Result < Self , CreateWithPersistError < P :: Error > > {
136
141
let existing = P :: initialize ( persister) . map_err ( CreateWithPersistError :: Persist ) ?;
137
142
if !existing. is_empty ( ) {
138
143
return Err ( CreateWithPersistError :: DataAlreadyExists ( existing) ) ;
@@ -142,17 +147,50 @@ impl PersistedWallet {
142
147
if let Some ( changeset) = inner. take_staged ( ) {
143
148
P :: persist ( persister, & changeset) . map_err ( CreateWithPersistError :: Persist ) ?;
144
149
}
145
- Ok ( Self ( inner) )
150
+ Ok ( Self {
151
+ inner,
152
+ marker : PhantomData ,
153
+ } )
154
+ }
155
+
156
+ /// Load a previously [`PersistedWallet`] from the given `persister` and `params`.
157
+ pub fn load (
158
+ persister : & mut P ,
159
+ params : LoadParams ,
160
+ ) -> Result < Option < Self > , LoadWithPersistError < P :: Error > > {
161
+ let changeset = P :: initialize ( persister) . map_err ( LoadWithPersistError :: Persist ) ?;
162
+ Wallet :: load_with_params ( changeset, params)
163
+ . map ( |opt| {
164
+ opt. map ( |inner| PersistedWallet {
165
+ inner,
166
+ marker : PhantomData ,
167
+ } )
168
+ } )
169
+ . map_err ( LoadWithPersistError :: InvalidChangeSet )
170
+ }
171
+
172
+ /// Persist staged changes of wallet into `persister`.
173
+ ///
174
+ /// If the `persister` errors, the staged changes will not be cleared.
175
+ pub fn persist ( & mut self , persister : & mut P ) -> Result < bool , P :: Error > {
176
+ match self . inner . staged_mut ( ) {
177
+ Some ( stage) => {
178
+ P :: persist ( persister, & * stage) ?;
179
+ let _ = stage. take ( ) ;
180
+ Ok ( true )
181
+ }
182
+ None => Ok ( false ) ,
183
+ }
146
184
}
185
+ }
147
186
187
+ /// Methods when `P` is an [`AsyncWalletPersister`].
188
+ impl < P : AsyncWalletPersister > PersistedWallet < P > {
148
189
/// Create a new [`PersistedWallet`] witht the given async `persister` and `params`.
149
- pub async fn create_async < P > (
190
+ pub async fn create_async (
150
191
persister : & mut P ,
151
192
params : CreateParams ,
152
- ) -> Result < Self , CreateWithPersistError < P :: Error > >
153
- where
154
- P : AsyncWalletPersister ,
155
- {
193
+ ) -> Result < Self , CreateWithPersistError < P :: Error > > {
156
194
let existing = P :: initialize ( persister)
157
195
. await
158
196
. map_err ( CreateWithPersistError :: Persist ) ?;
@@ -166,64 +204,35 @@ impl PersistedWallet {
166
204
. await
167
205
. map_err ( CreateWithPersistError :: Persist ) ?;
168
206
}
169
- Ok ( Self ( inner) )
170
- }
171
-
172
- /// Load a previously [`PersistedWallet`] from the given `persister` and `params`.
173
- pub fn load < P > (
174
- persister : & mut P ,
175
- params : LoadParams ,
176
- ) -> Result < Option < Self > , LoadWithPersistError < P :: Error > >
177
- where
178
- P : WalletPersister ,
179
- {
180
- let changeset = P :: initialize ( persister) . map_err ( LoadWithPersistError :: Persist ) ?;
181
- Wallet :: load_with_params ( changeset, params)
182
- . map ( |opt| opt. map ( PersistedWallet ) )
183
- . map_err ( LoadWithPersistError :: InvalidChangeSet )
207
+ Ok ( Self {
208
+ inner,
209
+ marker : PhantomData ,
210
+ } )
184
211
}
185
212
186
213
/// Load a previously [`PersistedWallet`] from the given async `persister` and `params`.
187
- pub async fn load_async < P > (
214
+ pub async fn load_async (
188
215
persister : & mut P ,
189
216
params : LoadParams ,
190
- ) -> Result < Option < Self > , LoadWithPersistError < P :: Error > >
191
- where
192
- P : AsyncWalletPersister ,
193
- {
217
+ ) -> Result < Option < Self > , LoadWithPersistError < P :: Error > > {
194
218
let changeset = P :: initialize ( persister)
195
219
. await
196
220
. map_err ( LoadWithPersistError :: Persist ) ?;
197
221
Wallet :: load_with_params ( changeset, params)
198
- . map ( |opt| opt. map ( PersistedWallet ) )
222
+ . map ( |opt| {
223
+ opt. map ( |inner| PersistedWallet {
224
+ inner,
225
+ marker : PhantomData ,
226
+ } )
227
+ } )
199
228
. map_err ( LoadWithPersistError :: InvalidChangeSet )
200
229
}
201
230
202
- /// Persist staged changes of wallet into `persister`.
203
- ///
204
- /// If the `persister` errors, the staged changes will not be cleared.
205
- pub fn persist < P > ( & mut self , persister : & mut P ) -> Result < bool , P :: Error >
206
- where
207
- P : WalletPersister ,
208
- {
209
- match self . 0 . staged_mut ( ) {
210
- Some ( stage) => {
211
- P :: persist ( persister, & * stage) ?;
212
- let _ = stage. take ( ) ;
213
- Ok ( true )
214
- }
215
- None => Ok ( false ) ,
216
- }
217
- }
218
-
219
231
/// Persist staged changes of wallet into an async `persister`.
220
232
///
221
233
/// If the `persister` errors, the staged changes will not be cleared.
222
- pub async fn persist_async < ' a , P > ( & ' a mut self , persister : & mut P ) -> Result < bool , P :: Error >
223
- where
224
- P : AsyncWalletPersister ,
225
- {
226
- match self . 0 . staged_mut ( ) {
234
+ pub async fn persist_async < ' a > ( & ' a mut self , persister : & mut P ) -> Result < bool , P :: Error > {
235
+ match self . inner . staged_mut ( ) {
227
236
Some ( stage) => {
228
237
P :: persist ( persister, & * stage) . await ?;
229
238
let _ = stage. take ( ) ;
0 commit comments