1 use std::{ 2 fs::File, 3 io::{BufReader, BufWriter, Read, Seek, Write}, 4 path::Path, 5 }; 6 7 use crate::{ 8 error::{self, Error, ErrorKind, EventKind}, 9 stream::{ 10 BinaryWriter, Event, Events, OwnedEvent, Reader, Writer, XmlReader, XmlWriteOptions, 11 XmlWriter, 12 }, 13 u64_to_usize, Date, Dictionary, Integer, Uid, 14 }; 15 16 /// Represents any plist value. 17 #[derive(Clone, Debug, PartialEq)] 18 pub enum Value { 19 Array(Vec<Value>), 20 Dictionary(Dictionary), 21 Boolean(bool), 22 Data(Vec<u8>), 23 Date(Date), 24 Real(f64), 25 Integer(Integer), 26 String(String), 27 Uid(Uid), 28 #[doc(hidden)] 29 __Nonexhaustive, 30 } 31 32 impl Value { 33 /// Reads a `Value` from a plist file of any encoding. from_file<P: AsRef<Path>>(path: P) -> Result<Value, Error>34 pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Value, Error> { 35 let file = File::open(path).map_err(error::from_io_without_position)?; 36 Value::from_reader(BufReader::new(file)) 37 } 38 39 /// Reads a `Value` from a seekable byte stream containing a plist of any encoding. from_reader<R: Read + Seek>(reader: R) -> Result<Value, Error>40 pub fn from_reader<R: Read + Seek>(reader: R) -> Result<Value, Error> { 41 let reader = Reader::new(reader); 42 Value::from_events(reader) 43 } 44 45 /// Reads a `Value` from a seekable byte stream containing an XML encoded plist. from_reader_xml<R: Read>(reader: R) -> Result<Value, Error>46 pub fn from_reader_xml<R: Read>(reader: R) -> Result<Value, Error> { 47 let reader = XmlReader::new(reader); 48 Value::from_events(reader) 49 } 50 51 /// Serializes a `Value` to a file as a binary encoded plist. to_file_binary<P: AsRef<Path>>(&self, path: P) -> Result<(), Error>52 pub fn to_file_binary<P: AsRef<Path>>(&self, path: P) -> Result<(), Error> { 53 let mut file = File::create(path).map_err(error::from_io_without_position)?; 54 self.to_writer_binary(BufWriter::new(&mut file))?; 55 file.sync_all().map_err(error::from_io_without_position)?; 56 Ok(()) 57 } 58 59 /// Serializes a `Value` to a file as an XML encoded plist. to_file_xml<P: AsRef<Path>>(&self, path: P) -> Result<(), Error>60 pub fn to_file_xml<P: AsRef<Path>>(&self, path: P) -> Result<(), Error> { 61 let mut file = File::create(path).map_err(error::from_io_without_position)?; 62 self.to_writer_xml(BufWriter::new(&mut file))?; 63 file.sync_all().map_err(error::from_io_without_position)?; 64 Ok(()) 65 } 66 67 /// Serializes a `Value` to a byte stream as a binary encoded plist. to_writer_binary<W: Write>(&self, writer: W) -> Result<(), Error>68 pub fn to_writer_binary<W: Write>(&self, writer: W) -> Result<(), Error> { 69 let mut writer = BinaryWriter::new(writer); 70 self.to_writer_inner(&mut writer) 71 } 72 73 /// Serializes a `Value` to a byte stream as an XML encoded plist. to_writer_xml<W: Write>(&self, writer: W) -> Result<(), Error>74 pub fn to_writer_xml<W: Write>(&self, writer: W) -> Result<(), Error> { 75 self.to_writer_xml_with_options(writer, &XmlWriteOptions::default()) 76 } 77 78 /// Serializes a `Value` to a stream, using custom [`XmlWriteOptions`]. 79 /// 80 /// If you need to serialize to a file, you must acquire an appropriate 81 /// `Write` handle yourself. 82 /// 83 /// # Examples 84 /// 85 /// ```no_run 86 /// use std::io::{BufWriter, Write}; 87 /// use std::fs::File; 88 /// use plist::{Dictionary, Value, XmlWriteOptions}; 89 /// 90 /// let value: Value = Dictionary::new().into(); 91 /// // .. add some keys & values 92 /// let mut file = File::create("com.example.myPlist.plist").unwrap(); 93 /// let options = XmlWriteOptions::default().indent_string(" "); 94 /// value.to_writer_xml_with_options(BufWriter::new(&mut file), &options).unwrap(); 95 /// file.sync_all().unwrap(); 96 /// ``` to_writer_xml_with_options<W: Write>( &self, writer: W, options: &XmlWriteOptions, ) -> Result<(), Error>97 pub fn to_writer_xml_with_options<W: Write>( 98 &self, 99 writer: W, 100 options: &XmlWriteOptions, 101 ) -> Result<(), Error> { 102 let mut writer = XmlWriter::new_with_options(writer, options); 103 self.to_writer_inner(&mut writer) 104 } 105 to_writer_inner(&self, writer: &mut dyn Writer) -> Result<(), Error>106 fn to_writer_inner(&self, writer: &mut dyn Writer) -> Result<(), Error> { 107 let events = self.events(); 108 for event in events { 109 writer.write(&event)?; 110 } 111 Ok(()) 112 } 113 114 /// Builds a single `Value` from an `Event` iterator. 115 /// On success any excess `Event`s will remain in the iterator. 116 #[cfg(feature = "enable_unstable_features_that_may_break_with_minor_version_bumps")] from_events<T>(events: T) -> Result<Value, Error> where T: IntoIterator<Item = Result<OwnedEvent, Error>>,117 pub fn from_events<T>(events: T) -> Result<Value, Error> 118 where 119 T: IntoIterator<Item = Result<OwnedEvent, Error>>, 120 { 121 Builder::new(events.into_iter()).build() 122 } 123 124 /// Builds a single `Value` from an `Event` iterator. 125 /// On success any excess `Event`s will remain in the iterator. 126 #[cfg(not(feature = "enable_unstable_features_that_may_break_with_minor_version_bumps"))] from_events<T>(events: T) -> Result<Value, Error> where T: IntoIterator<Item = Result<OwnedEvent, Error>>,127 pub(crate) fn from_events<T>(events: T) -> Result<Value, Error> 128 where 129 T: IntoIterator<Item = Result<OwnedEvent, Error>>, 130 { 131 Builder::new(events.into_iter()).build() 132 } 133 134 /// Converts a `Value` into an `Event` iterator. 135 #[cfg(feature = "enable_unstable_features_that_may_break_with_minor_version_bumps")] 136 #[doc(hidden)] 137 #[deprecated(since = "1.2.0", note = "use Value::events instead")] into_events(&self) -> Events138 pub fn into_events(&self) -> Events { 139 self.events() 140 } 141 142 /// Creates an `Event` iterator for this `Value`. 143 #[cfg(not(feature = "enable_unstable_features_that_may_break_with_minor_version_bumps"))] events(&self) -> Events144 pub(crate) fn events(&self) -> Events { 145 Events::new(self) 146 } 147 148 /// Creates an `Event` iterator for this `Value`. 149 #[cfg(feature = "enable_unstable_features_that_may_break_with_minor_version_bumps")] events(&self) -> Events150 pub fn events(&self) -> Events { 151 Events::new(self) 152 } 153 154 /// If the `Value` is a Array, returns the underlying `Vec`. 155 /// 156 /// Returns `None` otherwise. 157 /// 158 /// This method consumes the `Value`. To get a reference instead, use 159 /// `as_array`. into_array(self) -> Option<Vec<Value>>160 pub fn into_array(self) -> Option<Vec<Value>> { 161 match self { 162 Value::Array(dict) => Some(dict), 163 _ => None, 164 } 165 } 166 167 /// If the `Value` is an Array, returns the associated `Vec`. 168 /// 169 /// Returns `None` otherwise. as_array(&self) -> Option<&Vec<Value>>170 pub fn as_array(&self) -> Option<&Vec<Value>> { 171 match *self { 172 Value::Array(ref array) => Some(array), 173 _ => None, 174 } 175 } 176 177 /// If the `Value` is an Array, returns the associated mutable `Vec`. 178 /// 179 /// Returns `None` otherwise. as_array_mut(&mut self) -> Option<&mut Vec<Value>>180 pub fn as_array_mut(&mut self) -> Option<&mut Vec<Value>> { 181 match *self { 182 Value::Array(ref mut array) => Some(array), 183 _ => None, 184 } 185 } 186 187 /// If the `Value` is a Dictionary, returns the associated `BTreeMap`. 188 /// 189 /// Returns `None` otherwise. 190 /// 191 /// This method consumes the `Value`. To get a reference instead, use 192 /// `as_dictionary`. into_dictionary(self) -> Option<Dictionary>193 pub fn into_dictionary(self) -> Option<Dictionary> { 194 match self { 195 Value::Dictionary(dict) => Some(dict), 196 _ => None, 197 } 198 } 199 200 /// If the `Value` is a Dictionary, returns the associated `BTreeMap`. 201 /// 202 /// Returns `None` otherwise. as_dictionary(&self) -> Option<&Dictionary>203 pub fn as_dictionary(&self) -> Option<&Dictionary> { 204 match *self { 205 Value::Dictionary(ref dict) => Some(dict), 206 _ => None, 207 } 208 } 209 210 /// If the `Value` is a Dictionary, returns the associated mutable `BTreeMap`. 211 /// 212 /// Returns `None` otherwise. as_dictionary_mut(&mut self) -> Option<&mut Dictionary>213 pub fn as_dictionary_mut(&mut self) -> Option<&mut Dictionary> { 214 match *self { 215 Value::Dictionary(ref mut dict) => Some(dict), 216 _ => None, 217 } 218 } 219 220 /// If the `Value` is a Boolean, returns the associated `bool`. 221 /// 222 /// Returns `None` otherwise. as_boolean(&self) -> Option<bool>223 pub fn as_boolean(&self) -> Option<bool> { 224 match *self { 225 Value::Boolean(v) => Some(v), 226 _ => None, 227 } 228 } 229 230 /// If the `Value` is a Data, returns the underlying `Vec`. 231 /// 232 /// Returns `None` otherwise. 233 /// 234 /// This method consumes the `Value`. If this is not desired, please use 235 /// `as_data` method. into_data(self) -> Option<Vec<u8>>236 pub fn into_data(self) -> Option<Vec<u8>> { 237 match self { 238 Value::Data(data) => Some(data), 239 _ => None, 240 } 241 } 242 243 /// If the `Value` is a Data, returns the associated `Vec`. 244 /// 245 /// Returns `None` otherwise. as_data(&self) -> Option<&[u8]>246 pub fn as_data(&self) -> Option<&[u8]> { 247 match *self { 248 Value::Data(ref data) => Some(data), 249 _ => None, 250 } 251 } 252 253 /// If the `Value` is a Date, returns the associated `Date`. 254 /// 255 /// Returns `None` otherwise. as_date(&self) -> Option<Date>256 pub fn as_date(&self) -> Option<Date> { 257 match *self { 258 Value::Date(date) => Some(date), 259 _ => None, 260 } 261 } 262 263 /// If the `Value` is a Real, returns the associated `f64`. 264 /// 265 /// Returns `None` otherwise. as_real(&self) -> Option<f64>266 pub fn as_real(&self) -> Option<f64> { 267 match *self { 268 Value::Real(v) => Some(v), 269 _ => None, 270 } 271 } 272 273 /// If the `Value` is a signed Integer, returns the associated `i64`. 274 /// 275 /// Returns `None` otherwise. as_signed_integer(&self) -> Option<i64>276 pub fn as_signed_integer(&self) -> Option<i64> { 277 match *self { 278 Value::Integer(v) => v.as_signed(), 279 _ => None, 280 } 281 } 282 283 /// If the `Value` is an unsigned Integer, returns the associated `u64`. 284 /// 285 /// Returns `None` otherwise. as_unsigned_integer(&self) -> Option<u64>286 pub fn as_unsigned_integer(&self) -> Option<u64> { 287 match *self { 288 Value::Integer(v) => v.as_unsigned(), 289 _ => None, 290 } 291 } 292 293 /// If the `Value` is a String, returns the underlying `String`. 294 /// 295 /// Returns `None` otherwise. 296 /// 297 /// This method consumes the `Value`. If this is not desired, please use 298 /// `as_string` method. into_string(self) -> Option<String>299 pub fn into_string(self) -> Option<String> { 300 match self { 301 Value::String(v) => Some(v), 302 _ => None, 303 } 304 } 305 306 /// If the `Value` is a String, returns the associated `str`. 307 /// 308 /// Returns `None` otherwise. as_string(&self) -> Option<&str>309 pub fn as_string(&self) -> Option<&str> { 310 match *self { 311 Value::String(ref v) => Some(v), 312 _ => None, 313 } 314 } 315 } 316 317 impl From<Vec<Value>> for Value { from(from: Vec<Value>) -> Value318 fn from(from: Vec<Value>) -> Value { 319 Value::Array(from) 320 } 321 } 322 323 impl From<Dictionary> for Value { from(from: Dictionary) -> Value324 fn from(from: Dictionary) -> Value { 325 Value::Dictionary(from) 326 } 327 } 328 329 impl From<bool> for Value { from(from: bool) -> Value330 fn from(from: bool) -> Value { 331 Value::Boolean(from) 332 } 333 } 334 335 impl<'a> From<&'a bool> for Value { from(from: &'a bool) -> Value336 fn from(from: &'a bool) -> Value { 337 Value::Boolean(*from) 338 } 339 } 340 341 impl From<Date> for Value { from(from: Date) -> Value342 fn from(from: Date) -> Value { 343 Value::Date(from) 344 } 345 } 346 347 impl<'a> From<&'a Date> for Value { from(from: &'a Date) -> Value348 fn from(from: &'a Date) -> Value { 349 Value::Date(*from) 350 } 351 } 352 353 impl From<f64> for Value { from(from: f64) -> Value354 fn from(from: f64) -> Value { 355 Value::Real(from) 356 } 357 } 358 359 impl From<f32> for Value { from(from: f32) -> Value360 fn from(from: f32) -> Value { 361 Value::Real(from.into()) 362 } 363 } 364 365 impl From<i64> for Value { from(from: i64) -> Value366 fn from(from: i64) -> Value { 367 Value::Integer(Integer::from(from)) 368 } 369 } 370 371 impl From<i32> for Value { from(from: i32) -> Value372 fn from(from: i32) -> Value { 373 Value::Integer(Integer::from(from)) 374 } 375 } 376 377 impl From<i16> for Value { from(from: i16) -> Value378 fn from(from: i16) -> Value { 379 Value::Integer(Integer::from(from)) 380 } 381 } 382 383 impl From<i8> for Value { from(from: i8) -> Value384 fn from(from: i8) -> Value { 385 Value::Integer(Integer::from(from)) 386 } 387 } 388 389 impl From<u64> for Value { from(from: u64) -> Value390 fn from(from: u64) -> Value { 391 Value::Integer(Integer::from(from)) 392 } 393 } 394 395 impl From<u32> for Value { from(from: u32) -> Value396 fn from(from: u32) -> Value { 397 Value::Integer(Integer::from(from)) 398 } 399 } 400 401 impl From<u16> for Value { from(from: u16) -> Value402 fn from(from: u16) -> Value { 403 Value::Integer(Integer::from(from)) 404 } 405 } 406 407 impl From<u8> for Value { from(from: u8) -> Value408 fn from(from: u8) -> Value { 409 Value::Integer(Integer::from(from)) 410 } 411 } 412 413 impl<'a> From<&'a f64> for Value { from(from: &'a f64) -> Value414 fn from(from: &'a f64) -> Value { 415 Value::Real(*from) 416 } 417 } 418 419 impl<'a> From<&'a f32> for Value { from(from: &'a f32) -> Value420 fn from(from: &'a f32) -> Value { 421 Value::Real((*from).into()) 422 } 423 } 424 425 impl<'a> From<&'a i64> for Value { from(from: &'a i64) -> Value426 fn from(from: &'a i64) -> Value { 427 Value::Integer(Integer::from(*from)) 428 } 429 } 430 431 impl<'a> From<&'a i32> for Value { from(from: &'a i32) -> Value432 fn from(from: &'a i32) -> Value { 433 Value::Integer(Integer::from(*from)) 434 } 435 } 436 437 impl<'a> From<&'a i16> for Value { from(from: &'a i16) -> Value438 fn from(from: &'a i16) -> Value { 439 Value::Integer(Integer::from(*from)) 440 } 441 } 442 443 impl<'a> From<&'a i8> for Value { from(from: &'a i8) -> Value444 fn from(from: &'a i8) -> Value { 445 Value::Integer(Integer::from(*from)) 446 } 447 } 448 449 impl<'a> From<&'a u64> for Value { from(from: &'a u64) -> Value450 fn from(from: &'a u64) -> Value { 451 Value::Integer(Integer::from(*from)) 452 } 453 } 454 455 impl<'a> From<&'a u32> for Value { from(from: &'a u32) -> Value456 fn from(from: &'a u32) -> Value { 457 Value::Integer(Integer::from(*from)) 458 } 459 } 460 461 impl<'a> From<&'a u16> for Value { from(from: &'a u16) -> Value462 fn from(from: &'a u16) -> Value { 463 Value::Integer((*from).into()) 464 } 465 } 466 467 impl<'a> From<&'a u8> for Value { from(from: &'a u8) -> Value468 fn from(from: &'a u8) -> Value { 469 Value::Integer((*from).into()) 470 } 471 } 472 473 impl From<String> for Value { from(from: String) -> Value474 fn from(from: String) -> Value { 475 Value::String(from) 476 } 477 } 478 479 impl<'a> From<&'a str> for Value { from(from: &'a str) -> Value480 fn from(from: &'a str) -> Value { 481 Value::String(from.into()) 482 } 483 } 484 485 struct Builder<T> { 486 stream: T, 487 token: Option<OwnedEvent>, 488 } 489 490 impl<T: Iterator<Item = Result<OwnedEvent, Error>>> Builder<T> { new(stream: T) -> Builder<T>491 fn new(stream: T) -> Builder<T> { 492 Builder { 493 stream, 494 token: None, 495 } 496 } 497 build(mut self) -> Result<Value, Error>498 fn build(mut self) -> Result<Value, Error> { 499 self.bump()?; 500 self.build_value() 501 } 502 bump(&mut self) -> Result<(), Error>503 fn bump(&mut self) -> Result<(), Error> { 504 self.token = match self.stream.next() { 505 Some(Ok(token)) => Some(token), 506 Some(Err(err)) => return Err(err), 507 None => None, 508 }; 509 Ok(()) 510 } 511 build_value(&mut self) -> Result<Value, Error>512 fn build_value(&mut self) -> Result<Value, Error> { 513 match self.token.take() { 514 Some(Event::StartArray(len)) => Ok(Value::Array(self.build_array(len)?)), 515 Some(Event::StartDictionary(len)) => Ok(Value::Dictionary(self.build_dict(len)?)), 516 517 Some(Event::Boolean(b)) => Ok(Value::Boolean(b)), 518 Some(Event::Data(d)) => Ok(Value::Data(d.into_owned())), 519 Some(Event::Date(d)) => Ok(Value::Date(d)), 520 Some(Event::Integer(i)) => Ok(Value::Integer(i)), 521 Some(Event::Real(f)) => Ok(Value::Real(f)), 522 Some(Event::String(s)) => Ok(Value::String(s.into_owned())), 523 Some(Event::Uid(u)) => Ok(Value::Uid(u)), 524 525 Some(event @ Event::EndCollection) => Err(error::unexpected_event_type( 526 EventKind::ValueOrStartCollection, 527 &event, 528 )), 529 530 Some(Event::__Nonexhaustive) => unreachable!(), 531 532 None => Err(ErrorKind::UnexpectedEndOfEventStream.without_position()), 533 } 534 } 535 build_array(&mut self, len: Option<u64>) -> Result<Vec<Value>, Error>536 fn build_array(&mut self, len: Option<u64>) -> Result<Vec<Value>, Error> { 537 let mut values = match len.and_then(u64_to_usize) { 538 Some(len) => Vec::with_capacity(len), 539 None => Vec::new(), 540 }; 541 542 loop { 543 self.bump()?; 544 if let Some(Event::EndCollection) = self.token { 545 self.token.take(); 546 return Ok(values); 547 } 548 values.push(self.build_value()?); 549 } 550 } 551 build_dict(&mut self, _len: Option<u64>) -> Result<Dictionary, Error>552 fn build_dict(&mut self, _len: Option<u64>) -> Result<Dictionary, Error> { 553 let mut dict = Dictionary::new(); 554 555 loop { 556 self.bump()?; 557 match self.token.take() { 558 Some(Event::EndCollection) => return Ok(dict), 559 Some(Event::String(s)) => { 560 self.bump()?; 561 dict.insert(s.into_owned(), self.build_value()?); 562 } 563 Some(event) => { 564 return Err(error::unexpected_event_type( 565 EventKind::DictionaryKeyOrEndCollection, 566 &event, 567 )) 568 } 569 None => return Err(ErrorKind::UnexpectedEndOfEventStream.without_position()), 570 } 571 } 572 } 573 } 574 575 #[cfg(test)] 576 mod tests { 577 use std::time::SystemTime; 578 579 use super::*; 580 use crate::{stream::Event::*, Date, Dictionary, Value}; 581 582 #[test] value_accessors()583 fn value_accessors() { 584 let vec = vec![Value::Real(0.0)]; 585 let mut array = Value::Array(vec.clone()); 586 assert_eq!(array.as_array(), Some(&vec.clone())); 587 assert_eq!(array.as_array_mut(), Some(&mut vec.clone())); 588 589 let mut map = Dictionary::new(); 590 map.insert("key1".to_owned(), Value::String("value1".to_owned())); 591 let mut dict = Value::Dictionary(map.clone()); 592 assert_eq!(dict.as_dictionary(), Some(&map.clone())); 593 assert_eq!(dict.as_dictionary_mut(), Some(&mut map.clone())); 594 595 assert_eq!(Value::Boolean(true).as_boolean(), Some(true)); 596 597 let slice: &[u8] = &[1, 2, 3]; 598 assert_eq!(Value::Data(slice.to_vec()).as_data(), Some(slice)); 599 assert_eq!( 600 Value::Data(slice.to_vec()).into_data(), 601 Some(slice.to_vec()) 602 ); 603 604 let date: Date = SystemTime::now().into(); 605 assert_eq!(Value::Date(date.clone()).as_date(), Some(date)); 606 607 assert_eq!(Value::Real(0.0).as_real(), Some(0.0)); 608 assert_eq!(Value::Integer(1.into()).as_signed_integer(), Some(1)); 609 assert_eq!(Value::Integer(1.into()).as_unsigned_integer(), Some(1)); 610 assert_eq!(Value::Integer((-1).into()).as_unsigned_integer(), None); 611 assert_eq!( 612 Value::Integer((i64::max_value() as u64 + 1).into()).as_signed_integer(), 613 None 614 ); 615 assert_eq!(Value::String("2".to_owned()).as_string(), Some("2")); 616 assert_eq!( 617 Value::String("t".to_owned()).into_string(), 618 Some("t".to_owned()) 619 ); 620 } 621 622 #[test] builder()623 fn builder() { 624 // Input 625 let events = vec![ 626 StartDictionary(None), 627 String("Author".into()), 628 String("William Shakespeare".into()), 629 String("Lines".into()), 630 StartArray(None), 631 String("It is a tale told by an idiot,".into()), 632 String("Full of sound and fury, signifying nothing.".into()), 633 EndCollection, 634 String("Birthdate".into()), 635 Integer(1564.into()), 636 String("Height".into()), 637 Real(1.60), 638 EndCollection, 639 ]; 640 641 let builder = Builder::new(events.into_iter().map(|e| Ok(e))); 642 let plist = builder.build(); 643 644 // Expected output 645 let mut lines = Vec::new(); 646 lines.push(Value::String("It is a tale told by an idiot,".to_owned())); 647 lines.push(Value::String( 648 "Full of sound and fury, signifying nothing.".to_owned(), 649 )); 650 651 let mut dict = Dictionary::new(); 652 dict.insert( 653 "Author".to_owned(), 654 Value::String("William Shakespeare".to_owned()), 655 ); 656 dict.insert("Lines".to_owned(), Value::Array(lines)); 657 dict.insert("Birthdate".to_owned(), Value::Integer(1564.into())); 658 dict.insert("Height".to_owned(), Value::Real(1.60)); 659 660 assert_eq!(plist.unwrap(), Value::Dictionary(dict)); 661 } 662 } 663