grafbase_sdk/types/
configuration.rs1use serde::Deserialize;
2
3use crate::SdkError;
4
5pub struct Configuration(Vec<u8>);
7
8impl Configuration {
9 pub(crate) fn new(config: Vec<u8>) -> Self {
11 Self(config)
12 }
13
14 pub fn deserialize<'de, T>(&'de self) -> Result<T, SdkError>
20 where
21 T: Deserialize<'de>,
22 {
23 let mut deserializer = minicbor_serde::Deserializer::new(&self.0);
24 serde_path_to_error::deserialize(&mut deserializer).map_err(|err| {
25 if err.path().iter().len() == 0
26 || err
27 .path()
28 .iter()
29 .all(|seg| matches!(seg, serde_path_to_error::Segment::Unknown))
30 {
31 format!("Failed to deserialize configuration: {}", err.into_inner()).into()
32 } else {
33 format!("Failed to deserialize configuration at {}", err).into()
34 }
35 })
36 }
37}
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42 use serde::{Deserialize, Serialize};
43
44 #[derive(Debug, Serialize, Deserialize)]
45 struct TestConfig<S> {
46 name: String,
47 settings: S,
48 }
49
50 #[derive(Debug, Serialize, Deserialize)]
51 struct Settings {
52 enabled: bool,
53 count: u32,
54 }
55
56 #[derive(Debug, Serialize, Deserialize)]
57 struct InvalidSettings {
58 enabled: String,
59 count: u32,
60 }
61
62 #[test]
63 fn test_deserialize() {
64 let config_bytes = crate::cbor::to_vec(TestConfig {
66 name: "test".to_string(),
67 settings: Settings {
68 enabled: true,
69 count: 42,
70 },
71 })
72 .unwrap();
73 let configuration = Configuration::new(config_bytes);
74 let result: TestConfig<Settings> = configuration.deserialize().unwrap();
75 assert_eq!(result.name, "test");
76 assert!(result.settings.enabled);
77 assert_eq!(result.settings.count, 42);
78
79 let invalid_bytes = crate::cbor::to_vec(&TestConfig {
81 name: "test".to_string(),
82 settings: InvalidSettings {
83 enabled: "not_a_bool".to_string(),
84 count: 42,
85 },
86 })
87 .unwrap();
88 let invalid_configuration = Configuration::new(invalid_bytes);
89 let err = invalid_configuration.deserialize::<TestConfig<Settings>>().unwrap_err();
90
91 insta::assert_snapshot!(err, @"Failed to deserialize configuration at settings.enabled: unexpected type string at position 29: expected bool");
92
93 let invalid_bytes = crate::cbor::to_vec(serde_json::Value::Null).unwrap();
95 let invalid_configuration = Configuration::new(invalid_bytes);
96 let err = invalid_configuration.deserialize::<TestConfig<Settings>>().unwrap_err();
97
98 insta::assert_snapshot!(err, @"Failed to deserialize configuration: unexpected type null at position 0: expected map");
99 }
100}