facet_postcard/
shape_deser.rs1use facet_core::Shape;
7use facet_format::{DeserializeError, FormatDeserializer};
8use facet_value::Value;
9
10use crate::error::PostcardError;
11use crate::parser::PostcardParser;
12
13pub fn from_slice_with_shape(
37 input: &[u8],
38 source_shape: &'static Shape,
39) -> Result<Value, DeserializeError<PostcardError>> {
40 let parser = PostcardParser::new(input);
41 let mut de = FormatDeserializer::new_owned(parser);
42 de.deserialize_with_shape(source_shape)
43}
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48 use facet::Facet;
49
50 #[test]
51 fn test_from_slice_with_shape_primitives() {
52 let bytes = crate::to_vec(&42i32).unwrap();
54 let value = from_slice_with_shape(&bytes, i32::SHAPE).unwrap();
55 assert_eq!(value.as_number().unwrap().to_i64(), Some(42));
56
57 let bytes = crate::to_vec(&"hello".to_string()).unwrap();
59 let value = from_slice_with_shape(&bytes, String::SHAPE).unwrap();
60 assert_eq!(value.as_string().unwrap().as_str(), "hello");
61
62 let bytes = crate::to_vec(&true).unwrap();
64 let value = from_slice_with_shape(&bytes, bool::SHAPE).unwrap();
65 assert_eq!(value.as_bool(), Some(true));
66 }
67
68 #[test]
69 fn test_from_slice_with_shape_struct() {
70 #[derive(Facet)]
71 struct Point {
72 x: i32,
73 y: i32,
74 }
75
76 let point = Point { x: 10, y: 20 };
77 let bytes = crate::to_vec(&point).unwrap();
78 let value = from_slice_with_shape(&bytes, Point::SHAPE).unwrap();
79
80 let obj = value.as_object().unwrap();
81 assert_eq!(obj.get("x").unwrap().as_number().unwrap().to_i64(), Some(10));
82 assert_eq!(obj.get("y").unwrap().as_number().unwrap().to_i64(), Some(20));
83 }
84
85 #[test]
86 fn test_from_slice_with_shape_vec() {
87 let vec = vec![1i32, 2, 3, 4, 5];
88 let bytes = crate::to_vec(&vec).unwrap();
89 let value = from_slice_with_shape(&bytes, <Vec<i32>>::SHAPE).unwrap();
90
91 let arr = value.as_array().unwrap();
92 assert_eq!(arr.len(), 5);
93 assert_eq!(arr.get(0).unwrap().as_number().unwrap().to_i64(), Some(1));
94 assert_eq!(arr.get(4).unwrap().as_number().unwrap().to_i64(), Some(5));
95 }
96
97 #[test]
98 fn test_from_slice_with_shape_option() {
99 let opt: Option<i32> = Some(42);
101 let bytes = crate::to_vec(&opt).unwrap();
102 let value = from_slice_with_shape(&bytes, <Option<i32>>::SHAPE).unwrap();
103 assert_eq!(value.as_number().unwrap().to_i64(), Some(42));
104
105 let opt: Option<i32> = None;
107 let bytes = crate::to_vec(&opt).unwrap();
108 let value = from_slice_with_shape(&bytes, <Option<i32>>::SHAPE).unwrap();
109 assert!(value.is_null());
110 }
111
112 #[test]
113 fn test_from_slice_with_shape_enum() {
114 #[derive(Facet)]
115 #[repr(u8)]
116 #[allow(dead_code)]
117 enum Message {
118 Ping,
119 Text(String),
120 Point { x: i32, y: i32 },
121 }
122
123 let msg = Message::Ping;
125 let bytes = crate::to_vec(&msg).unwrap();
126 let value = from_slice_with_shape(&bytes, Message::SHAPE).unwrap();
127 assert_eq!(value.as_string().unwrap().as_str(), "Ping");
128
129 let msg = Message::Text("hello".into());
131 let bytes = crate::to_vec(&msg).unwrap();
132 let value = from_slice_with_shape(&bytes, Message::SHAPE).unwrap();
133 let obj = value.as_object().unwrap();
134 assert_eq!(obj.get("Text").unwrap().as_string().unwrap().as_str(), "hello");
135
136 let msg = Message::Point { x: 10, y: 20 };
138 let bytes = crate::to_vec(&msg).unwrap();
139 let value = from_slice_with_shape(&bytes, Message::SHAPE).unwrap();
140 let obj = value.as_object().unwrap();
141 let inner = obj.get("Point").unwrap().as_object().unwrap();
142 assert_eq!(inner.get("x").unwrap().as_number().unwrap().to_i64(), Some(10));
143 assert_eq!(inner.get("y").unwrap().as_number().unwrap().to_i64(), Some(20));
144 }
145}