1use core::marker::PhantomData;
2use schemars::{gen::SchemaGenerator, schema::Schema, JsonSchema};
3use serde::de::{DeserializeOwned, SeqAccess, Visitor};
4use serde::ser::SerializeSeq;
5use serde::{Deserialize, Deserializer, Serialize, Serializer};
6use serde_json::Value;
7use std::fmt;
8use std::fmt::Debug;
9
10#[derive(Debug, Clone)]
11pub enum TryParse<T: JsonSchema> {
12 Parsed(T),
13 Unparsed(Value),
14 NotPresent,
15}
16
17impl<T: JsonSchema> JsonSchema for TryParse<T> {
18 fn schema_name() -> String {
19 format!("Try<{}>", std::any::type_name::<T>())
20 }
21
22 fn json_schema(gen: &mut SchemaGenerator) -> Schema {
23 gen.subschema_for::<T>()
24 }
25}
26
27impl<'de, T: DeserializeOwned + JsonSchema> Deserialize<'de> for TryParse<T> {
28 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
29 match Option::<Value>::deserialize(deserializer)? {
30 None => Ok(TryParse::NotPresent),
31 Some(value) => match T::deserialize(&value) {
32 Ok(t) => Ok(TryParse::Parsed(t)),
33 Err(_) => Ok(TryParse::Unparsed(value)),
34 },
35 }
36 }
37}
38
39#[derive(Debug, Clone, JsonSchema)]
40#[serde(transparent)]
41pub struct TryVec<T: JsonSchema> {
42 inner: Vec<TryParse<T>>,
43}
44
45impl<T: JsonSchema> TryVec<T> {
46 pub fn new(mut vec: Vec<T>) -> Self {
47 let mut vec_marked: Vec<TryParse<T>> = Vec::new();
48 for item in vec.drain(..) {
49 vec_marked.push(TryParse::Parsed(item));
50 }
51 TryVec { inner: vec_marked }
52 }
53
54 pub fn new_empty() -> Self {
55 TryVec { inner: Vec::new() }
56 }
57
58 pub fn take_inner(self) -> Vec<T> {
59 let mut vec: Vec<T> = Vec::new();
60 for item in self.inner {
61 match item {
62 TryParse::Parsed(i) => vec.push(i),
63 _ => continue,
64 };
65 }
66 return vec;
67 }
68}
69
70impl<T: JsonSchema> Serialize for TryVec<T>
71where
72 T: Serialize,
73{
74 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
75 where
76 S: Serializer,
77 {
78 let mut seq = serializer.serialize_seq(Some(self.inner.len()))?;
79 for element in &self.inner {
80 match element {
81 TryParse::Parsed(t) => seq.serialize_element(t)?,
82 _ => continue,
83 };
84 }
85 seq.end()
86 }
87}
88
89struct TryVecVisitor<T: JsonSchema> {
90 marker: PhantomData<fn() -> TryVec<T>>,
91}
92
93impl<T: JsonSchema> TryVecVisitor<T> {
94 fn new() -> Self {
95 TryVecVisitor {
96 marker: PhantomData,
97 }
98 }
99}
100
101impl<'de, T> Visitor<'de> for TryVecVisitor<T>
102where
103 T: DeserializeOwned + JsonSchema,
104{
105 type Value = TryVec<T>;
106
107 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
109 formatter.write_str("a seqence")
110 }
111
112 fn visit_seq<M>(self, mut access: M) -> Result<Self::Value, M::Error>
113 where
114 M: SeqAccess<'de>,
115 {
116 let mut vec = Vec::new();
117
118 loop {
119 let res = match access.next_element() {
120 Ok(val) => val,
121 Err(err) => {
122 println!(
123 "Failed to parse event because '{}', the event will be discarded",
124 err
125 );
126 continue;
127 }
128 };
129 match res {
130 Some(item) => vec.push(item),
131 None => break,
132 };
133 }
134
135 Ok(TryVec { inner: vec })
136 }
137}
138
139impl<'de, T: JsonSchema> Deserialize<'de> for TryVec<T>
140where
141 T: DeserializeOwned,
142{
143 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
144 where
145 D: Deserializer<'de>,
146 {
147 deserializer.deserialize_seq(TryVecVisitor::new())
148 }
149}
150
151#[cfg(test)]
152mod test {
153 use schemars::JsonSchema;
154 use serde::{Deserialize, Serialize};
155
156 use super::TryVec;
157
158 #[derive(Deserialize, Serialize, JsonSchema, Debug)]
159 struct TestEvent {
160 data: String,
161 }
162
163 fn assert_serialized_deserialized_eq(data: &str, eq: &str) {
164 let deserialized = serde_json::from_str::<TryVec<TestEvent>>(data).unwrap();
165 let serialized = serde_json::to_string(&deserialized).unwrap();
166 assert_eq!(serialized, eq);
167 }
168
169 #[test]
170 fn test_serialize_deserialize() {
171 println!("test empty array");
172 assert_serialized_deserialized_eq(r#"[]"#, r#"[]"#);
173
174 println!("test one valid event");
175 assert_serialized_deserialized_eq(r#"[{"data":"test"}]"#, r#"[{"data":"test"}]"#);
176
177 println!("test invalid type int, skip event");
178 assert_serialized_deserialized_eq(r#"[{ "data": 1 }]"#, r#"[]"#);
179
180 println!("test invalid type dict, skip event");
181 assert_serialized_deserialized_eq(r#"[{"data":{}}]"#, r#"[]"#);
182
183 println!("test invalid type arr, skip event");
184 assert_serialized_deserialized_eq(r#"[{"data":[]}]"#, r#"[]"#);
185
186 println!("test multiple valid events");
187 assert_serialized_deserialized_eq(
188 r#"[{"data":"test"},{"data":"test2"},{"data":"test3"}]"#,
189 r#"[{"data":"test"},{"data":"test2"},{"data":"test3"}]"#,
190 );
191
192 println!("test invalid event in middle of sequence, skip one event");
193 assert_serialized_deserialized_eq(
194 r#"[{"data":"test"},{"data":2},{"data":"test3"}]"#,
195 r#"[{"data":"test"},{"data":"test3"}]"#,
196 );
197
198 println!("test utf-16 character");
199 assert_serialized_deserialized_eq(r#"[{"data":"\ud835\udc47"}]"#, r#"[{"data":"𝑇"}]"#);
200
201 println!("test invalid utf-8/16, skip event");
202 assert_serialized_deserialized_eq(r#"[{"data":"\ud835"}]"#, r#"[]"#);
203 }
204
205 #[test]
206 fn test_methods() {
207 let tryvec = TryVec::<TestEvent>::new_empty();
208 assert_eq!(tryvec.take_inner().len(), Vec::<TestEvent>::new().len());
209 }
210}