1 // Copyright (C) 2018 François Laignel <fengalin@free.fr> 2 // 3 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or 4 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license 5 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your 6 // option. This file may not be copied, modified, or distributed 7 // except according to those terms. 8 9 use serde::de; 10 use serde::de::{Deserialize, Deserializer, EnumAccess, SeqAccess, VariantAccess, Visitor}; 11 use serde::ser::{Serialize, SerializeSeq, SerializeTuple, Serializer}; 12 13 use std::fmt; 14 15 use Caps; 16 use CapsFeatures; 17 use CapsFeaturesRef; 18 use CapsRef; 19 use Structure; 20 use StructureRef; 21 22 enum CapsVariantKinds { 23 Any, 24 Empty, 25 Some, 26 } 27 28 const CAPS_VARIANT_ANY_ID: u32 = 0; 29 const CAPS_VARIANT_ANY_STR: &str = "Any"; 30 const CAPS_VARIANT_EMPTY_ID: u32 = 1; 31 const CAPS_VARIANT_EMPTY_STR: &str = "Empty"; 32 const CAPS_VARIANT_SOME_ID: u32 = 2; 33 const CAPS_VARIANT_SOME_STR: &str = "Some"; 34 35 const CAPS_VARIANT_NAMES: &[&str] = &[ 36 &CAPS_VARIANT_ANY_STR, 37 &CAPS_VARIANT_EMPTY_STR, 38 &CAPS_VARIANT_SOME_STR, 39 ]; 40 41 struct CapsItemSe<'a>(&'a StructureRef, Option<&'a CapsFeaturesRef>); 42 impl<'a> Serialize for CapsItemSe<'a> { serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>43 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { 44 let mut tup = serializer.serialize_tuple(2)?; 45 tup.serialize_element(self.0)?; 46 tup.serialize_element(&self.1)?; 47 tup.end() 48 } 49 } 50 51 struct CapsForIterSe<'a>(&'a CapsRef); 52 impl<'a> Serialize for CapsForIterSe<'a> { serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>53 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { 54 let iter = self.0.iter_with_features(); 55 let size = iter.size_hint().0; 56 if size > 0 { 57 let mut seq = serializer.serialize_seq(Some(size))?; 58 for (structure, features) in iter { 59 let features = if !features.is_any() 60 && features.is_equal(::CAPS_FEATURES_MEMORY_SYSTEM_MEMORY.as_ref()) 61 { 62 None 63 } else { 64 Some(features) 65 }; 66 seq.serialize_element(&CapsItemSe(structure, features))?; 67 } 68 seq.end() 69 } else { 70 let seq = serializer.serialize_seq(None)?; 71 seq.end() 72 } 73 } 74 } 75 76 impl Serialize for CapsRef { serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>77 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { 78 if self.is_any() { 79 serializer.serialize_unit_variant( 80 stringify!(Caps), 81 CAPS_VARIANT_ANY_ID, 82 CAPS_VARIANT_ANY_STR, 83 ) 84 } else if self.is_empty() { 85 serializer.serialize_unit_variant( 86 stringify!(Caps), 87 CAPS_VARIANT_EMPTY_ID, 88 CAPS_VARIANT_EMPTY_STR, 89 ) 90 } else { 91 serializer.serialize_newtype_variant( 92 stringify!(Caps), 93 CAPS_VARIANT_SOME_ID, 94 CAPS_VARIANT_SOME_STR, 95 &CapsForIterSe(&self), 96 ) 97 } 98 } 99 } 100 101 impl Serialize for Caps { serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>102 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { 103 self.as_ref().serialize(serializer) 104 } 105 } 106 107 struct CapsItemDe(Structure, Option<CapsFeatures>); 108 109 struct CapsItemVisitor; 110 impl<'de> Visitor<'de> for CapsItemVisitor { 111 type Value = CapsItemDe; 112 expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result113 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 114 formatter.write_str("a tuple `(Structure, Option<CapsFeature>)`") 115 } 116 visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error>117 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> { 118 let structure = seq 119 .next_element::<Structure>()? 120 .ok_or_else(|| de::Error::custom("Expected a `Structure` for `Caps` item"))?; 121 let features_option = seq.next_element::<Option<CapsFeatures>>()?.ok_or_else(|| { 122 de::Error::custom("Expected an `Option<CapsFeature>` for `Caps` item") 123 })?; 124 125 Ok(CapsItemDe(structure, features_option)) 126 } 127 } 128 129 impl<'de> Deserialize<'de> for CapsItemDe { deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<CapsItemDe, D::Error>130 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<CapsItemDe, D::Error> { 131 deserializer.deserialize_tuple(2, CapsItemVisitor) 132 } 133 } 134 135 struct CapsSome(Caps); 136 137 struct CapsSomeVisitor; 138 impl<'de> Visitor<'de> for CapsSomeVisitor { 139 type Value = CapsSome; 140 expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result141 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 142 formatter.write_str("a sequence of `(Structure, Option<CapsFeature>)`") 143 } 144 visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error>145 fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> { 146 let mut caps = Caps::new_empty(); 147 { 148 let caps = caps.get_mut().unwrap(); 149 while let Some(caps_item) = seq.next_element::<CapsItemDe>()? { 150 caps.append_structure_full(caps_item.0, caps_item.1); 151 } 152 } 153 Ok(CapsSome(caps)) 154 } 155 } 156 157 impl<'de> Deserialize<'de> for CapsSome { deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<CapsSome, D::Error>158 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<CapsSome, D::Error> { 159 deserializer.deserialize_seq(CapsSomeVisitor) 160 } 161 } 162 163 struct CapsVariantKindsVisitor; 164 impl<'de> Visitor<'de> for CapsVariantKindsVisitor { 165 type Value = CapsVariantKinds; 166 expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result167 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 168 formatter.write_str("a Caps variant kind (`Any`, `None` or `Some`)") 169 } 170 visit_u32<E: de::Error>(self, value: u32) -> Result<Self::Value, E>171 fn visit_u32<E: de::Error>(self, value: u32) -> Result<Self::Value, E> { 172 match value { 173 CAPS_VARIANT_ANY_ID => Ok(CapsVariantKinds::Any), 174 CAPS_VARIANT_EMPTY_ID => Ok(CapsVariantKinds::Empty), 175 CAPS_VARIANT_SOME_ID => Ok(CapsVariantKinds::Some), 176 _ => Err(de::Error::invalid_value( 177 de::Unexpected::Unsigned(u64::from(value)), 178 &self, 179 )), 180 } 181 } 182 visit_str<E: de::Error>(self, value: &str) -> Result<Self::Value, E>183 fn visit_str<E: de::Error>(self, value: &str) -> Result<Self::Value, E> { 184 match value { 185 CAPS_VARIANT_ANY_STR => Ok(CapsVariantKinds::Any), 186 CAPS_VARIANT_EMPTY_STR => Ok(CapsVariantKinds::Empty), 187 CAPS_VARIANT_SOME_STR => Ok(CapsVariantKinds::Some), 188 _ => Err(de::Error::unknown_variant(value, CAPS_VARIANT_NAMES)), 189 } 190 } 191 } 192 193 impl<'de> Deserialize<'de> for CapsVariantKinds { deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>194 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> { 195 deserializer.deserialize_identifier(CapsVariantKindsVisitor) 196 } 197 } 198 199 struct CapsVisitor; 200 impl<'de> Visitor<'de> for CapsVisitor { 201 type Value = Caps; 202 expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result203 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { 204 formatter.write_str("a Caps enum (`Any`, `None` or `Some()`)") 205 } 206 visit_enum<A: EnumAccess<'de>>(self, data: A) -> Result<Self::Value, A::Error>207 fn visit_enum<A: EnumAccess<'de>>(self, data: A) -> Result<Self::Value, A::Error> { 208 let res = match data.variant()? { 209 (CapsVariantKinds::Any, _v) => Caps::new_any(), 210 (CapsVariantKinds::Empty, _v) => Caps::new_empty(), 211 (CapsVariantKinds::Some, v) => v 212 .newtype_variant::<CapsSome>() 213 .map(|caps_some| caps_some.0)?, 214 }; 215 216 Ok(res) 217 } 218 } 219 220 impl<'de> Deserialize<'de> for Caps { deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>221 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> { 222 deserializer.deserialize_enum(stringify!(Caps), CAPS_VARIANT_NAMES, CapsVisitor) 223 } 224 } 225 226 #[cfg(test)] 227 mod tests { 228 extern crate ron; 229 230 use Array; 231 use Caps; 232 use CapsFeatures; 233 use Fraction; 234 235 #[test] test_serialize()236 fn test_serialize() { 237 ::init().unwrap(); 238 239 let caps = Caps::builder("foo/bar") 240 .field("int", &12) 241 .field("bool", &true) 242 .field("string", &"bla") 243 .field("fraction", &Fraction::new(1, 2)) 244 .field("array", &Array::new(&[&1, &2])) 245 .build(); 246 247 let mut pretty_config = ron::ser::PrettyConfig::default(); 248 pretty_config.new_line = "".to_string(); 249 250 let res = ron::ser::to_string_pretty(&caps, pretty_config); 251 assert_eq!( 252 Ok(concat!( 253 "Some([", 254 " ((\"foo/bar\", [", 255 " (\"int\", \"i32\", 12),", 256 " (\"bool\", \"bool\", true),", 257 " (\"string\", \"String\", Some(\"bla\")),", 258 " (\"fraction\", \"Fraction\", (1, 2)),", 259 " (\"array\", \"Array\", [", 260 " (\"i32\", 1),", 261 " (\"i32\", 2),", 262 " ]),", 263 " ]), None),", 264 "])" 265 ) 266 .to_owned()), 267 res, 268 ); 269 270 let caps = Caps::builder("foo/bar") 271 .field("int", &12) 272 .field("bool", &true) 273 .field("string", &"bla") 274 .field("fraction", &Fraction::new(1, 2)) 275 .field("array", &Array::new(&[&1, &2])) 276 .features(&["foo:bar", "foo:baz"]) 277 .build(); 278 279 let mut pretty_config = ron::ser::PrettyConfig::default(); 280 pretty_config.new_line = "".to_string(); 281 282 let res = ron::ser::to_string_pretty(&caps, pretty_config); 283 assert_eq!( 284 Ok(concat!( 285 "Some([", 286 " ((\"foo/bar\", [", 287 " (\"int\", \"i32\", 12),", 288 " (\"bool\", \"bool\", true),", 289 " (\"string\", \"String\", Some(\"bla\")),", 290 " (\"fraction\", \"Fraction\", (1, 2)),", 291 " (\"array\", \"Array\", [", 292 " (\"i32\", 1),", 293 " (\"i32\", 2),", 294 " ]),", 295 " ]), Some(Some([", 296 " \"foo:bar\",", 297 " \"foo:baz\",", 298 " ]))),", 299 "])" 300 ) 301 .to_owned()), 302 res, 303 ); 304 305 let caps = Caps::builder("foo/bar") 306 .field("int", &12) 307 .field("bool", &true) 308 .field("string", &"bla") 309 .field("fraction", &Fraction::new(1, 2)) 310 .field("array", &Array::new(&[&1, &2])) 311 .any_features() 312 .build(); 313 314 let mut pretty_config = ron::ser::PrettyConfig::default(); 315 pretty_config.new_line = "".to_string(); 316 317 let res = ron::ser::to_string_pretty(&caps, pretty_config.clone()); 318 assert_eq!( 319 Ok(concat!( 320 "Some([", 321 " ((\"foo/bar\", [", 322 " (\"int\", \"i32\", 12),", 323 " (\"bool\", \"bool\", true),", 324 " (\"string\", \"String\", Some(\"bla\")),", 325 " (\"fraction\", \"Fraction\", (1, 2)),", 326 " (\"array\", \"Array\", [", 327 " (\"i32\", 1),", 328 " (\"i32\", 2),", 329 " ]),", 330 " ]), Some(Any)),", 331 "])" 332 ) 333 .to_owned()), 334 res, 335 ); 336 337 let caps_any = Caps::new_any(); 338 let res = ron::ser::to_string_pretty(&caps_any, pretty_config.clone()); 339 assert_eq!(Ok("Any".to_owned()), res); 340 341 let caps_empty = Caps::new_empty(); 342 let res = ron::ser::to_string_pretty(&caps_empty, pretty_config); 343 assert_eq!(Ok("Empty".to_owned()), res); 344 } 345 346 #[test] test_deserialize()347 fn test_deserialize() { 348 use Structure; 349 350 ::init().unwrap(); 351 352 let caps_ron = "Any"; 353 let caps: Caps = ron::de::from_str(caps_ron).unwrap(); 354 assert!(caps.is_any()); 355 356 let caps_ron = "Empty"; 357 let caps: Caps = ron::de::from_str(caps_ron).unwrap(); 358 assert!(caps.is_empty()); 359 360 let caps_ron = r#" 361 Some([ 362 ( 363 ("foo/bar", [ 364 ("int", "i32", 12), 365 ("bool", "bool", true), 366 ("string", "String", Some("bla")), 367 ("fraction", "Fraction", (1, 2)), 368 ("array", "Array", [ 369 ("i32", 1), 370 ("i32", 2), 371 ]), 372 ]), 373 None, 374 ), 375 ])"#; 376 let caps: Caps = ron::de::from_str(caps_ron).unwrap(); 377 let s = caps.get_structure(0).unwrap(); 378 assert_eq!( 379 s, 380 Structure::new( 381 "foo/bar", 382 &[ 383 ("int", &12), 384 ("bool", &true), 385 ("string", &"bla"), 386 ("fraction", &Fraction::new(1, 2)), 387 ("array", &Array::new(&[&1, &2])), 388 ], 389 ) 390 .as_ref() 391 ); 392 393 let caps_ron = r#" 394 Some([ 395 ( 396 ("foo/bar", [ 397 ("int", "i32", 12), 398 ("bool", "bool", true), 399 ("string", "String", None), 400 ("fraction", "Fraction", (1, 2)), 401 ("array", "Array", [ 402 ("i32", 1), 403 ("i32", 2), 404 ]), 405 ]), 406 Some(Some(["foo:bar", "foo:baz"])), 407 ), 408 ])"#; 409 let caps: Caps = ron::de::from_str(caps_ron).unwrap(); 410 let s = caps.get_structure(0).unwrap(); 411 let str_none: Option<&str> = None; 412 assert_eq!( 413 s, 414 Structure::new( 415 "foo/bar", 416 &[ 417 ("int", &12), 418 ("bool", &true), 419 ("string", &str_none), 420 ("fraction", &Fraction::new(1, 2)), 421 ("array", &Array::new(&[&1, &2])), 422 ], 423 ) 424 .as_ref() 425 ); 426 let f = caps.get_features(0).unwrap(); 427 assert!(f.is_equal(CapsFeatures::new(&["foo:bar", "foo:baz"]).as_ref())); 428 429 let caps_ron = r#" 430 Some([ 431 ( 432 ("foo/bar", [ 433 ("int", "i32", 12), 434 ("bool", "bool", true), 435 ("string", "String", Some("bla")), 436 ("fraction", "Fraction", (1, 2)), 437 ("array", "Array", [ 438 ("i32", 1), 439 ("i32", 2), 440 ]), 441 ]), 442 Some(Any), 443 ), 444 ])"#; 445 let caps: Caps = ron::de::from_str(caps_ron).unwrap(); 446 let s = caps.get_structure(0).unwrap(); 447 assert_eq!( 448 s, 449 Structure::new( 450 "foo/bar", 451 &[ 452 ("int", &12), 453 ("bool", &true), 454 ("string", &"bla"), 455 ("fraction", &Fraction::new(1, 2)), 456 ("array", &Array::new(&[&1, &2])), 457 ], 458 ) 459 .as_ref() 460 ); 461 let f = caps.get_features(0).unwrap(); 462 assert!(f.is_any()); 463 } 464 465 #[test] test_serde_roundtrip()466 fn test_serde_roundtrip() { 467 ::init().unwrap(); 468 469 let caps = Caps::new_any(); 470 let caps_ser = ron::ser::to_string(&caps).unwrap(); 471 let caps_de: Caps = ron::de::from_str(caps_ser.as_str()).unwrap(); 472 assert!(caps_de.is_any()); 473 474 let caps = Caps::new_empty(); 475 let caps_ser = ron::ser::to_string(&caps).unwrap(); 476 let caps_de: Caps = ron::de::from_str(caps_ser.as_str()).unwrap(); 477 assert!(caps_de.is_empty()); 478 479 let caps = Caps::builder("foo/bar") 480 .field("int", &12) 481 .field("bool", &true) 482 .field("string", &"bla") 483 .field("fraction", &Fraction::new(1, 2)) 484 .field("array", &Array::new(&[&1, &2])) 485 .build(); 486 let caps_ser = ron::ser::to_string(&caps).unwrap(); 487 let caps_de: Caps = ron::de::from_str(caps_ser.as_str()).unwrap(); 488 assert!(caps_de.is_strictly_equal(&caps)); 489 490 let caps = Caps::builder("foo/bar") 491 .field("int", &12) 492 .field("bool", &true) 493 .field("string", &"bla") 494 .field("fraction", &Fraction::new(1, 2)) 495 .field("array", &Array::new(&[&1, &2])) 496 .features(&["foo:bar", "foo:baz"]) 497 .build(); 498 let caps_ser = ron::ser::to_string(&caps).unwrap(); 499 let caps_de: Caps = ron::de::from_str(caps_ser.as_str()).unwrap(); 500 assert!(caps_de.is_strictly_equal(&caps)); 501 502 let caps = Caps::builder("foo/bar") 503 .field("int", &12) 504 .field("bool", &true) 505 .field("string", &"bla") 506 .field("fraction", &Fraction::new(1, 2)) 507 .field("array", &Array::new(&[&1, &2])) 508 .any_features() 509 .build(); 510 let caps_ser = ron::ser::to_string(&caps).unwrap(); 511 let caps_de: Caps = ron::de::from_str(caps_ser.as_str()).unwrap(); 512 assert!(caps_de.is_strictly_equal(&caps)); 513 } 514 } 515