kernel/event/record/
provider.rs1use serde::{Deserialize, Serialize};
10
11use crate::error::AxError;
12
13#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
20#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
21#[serde(untagged)]
22pub enum ProviderDegraded {
23 Refused(AxError),
25 VaultFellBack(VaultFellBack),
27}
28
29impl<'de> Deserialize<'de> for ProviderDegraded {
34 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
35 let line = serde_json::Value::deserialize(deserializer)?;
36 AxError::deserialize(&line)
37 .map(Self::Refused)
38 .or_else(|as_refusal| {
39 VaultFellBack::deserialize(&line)
40 .map(Self::VaultFellBack)
41 .map_err(|as_fallback| {
42 serde::de::Error::custom(format!(
43 "neither a provider refusal ({as_refusal}) nor a vault fallback ({as_fallback})"
44 ))
45 })
46 })
47 }
48}
49
50#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
52#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
53pub struct VaultFellBack {
54 pub component: String,
56 pub fallback: String,
58 pub persistence: String,
60 pub reason: String,
62}
63
64#[cfg(test)]
65#[allow(clippy::unwrap_used, reason = "test code")]
66mod tests {
67 use super::*;
68 use crate::event::Payload;
69
70 #[test]
71 fn a_vault_line_keeps_the_bytes_its_ledger_already_holds() {
72 let line = r#"{"component":"vault","fallback":"session-memory","persistence":"this-process","reason":"probe reference unparsable"}"#;
73 let read: ProviderDegraded = serde_json::from_str::<Payload>(line)
74 .unwrap()
75 .read()
76 .unwrap();
77 assert!(matches!(read, ProviderDegraded::VaultFellBack(_)));
78 assert_eq!(
79 serde_json::to_string(&Payload::of(&read).unwrap()).unwrap(),
80 line
81 );
82 }
83
84 #[test]
85 fn a_line_that_is_neither_shape_names_what_each_shape_missed() {
86 let line = r#"{"code":"E_PROVIDER","component":"vault"}"#;
87 let err = serde_json::from_str::<Payload>(line)
88 .unwrap()
89 .read::<ProviderDegraded>()
90 .unwrap_err()
91 .to_string();
92 assert!(
93 err.contains("missing field `action`") && err.contains("missing field `fallback`"),
94 "{err}"
95 );
96 }
97}