fuchsia_component_config/
lib.rs1use fuchsia_inspect::Node;
8use fuchsia_runtime::{take_startup_handle, HandleInfo, HandleType};
9
10pub trait Config: Sized {
11 fn take_from_startup_handle() -> Self {
17 let handle_info = HandleInfo::new(HandleType::ComponentConfigVmo, 0);
18 let config_vmo: zx::Vmo =
19 take_startup_handle(handle_info).expect("Config VMO handle must be present.").into();
20 Self::from_vmo(&config_vmo).expect("Config VMO handle must be valid.")
21 }
22
23 fn from_vmo(vmo: &zx::Vmo) -> Result<Self, Error> {
25 let config_size = vmo.get_content_size().map_err(Error::GettingContentSize)?;
26 let config_bytes = vmo.read_to_vec(0, config_size).map_err(Error::ReadingConfigBytes)?;
27 Self::from_bytes(&config_bytes)
28 }
29
30 fn from_bytes(bytes: &[u8]) -> Result<Self, Error>;
32
33 fn record_inspect(&self, inspector_node: &Node);
35}
36
37#[derive(Debug)]
38pub enum Error {
39 GettingContentSize(zx::Status),
41 ReadingConfigBytes(zx::Status),
43 TooFewBytes,
45 ChecksumMismatch { expected_checksum: Vec<u8>, observed_checksum: Vec<u8> },
47 Unpersist(fidl::Error),
49}
50
51impl std::fmt::Display for Error {
52 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53 match self {
54 Self::GettingContentSize(status) => {
55 write!(f, "Failed to get content size: {status}")
56 }
57 Self::ReadingConfigBytes(status) => {
58 write!(f, "Failed to read VMO content: {status}")
59 }
60 Self::TooFewBytes => {
61 write!(f, "VMO content is not large enough for this config library.")
62 }
63 Self::ChecksumMismatch { expected_checksum, observed_checksum } => {
64 write!(
65 f,
66 "ABI checksum mismatch, expected {:?}, got {:?}",
67 expected_checksum, observed_checksum,
68 )
69 }
70 Self::Unpersist(fidl_error) => {
71 write!(f, "Failed to parse contents of config VMO: {fidl_error}")
72 }
73 }
74 }
75}
76
77impl std::error::Error for Error {
78 #[allow(unused_parens, reason = "rustfmt errors without parens here")]
79 fn source(&self) -> Option<(&'_ (dyn std::error::Error + 'static))> {
80 match self {
81 Self::GettingContentSize(ref status) | Self::ReadingConfigBytes(ref status) => {
82 Some(status)
83 }
84 Self::TooFewBytes => None,
85 Self::ChecksumMismatch { .. } => None,
86 Self::Unpersist(ref fidl_error) => Some(fidl_error),
87 }
88 }
89 fn description(&self) -> &str {
90 match self {
91 Self::GettingContentSize(_) => "getting content size",
92 Self::ReadingConfigBytes(_) => "reading VMO contents",
93 Self::TooFewBytes => "VMO contents too small",
94 Self::ChecksumMismatch { .. } => "ABI checksum mismatch",
95 Self::Unpersist(_) => "FIDL parsing error",
96 }
97 }
98}