1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
//! Local fetch construction and fetch/push validation work, separate from receiver messages.
use std::sync::atomic::AtomicBool;
/// Completed work while constructing a fetch from a local repository.
///
/// Observers run synchronously and must return promptly. Cancellation remains controlled by
/// [`crate::transport::TransportControl`]; callbacks cannot undo a completed operation.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum LocalFetchProgress {
/// Unique selected source objects examined so far. The total is not yet known.
/// Structured objects are decoded; packed blobs use framing and delta-size prefixes. Known
/// complete-history boundaries are excluded. Identity verification follows during pack import.
Reading {
/// Completed source objects; begins at zero and never decreases.
objects: u64,
},
/// Successfully encoded outgoing entries and the selected unique-object total.
/// Finishing these counts does not establish a finished pack/index pair.
Packing {
/// `(done, total)`; excludes objects already in verified known history.
objects: (u64, u64),
},
/// Construction and the final cancellation/deadline check succeeded. Last notification;
/// setting cancellation here cannot undo completion. Installation and publication are separate.
Complete,
}
/// A snapshot of completed pack-validation work for a fetch or native local push.
///
/// Counts describe pack processing after network download, not network byte transfer. Object and
/// delta counters never decrease during one validation; delta totals become known only after all
/// entries have been decoded. Finishing either count does not establish a valid fetch: index
/// construction, thin-pack rewriting and selected-tip connectivity can still fail. Only
/// `complete` marks successful validation. Installation and reference publication remain separate.
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
#[non_exhaustive]
pub struct ValidationProgress {
/// Successfully inflated pack entries and the pack header's entry count, `(done, total)`.
/// Includes delta programs; it does not imply reconstructed or connected objects.
pub objects: (u64, u64),
/// Successfully reconstructed delta entries and the actual delta entry count, `(done, total)`.
/// `None` means entry decoding has not established the total. External thin-pack bases are not
/// counted as additional received objects or deltas.
pub deltas: Option<(u64, u64)>,
/// True only after pack, index, thin-pack rewriting and connectivity validation succeed and
/// the final cancellation check passes. This is the last notification; callback-triggered
/// cancellation at this point cannot undo completed validation.
pub complete: bool,
}
pub(crate) struct ValidationObserver<'a> {
pub cancel: &'a AtomicBool,
value: ValidationProgress,
notify: &'a mut dyn FnMut(ValidationProgress),
}
impl<'a> ValidationObserver<'a> {
pub fn new(cancel: &'a AtomicBool, notify: &'a mut dyn FnMut(ValidationProgress)) -> Self {
Self {
cancel,
value: ValidationProgress::default(),
notify,
}
}
pub fn decoding(&mut self, total: usize) {
self.value.objects = (0, total as u64);
(self.notify)(self.value);
}
pub fn decoded(&mut self) {
self.value.objects.0 += 1;
(self.notify)(self.value);
}
pub fn resolving(&mut self, total: usize) {
self.value.deltas = Some((0, total as u64));
(self.notify)(self.value);
}
pub fn resolved_delta(&mut self) {
self.value.deltas.as_mut().unwrap().0 += 1;
(self.notify)(self.value);
}
pub fn complete(&mut self) {
self.value.deltas.get_or_insert((0, 0));
self.value.complete = true;
(self.notify)(self.value);
}
}