de.rs (7176B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2025 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or modify it under the 6 terms of the GNU Affero General Public License as published by the Free Software 7 Foundation; either version 3, or (at your option) any later version. 8 9 TALER is distributed in the hope that it will be useful, but WITHOUT ANY 10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 12 13 You should have received a copy of the GNU Affero General Public License along with 14 TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 17 use serde::{ 18 Deserialize, 19 de::{self, Error, Visitor, value::SeqDeserializer}, 20 forward_to_deserialize_any, 21 }; 22 23 /// Parse notification message content 24 pub fn from_str<'de, T: Deserialize<'de>>( 25 notification: &'de str, 26 ) -> Result<T, serde::de::value::Error> { 27 T::deserialize(Deserializer(notification)) 28 } 29 30 macro_rules! gen_fn { 31 (deserialize_unit_struct, $self:ident, $v:ident, $content:block) => { 32 gen_fn!(deserialize_unit_struct, $self, (_name: &'static str, $v: V), $content); 33 }; 34 (deserialize_newtype_struct, $self:ident, $v:ident, $content:block) => { 35 gen_fn!(deserialize_newtype_struct, $self, (_name: &'static str, $v: V), $content); 36 }; 37 (deserialize_tuple, $self:ident, $v:ident, $content:block) => { 38 gen_fn!(deserialize_tuple, $self, (_len: usize, $v: V), $content); 39 }; 40 (deserialize_tuple_struct, $self:ident, $v:ident, $content:block) => { 41 gen_fn!(deserialize_tuple_struct, $self, (_name: &'static str, _len: usize, $v: V), $content); 42 }; 43 (deserialize_struct, $self:ident, $v:ident, $content:block) => { 44 gen_fn!(deserialize_struct, $self, (_name: &'static str, _fields: &'static [&'static str], $v: V), $content); 45 }; 46 (deserialize_enum, $self:ident, $v:ident, $content:block) => { 47 gen_fn!(deserialize_enum, $self, (_name: &'static str, _variants: &'static [&'static str], $v: V), $content); 48 }; 49 ($fn:ident, $self:ident, $v:ident, $content:block) => { gen_fn!($fn, $self, ($v: V), $content); }; 50 ($fn:ident, $self:ident, ($($arg:ident: $type:ty),*), $content:block) => { 51 fn $fn<V: Visitor<'de>>($self$(, $arg: $type)*) -> Result<V::Value, de::value::Error> { 52 $content 53 } 54 }; 55 } 56 57 macro_rules! forward_to_parse { 58 ($(($from:ident, $visit_func:ident)),*$(,)?) => { 59 $( 60 gen_fn!($from, self, visitor, { 61 visitor.$visit_func( 62 self.0 63 .parse() 64 .map_err(|e| Error::custom(format!("{}", e)))?, 65 ) 66 }); 67 )* 68 } 69 } 70 71 macro_rules! forward_to_other { 72 ($(($from:ident, $to:ident)),*$(,)?) => { 73 $( 74 gen_fn!($from, self, visitor, { 75 self.$to(visitor) 76 }); 77 )* 78 } 79 } 80 81 macro_rules! fail_unsupported { 82 ($(($from:ident, $ty:expr)),*$(,)?) => { 83 $( 84 gen_fn!($from, self, _visitor, { 85 Err(Error::custom(format!("cannot deserialize non primitive type {}", $ty))) 86 }); 87 )* 88 } 89 } 90 91 /// Space-separated values deserializer for Postgres notification 92 /// Support tuples only 93 struct Deserializer<'de>(&'de str); 94 95 impl<'de> serde::de::Deserializer<'de> for Deserializer<'de> { 96 type Error = de::value::Error; 97 98 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> 99 where 100 V: Visitor<'de>, 101 { 102 let de = SeqDeserializer::new(self.0.split(' ').map(PlainDe)); 103 visitor.visit_seq(de) 104 } 105 106 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error> 107 where 108 V: Visitor<'de>, 109 { 110 PlainDe(self.0).deserialize_unit(visitor) 111 } 112 113 forward_to_deserialize_any! { 114 bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string 115 bytes byte_buf option unit_struct newtype_struct seq tuple 116 tuple_struct map struct enum identifier ignored_any 117 } 118 } 119 120 /// Deserializer for any plain value that can be parsed from a string 121 struct PlainDe<'de>(&'de str); 122 123 impl<'de> serde::de::IntoDeserializer<'de> for PlainDe<'de> { 124 type Deserializer = Self; 125 126 fn into_deserializer(self) -> Self::Deserializer { 127 self 128 } 129 } 130 131 impl<'de> serde::de::Deserializer<'de> for PlainDe<'de> { 132 type Error = serde::de::value::Error; 133 134 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error> 135 where 136 V: Visitor<'de>, 137 { 138 visitor.visit_borrowed_str(self.0) 139 } 140 141 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error> 142 where 143 V: Visitor<'de>, 144 { 145 if self.0.is_empty() { 146 visitor.visit_none() 147 } else { 148 visitor.visit_some(self) 149 } 150 } 151 152 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error> 153 where 154 V: Visitor<'de>, 155 { 156 if self.0.is_empty() { 157 visitor.visit_unit() 158 } else { 159 Err(Error::custom("expected empty string for unit")) 160 } 161 } 162 163 forward_to_parse!( 164 (deserialize_i8, visit_i8), 165 (deserialize_i16, visit_i16), 166 (deserialize_i32, visit_i32), 167 (deserialize_i64, visit_i64), 168 (deserialize_i128, visit_i128), 169 (deserialize_u8, visit_u8), 170 (deserialize_u16, visit_u16), 171 (deserialize_u32, visit_u32), 172 (deserialize_u64, visit_u64), 173 (deserialize_u128, visit_u128), 174 (deserialize_f32, visit_f32), 175 (deserialize_f64, visit_f64), 176 (deserialize_char, visit_char), 177 (deserialize_bool, visit_bool) 178 ); 179 180 forward_to_other!( 181 (deserialize_string, deserialize_str), 182 (deserialize_any, deserialize_str), 183 (deserialize_unit_struct, deserialize_unit), 184 ); 185 186 fail_unsupported!( 187 (deserialize_bytes, "bytes"), 188 (deserialize_byte_buf, "bytes"), 189 (deserialize_seq, "seq"), 190 (deserialize_tuple_struct, "tuple"), 191 (deserialize_tuple, "tuple"), 192 (deserialize_map, "map"), 193 (deserialize_struct, "struct"), 194 (deserialize_newtype_struct, "struct"), 195 (deserialize_enum, "enum"), 196 (deserialize_identifier, "identifier"), 197 (deserialize_ignored_any, "any") 198 ); 199 } 200 201 #[test] 202 pub fn parse() { 203 // Parse simple message 204 assert_eq!((1,), from_str::<(u8,)>("1").unwrap()); 205 assert_eq!((false,), from_str::<(bool,)>("false").unwrap()); 206 assert_eq!(("username",), from_str::<(&str,)>("username").unwrap()); 207 208 // Parse composite message 209 assert_eq!((1, false), from_str::<(u8, bool)>("1 false").unwrap()); 210 assert_eq!([1, 2, 3, 4], from_str::<[u8; 4]>("1 2 3 4").unwrap()); 211 212 // Parse corner case 213 assert_eq!((), from_str::<()>("").unwrap()); 214 assert_eq!((1, None), from_str::<(u8, Option<bool>)>("1 ").unwrap()); 215 assert_eq!((1, ()), from_str::<(u8, ())>("1 ").unwrap()); 216 assert_eq!( 217 (1, (), true), 218 from_str::<(u8, (), bool)>("1 true").unwrap() 219 ); 220 }