Skip to content

Commit

Permalink
Introduce Data type to use with serde
Browse files Browse the repository at this point in the history
  • Loading branch information
zummenix committed Nov 20, 2022
1 parent 06ac5b2 commit 09fc0f9
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 1 deletion.
121 changes: 121 additions & 0 deletions src/data.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
use std::fmt;

/// A byte buffer used for serialization to and from the plist data type.
///
/// You use it in types with derived `Serialize`/`Deserialize` traits.
///
/// ## Examples
///
/// ```rust
/// extern crate plist;
/// #[macro_use]
/// extern crate serde_derive;
///
/// # fn main() {
/// #[derive(Deserialize, Serialize)]
/// struct Info {
/// blob: plist::Data,
/// }
///
/// let actual = Info { blob: plist::Data::new(vec![1, 2, 3, 4]) };
///
/// let mut xml_byte_buffer: Vec<u8> = vec![];
/// plist::to_writer_xml(&mut xml_byte_buffer, &actual)
/// .expect("serialize into xml");
///
/// let expected: Info = plist::from_reader_xml(xml_byte_buffer.as_slice())
/// .expect("deserialize from xml");
///
/// assert_eq!(actual.blob, expected.blob);
/// # }
/// ```
#[derive(Clone, PartialEq, Eq)]
pub struct Data {
inner: Vec<u8>,
}

impl Data {
/// Creates a new `Data` from vec of bytes.
pub fn new(bytes: Vec<u8>) -> Self {
Data { inner: bytes }
}
}

impl From<Vec<u8>> for Data {
fn from(from: Vec<u8>) -> Self {
Data { inner: from }
}
}

impl From<Data> for Vec<u8> {
fn from(from: Data) -> Self {
from.inner
}
}

impl AsRef<[u8]> for Data {
fn as_ref(&self) -> &[u8] {
self.inner.as_ref()
}
}

impl AsMut<[u8]> for Data {
fn as_mut(&mut self) -> &mut [u8] {
self.inner.as_mut()
}
}

impl fmt::Debug for Data {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.inner.fmt(f)
}
}

pub mod serde_impls {
use serde::{de, ser};
use std::fmt;

use crate::Data;

impl ser::Serialize for Data {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: ser::Serializer,
{
serializer.serialize_bytes(self.as_ref())
}
}

struct DataVisitor;

impl<'de> de::Visitor<'de> for DataVisitor {
type Value = Data;

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a byte array")
}

fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: de::Error,
{
self.visit_byte_buf(v.to_owned())
}

fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(v.into())
}
}

impl<'de> de::Deserialize<'de> for Data {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: de::Deserializer<'de>,
{
deserializer.deserialize_byte_buf(DataVisitor)
}
}
}
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,16 @@ pub mod stream;
#[cfg(not(feature = "enable_unstable_features_that_may_break_with_minor_version_bumps"))]
mod stream;

#[cfg(feature = "serde")]
mod data;
mod date;
mod error;
mod integer;
mod uid;
mod value;

#[cfg(feature = "serde")]
pub use data::Data;
pub use date::{Date, InvalidXmlDate};
pub use dictionary::Dictionary;
pub use error::Error;
Expand Down
6 changes: 5 additions & 1 deletion src/serde_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::{collections::BTreeMap, fmt::Debug, fs::File, io::Cursor};

use crate::{
stream::{private::Sealed, Event, OwnedEvent, Writer},
Date, Deserializer, Dictionary, Error, Integer, Serializer, Uid, Value,
Data, Date, Deserializer, Dictionary, Error, Integer, Serializer, Uid, Value,
};

struct VecWriter {
Expand Down Expand Up @@ -130,6 +130,7 @@ struct DogInner {
b: usize,
c: Vec<String>,
d: Option<Uid>,
e: Data,
}

#[test]
Expand All @@ -149,6 +150,7 @@ fn dog() {
b: 12,
c: vec!["a".to_string(), "b".to_string()],
d: Some(Uid::new(42)),
e: Data::new(vec![20, 22]),
}],
});

Expand All @@ -170,6 +172,8 @@ fn dog() {
Event::EndCollection,
Event::String("d".into()),
Event::Uid(Uid::new(42)),
Event::String("e".into()),
Event::Data(vec![20, 22].into()),
Event::EndCollection,
Event::EndCollection,
Event::EndCollection,
Expand Down

0 comments on commit 09fc0f9

Please sign in to comment.