fidl_fuchsia_update_installer_ext/
options.rs1use fuchsia_inspect as inspect;
8use proptest_derive::Arbitrary;
9use serde::{Deserialize, Serialize};
10use thiserror::Error;
11
12#[derive(Clone, Debug, Copy, PartialEq, Arbitrary, Serialize, Deserialize)]
14pub enum Initiator {
15 User,
18
19 Service,
21}
22
23impl Initiator {
24 fn name(&self) -> &'static str {
25 match self {
26 Initiator::User => "User",
27 Initiator::Service => "Service",
28 }
29 }
30}
31
32#[derive(Clone, Copy, Debug, PartialEq, Eq, Arbitrary, Serialize, Deserialize)]
34pub struct Range {
35 pub offset: u64,
37 pub size: u64,
39}
40
41#[derive(Clone, Debug, PartialEq, Arbitrary, Serialize, Deserialize)]
43pub struct Options {
44 pub initiator: Initiator,
46
47 pub allow_attach_to_existing_attempt: bool,
54
55 pub should_write_recovery: bool,
58
59 pub manifest_range: Option<Range>,
61}
62
63impl Options {
64 pub fn write_to_inspect(&self, node: &inspect::Node) {
66 let Options {
67 initiator,
68 allow_attach_to_existing_attempt,
69 should_write_recovery,
70 manifest_range,
71 } = self;
72 node.record_string("initiator", initiator.name());
73 node.record_bool("allow_attach_to_existing_attempt", *allow_attach_to_existing_attempt);
74 node.record_bool("should_write_recovery", *should_write_recovery);
75 if let Some(range) = manifest_range {
76 node.record_child("manifest_range", |range_node| {
77 range_node.record_uint("offset", range.offset);
78 range_node.record_uint("size", range.size);
79 });
80 }
81 }
82}
83
84#[derive(Error, Debug, PartialEq)]
86pub enum OptionsParseError {
87 #[error("missing initiator")]
89 MissingInitiator,
90}
91
92impl From<fidl_fuchsia_update_installer::Range> for Range {
93 fn from(data: fidl_fuchsia_update_installer::Range) -> Self {
94 Self { offset: data.offset, size: data.size }
95 }
96}
97
98impl From<&Range> for fidl_fuchsia_update_installer::Range {
99 fn from(range: &Range) -> Self {
100 Self { offset: range.offset, size: range.size }
101 }
102}
103
104impl TryFrom<fidl_fuchsia_update_installer::Options> for Options {
105 type Error = OptionsParseError;
106
107 fn try_from(data: fidl_fuchsia_update_installer::Options) -> Result<Self, OptionsParseError> {
108 let initiator =
109 data.initiator.map(|o| o.into()).ok_or(OptionsParseError::MissingInitiator)?;
110
111 let manifest_range = data.manifest_range.map(Range::from);
112
113 Ok(Self {
114 initiator,
115 allow_attach_to_existing_attempt: data
116 .allow_attach_to_existing_attempt
117 .unwrap_or(false),
118 should_write_recovery: data.should_write_recovery.unwrap_or(true),
119 manifest_range,
120 })
121 }
122}
123
124impl From<&Options> for fidl_fuchsia_update_installer::Options {
125 fn from(options: &Options) -> Self {
126 Self {
127 initiator: Some(options.initiator.into()),
128 allow_attach_to_existing_attempt: Some(options.allow_attach_to_existing_attempt),
129 should_write_recovery: Some(options.should_write_recovery),
130 manifest_range: options.manifest_range.as_ref().map(|r| r.into()),
131 ..Default::default()
132 }
133 }
134}
135
136impl From<Options> for fidl_fuchsia_update_installer::Options {
137 fn from(data: Options) -> Self {
138 (&data).into()
139 }
140}
141
142impl From<fidl_fuchsia_update_installer::Initiator> for Initiator {
143 fn from(fidl_initiator: fidl_fuchsia_update_installer::Initiator) -> Self {
144 match fidl_initiator {
145 fidl_fuchsia_update_installer::Initiator::User => Initiator::User,
146 fidl_fuchsia_update_installer::Initiator::Service => Initiator::Service,
147 }
148 }
149}
150
151impl From<Initiator> for fidl_fuchsia_update_installer::Initiator {
152 fn from(initiator: Initiator) -> Self {
153 match initiator {
154 Initiator::User => fidl_fuchsia_update_installer::Initiator::User,
155 Initiator::Service => fidl_fuchsia_update_installer::Initiator::Service,
156 }
157 }
158}
159
160#[cfg(test)]
161mod tests {
162
163 use super::*;
164 use proptest::prelude::*;
165
166 proptest! {
167 #[test]
168 fn options_roundtrips_through_fidl(options: Options) {
171 let as_fidl: fidl_fuchsia_update_installer::Options = options.clone().into();
172 prop_assert_eq!(as_fidl.try_into(), Ok(options));
173 }
174
175 #[test]
176 fn fidl_options_sans_initiator_error(options: Options) {
178 let mut as_fidl: fidl_fuchsia_update_installer::Options = options.into();
179 as_fidl.initiator = None;
180 prop_assert_eq!(Options::try_from(as_fidl), Err(OptionsParseError::MissingInitiator));
181 }
182 }
183}