1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
//! Deserialization traits. //! //! Deserialization in miniserde works by returning a "place" into which data //! may be written through the methods of the `Visitor` trait object. //! //! Use the `make_place!` macro to acquire a "place" type. A library may use a //! single place type across all of its Deserialize impls, or each impl or each //! module may use a private place type. There is no difference. //! //! A place is simply: //! //! ```rust //! struct Place<T> { //! out: Option<T>, //! } //! ``` //! //! Upon successful deserialization the output object is written as `Some(T)` //! into the `out` field of the place. //! //! ## Deserializing a primitive //! //! The Visitor trait has a method corresponding to each supported primitive //! type. //! //! ```rust //! #[macro_use] //! extern crate miniserde; //! //! use miniserde::Result; //! use miniserde::de::{Deserialize, Visitor}; //! //! make_place!(Place); //! //! struct MyBoolean(bool); //! //! // The Visitor trait has a selection of methods corresponding to different //! // data types. We override the ones that our Rust type supports //! // deserializing from, and write the result into the `out` field of our //! // output place. //! // //! // These methods may perform validation and decide to return an error. //! impl Visitor for Place<MyBoolean> { //! fn boolean(&mut self, b: bool) -> Result<()> { //! self.out = Some(MyBoolean(b)); //! Ok(()) //! } //! } //! //! impl Deserialize for MyBoolean { //! fn begin(out: &mut Option<Self>) -> &mut Visitor { //! // All Deserialize impls will look exactly like this. There is no //! // other correct implementation of Deserialize. //! Place::new(out) //! } //! } //! # //! # fn main() {} //! ``` //! //! ## Deserializing a sequence //! //! In the case of a sequence (JSON array), the visitor method returns a builder //! that can hand out places to write sequence elements one element at a time. //! //! ```rust //! #[macro_use] //! extern crate miniserde; //! //! use miniserde::Result; //! use miniserde::de::{Deserialize, Seq, Visitor}; //! use std::mem; //! //! make_place!(Place); //! //! struct MyVec<T>(Vec<T>); //! //! impl<T: Deserialize> Visitor for Place<MyVec<T>> { //! fn seq(&mut self) -> Result<Box<Seq + '_>> { //! Ok(Box::new(VecBuilder { //! out: &mut self.out, //! vec: Vec::new(), //! element: None, //! })) //! } //! } //! //! struct VecBuilder<'a, T: 'a> { //! // At the end, output will be written here. //! out: &'a mut Option<MyVec<T>>, //! // Previous elements are accumulated here. //! vec: Vec<T>, //! // Next element will be placed here. //! element: Option<T>, //! } //! //! impl<'a, T: Deserialize> Seq for VecBuilder<'a, T> { //! fn element(&mut self) -> Result<&mut Visitor> { //! // Free up the place by transfering the most recent element //! // into self.vec. //! self.vec.extend(self.element.take()); //! // Hand out a place to write the next element. //! Ok(Deserialize::begin(&mut self.element)) //! } //! //! fn finish(&mut self) -> Result<()> { //! // Transfer the last element. //! self.vec.extend(self.element.take()); //! // Move the output object into self.out. //! let vec = mem::replace(&mut self.vec, Vec::new()); //! *self.out = Some(MyVec(vec)); //! Ok(()) //! } //! } //! //! impl<T: Deserialize> Deserialize for MyVec<T> { //! fn begin(out: &mut Option<Self>) -> &mut Visitor { //! // As mentioned, all Deserialize impls will look like this. //! Place::new(out) //! } //! } //! # //! # fn main() {} //! ``` //! //! ## Deserializing a map or struct //! //! This code demonstrates what is generated for structs by //! `#[derive(MiniDeserialize)]`. //! //! ```rust //! #[macro_use] //! extern crate miniserde; //! //! use miniserde::Result; //! use miniserde::de::{Deserialize, Map, Visitor}; //! //! make_place!(Place); //! //! // The struct that we would like to deserialize. //! struct Demo { //! code: u32, //! message: String, //! } //! //! impl Visitor for Place<Demo> { //! fn map(&mut self) -> Result<Box<Map + '_>> { //! // Like for sequences, we produce a builder that can hand out places //! // to write one struct field at a time. //! Ok(Box::new(DemoBuilder { //! code: None, //! message: None, //! out: &mut self.out, //! })) //! } //! } //! //! struct DemoBuilder<'a> { //! code: Option<u32>, //! message: Option<String>, //! out: &'a mut Option<Demo>, //! } //! //! impl<'a> Map for DemoBuilder<'a> { //! fn key(&mut self, k: &str) -> Result<&mut Visitor> { //! // Figure out which field is being deserialized and return a place //! // to write it. //! // //! // The code here ignores unrecognized fields but an implementation //! // would be free to return an error instead. Similarly an //! // implementation may want to check for duplicate fields by //! // returning an error if the current field already has a value. //! match k { //! "code" => Ok(Deserialize::begin(&mut self.code)), //! "message" => Ok(Deserialize::begin(&mut self.message)), //! _ => Ok(Visitor::ignore()), //! } //! } //! //! fn finish(&mut self) -> Result<()> { //! // Make sure we have every field and then write the output object //! // into self.out. //! let code = self.code.take().ok_or(miniserde::Error)?; //! let message = self.message.take().ok_or(miniserde::Error)?; //! *self.out = Some(Demo { code, message }); //! Ok(()) //! } //! } //! //! impl Deserialize for Demo { //! fn begin(out: &mut Option<Self>) -> &mut Visitor { //! // All Deserialize impls look like this. //! Place::new(out) //! } //! } //! # //! # fn main() {} //! ``` mod impls; use error::{Error, Result}; /// Trait for data structures that can be deserialized from a JSON string. /// /// [Refer to the module documentation for examples.][::de] pub trait Deserialize: Sized { /// The only correct implementation of this method is: /// /// ```rust /// # #[macro_use] /// # extern crate miniserde; /// # /// # use miniserde::de::{Deserialize, Visitor}; /// # /// # make_place!(Place); /// # struct S; /// # impl Visitor for Place<S> {} /// # /// # impl Deserialize for S { /// fn begin(out: &mut Option<Self>) -> &mut Visitor { /// Place::new(out) /// } /// # } /// # /// # fn main() {} /// ``` fn begin(out: &mut Option<Self>) -> &mut Visitor; // Not public API. This method is only intended for Option<T>, should not // need to be implemented outside of this crate. #[doc(hidden)] #[inline] fn default() -> Option<Self> { None } } /// Trait that can write data into an output place. /// /// [Refer to the module documentation for examples.][::de] pub trait Visitor { fn null(&mut self) -> Result<()> { Err(Error) } fn boolean(&mut self, b: bool) -> Result<()> { let _ = b; Err(Error) } fn string(&mut self, s: &str) -> Result<()> { let _ = s; Err(Error) } fn negative(&mut self, n: i64) -> Result<()> { let _ = n; Err(Error) } fn nonnegative(&mut self, n: u64) -> Result<()> { let _ = n; Err(Error) } fn float(&mut self, n: f64) -> Result<()> { let _ = n; Err(Error) } fn seq(&mut self) -> Result<Box<Seq + '_>> { Err(Error) } fn map(&mut self) -> Result<Box<Map + '_>> { Err(Error) } } /// Trait that can hand out places to write sequence elements. /// /// [Refer to the module documentation for examples.][::de] pub trait Seq { fn element(&mut self) -> Result<&mut Visitor>; fn finish(&mut self) -> Result<()>; } /// Trait that can hand out places to write values of a map. /// /// [Refer to the module documentation for examples.][::de] pub trait Map { fn key(&mut self, k: &str) -> Result<&mut Visitor>; fn finish(&mut self) -> Result<()>; }