intel_crashlog/collateral/
target_info.rs1use super::{CollateralManager, CollateralTree, ItemPath};
5use crate::Error;
6use crate::utils::Map;
7#[cfg(not(feature = "std"))]
8use alloc::string::String;
9use serde::{Deserialize, Deserializer};
10
11#[derive(Debug, Deserialize)]
13pub struct TargetInfo {
14 pub product: String,
16 pub product_id: String,
18 #[serde(default = "default_variant")]
20 pub variant: String,
21 #[serde(default, deserialize_with = "deserialize_die_ids")]
23 pub die_id: Map<u8, String>,
24}
25
26fn default_variant() -> String {
27 String::from("all")
28}
29
30fn deserialize_die_ids<'de, D>(deserializer: D) -> Result<Map<u8, String>, D::Error>
31where
32 D: Deserializer<'de>,
33{
34 let map: Map<String, String> = Deserialize::deserialize(deserializer)?;
35 Ok(map
36 .into_iter()
37 .filter_map(|(key, value)| {
38 key.parse::<u8>()
39 .inspect_err(|_| log::warn!("Invalid die ID value: {key}"))
40 .ok()
41 .map(|k| (k, value))
42 })
43 .collect())
44}
45
46impl<T: CollateralTree> CollateralManager<T> {
47 pub(super) fn update_target_info(&mut self) -> Result<(), Error> {
48 self.target_info.clear();
49 let path = ItemPath::new(["target_info.json"]);
50 for pvss in self.tree.search(&path)? {
51 let res = serde_json::from_slice::<TargetInfo>(&self.tree.get(&pvss, &path)?)
52 .inspect_err(|err| log::warn!("Invalid target info ({pvss}): {err}"));
53
54 let Ok(target_info) = res else {
55 continue;
56 };
57
58 let product_id = if target_info.product_id.starts_with("0x") {
59 u32::from_str_radix(&target_info.product_id[2..], 16)
60 } else {
61 target_info.product_id.parse()
62 };
63
64 if let Ok(product_id) = product_id {
65 log::trace!("Loading target info: {target_info:?}");
66 self.target_info.insert(product_id, target_info);
67 }
68 }
69 Ok(())
70 }
71}