mcumgr_toolkit/client/
image_run_state.rs1use crate::commands::image::ImageState;
2
3#[derive(Clone, Debug, Eq, PartialEq)]
5pub enum ImageRunState<'a> {
6 Stable(&'a ImageState),
9 Pending {
11 current: Option<&'a ImageState>,
13 next: &'a ImageState,
19 },
20 Testing {
25 current: &'a ImageState,
27 fallback: &'a ImageState,
29 },
30 Unknown(Option<&'a ImageState>),
35 Inconsistent,
39}
40
41pub fn analyze(image_state: &[ImageState], image_id: u32) -> ImageRunState<'_> {
43 fn find_unique(
44 image_id: u32,
45 image_state: &[ImageState],
46 predicate: impl Fn(&ImageState) -> bool,
47 ) -> Option<Option<&'_ ImageState>> {
48 let mut matches = image_state
49 .iter()
50 .filter(|img| img.image == image_id)
51 .filter(|img| predicate(img));
52
53 let first = matches.next();
54
55 match matches.next() {
56 Some(_) => None, None => Some(first), }
59 }
60
61 let active = match find_unique(image_id, image_state, |img| img.active) {
62 Some(value) => value,
63 None => return ImageRunState::Inconsistent,
64 };
65
66 let confirmed = match find_unique(image_id, image_state, |img| img.confirmed) {
67 Some(value) => value,
68 None => return ImageRunState::Inconsistent,
69 };
70
71 let pending = match find_unique(image_id, image_state, |img| img.pending) {
72 Some(value) => value,
73 None => return ImageRunState::Inconsistent,
74 };
75
76 if let Some(pending) = pending {
77 return ImageRunState::Pending {
78 current: active.or(confirmed),
79 next: pending,
80 };
81 }
82
83 match (active, confirmed) {
84 (Some(active), Some(confirmed)) if active.slot == confirmed.slot => {
85 ImageRunState::Stable(active)
86 }
87 (Some(active), Some(confirmed)) => ImageRunState::Testing {
88 current: active,
89 fallback: confirmed,
90 },
91 (Some(active), None) => ImageRunState::Stable(active),
92 (None, Some(confirmed)) => ImageRunState::Stable(confirmed),
93 (None, None) => {
94 ImageRunState::Unknown(
96 image_state
97 .iter()
98 .filter(|img| img.image == image_id)
99 .find(|img| img.slot == 0),
100 )
101 }
102 }
103}