1use std::{fmt, marker::PhantomData};
9
10use serde::{
11 de::{self, SeqAccess, Visitor},
12 Deserialize, Deserializer,
13};
14use serde_json::{value::RawValue as RawJsonValue, Value as JsonValue};
15use tracing::debug;
16
17pub mod base64;
18mod buf;
19pub mod can_be_empty;
20mod cow;
21pub mod duration;
22pub mod json_string;
23mod raw;
24pub mod single_element_seq;
25mod strings;
26pub mod test;
27
28pub use self::{
29 base64::{Base64, Base64DecodeError},
30 buf::{json_to_buf, slice_to_buf},
31 can_be_empty::{is_empty, CanBeEmpty},
32 cow::deserialize_cow_str,
33 raw::Raw,
34 strings::{
35 btreemap_deserialize_v1_powerlevel_values, deserialize_as_number_or_string,
36 deserialize_as_optional_number_or_string, deserialize_v1_powerlevel, empty_string_as_none,
37 none_as_empty_string,
38 },
39};
40
41pub type JsonObject = serde_json::Map<String, JsonValue>;
43
44pub fn is_default<T: Default + PartialEq>(val: &T) -> bool {
46 *val == T::default()
47}
48
49pub fn none_as_default<'de, D, T>(deserializer: D) -> Result<T, D::Error>
51where
52 D: Deserializer<'de>,
53 T: Default + Deserialize<'de>,
54{
55 Ok(Option::deserialize(deserializer)?.unwrap_or_default())
56}
57
58pub fn default_true() -> bool {
62 true
63}
64
65#[allow(clippy::trivially_copy_pass_by_ref)]
69pub fn is_true(b: &bool) -> bool {
70 *b
71}
72
73pub fn from_raw_json_value<'a, T, E>(val: &'a RawJsonValue) -> Result<T, E>
75where
76 T: Deserialize<'a>,
77 E: de::Error,
78{
79 serde_json::from_str(val.get()).map_err(E::custom)
80}
81
82pub fn default_on_error<'de, D, T>(deserializer: D) -> Result<T, D::Error>
86where
87 D: Deserializer<'de>,
88 T: Deserialize<'de> + Default,
89{
90 Ok(T::deserialize(deserializer).unwrap_or_else(|error| {
91 debug!("deserialization error, using default value: {error}");
92 T::default()
93 }))
94}
95
96pub fn ignore_invalid_vec_items<'de, D, T>(deserializer: D) -> Result<Vec<T>, D::Error>
99where
100 D: Deserializer<'de>,
101 T: Deserialize<'de>,
102{
103 struct SkipInvalid<T>(PhantomData<T>);
104
105 impl<'de, T> Visitor<'de> for SkipInvalid<T>
106 where
107 T: Deserialize<'de>,
108 {
109 type Value = Vec<T>;
110
111 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
112 formatter.write_str("Vec with possibly invalid items")
113 }
114
115 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
116 where
117 A: SeqAccess<'de>,
118 {
119 let mut vec = Vec::new();
120
121 while let Some(result) = seq.next_element::<T>().transpose() {
122 let Ok(elem) = result else {
123 continue;
124 };
125
126 vec.push(elem);
127 }
128
129 Ok(vec)
130 }
131 }
132
133 deserializer.deserialize_seq(SkipInvalid(PhantomData))
134}
135
136pub use ruma_macros::{
137 AsRefStr, AsStrAsRefStr, DebugAsRefStr, DeserializeFromCowStr, DisplayAsRefStr, FromString,
138 OrdAsRefStr, PartialEqAsRefStr, PartialOrdAsRefStr, SerializeAsRefStr, StringEnum,
139 _FakeDeriveSerde,
140};