@@ -28,6 +28,12 @@ pub struct FetchedEntity {
28
28
pub entity : Entity ,
29
29
}
30
30
31
+ #[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
32
+ pub struct FetchedEntitiesFingerprint {
33
+ pub len : usize ,
34
+ pub last_offset_hash : u64 ,
35
+ }
36
+
31
37
#[ must_use]
32
38
pub fn last_offset_hash_of_fetched_entities < ' a > (
33
39
fetched_entities : impl Into < Option < & ' a [ FetchedEntity ] > > ,
@@ -40,6 +46,32 @@ pub fn last_offset_hash_of_fetched_entities<'a>(
40
46
} )
41
47
}
42
48
49
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Default ) ]
50
+ pub enum FetchStateTag {
51
+ #[ default]
52
+ Initial ,
53
+ Ready ,
54
+ Pending ,
55
+ Failed ,
56
+ }
57
+
58
+ impl FetchStateTag {
59
+ /// Check whether the state is stable.
60
+ #[ must_use]
61
+ pub const fn is_idle ( & self ) -> bool {
62
+ match self {
63
+ Self :: Initial | Self :: Ready | Self :: Failed => true ,
64
+ Self :: Pending => false ,
65
+ }
66
+ }
67
+ }
68
+
69
+ #[ derive( Debug , Clone , Default , PartialEq , Eq ) ]
70
+ pub struct FetchStateLite {
71
+ pub tag : FetchStateTag ,
72
+ pub fetched_entities_fingerprint : Option < FetchedEntitiesFingerprint > ,
73
+ }
74
+
43
75
#[ derive( Debug , Default ) ]
44
76
enum FetchState {
45
77
#[ default]
@@ -53,19 +85,42 @@ enum FetchState {
53
85
} ,
54
86
Failed {
55
87
fetched_entities_before : Option < Vec < FetchedEntity > > ,
56
- err : anyhow:: Error ,
88
+ error : anyhow:: Error ,
57
89
} ,
58
90
}
59
91
60
92
impl FetchState {
61
93
#[ must_use]
62
- const fn is_idle ( & self ) -> bool {
94
+ const fn state_tag ( & self ) -> FetchStateTag {
63
95
match self {
64
- Self :: Initial | Self :: Ready { .. } | Self :: Failed { .. } => true ,
65
- Self :: Pending { .. } => false ,
96
+ Self :: Initial => FetchStateTag :: Initial ,
97
+ Self :: Ready { .. } => FetchStateTag :: Ready ,
98
+ Self :: Failed { .. } => FetchStateTag :: Failed ,
99
+ Self :: Pending { .. } => FetchStateTag :: Pending ,
100
+ }
101
+ }
102
+
103
+ #[ must_use]
104
+ fn clone_lite ( & self ) -> FetchStateLite {
105
+ let tag = self . state_tag ( ) ;
106
+ let fetched_entities_fingerprint = self . fetched_entities_fingerprint ( ) ;
107
+ FetchStateLite {
108
+ tag,
109
+ fetched_entities_fingerprint,
66
110
}
67
111
}
68
112
113
+ #[ must_use]
114
+ fn equals_lite ( & self , other : & FetchStateLite ) -> bool {
115
+ self . clone_lite ( ) == * other
116
+ }
117
+
118
+ /// Check whether the state is stable.
119
+ #[ must_use]
120
+ const fn is_idle ( & self ) -> bool {
121
+ self . state_tag ( ) . is_idle ( )
122
+ }
123
+
69
124
#[ must_use]
70
125
fn fetched_entities ( & self ) -> Option < & [ FetchedEntity ] > {
71
126
match self {
@@ -84,6 +139,17 @@ impl FetchState {
84
139
}
85
140
}
86
141
142
+ #[ must_use]
143
+ fn fetched_entities_fingerprint ( & self ) -> Option < FetchedEntitiesFingerprint > {
144
+ let fetched_entities = self . fetched_entities ( ) ?;
145
+ let len = fetched_entities. len ( ) ;
146
+ let last_offset_hash = last_offset_hash_of_fetched_entities ( fetched_entities) ;
147
+ Some ( FetchedEntitiesFingerprint {
148
+ len,
149
+ last_offset_hash,
150
+ } )
151
+ }
152
+
87
153
#[ must_use]
88
154
const fn should_prefetch ( & self ) -> bool {
89
155
matches ! ( self , Self :: Initial )
@@ -92,8 +158,8 @@ impl FetchState {
92
158
#[ must_use]
93
159
const fn can_fetch_more ( & self ) -> Option < bool > {
94
160
match self {
95
- Self :: Initial => Some ( true ) , // always
96
- Self :: Pending { .. } | Self :: Failed { .. } => None , // undefined
161
+ Self :: Initial => Some ( true ) , // always, i.e. try at least once
162
+ Self :: Pending { .. } | Self :: Failed { .. } => None , // undefined
97
163
Self :: Ready { can_fetch_more, .. } => Some ( * can_fetch_more) , // maybe
98
164
}
99
165
}
@@ -102,7 +168,7 @@ impl FetchState {
102
168
const fn last_error ( & self ) -> Option < & anyhow:: Error > {
103
169
match self {
104
170
Self :: Initial | Self :: Pending { .. } | Self :: Ready { .. } => None ,
105
- Self :: Failed { err , .. } => Some ( err ) ,
171
+ Self :: Failed { error , .. } => Some ( error ) ,
106
172
}
107
173
}
108
174
@@ -189,8 +255,8 @@ impl FetchState {
189
255
}
190
256
191
257
#[ allow( clippy:: needless_pass_by_value) ]
192
- fn fetch_more_failed ( & mut self , err : anyhow:: Error ) -> bool {
193
- log:: warn!( "Fetching failed: {err }" ) ;
258
+ fn fetch_more_failed ( & mut self , error : anyhow:: Error ) -> bool {
259
+ log:: warn!( "Fetching failed: {error }" ) ;
194
260
let Self :: Pending {
195
261
fetched_entities_before,
196
262
} = self
@@ -202,12 +268,19 @@ impl FetchState {
202
268
let fetched_entities_before = std:: mem:: take ( fetched_entities_before) ;
203
269
* self = Self :: Failed {
204
270
fetched_entities_before,
205
- err ,
271
+ error ,
206
272
} ;
207
273
true
208
274
}
209
275
}
210
276
277
+ #[ derive( Debug , Clone , Default , PartialEq ) ]
278
+ pub struct StateLite {
279
+ pub default_params : Params ,
280
+ pub context : Context ,
281
+ pub fetch : FetchStateLite ,
282
+ }
283
+
211
284
#[ derive( Debug ) ]
212
285
pub struct State {
213
286
default_params : Params ,
@@ -271,6 +344,45 @@ impl State {
271
344
self . fetch . fetched_entities ( )
272
345
}
273
346
347
+ #[ must_use]
348
+ pub fn fetched_entities_fingerprint ( & self ) -> Option < FetchedEntitiesFingerprint > {
349
+ self . fetch . fetched_entities_fingerprint ( )
350
+ }
351
+
352
+ #[ must_use]
353
+ pub fn clone_lite ( & self ) -> StateLite {
354
+ let Self {
355
+ default_params,
356
+ context,
357
+ fetch,
358
+ } = self ;
359
+ let default_params = default_params. clone ( ) ;
360
+ let context = context. clone ( ) ;
361
+ let fetch = fetch. clone_lite ( ) ;
362
+ StateLite {
363
+ default_params,
364
+ context,
365
+ fetch,
366
+ }
367
+ }
368
+
369
+ #[ must_use]
370
+ pub fn equals_lite ( & self , other : & StateLite ) -> bool {
371
+ let Self {
372
+ default_params,
373
+ context,
374
+ fetch,
375
+ } = self ;
376
+ let StateLite {
377
+ default_params : other_default_params,
378
+ context : other_context,
379
+ fetch : other_fetch,
380
+ } = other;
381
+ default_params == other_default_params
382
+ && context == other_context
383
+ && fetch. equals_lite ( other_fetch)
384
+ }
385
+
274
386
pub fn reset ( & mut self ) -> bool {
275
387
// Cloning the default params once for pre-creating the target state
276
388
// is required to avoid redundant code for determining in advance if
0 commit comments