serde: separate serde impl and tests from base module

+ fix erroneous `datetime` instead of `buffer` in `BufferRef::serialize`
+ remove ser/de for `Value`s with types `ULong` & `ILong`
This commit is contained in:
François Laignel 2018-07-16 21:46:10 +02:00 committed by Sebastian Dröge
parent 3f0cd6fb87
commit 90b046fbcf
24 changed files with 2949 additions and 2894 deletions

View file

@ -579,79 +579,6 @@ lazy_static! {
*BUFFER_COPY_METADATA | ::BufferCopyFlags::MEMORY;
}
#[cfg(feature = "ser_de")]
pub(crate) mod serde {
use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer, SerializeStruct};
use serde_bytes::{Bytes, ByteBuf};
use Buffer;
use BufferFlags;
use BufferRef;
use ClockTime;
impl<'a> Serialize for BufferRef {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut datetime = serializer.serialize_struct("Buffer", 6)?;
datetime.serialize_field("pts", &self.get_pts())?;
datetime.serialize_field("dts", &self.get_dts())?;
datetime.serialize_field("duration", &self.get_duration())?;
datetime.serialize_field("offset", &self.get_offset())?;
datetime.serialize_field("offset_end", &self.get_offset_end())?;
datetime.serialize_field("flags", &self.get_flags())?;
{
let data = self.map_readable().unwrap();
datetime.serialize_field("buffer", &Bytes::new(data.as_slice()))?;
}
datetime.end()
}
}
impl<'a> Serialize for Buffer {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.as_ref().serialize(serializer)
}
}
#[derive(Deserialize)]
struct BufferDe {
pts: ClockTime,
dts: ClockTime,
duration: ClockTime,
offset: u64,
offset_end: u64,
flags: BufferFlags,
buffer: ByteBuf,
}
impl From<BufferDe> for Buffer {
fn from(mut buf_de: BufferDe) -> Self {
// Move the `ByteBuff`'s byte array into the `gst::Buffer`
// Are we really avoiding copies with that?
let drained_buffer: &mut Vec<u8> = buf_de.buffer.as_mut();
let mut buffer =
Buffer::from_slice(drained_buffer.drain(..).collect::<Vec<u8>>()).unwrap();
{
let buffer = buffer.get_mut().unwrap();
buffer.set_pts(buf_de.pts);
buffer.set_dts(buf_de.dts);
buffer.set_duration(buf_de.duration);
buffer.set_offset(buf_de.offset);
buffer.set_offset_end(buf_de.offset_end);
buffer.set_flags(buf_de.flags);
}
buffer
}
}
impl<'de> Deserialize<'de> for Buffer {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
BufferDe::deserialize(deserializer)
.and_then(|buffer_de| Ok(buffer_de.into()))
}
}
}
#[cfg(test)]
mod tests {
use super::*;
@ -723,165 +650,4 @@ mod tests {
assert_eq!(data.as_slice(), vec![0, 2, 3, 4].as_slice());
}
}
#[cfg(feature = "ser_de")]
#[test]
fn test_serialize() {
extern crate ron;
extern crate serde_json;
extern crate serde_pickle;
use Buffer;
use BufferFlags;
::init().unwrap();
let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]).unwrap();
{
let buffer = buffer.get_mut().unwrap();
buffer.set_pts(1.into());
buffer.set_offset(3);
buffer.set_offset_end(4);
buffer.set_duration(5.into());
buffer.set_flags(BufferFlags::LIVE | BufferFlags::LAST);
}
// don't use newlines
let mut pretty_config = ron::ser::PrettyConfig::default();
pretty_config.new_line = "".to_string();
let res = ron::ser::to_string_pretty(&buffer, pretty_config);
assert_eq!(
Ok(
concat!(
"(",
" pts: Some(1),",
" dts: None,",
" duration: Some(5),",
" offset: 3,",
" offset_end: 4,",
" flags: (",
" bits: 1048592,",
" ),",
" buffer: \"AQIDBA==\",",
")"
)
.to_owned()
),
res
);
let res = serde_json::to_string(&buffer).unwrap();
assert_eq!(
concat!(
"{",
"\"pts\":1,",
"\"dts\":null,",
"\"duration\":5,",
"\"offset\":3,",
"\"offset_end\":4,",
"\"flags\":{\"bits\":1048592},",
"\"buffer\":[1,2,3,4]",
"}"
)
.to_owned(),
res
);
let res = serde_pickle::to_vec(&buffer, true).unwrap();
assert_eq!(
vec![
128, 3, 125, 40, 88, 3, 0, 0, 0, 112, 116, 115, 74, 1, 0, 0, 0, 88, 3, 0, 0, 0, 100,
116, 115, 78, 88, 8, 0, 0, 0, 100, 117, 114, 97, 116, 105, 111, 110, 74, 5, 0, 0, 0,
88, 6, 0, 0, 0, 111, 102, 102, 115, 101, 116, 74, 3, 0, 0, 0, 88, 10, 0, 0, 0, 111,
102, 102, 115, 101, 116, 95, 101, 110, 100, 74, 4, 0, 0, 0, 88, 5, 0, 0, 0, 102, 108,
97, 103, 115, 125, 40, 88, 4, 0, 0, 0, 98, 105, 116, 115, 74, 16, 0, 16, 0, 117, 88,
6, 0, 0, 0, 98, 117, 102, 102, 101, 114, 67,
4, 1, 2, 3, 4, 117, 46
],
res
);
}
#[cfg(feature = "ser_de")]
#[test]
fn test_deserialize() {
extern crate ron;
extern crate serde_json;
extern crate serde_pickle;
use Buffer;
use BufferFlags;
::init().unwrap();
let buffer_ron = r#"
(
pts: Some(1),
dts: None,
duration: Some(5),
offset: 3,
offset_end: 4,
flags: (
bits: 1048592,
),
buffer: "AQIDBA==",
)
"#;
let buffer: Buffer = ron::de::from_str(buffer_ron).unwrap();
assert_eq!(buffer.get_pts(), 1.into());
assert_eq!(buffer.get_dts(), None.into());
assert_eq!(buffer.get_offset(), 3);
assert_eq!(buffer.get_offset_end(), 4);
assert_eq!(buffer.get_duration(), 5.into());
assert_eq!(buffer.get_flags(), BufferFlags::LIVE | BufferFlags::LAST);
{
let data = buffer.map_readable().unwrap();
assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
}
let buffer_json = r#"
{
"pts":1,
"dts":null,
"duration":5,
"offset":3,
"offset_end":4,
"flags":{"bits":1048592},
"buffer":[1,2,3,4]
}
"#;
let buffer: Buffer = serde_json::from_str(buffer_json).unwrap();
assert_eq!(buffer.get_pts(), 1.into());
assert_eq!(buffer.get_dts(), None.into());
assert_eq!(buffer.get_offset(), 3);
assert_eq!(buffer.get_offset_end(), 4);
assert_eq!(buffer.get_duration(), 5.into());
assert_eq!(buffer.get_flags(), BufferFlags::LIVE | BufferFlags::LAST);
{
let data = buffer.map_readable().unwrap();
assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
}
let buffer_pickle: &[u8] = &[
128, 3, 125, 40, 88, 3, 0, 0, 0, 112, 116, 115, 74, 1, 0, 0, 0, 88, 3, 0, 0, 0, 100,
116, 115, 78, 88, 8, 0, 0, 0, 100, 117, 114, 97, 116, 105, 111, 110, 74, 5, 0, 0, 0,
88, 6, 0, 0, 0, 111, 102, 102, 115, 101, 116, 74, 3, 0, 0, 0, 88, 10, 0, 0, 0, 111,
102, 102, 115, 101, 116, 95, 101, 110, 100, 74, 4, 0, 0, 0, 88, 5, 0, 0, 0, 102, 108,
97, 103, 115, 125, 40, 88, 4, 0, 0, 0, 98, 105, 116, 115, 74, 16, 0, 16, 0, 117, 88,
6, 0, 0, 0, 98, 117, 102, 102, 101, 114, 67,
4, 1, 2, 3, 4, 117, 46
];
let buffer: Buffer = serde_pickle::from_slice(buffer_pickle).unwrap();
assert_eq!(buffer.get_pts(), 1.into());
assert_eq!(buffer.get_dts(), None.into());
assert_eq!(buffer.get_offset(), 3);
assert_eq!(buffer.get_offset_end(), 4);
assert_eq!(buffer.get_duration(), 5.into());
assert_eq!(buffer.get_flags(), BufferFlags::LIVE | BufferFlags::LAST);
{
let data = buffer.map_readable().unwrap();
assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
}
}
}

View file

@ -0,0 +1,231 @@
// Copyright (C) 2018 François Laignel <fengalin@free.fr>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer, SerializeStruct};
use serde_bytes::{Bytes, ByteBuf};
use Buffer;
use BufferFlags;
use BufferRef;
use ClockTime;
impl<'a> Serialize for BufferRef {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut buffer = serializer.serialize_struct("Buffer", 6)?;
buffer.serialize_field("pts", &self.get_pts())?;
buffer.serialize_field("dts", &self.get_dts())?;
buffer.serialize_field("duration", &self.get_duration())?;
buffer.serialize_field("offset", &self.get_offset())?;
buffer.serialize_field("offset_end", &self.get_offset_end())?;
buffer.serialize_field("flags", &self.get_flags())?;
{
let data = self.map_readable().unwrap();
buffer.serialize_field("buffer", &Bytes::new(data.as_slice()))?;
}
buffer.end()
}
}
impl<'a> Serialize for Buffer {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.as_ref().serialize(serializer)
}
}
#[derive(Deserialize)]
struct BufferDe {
pts: ClockTime,
dts: ClockTime,
duration: ClockTime,
offset: u64,
offset_end: u64,
flags: BufferFlags,
buffer: ByteBuf,
}
impl From<BufferDe> for Buffer {
fn from(mut buf_de: BufferDe) -> Self {
// Move the `ByteBuff`'s byte array into the `gst::Buffer`
// Are we really avoiding copies with that?
let drained_buffer: &mut Vec<u8> = buf_de.buffer.as_mut();
let mut buffer =
Buffer::from_slice(drained_buffer.drain(..).collect::<Vec<u8>>()).unwrap();
{
let buffer = buffer.get_mut().unwrap();
buffer.set_pts(buf_de.pts);
buffer.set_dts(buf_de.dts);
buffer.set_duration(buf_de.duration);
buffer.set_offset(buf_de.offset);
buffer.set_offset_end(buf_de.offset_end);
buffer.set_flags(buf_de.flags);
}
buffer
}
}
impl<'de> Deserialize<'de> for Buffer {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
BufferDe::deserialize(deserializer)
.and_then(|buffer_de| Ok(buffer_de.into()))
}
}
#[cfg(test)]
mod tests {
extern crate ron;
extern crate serde_json;
extern crate serde_pickle;
use Buffer;
use BufferFlags;
#[test]
fn test_serialize() {
::init().unwrap();
let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]).unwrap();
{
let buffer = buffer.get_mut().unwrap();
buffer.set_pts(1.into());
buffer.set_offset(3);
buffer.set_offset_end(4);
buffer.set_duration(5.into());
buffer.set_flags(BufferFlags::LIVE | BufferFlags::LAST);
}
let mut pretty_config = ron::ser::PrettyConfig::default();
pretty_config.new_line = "".to_string();
let res = ron::ser::to_string_pretty(&buffer, pretty_config);
assert_eq!(
Ok(
concat!(
"(",
" pts: Some(1),",
" dts: None,",
" duration: Some(5),",
" offset: 3,",
" offset_end: 4,",
" flags: (",
" bits: 1048592,",
" ),",
" buffer: \"AQIDBA==\",",
")"
)
.to_owned()
),
res
);
let res = serde_json::to_string(&buffer).unwrap();
assert_eq!(
concat!(
"{",
"\"pts\":1,",
"\"dts\":null,",
"\"duration\":5,",
"\"offset\":3,",
"\"offset_end\":4,",
"\"flags\":{\"bits\":1048592},",
"\"buffer\":[1,2,3,4]",
"}"
)
.to_owned(),
res
);
let res = serde_pickle::to_vec(&buffer, true).unwrap();
assert_eq!(
vec![
128, 3, 125, 40, 88, 3, 0, 0, 0, 112, 116, 115, 74, 1, 0, 0, 0, 88, 3, 0, 0, 0, 100,
116, 115, 78, 88, 8, 0, 0, 0, 100, 117, 114, 97, 116, 105, 111, 110, 74, 5, 0, 0, 0,
88, 6, 0, 0, 0, 111, 102, 102, 115, 101, 116, 74, 3, 0, 0, 0, 88, 10, 0, 0, 0, 111,
102, 102, 115, 101, 116, 95, 101, 110, 100, 74, 4, 0, 0, 0, 88, 5, 0, 0, 0, 102, 108,
97, 103, 115, 125, 40, 88, 4, 0, 0, 0, 98, 105, 116, 115, 74, 16, 0, 16, 0, 117, 88,
6, 0, 0, 0, 98, 117, 102, 102, 101, 114, 67,
4, 1, 2, 3, 4, 117, 46
],
res
);
}
#[test]
fn test_deserialize() {
::init().unwrap();
let buffer_ron = r#"
(
pts: Some(1),
dts: None,
duration: Some(5),
offset: 3,
offset_end: 4,
flags: (
bits: 1048592,
),
buffer: "AQIDBA==",
)
"#;
let buffer: Buffer = ron::de::from_str(buffer_ron).unwrap();
assert_eq!(buffer.get_pts(), 1.into());
assert_eq!(buffer.get_dts(), None.into());
assert_eq!(buffer.get_offset(), 3);
assert_eq!(buffer.get_offset_end(), 4);
assert_eq!(buffer.get_duration(), 5.into());
assert_eq!(buffer.get_flags(), BufferFlags::LIVE | BufferFlags::LAST);
{
let data = buffer.map_readable().unwrap();
assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
}
let buffer_json = r#"
{
"pts":1,
"dts":null,
"duration":5,
"offset":3,
"offset_end":4,
"flags":{"bits":1048592},
"buffer":[1,2,3,4]
}
"#;
let buffer: Buffer = serde_json::from_str(buffer_json).unwrap();
assert_eq!(buffer.get_pts(), 1.into());
assert_eq!(buffer.get_dts(), None.into());
assert_eq!(buffer.get_offset(), 3);
assert_eq!(buffer.get_offset_end(), 4);
assert_eq!(buffer.get_duration(), 5.into());
assert_eq!(buffer.get_flags(), BufferFlags::LIVE | BufferFlags::LAST);
{
let data = buffer.map_readable().unwrap();
assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
}
let buffer_pickle: &[u8] = &[
128, 3, 125, 40, 88, 3, 0, 0, 0, 112, 116, 115, 74, 1, 0, 0, 0, 88, 3, 0, 0, 0, 100,
116, 115, 78, 88, 8, 0, 0, 0, 100, 117, 114, 97, 116, 105, 111, 110, 74, 5, 0, 0, 0,
88, 6, 0, 0, 0, 111, 102, 102, 115, 101, 116, 74, 3, 0, 0, 0, 88, 10, 0, 0, 0, 111,
102, 102, 115, 101, 116, 95, 101, 110, 100, 74, 4, 0, 0, 0, 88, 5, 0, 0, 0, 102, 108,
97, 103, 115, 125, 40, 88, 4, 0, 0, 0, 98, 105, 116, 115, 74, 16, 0, 16, 0, 117, 88,
6, 0, 0, 0, 98, 117, 102, 102, 101, 114, 67,
4, 1, 2, 3, 4, 117, 46
];
let buffer: Buffer = serde_pickle::from_slice(buffer_pickle).unwrap();
assert_eq!(buffer.get_pts(), 1.into());
assert_eq!(buffer.get_dts(), None.into());
assert_eq!(buffer.get_offset(), 3);
assert_eq!(buffer.get_offset_end(), 4);
assert_eq!(buffer.get_duration(), 5.into());
assert_eq!(buffer.get_flags(), BufferFlags::LIVE | BufferFlags::LAST);
{
let data = buffer.map_readable().unwrap();
assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
}
}
}

View file

@ -193,195 +193,3 @@ impl<'a> DoubleEndedIterator for Iter<'a> {
}
impl<'a> ExactSizeIterator for Iter<'a> {}
#[cfg(feature = "ser_de")]
pub(crate) mod serde {
use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
use serde::ser::{Serialize, Serializer, SerializeSeq};
use std::fmt;
use Buffer;
use BufferList;
use BufferListRef;
impl Serialize for BufferListRef {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut iter = self.iter();
let (remaining, _) = iter.size_hint();
if remaining > 0 {
let mut seq = serializer.serialize_seq(Some(remaining))?;
while let Some(ref buffer) = iter.next() {
seq.serialize_element(buffer)?;
}
seq.end()
} else {
let seq = serializer.serialize_seq(None)?;
seq.end()
}
}
}
impl Serialize for BufferList {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.as_ref().serialize(serializer)
}
}
struct BufferListVisitor;
impl<'de> Visitor<'de> for BufferListVisitor {
type Value = BufferList;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a sequence of Buffers")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
let mut buffer_list = BufferList::new();
{
let buffer_list = buffer_list.get_mut().unwrap();
while let Some(buffer) = seq.next_element::<Buffer>()? {
buffer_list.add(buffer);
}
}
Ok(buffer_list)
}
}
impl<'de> Deserialize<'de> for BufferList {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_seq(BufferListVisitor)
}
}
}
#[cfg(test)]
mod tests {
#[cfg(feature = "ser_de")]
#[test]
fn test_serialize() {
extern crate ron;
use Buffer;
use BufferList;
::init().unwrap();
let mut buffer_list = BufferList::new();
{
let buffer_list = buffer_list.get_mut().unwrap();
let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]).unwrap();
{
let buffer = buffer.get_mut().unwrap();
buffer.set_pts(1.into());
buffer.set_offset(0);
buffer.set_offset_end(4);
buffer.set_duration(4.into());
}
buffer_list.add(buffer);
let mut buffer = Buffer::from_slice(vec![5, 6]).unwrap();
{
let buffer = buffer.get_mut().unwrap();
buffer.set_pts(5.into());
buffer.set_offset(4);
buffer.set_offset_end(6);
buffer.set_duration(2.into());
}
buffer_list.add(buffer);
}
// don't use newlines
let mut pretty_config = ron::ser::PrettyConfig::default();
pretty_config.new_line = "".to_string();
let res = ron::ser::to_string_pretty(&buffer_list, pretty_config);
assert_eq!(
Ok(
concat!(
"[",
" (",
" pts: Some(1),",
" dts: None,",
" duration: Some(4),",
" offset: 0,",
" offset_end: 4,",
" flags: (",
" bits: 0,",
" ),",
" buffer: \"AQIDBA==\",",
" ),",
" (",
" pts: Some(5),",
" dts: None,",
" duration: Some(2),",
" offset: 4,",
" offset_end: 6,",
" flags: (",
" bits: 0,",
" ),",
" buffer: \"BQY=\",",
" ),",
"]"
)
.to_owned()
),
res,
);
}
#[cfg(feature = "ser_de")]
#[test]
fn test_deserialize() {
extern crate ron;
use BufferList;
::init().unwrap();
let buffer_list_ron = r#"
[
(
pts: Some(1),
dts: None,
duration: Some(4),
offset: 0,
offset_end: 4,
flags: (
bits: 0,
),
buffer: "AQIDBA==",
),
(
pts: Some(5),
dts: None,
duration: Some(2),
offset: 4,
offset_end: 6,
flags: (
bits: 0,
),
buffer: "BQY=",
),
]
"#;
let buffer_list: BufferList = ron::de::from_str(buffer_list_ron).unwrap();
let mut iter = buffer_list.iter();
let buffer = iter.next().unwrap();
assert_eq!(buffer.get_pts(), 1.into());
assert_eq!(buffer.get_dts(), None.into());
{
let data = buffer.map_readable().unwrap();
assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
}
let buffer = iter.next().unwrap();
assert_eq!(buffer.get_pts(), 5.into());
{
let data = buffer.map_readable().unwrap();
assert_eq!(data.as_slice(), vec![5, 6].as_slice());
}
}
}

View file

@ -0,0 +1,190 @@
// Copyright (C) 2018 François Laignel <fengalin@free.fr>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
use serde::ser::{Serialize, Serializer, SerializeSeq};
use std::fmt;
use Buffer;
use BufferList;
use BufferListRef;
impl Serialize for BufferListRef {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut iter = self.iter();
let (remaining, _) = iter.size_hint();
if remaining > 0 {
let mut seq = serializer.serialize_seq(Some(remaining))?;
while let Some(ref buffer) = iter.next() {
seq.serialize_element(buffer)?;
}
seq.end()
} else {
let seq = serializer.serialize_seq(None)?;
seq.end()
}
}
}
impl Serialize for BufferList {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.as_ref().serialize(serializer)
}
}
struct BufferListVisitor;
impl<'de> Visitor<'de> for BufferListVisitor {
type Value = BufferList;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a sequence of Buffers")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
let mut buffer_list = BufferList::new();
{
let buffer_list = buffer_list.get_mut().unwrap();
while let Some(buffer) = seq.next_element::<Buffer>()? {
buffer_list.add(buffer);
}
}
Ok(buffer_list)
}
}
impl<'de> Deserialize<'de> for BufferList {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_seq(BufferListVisitor)
}
}
#[cfg(test)]
mod tests {
extern crate ron;
use BufferList;
#[test]
fn test_serialize() {
use Buffer;
::init().unwrap();
let mut buffer_list = BufferList::new();
{
let buffer_list = buffer_list.get_mut().unwrap();
let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]).unwrap();
{
let buffer = buffer.get_mut().unwrap();
buffer.set_pts(1.into());
buffer.set_offset(0);
buffer.set_offset_end(4);
buffer.set_duration(4.into());
}
buffer_list.add(buffer);
let mut buffer = Buffer::from_slice(vec![5, 6]).unwrap();
{
let buffer = buffer.get_mut().unwrap();
buffer.set_pts(5.into());
buffer.set_offset(4);
buffer.set_offset_end(6);
buffer.set_duration(2.into());
}
buffer_list.add(buffer);
}
let mut pretty_config = ron::ser::PrettyConfig::default();
pretty_config.new_line = "".to_string();
let res = ron::ser::to_string_pretty(&buffer_list, pretty_config);
assert_eq!(
Ok(
concat!(
"[",
" (",
" pts: Some(1),",
" dts: None,",
" duration: Some(4),",
" offset: 0,",
" offset_end: 4,",
" flags: (",
" bits: 0,",
" ),",
" buffer: \"AQIDBA==\",",
" ),",
" (",
" pts: Some(5),",
" dts: None,",
" duration: Some(2),",
" offset: 4,",
" offset_end: 6,",
" flags: (",
" bits: 0,",
" ),",
" buffer: \"BQY=\",",
" ),",
"]"
)
.to_owned()
),
res,
);
}
#[test]
fn test_deserialize() {
::init().unwrap();
let buffer_list_ron = r#"
[
(
pts: Some(1),
dts: None,
duration: Some(4),
offset: 0,
offset_end: 4,
flags: (
bits: 0,
),
buffer: "AQIDBA==",
),
(
pts: Some(5),
dts: None,
duration: Some(2),
offset: 4,
offset_end: 6,
flags: (
bits: 0,
),
buffer: "BQY=",
),
]
"#;
let buffer_list: BufferList = ron::de::from_str(buffer_list_ron).unwrap();
let mut iter = buffer_list.iter();
let buffer = iter.next().unwrap();
assert_eq!(buffer.get_pts(), 1.into());
assert_eq!(buffer.get_dts(), None.into());
{
let data = buffer.map_readable().unwrap();
assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
}
let buffer = iter.next().unwrap();
assert_eq!(buffer.get_pts(), 5.into());
{
let data = buffer.map_readable().unwrap();
assert_eq!(data.as_slice(), vec![5, 6].as_slice());
}
}
}

View file

@ -402,67 +402,6 @@ impl Builder {
}
}
#[cfg(feature = "ser_de")]
pub(crate) mod serde {
use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
use serde::ser::{Serialize, Serializer, SerializeSeq};
use std::fmt;
use Caps;
use CapsRef;
use Structure;
impl<'a> Serialize for CapsRef {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let iter = self.iter();
let size = iter.size_hint().0;
if size > 0 {
let mut seq = serializer.serialize_seq(Some(size))?;
for structure in iter {
seq.serialize_element(structure)?;
}
seq.end()
} else {
let seq = serializer.serialize_seq(None)?;
seq.end()
}
}
}
impl<'a> Serialize for Caps {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.as_ref().serialize(serializer)
}
}
struct CapsVisitor;
impl<'de> Visitor<'de> for CapsVisitor {
type Value = Caps;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a sequence of `Structure`s")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
let mut caps = Caps::new_empty();
{
let caps = caps.get_mut().unwrap();
while let Some(structure) = seq.next_element::<Structure>()? {
caps.append_structure(structure);
}
}
Ok(caps)
}
}
impl<'de> Deserialize<'de> for Caps {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_seq(CapsVisitor)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
@ -520,83 +459,4 @@ mod tests {
"foo/bar, int=(int)12, bool=(boolean)true, string=(string)bla, fraction=(fraction)1/2, array=(int)< 1, 2 >"
);
}
#[cfg(feature = "ser_de")]
#[test]
fn test_serialize() {
extern crate ron;
::init().unwrap();
let caps = Caps::builder("foo/bar")
.field("int", &12)
.field("bool", &true)
.field("string", &"bla")
.field("fraction", &Fraction::new(1, 2))
.field("array", &Array::new(&[&1, &2]))
.build();
// don't use newlines
let mut pretty_config = ron::ser::PrettyConfig::default();
pretty_config.new_line = "".to_string();
let res = ron::ser::to_string_pretty(&caps, pretty_config);
assert_eq!(
Ok(
concat!(
"[",
" (\"foo/bar\", [",
" (\"int\", \"i32\", 12),",
" (\"bool\", \"bool\", true),",
" (\"string\", \"String\", \"bla\"),",
" (\"fraction\", \"Fraction\", (1, 2)),",
" (\"array\", \"Array\", [",
" (\"i32\", 1),",
" (\"i32\", 2),",
" ]),",
" ]),",
"]"
)
.to_owned()
),
res,
);
}
#[cfg(feature = "ser_de")]
#[test]
fn test_deserialize() {
extern crate ron;
::init().unwrap();
let caps_ron = r#"
[
("foo/bar", [
("int", "i32", 12),
("bool", "bool", true),
("string", "String", "bla"),
("fraction", "Fraction", (1, 2)),
("array", "Array", [
("i32", 1),
("i32", 2),
]),
]),
]"#;
let caps: Caps = ron::de::from_str(caps_ron).unwrap();
let s = caps.get_structure(0).unwrap();
assert_eq!(
s,
Structure::new(
"foo/bar",
&[
("int", &12),
("bool", &true),
("string", &"bla"),
("fraction", &Fraction::new(1, 2)),
("array", &Array::new(&[&1, &2])),
],
).as_ref()
);
}
}

148
gstreamer/src/caps_serde.rs Normal file
View file

@ -0,0 +1,148 @@
// Copyright (C) 2018 François Laignel <fengalin@free.fr>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
use serde::ser::{Serialize, Serializer, SerializeSeq};
use std::fmt;
use Caps;
use CapsRef;
use Structure;
impl<'a> Serialize for CapsRef {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let iter = self.iter();
let size = iter.size_hint().0;
if size > 0 {
let mut seq = serializer.serialize_seq(Some(size))?;
for structure in iter {
seq.serialize_element(structure)?;
}
seq.end()
} else {
let seq = serializer.serialize_seq(None)?;
seq.end()
}
}
}
impl<'a> Serialize for Caps {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.as_ref().serialize(serializer)
}
}
struct CapsVisitor;
impl<'de> Visitor<'de> for CapsVisitor {
type Value = Caps;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a sequence of `Structure`s")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
let mut caps = Caps::new_empty();
{
let caps = caps.get_mut().unwrap();
while let Some(structure) = seq.next_element::<Structure>()? {
caps.append_structure(structure);
}
}
Ok(caps)
}
}
impl<'de> Deserialize<'de> for Caps {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_seq(CapsVisitor)
}
}
#[cfg(test)]
mod tests {
extern crate ron;
use Array;
use Caps;
use Fraction;
#[test]
fn test_serialize() {
::init().unwrap();
let caps = Caps::builder("foo/bar")
.field("int", &12)
.field("bool", &true)
.field("string", &"bla")
.field("fraction", &Fraction::new(1, 2))
.field("array", &Array::new(&[&1, &2]))
.build();
let mut pretty_config = ron::ser::PrettyConfig::default();
pretty_config.new_line = "".to_string();
let res = ron::ser::to_string_pretty(&caps, pretty_config);
assert_eq!(
Ok(
concat!(
"[",
" (\"foo/bar\", [",
" (\"int\", \"i32\", 12),",
" (\"bool\", \"bool\", true),",
" (\"string\", \"String\", \"bla\"),",
" (\"fraction\", \"Fraction\", (1, 2)),",
" (\"array\", \"Array\", [",
" (\"i32\", 1),",
" (\"i32\", 2),",
" ]),",
" ]),",
"]"
)
.to_owned()
),
res,
);
}
#[test]
fn test_deserialize() {
use Structure;
::init().unwrap();
let caps_ron = r#"
[
("foo/bar", [
("int", "i32", 12),
("bool", "bool", true),
("string", "String", "bla"),
("fraction", "Fraction", (1, 2)),
("array", "Array", [
("i32", 1),
("i32", 2),
]),
]),
]"#;
let caps: Caps = ron::de::from_str(caps_ron).unwrap();
let s = caps.get_structure(0).unwrap();
assert_eq!(
s,
Structure::new(
"foo/bar",
&[
("int", &12),
("bool", &true),
("string", &"bla"),
("fraction", &Fraction::new(1, 2)),
("array", &Array::new(&[&1, &2])),
],
).as_ref()
);
}
}

View file

@ -105,53 +105,6 @@ impl fmt::Display for ClockTime {
}
}
#[cfg(feature = "ser_de")]
pub(crate) mod serde {
use serde::de;
use serde::de::{Deserialize, Deserializer, Visitor};
use serde::ser::{Serialize, Serializer};
use std::fmt;
use ClockTime;
impl<'a> Serialize for ClockTime {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
match self.nanoseconds() {
Some(ref value) => serializer.serialize_some(value),
None => serializer.serialize_none(),
}
}
}
struct ClockTimeVisitor;
impl<'de> Visitor<'de> for ClockTimeVisitor {
type Value = ClockTime;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an optional u64 ClockTime with ns precision")
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
u64::deserialize(deserializer)
.and_then(|value| Ok(ClockTime::from_nseconds(value)))
}
fn visit_none<E: de::Error>(self) -> Result<Self::Value, E> {
Ok(ClockTime(None))
}
}
impl<'de> Deserialize<'de> for ClockTime {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_option(ClockTimeVisitor)
}
}
}
#[doc(hidden)]
impl ToGlib for ClockTime {
type GlibType = ffi::GstClockTime;
@ -203,74 +156,3 @@ impl glib::StaticType for ClockTime {
<u64 as glib::StaticType>::static_type()
}
}
#[cfg(test)]
mod tests {
#[cfg(feature = "ser_de")]
#[test]
fn test_serialize() {
extern crate ron;
extern crate serde_json;
use ClockTime;
::init().unwrap();
// Some
let clocktime = ClockTime::from_nseconds(42_123_456_789);
// don't use newlines
let mut pretty_config = ron::ser::PrettyConfig::default();
pretty_config.new_line = "".to_string();
let res = ron::ser::to_string_pretty(&clocktime, pretty_config.clone());
assert_eq!(Ok("Some(42123456789)".to_owned()), res);
let res = serde_json::to_string(&clocktime).unwrap();
assert_eq!("42123456789".to_owned(), res);
// None
let clocktime = ClockTime(None);
let res = ron::ser::to_string_pretty(&clocktime, pretty_config);
assert_eq!(Ok("None".to_owned()), res);
let res = serde_json::to_string(&clocktime).unwrap();
assert_eq!("null".to_owned(), res);
}
#[cfg(feature = "ser_de")]
#[test]
fn test_deserialize() {
extern crate ron;
extern crate serde_json;
use ClockTime;
::init().unwrap();
// Some
let clocktime_ron = "Some(42123456789)";
let clocktime: ClockTime = ron::de::from_str(clocktime_ron).unwrap();
assert_eq!(clocktime.seconds(), Some(42));
assert_eq!(clocktime.mseconds(), Some(42_123));
assert_eq!(clocktime.useconds(), Some(42_123_456));
assert_eq!(clocktime.nseconds(), Some(42_123_456_789));
let clocktime_json = "42123456789";
let clocktime: ClockTime = serde_json::from_str(clocktime_json).unwrap();
assert_eq!(clocktime.seconds(), Some(42));
assert_eq!(clocktime.mseconds(), Some(42_123));
assert_eq!(clocktime.useconds(), Some(42_123_456));
assert_eq!(clocktime.nseconds(), Some(42_123_456_789));
// None
let clocktime_ron = "None";
let clocktime: ClockTime = ron::de::from_str(clocktime_ron).unwrap();
assert_eq!(clocktime.nseconds(), None);
let clocktime_json = "null";
let clocktime: ClockTime = serde_json::from_str(clocktime_json).unwrap();
assert_eq!(clocktime.nseconds(), None);
}
}

View file

@ -0,0 +1,114 @@
// Copyright (C) 2018 François Laignel <fengalin@free.fr>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use serde::de;
use serde::de::{Deserialize, Deserializer, Visitor};
use serde::ser::{Serialize, Serializer};
use std::fmt;
use ClockTime;
impl<'a> Serialize for ClockTime {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
match self.nanoseconds() {
Some(ref value) => serializer.serialize_some(value),
None => serializer.serialize_none(),
}
}
}
struct ClockTimeVisitor;
impl<'de> Visitor<'de> for ClockTimeVisitor {
type Value = ClockTime;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an optional u64 ClockTime with ns precision")
}
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
u64::deserialize(deserializer)
.and_then(|value| Ok(ClockTime::from_nseconds(value)))
}
fn visit_none<E: de::Error>(self) -> Result<Self::Value, E> {
Ok(ClockTime(None))
}
}
impl<'de> Deserialize<'de> for ClockTime {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_option(ClockTimeVisitor)
}
}
#[cfg(test)]
mod tests {
extern crate ron;
extern crate serde_json;
use ClockTime;
#[test]
fn test_serialize() {
::init().unwrap();
// Some
let clocktime = ClockTime::from_nseconds(42_123_456_789);
let mut pretty_config = ron::ser::PrettyConfig::default();
pretty_config.new_line = "".to_string();
let res = ron::ser::to_string_pretty(&clocktime, pretty_config.clone());
assert_eq!(Ok("Some(42123456789)".to_owned()), res);
let res = serde_json::to_string(&clocktime).unwrap();
assert_eq!("42123456789".to_owned(), res);
// None
let clocktime = ClockTime(None);
let res = ron::ser::to_string_pretty(&clocktime, pretty_config);
assert_eq!(Ok("None".to_owned()), res);
let res = serde_json::to_string(&clocktime).unwrap();
assert_eq!("null".to_owned(), res);
}
#[test]
fn test_deserialize() {
::init().unwrap();
// Some
let clocktime_ron = "Some(42123456789)";
let clocktime: ClockTime = ron::de::from_str(clocktime_ron).unwrap();
assert_eq!(clocktime.seconds(), Some(42));
assert_eq!(clocktime.mseconds(), Some(42_123));
assert_eq!(clocktime.useconds(), Some(42_123_456));
assert_eq!(clocktime.nseconds(), Some(42_123_456_789));
let clocktime_json = "42123456789";
let clocktime: ClockTime = serde_json::from_str(clocktime_json).unwrap();
assert_eq!(clocktime.seconds(), Some(42));
assert_eq!(clocktime.mseconds(), Some(42_123));
assert_eq!(clocktime.useconds(), Some(42_123_456));
assert_eq!(clocktime.nseconds(), Some(42_123_456_789));
// None
let clocktime_ron = "None";
let clocktime: ClockTime = ron::de::from_str(clocktime_ron).unwrap();
assert_eq!(clocktime.nseconds(), None);
let clocktime_json = "null";
let clocktime: ClockTime = serde_json::from_str(clocktime_json).unwrap();
assert_eq!(clocktime.nseconds(), None);
}
}

View file

@ -18,151 +18,3 @@ impl fmt::Display for DateTime {
)
}
}
#[cfg(feature = "ser_de")]
pub(crate) mod serde {
use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer, SerializeStruct};
use DateTime;
impl<'a> Serialize for DateTime {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut datetime = serializer.serialize_struct("DateTime", 8)?;
datetime.serialize_field("tz_offset", &self.get_time_zone_offset())?;
datetime.serialize_field("y", &self.get_year())?;
datetime.serialize_field("m", &self.get_month())?;
datetime.serialize_field("d", &self.get_day())?;
datetime.serialize_field("h", &self.get_hour())?;
datetime.serialize_field("mn", &self.get_minute())?;
datetime.serialize_field("s", &self.get_second())?;
datetime.serialize_field("us", &self.get_microsecond())?;
datetime.end()
}
}
#[derive(Deserialize)]
struct DateTimeDe {
tz_offset: f32,
y: i32,
m: i32,
d: i32,
h: i32,
mn: i32,
s: i32,
us: i32,
}
impl From<DateTimeDe> for DateTime {
fn from(dt_de: DateTimeDe) -> Self {
::DateTime::new(
dt_de.tz_offset,
dt_de.y,
dt_de.m,
dt_de.d,
dt_de.h,
dt_de.mn,
f64::from(dt_de.s) + f64::from(dt_de.us) / 1_000_000f64,
)
}
}
impl<'de> Deserialize<'de> for DateTime {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
DateTimeDe::deserialize(deserializer)
.and_then(|datetime_de| Ok(datetime_de.into()))
}
}
}
#[cfg(test)]
mod tests {
#[cfg(feature = "ser_de")]
#[test]
fn test_serialize() {
extern crate ron;
extern crate serde_json;
use DateTime;
::init().unwrap();
let datetime = DateTime::new(2f32, 2018, 5, 28, 16, 6, 42.841f64);
// don't use newlines
let mut pretty_config = ron::ser::PrettyConfig::default();
pretty_config.new_line = "".to_string();
let res = ron::ser::to_string_pretty(&datetime, pretty_config);
assert_eq!(
Ok(
concat!(
"(",
" tz_offset: 2,",
" y: 2018,",
" m: 5,",
" d: 28,",
" h: 16,",
" mn: 6,",
" s: 42,",
" us: 841000,",
")"
)
.to_owned()
),
res,
);
let res = serde_json::to_string(&datetime).unwrap();
assert_eq!(
"{\"tz_offset\":2.0,\"y\":2018,\"m\":5,\"d\":28,\"h\":16,\"mn\":6,\"s\":42,\"us\":841000}"
.to_owned(),
res,
);
}
#[cfg(feature = "ser_de")]
#[test]
fn test_deserialize() {
extern crate ron;
extern crate serde_json;
use DateTime;
::init().unwrap();
let datetime_ron = r#"
(
tz_offset: 2,
y: 2018,
m: 5,
d: 28,
h: 16,
mn: 6,
s: 42,
us: 841000,
)
"#;
let datetime: DateTime = ron::de::from_str(datetime_ron).unwrap();
assert_eq!(datetime.get_time_zone_offset(), 2f32);
assert_eq!(datetime.get_year(), 2018);
assert_eq!(datetime.get_month(), 5);
assert_eq!(datetime.get_day(), 28);
assert_eq!(datetime.get_hour(), 16);
assert_eq!(datetime.get_minute(), 6);
assert_eq!(datetime.get_second(), 42);
assert_eq!(datetime.get_microsecond(), 841_000);
let datetime_json = r#"
{"tz_offset":2.0,"y":2018,"m":5,"d":28,"h":16,"mn":6,"s":42,"us":841000}
"#;
let datetime: DateTime = serde_json::from_str(datetime_json).unwrap();
assert_eq!(datetime.get_time_zone_offset(), 2f32);
assert_eq!(datetime.get_year(), 2018);
assert_eq!(datetime.get_month(), 5);
assert_eq!(datetime.get_day(), 28);
assert_eq!(datetime.get_hour(), 16);
assert_eq!(datetime.get_minute(), 6);
assert_eq!(datetime.get_second(), 42);
assert_eq!(datetime.get_microsecond(), 841_000);
}
}

View file

@ -0,0 +1,144 @@
// Copyright (C) 2018 François Laignel <fengalin@free.fr>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer, SerializeStruct};
use DateTime;
impl<'a> Serialize for DateTime {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut datetime = serializer.serialize_struct("DateTime", 8)?;
datetime.serialize_field("tz_offset", &self.get_time_zone_offset())?;
datetime.serialize_field("y", &self.get_year())?;
datetime.serialize_field("m", &self.get_month())?;
datetime.serialize_field("d", &self.get_day())?;
datetime.serialize_field("h", &self.get_hour())?;
datetime.serialize_field("mn", &self.get_minute())?;
datetime.serialize_field("s", &self.get_second())?;
datetime.serialize_field("us", &self.get_microsecond())?;
datetime.end()
}
}
#[derive(Deserialize)]
struct DateTimeDe {
tz_offset: f32,
y: i32,
m: i32,
d: i32,
h: i32,
mn: i32,
s: i32,
us: i32,
}
impl From<DateTimeDe> for DateTime {
fn from(dt_de: DateTimeDe) -> Self {
::DateTime::new(
dt_de.tz_offset,
dt_de.y,
dt_de.m,
dt_de.d,
dt_de.h,
dt_de.mn,
f64::from(dt_de.s) + f64::from(dt_de.us) / 1_000_000f64,
)
}
}
impl<'de> Deserialize<'de> for DateTime {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
DateTimeDe::deserialize(deserializer)
.and_then(|datetime_de| Ok(datetime_de.into()))
}
}
#[cfg(test)]
mod tests {
extern crate ron;
extern crate serde_json;
use DateTime;
#[test]
fn test_serialize() {
::init().unwrap();
let datetime = DateTime::new(2f32, 2018, 5, 28, 16, 6, 42.841f64);
let mut pretty_config = ron::ser::PrettyConfig::default();
pretty_config.new_line = "".to_string();
let res = ron::ser::to_string_pretty(&datetime, pretty_config);
assert_eq!(
Ok(
concat!(
"(",
" tz_offset: 2,",
" y: 2018,",
" m: 5,",
" d: 28,",
" h: 16,",
" mn: 6,",
" s: 42,",
" us: 841000,",
")"
)
.to_owned()
),
res,
);
let res = serde_json::to_string(&datetime).unwrap();
assert_eq!(
"{\"tz_offset\":2.0,\"y\":2018,\"m\":5,\"d\":28,\"h\":16,\"mn\":6,\"s\":42,\"us\":841000}"
.to_owned(),
res,
);
}
#[test]
fn test_deserialize() {
::init().unwrap();
let datetime_ron = r#"
(
tz_offset: 2,
y: 2018,
m: 5,
d: 28,
h: 16,
mn: 6,
s: 42,
us: 841000,
)
"#;
let datetime: DateTime = ron::de::from_str(datetime_ron).unwrap();
assert_eq!(datetime.get_time_zone_offset(), 2f32);
assert_eq!(datetime.get_year(), 2018);
assert_eq!(datetime.get_month(), 5);
assert_eq!(datetime.get_day(), 28);
assert_eq!(datetime.get_hour(), 16);
assert_eq!(datetime.get_minute(), 6);
assert_eq!(datetime.get_second(), 42);
assert_eq!(datetime.get_microsecond(), 841_000);
let datetime_json = r#"
{"tz_offset":2.0,"y":2018,"m":5,"d":28,"h":16,"mn":6,"s":42,"us":841000}
"#;
let datetime: DateTime = serde_json::from_str(datetime_json).unwrap();
assert_eq!(datetime.get_time_zone_offset(), 2f32);
assert_eq!(datetime.get_year(), 2018);
assert_eq!(datetime.get_month(), 5);
assert_eq!(datetime.get_day(), 28);
assert_eq!(datetime.get_hour(), 16);
assert_eq!(datetime.get_minute(), 6);
assert_eq!(datetime.get_second(), 42);
assert_eq!(datetime.get_microsecond(), 841_000);
}
}

View file

@ -504,7 +504,6 @@ mod tests {
::init().unwrap();
// don't use newlines
let mut pretty_config = ron::ser::PrettyConfig::default();
pretty_config.new_line = "".to_string();

View file

@ -75,23 +75,45 @@ pub mod miniobject;
pub use miniobject::{GstRc, MiniObject};
pub mod message;
pub use message::{Message, MessageErrorDomain, MessageRef, MessageView};
#[macro_use]
mod value;
pub use value::*;
#[cfg(feature = "ser_de")]
#[macro_use]
pub(crate) mod value_serde;
pub mod structure;
pub use structure::{Structure, StructureRef};
#[cfg(feature = "ser_de")]
pub(crate) mod structure_serde;
pub mod caps;
pub use caps::{Caps, CapsRef};
#[cfg(feature = "ser_de")]
pub(crate) mod caps_serde;
pub mod tags;
pub use tags::{Tag, TagList, TagListRef};
#[cfg(feature = "ser_de")]
pub(crate) mod tags_serde;
pub mod buffer;
pub use buffer::{
Buffer, BufferMap, BufferRef, MappedBuffer, BUFFER_COPY_ALL, BUFFER_COPY_METADATA,
};
#[cfg(feature = "ser_de")]
pub(crate) mod buffer_serde;
pub mod sample;
pub use sample::{Sample, SampleRef};
#[cfg(feature = "ser_de")]
pub(crate) mod sample_serde;
pub mod bufferlist;
pub use bufferlist::{BufferList, BufferListRef};
#[cfg(feature = "ser_de")]
pub(crate) mod bufferlist_serde;
pub mod query;
pub use query::{Query, QueryRef, QueryView};
pub mod event;
@ -128,7 +150,11 @@ cfg_if! {
mod child_proxy;
mod clock_time;
#[cfg(feature = "ser_de")]
pub(crate) mod clock_time_serde;
mod date_time;
#[cfg(feature = "ser_de")]
mod date_time_serde;
mod device_monitor;
mod device_provider;
mod enums;
@ -191,9 +217,13 @@ pub use format::{FormattedValue, GenericFormattedValue, SpecificFormattedValue};
mod segment;
pub use segment::*;
#[cfg(feature = "ser_de")]
pub(crate) mod segment_serde;
pub mod toc;
pub use toc::{Toc, TocEntry, TocEntryRef, TocRef};
#[cfg(feature = "ser_de")]
pub(crate) mod toc_serde;
mod clock;
pub use clock::{ClockExtManual, ClockId};

View file

@ -127,75 +127,6 @@ impl fmt::Debug for SampleRef {
unsafe impl Sync for SampleRef {}
unsafe impl Send for SampleRef {}
#[cfg(feature = "ser_de")]
pub(crate) mod serde {
use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer, SerializeStruct};
use Buffer;
use BufferList;
use Caps;
use GenericFormattedValue;
use Sample;
use SampleRef;
use Segment;
use Structure;
impl<'a> Serialize for SampleRef {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut sample = serializer.serialize_struct("Sample", 5)?;
sample.serialize_field("buffer", &self.get_buffer())?;
sample.serialize_field("buffer_list", &self.get_buffer_list())?;
sample.serialize_field("caps", &self.get_caps())?;
sample.serialize_field("segment", &self.get_segment())?;
sample.serialize_field("info", &self.get_info())?;
sample.end()
}
}
impl<'a> Serialize for Sample {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.as_ref().serialize(serializer)
}
}
#[derive(Deserialize)]
struct SampleDe {
buffer: Option<Buffer>,
buffer_list: Option<BufferList>,
caps: Option<Caps>,
segment: Option<Segment>,
info: Option<Structure>,
}
impl From<SampleDe> for Sample {
fn from(mut buf_de: SampleDe) -> Self {
if buf_de.buffer.is_some() {
Sample::new::<GenericFormattedValue>(
buf_de.buffer.as_ref(),
buf_de.caps.as_ref(),
buf_de.segment.as_ref(),
buf_de.info.take(),
)
} else {
Sample::with_buffer_list::<GenericFormattedValue>(
buf_de.buffer_list.as_ref(),
buf_de.caps.as_ref(),
buf_de.segment.as_ref(),
buf_de.info.take(),
)
}
}
}
impl<'de> Deserialize<'de> for Sample {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
SampleDe::deserialize(deserializer)
.and_then(|sample_de| Ok(sample_de.into()))
}
}
}
#[cfg(test)]
mod tests {
@ -214,258 +145,4 @@ mod tests {
assert!(sample.get_info().is_some());
}
#[cfg(feature = "ser_de")]
#[test]
fn test_serialize() {
extern crate ron;
use Buffer;
use Caps;
use ClockTime;
use Format;
use GenericFormattedValue;
use Sample;
use Segment;
use SegmentFlags;
use Structure;
::init().unwrap();
let mut pretty_config = ron::ser::PrettyConfig::default();
pretty_config.new_line = "".to_string();
let sample = {
let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]).unwrap();
{
let buffer = buffer.get_mut().unwrap();
buffer.set_pts(1.into());
buffer.set_offset(0);
buffer.set_offset_end(4);
buffer.set_duration(4.into());
}
let caps = Caps::builder("sample/caps")
.field("int", &12)
.field("bool", &true)
.build();
let mut segment = Segment::new();
segment.set_flags(SegmentFlags::RESET | SegmentFlags::SEGMENT);
segment.set_rate(1f64);
segment.set_applied_rate(0.9f64);
segment.set_format(Format::Time);
segment.set_base(GenericFormattedValue::Time(ClockTime::from_nseconds(123)));
segment.set_offset(GenericFormattedValue::Time(ClockTime::from_nseconds(42)));
segment.set_start(GenericFormattedValue::Time(ClockTime::from_nseconds(1024)));
segment.set_stop(GenericFormattedValue::Time(ClockTime::from_nseconds(2048)));
segment.set_time(GenericFormattedValue::Time(ClockTime::from_nseconds(1042)));
segment.set_position(GenericFormattedValue::Time(ClockTime::from_nseconds(256)));
segment.set_duration(GenericFormattedValue::Time(ClockTime::none()));
let info = Structure::builder("sample.info")
.field("f3", &123i32)
.build();
Sample::new::<GenericFormattedValue>(
Some(&buffer),
Some(&caps),
Some(&segment),
Some(info),
)
};
let res = ron::ser::to_string_pretty(&sample, pretty_config.clone());
assert_eq!(
Ok(
concat!(
"(",
" buffer: Some((",
" pts: Some(1),",
" dts: None,",
" duration: Some(4),",
" offset: 0,",
" offset_end: 4,",
" flags: (",
" bits: 0,",
" ),",
" buffer: \"AQIDBA==\",",
" )),",
" buffer_list: None,",
" caps: Some([",
" (\"sample/caps\", [",
" (\"int\", \"i32\", 12),",
" (\"bool\", \"bool\", true),",
" ]),",
" ]),",
" segment: Some((",
" flags: (",
" bits: 9,",
" ),",
" rate: 1,",
" applied_rate: 0.9,",
" format: Time,",
" base: 123,",
" offset: 42,",
" start: 1024,",
" stop: 2048,",
" time: 1042,",
" position: 256,",
" duration: -1,",
" )),",
" info: Some((\"sample.info\", [",
" (\"f3\", \"i32\", 123),",
" ])),",
")"
)
.to_owned()
),
res
);
let sample = {
let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]).unwrap();
{
let buffer = buffer.get_mut().unwrap();
buffer.set_pts(1.into());
buffer.set_offset(0);
buffer.set_offset_end(4);
buffer.set_duration(4.into());
}
Sample::new::<GenericFormattedValue>(Some(&buffer), None, None, None)
};
// `Sample`'s `Segment` is allocated in GStreamer 1.x, should be fixed in version 2.0
let res = ron::ser::to_string_pretty(&sample, pretty_config);
assert_eq!(
Ok(
concat!(
"(",
" buffer: Some((",
" pts: Some(1),",
" dts: None,",
" duration: Some(4),",
" offset: 0,",
" offset_end: 4,",
" flags: (",
" bits: 0,",
" ),",
" buffer: \"AQIDBA==\",",
" )),",
" buffer_list: None,",
" caps: None,",
" segment: Some((",
" flags: (",
" bits: 0,",
" ),",
" rate: 1,",
" applied_rate: 1,",
" format: Time,",
" base: 0,",
" offset: 0,",
" start: 0,",
" stop: -1,",
" time: 0,",
" position: 0,",
" duration: -1,",
" )),",
" info: None,",
")"
)
.to_owned()
),
res
);
}
#[cfg(feature = "ser_de")]
#[test]
fn test_deserialize() {
extern crate ron;
use Sample;
::init().unwrap();
let buffer_ron = r#"
(
buffer: Some((
pts: Some(1),
dts: None,
duration: Some(4),
offset: 0,
offset_end: 4,
flags: (
bits: 0,
),
buffer: "AQIDBA==",
)),
buffer_list: None,
caps: Some([
("sample/caps", [
("int", "i32", 12),
("bool", "bool", true),
]),
]),
segment: Some((
flags: (
bits: 0,
),
rate: 1,
applied_rate: 0.9,
format: Time,
base: 123,
offset: 42,
start: 1024,
stop: 2048,
time: 1042,
position: 256,
duration: -1,
)),
info: Some(("sample.info", [
("f3", "i32", 123),
])),
)"#;
let sample: Sample = ron::de::from_str(buffer_ron).unwrap();
let buffer = sample.get_buffer().unwrap();
assert_eq!(buffer.get_pts(), 1.into());
assert_eq!(buffer.get_offset_end(), 4);
{
let data = buffer.map_readable().unwrap();
assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
}
assert!(sample.get_buffer_list().is_none());
assert!(sample.get_caps().is_some());
assert!(sample.get_segment().is_some());
assert!(sample.get_info().is_some());
let buffer_ron = r#"
(
buffer: None,
buffer_list: Some([
(
pts: Some(1),
dts: None,
duration: Some(4),
offset: 0,
offset_end: 4,
flags: (
bits: 0,
),
buffer: "AQIDBA==",
),
]),
caps: None,
segment: None,
info: None,
)"#;
let sample: Sample = ron::de::from_str(buffer_ron).unwrap();
assert!(sample.get_buffer().is_none());
assert!(sample.get_buffer_list().is_some());
assert!(sample.get_caps().is_none());
// Not true in GStreamer 1.x, should be fixed in version 2.0
//assert!(sample.get_segment().is_none());
assert!(sample.get_info().is_none());
}
}

View file

@ -0,0 +1,325 @@
// Copyright (C) 2018 François Laignel <fengalin@free.fr>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer, SerializeStruct};
use Buffer;
use BufferList;
use Caps;
use GenericFormattedValue;
use Sample;
use SampleRef;
use Segment;
use Structure;
impl<'a> Serialize for SampleRef {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut sample = serializer.serialize_struct("Sample", 5)?;
sample.serialize_field("buffer", &self.get_buffer())?;
sample.serialize_field("buffer_list", &self.get_buffer_list())?;
sample.serialize_field("caps", &self.get_caps())?;
sample.serialize_field("segment", &self.get_segment())?;
sample.serialize_field("info", &self.get_info())?;
sample.end()
}
}
impl<'a> Serialize for Sample {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.as_ref().serialize(serializer)
}
}
#[derive(Deserialize)]
struct SampleDe {
buffer: Option<Buffer>,
buffer_list: Option<BufferList>,
caps: Option<Caps>,
segment: Option<Segment>,
info: Option<Structure>,
}
impl From<SampleDe> for Sample {
fn from(mut buf_de: SampleDe) -> Self {
if buf_de.buffer.is_some() {
Sample::new::<GenericFormattedValue>(
buf_de.buffer.as_ref(),
buf_de.caps.as_ref(),
buf_de.segment.as_ref(),
buf_de.info.take(),
)
} else {
Sample::with_buffer_list::<GenericFormattedValue>(
buf_de.buffer_list.as_ref(),
buf_de.caps.as_ref(),
buf_de.segment.as_ref(),
buf_de.info.take(),
)
}
}
}
impl<'de> Deserialize<'de> for Sample {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
SampleDe::deserialize(deserializer)
.and_then(|sample_de| Ok(sample_de.into()))
}
}
#[cfg(test)]
mod tests {
extern crate ron;
use Sample;
#[test]
fn test_serialize() {
use Buffer;
use Caps;
use ClockTime;
use Format;
use GenericFormattedValue;
use Segment;
use SegmentFlags;
use Structure;
::init().unwrap();
let mut pretty_config = ron::ser::PrettyConfig::default();
pretty_config.new_line = "".to_string();
let sample = {
let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]).unwrap();
{
let buffer = buffer.get_mut().unwrap();
buffer.set_pts(1.into());
buffer.set_offset(0);
buffer.set_offset_end(4);
buffer.set_duration(4.into());
}
let caps = Caps::builder("sample/caps")
.field("int", &12)
.field("bool", &true)
.build();
let mut segment = Segment::new();
segment.set_flags(SegmentFlags::RESET | SegmentFlags::SEGMENT);
segment.set_rate(1f64);
segment.set_applied_rate(0.9f64);
segment.set_format(Format::Time);
segment.set_base(GenericFormattedValue::Time(ClockTime::from_nseconds(123)));
segment.set_offset(GenericFormattedValue::Time(ClockTime::from_nseconds(42)));
segment.set_start(GenericFormattedValue::Time(ClockTime::from_nseconds(1024)));
segment.set_stop(GenericFormattedValue::Time(ClockTime::from_nseconds(2048)));
segment.set_time(GenericFormattedValue::Time(ClockTime::from_nseconds(1042)));
segment.set_position(GenericFormattedValue::Time(ClockTime::from_nseconds(256)));
segment.set_duration(GenericFormattedValue::Time(ClockTime::none()));
let info = Structure::builder("sample.info")
.field("f3", &123i32)
.build();
Sample::new::<GenericFormattedValue>(
Some(&buffer),
Some(&caps),
Some(&segment),
Some(info),
)
};
let res = ron::ser::to_string_pretty(&sample, pretty_config.clone());
assert_eq!(
Ok(
concat!(
"(",
" buffer: Some((",
" pts: Some(1),",
" dts: None,",
" duration: Some(4),",
" offset: 0,",
" offset_end: 4,",
" flags: (",
" bits: 0,",
" ),",
" buffer: \"AQIDBA==\",",
" )),",
" buffer_list: None,",
" caps: Some([",
" (\"sample/caps\", [",
" (\"int\", \"i32\", 12),",
" (\"bool\", \"bool\", true),",
" ]),",
" ]),",
" segment: Some((",
" flags: (",
" bits: 9,",
" ),",
" rate: 1,",
" applied_rate: 0.9,",
" format: Time,",
" base: 123,",
" offset: 42,",
" start: 1024,",
" stop: 2048,",
" time: 1042,",
" position: 256,",
" duration: -1,",
" )),",
" info: Some((\"sample.info\", [",
" (\"f3\", \"i32\", 123),",
" ])),",
")"
)
.to_owned()
),
res
);
let sample = {
let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]).unwrap();
{
let buffer = buffer.get_mut().unwrap();
buffer.set_pts(1.into());
buffer.set_offset(0);
buffer.set_offset_end(4);
buffer.set_duration(4.into());
}
Sample::new::<GenericFormattedValue>(Some(&buffer), None, None, None)
};
// `Sample`'s `Segment` is allocated in GStreamer 1.x, should be fixed in version 2.0
let res = ron::ser::to_string_pretty(&sample, pretty_config);
assert_eq!(
Ok(
concat!(
"(",
" buffer: Some((",
" pts: Some(1),",
" dts: None,",
" duration: Some(4),",
" offset: 0,",
" offset_end: 4,",
" flags: (",
" bits: 0,",
" ),",
" buffer: \"AQIDBA==\",",
" )),",
" buffer_list: None,",
" caps: None,",
" segment: Some((",
" flags: (",
" bits: 0,",
" ),",
" rate: 1,",
" applied_rate: 1,",
" format: Time,",
" base: 0,",
" offset: 0,",
" start: 0,",
" stop: -1,",
" time: 0,",
" position: 0,",
" duration: -1,",
" )),",
" info: None,",
")"
)
.to_owned()
),
res
);
}
#[test]
fn test_deserialize() {
::init().unwrap();
let buffer_ron = r#"
(
buffer: Some((
pts: Some(1),
dts: None,
duration: Some(4),
offset: 0,
offset_end: 4,
flags: (
bits: 0,
),
buffer: "AQIDBA==",
)),
buffer_list: None,
caps: Some([
("sample/caps", [
("int", "i32", 12),
("bool", "bool", true),
]),
]),
segment: Some((
flags: (
bits: 0,
),
rate: 1,
applied_rate: 0.9,
format: Time,
base: 123,
offset: 42,
start: 1024,
stop: 2048,
time: 1042,
position: 256,
duration: -1,
)),
info: Some(("sample.info", [
("f3", "i32", 123),
])),
)"#;
let sample: Sample = ron::de::from_str(buffer_ron).unwrap();
let buffer = sample.get_buffer().unwrap();
assert_eq!(buffer.get_pts(), 1.into());
assert_eq!(buffer.get_offset_end(), 4);
{
let data = buffer.map_readable().unwrap();
assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
}
assert!(sample.get_buffer_list().is_none());
assert!(sample.get_caps().is_some());
assert!(sample.get_segment().is_some());
assert!(sample.get_info().is_some());
let buffer_ron = r#"
(
buffer: None,
buffer_list: Some([
(
pts: Some(1),
dts: None,
duration: Some(4),
offset: 0,
offset_end: 4,
flags: (
bits: 0,
),
buffer: "AQIDBA==",
),
]),
caps: None,
segment: None,
info: None,
)"#;
let sample: Sample = ron::de::from_str(buffer_ron).unwrap();
assert!(sample.get_buffer().is_none());
assert!(sample.get_buffer_list().is_some());
assert!(sample.get_caps().is_none());
// Not true in GStreamer 1.x, should be fixed in version 2.0
//assert!(sample.get_segment().is_none());
assert!(sample.get_info().is_none());
}
}

View file

@ -655,176 +655,3 @@ impl glib::translate::FromGlibPtrFull<*mut ffi::GstSegment> for Segment {
segment
}
}
#[cfg(feature = "ser_de")]
pub(crate) mod serde {
use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer, SerializeStruct};
use Format;
use GenericFormattedValue;
use Segment;
use SegmentFlags;
impl<'a> Serialize for Segment {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut datetime = serializer.serialize_struct("Segment", 11)?;
datetime.serialize_field("flags", &self.get_flags())?;
datetime.serialize_field("rate", &self.get_rate())?;
datetime.serialize_field("applied_rate", &self.get_applied_rate())?;
datetime.serialize_field("format", &self.get_format())?;
datetime.serialize_field("base", &self.get_base().get_value())?;
datetime.serialize_field("offset", &self.get_offset().get_value())?;
datetime.serialize_field("start", &self.get_start().get_value())?;
datetime.serialize_field("stop", &self.get_stop().get_value())?;
datetime.serialize_field("time", &self.get_time().get_value())?;
datetime.serialize_field("position", &self.get_position().get_value())?;
datetime.serialize_field("duration", &self.get_duration().get_value())?;
datetime.end()
}
}
#[derive(Deserialize)]
struct SegmentDe {
flags: SegmentFlags,
rate: f64,
applied_rate: f64,
format: Format,
base: i64,
offset: i64,
start: i64,
stop: i64,
time: i64,
position: i64,
duration: i64,
}
impl From<SegmentDe> for Segment {
fn from(segment_de: SegmentDe) -> Self {
let mut segment = Segment::new();
segment.set_flags(segment_de.flags);
segment.set_rate(segment_de.rate);
segment.set_applied_rate(segment_de.applied_rate);
segment.set_format(segment_de.format);
segment.set_base(GenericFormattedValue::new(segment_de.format, segment_de.base));
segment.set_offset(GenericFormattedValue::new(segment_de.format, segment_de.offset));
segment.set_start(GenericFormattedValue::new(segment_de.format, segment_de.start));
segment.set_stop(GenericFormattedValue::new(segment_de.format, segment_de.stop));
segment.set_time(GenericFormattedValue::new(segment_de.format, segment_de.time));
segment.set_position(GenericFormattedValue::new(segment_de.format, segment_de.position));
segment.set_duration(GenericFormattedValue::new(segment_de.format, segment_de.duration));
segment
}
}
impl<'de> Deserialize<'de> for Segment {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
SegmentDe::deserialize(deserializer)
.and_then(|segment_de| Ok(segment_de.into()))
}
}
}
#[cfg(test)]
mod tests {
#[cfg(feature = "ser_de")]
#[test]
fn test_serialize() {
extern crate ron;
use ClockTime;
use Format;
use GenericFormattedValue;
use Segment;
use SegmentFlags;
::init().unwrap();
let mut segment = Segment::new();
segment.set_flags(SegmentFlags::RESET | SegmentFlags::SEGMENT);
segment.set_rate(1f64);
segment.set_applied_rate(0.9f64);
segment.set_format(Format::Time);
segment.set_base(GenericFormattedValue::Time(ClockTime::from_nseconds(123)));
segment.set_offset(GenericFormattedValue::Time(ClockTime::from_nseconds(42)));
segment.set_start(GenericFormattedValue::Time(ClockTime::from_nseconds(1024)));
segment.set_stop(GenericFormattedValue::Time(ClockTime::from_nseconds(2048)));
segment.set_time(GenericFormattedValue::Time(ClockTime::from_nseconds(1042)));
segment.set_position(GenericFormattedValue::Time(ClockTime::from_nseconds(256)));
segment.set_duration(GenericFormattedValue::Time(ClockTime::none()));
let mut pretty_config = ron::ser::PrettyConfig::default();
pretty_config.new_line = "".to_string();
let res = ron::ser::to_string_pretty(&segment, pretty_config);
assert_eq!(
Ok(
concat!(
"(",
" flags: (",
" bits: 9,",
" ),",
" rate: 1,",
" applied_rate: 0.9,",
" format: Time,",
" base: 123,",
" offset: 42,",
" start: 1024,",
" stop: 2048,",
" time: 1042,",
" position: 256,",
" duration: -1,",
")"
)
.to_owned()
),
res,
);
}
#[cfg(feature = "ser_de")]
#[test]
fn test_deserialize() {
extern crate ron;
use ClockTime;
use Format;
use GenericFormattedValue;
use Segment;
use SegmentFlags;
::init().unwrap();
let segment_ron = r#"
(
flags: (
bits: 9,
),
rate: 1,
applied_rate: 0.9,
format: Time,
base: 123,
offset: 42,
start: 1024,
stop: 2048,
time: 1042,
position: 256,
duration: -1,
)
"#;
let segment: Segment = ron::de::from_str(segment_ron).unwrap();
assert_eq!(segment.get_flags(), SegmentFlags::RESET | SegmentFlags::SEGMENT);
assert_eq!(segment.get_rate(), 1f64);
assert_eq!(segment.get_applied_rate(), 0.9f64);
assert_eq!(segment.get_format(), Format::Time);
assert_eq!(segment.get_base(), GenericFormattedValue::Time(ClockTime::from_nseconds(123)));
assert_eq!(segment.get_offset(), GenericFormattedValue::Time(ClockTime::from_nseconds(42)));
assert_eq!(segment.get_start(), GenericFormattedValue::Time(ClockTime::from_nseconds(1024)));
assert_eq!(segment.get_stop(), GenericFormattedValue::Time(ClockTime::from_nseconds(2048)));
assert_eq!(segment.get_time(), GenericFormattedValue::Time(ClockTime::from_nseconds(1042)));
assert_eq!(segment.get_position(), GenericFormattedValue::Time(ClockTime::from_nseconds(256)));
assert_eq!(segment.get_duration(), GenericFormattedValue::Time(ClockTime::none()));
}
}

View file

@ -0,0 +1,167 @@
// Copyright (C) 2018 François Laignel <fengalin@free.fr>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer, SerializeStruct};
use Format;
use GenericFormattedValue;
use Segment;
use SegmentFlags;
impl<'a> Serialize for Segment {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut datetime = serializer.serialize_struct("Segment", 11)?;
datetime.serialize_field("flags", &self.get_flags())?;
datetime.serialize_field("rate", &self.get_rate())?;
datetime.serialize_field("applied_rate", &self.get_applied_rate())?;
datetime.serialize_field("format", &self.get_format())?;
datetime.serialize_field("base", &self.get_base().get_value())?;
datetime.serialize_field("offset", &self.get_offset().get_value())?;
datetime.serialize_field("start", &self.get_start().get_value())?;
datetime.serialize_field("stop", &self.get_stop().get_value())?;
datetime.serialize_field("time", &self.get_time().get_value())?;
datetime.serialize_field("position", &self.get_position().get_value())?;
datetime.serialize_field("duration", &self.get_duration().get_value())?;
datetime.end()
}
}
#[derive(Deserialize)]
struct SegmentDe {
flags: SegmentFlags,
rate: f64,
applied_rate: f64,
format: Format,
base: i64,
offset: i64,
start: i64,
stop: i64,
time: i64,
position: i64,
duration: i64,
}
impl From<SegmentDe> for Segment {
fn from(segment_de: SegmentDe) -> Self {
let mut segment = Segment::new();
segment.set_flags(segment_de.flags);
segment.set_rate(segment_de.rate);
segment.set_applied_rate(segment_de.applied_rate);
segment.set_format(segment_de.format);
segment.set_base(GenericFormattedValue::new(segment_de.format, segment_de.base));
segment.set_offset(GenericFormattedValue::new(segment_de.format, segment_de.offset));
segment.set_start(GenericFormattedValue::new(segment_de.format, segment_de.start));
segment.set_stop(GenericFormattedValue::new(segment_de.format, segment_de.stop));
segment.set_time(GenericFormattedValue::new(segment_de.format, segment_de.time));
segment.set_position(GenericFormattedValue::new(segment_de.format, segment_de.position));
segment.set_duration(GenericFormattedValue::new(segment_de.format, segment_de.duration));
segment
}
}
impl<'de> Deserialize<'de> for Segment {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
SegmentDe::deserialize(deserializer)
.and_then(|segment_de| Ok(segment_de.into()))
}
}
#[cfg(test)]
mod tests {
extern crate ron;
use ClockTime;
use Format;
use GenericFormattedValue;
use Segment;
use SegmentFlags;
#[test]
fn test_serialize() {
::init().unwrap();
let mut segment = Segment::new();
segment.set_flags(SegmentFlags::RESET | SegmentFlags::SEGMENT);
segment.set_rate(1f64);
segment.set_applied_rate(0.9f64);
segment.set_format(Format::Time);
segment.set_base(GenericFormattedValue::Time(ClockTime::from_nseconds(123)));
segment.set_offset(GenericFormattedValue::Time(ClockTime::from_nseconds(42)));
segment.set_start(GenericFormattedValue::Time(ClockTime::from_nseconds(1024)));
segment.set_stop(GenericFormattedValue::Time(ClockTime::from_nseconds(2048)));
segment.set_time(GenericFormattedValue::Time(ClockTime::from_nseconds(1042)));
segment.set_position(GenericFormattedValue::Time(ClockTime::from_nseconds(256)));
segment.set_duration(GenericFormattedValue::Time(ClockTime::none()));
let mut pretty_config = ron::ser::PrettyConfig::default();
pretty_config.new_line = "".to_string();
let res = ron::ser::to_string_pretty(&segment, pretty_config);
assert_eq!(
Ok(
concat!(
"(",
" flags: (",
" bits: 9,",
" ),",
" rate: 1,",
" applied_rate: 0.9,",
" format: Time,",
" base: 123,",
" offset: 42,",
" start: 1024,",
" stop: 2048,",
" time: 1042,",
" position: 256,",
" duration: -1,",
")"
)
.to_owned()
),
res,
);
}
#[test]
fn test_deserialize() {
::init().unwrap();
let segment_ron = r#"
(
flags: (
bits: 9,
),
rate: 1,
applied_rate: 0.9,
format: Time,
base: 123,
offset: 42,
start: 1024,
stop: 2048,
time: 1042,
position: 256,
duration: -1,
)
"#;
let segment: Segment = ron::de::from_str(segment_ron).unwrap();
assert_eq!(segment.get_flags(), SegmentFlags::RESET | SegmentFlags::SEGMENT);
assert_eq!(segment.get_rate(), 1f64);
assert_eq!(segment.get_applied_rate(), 0.9f64);
assert_eq!(segment.get_format(), Format::Time);
assert_eq!(segment.get_base(), GenericFormattedValue::Time(ClockTime::from_nseconds(123)));
assert_eq!(segment.get_offset(), GenericFormattedValue::Time(ClockTime::from_nseconds(42)));
assert_eq!(segment.get_start(), GenericFormattedValue::Time(ClockTime::from_nseconds(1024)));
assert_eq!(segment.get_stop(), GenericFormattedValue::Time(ClockTime::from_nseconds(2048)));
assert_eq!(segment.get_time(), GenericFormattedValue::Time(ClockTime::from_nseconds(1042)));
assert_eq!(segment.get_position(), GenericFormattedValue::Time(ClockTime::from_nseconds(256)));
assert_eq!(segment.get_duration(), GenericFormattedValue::Time(ClockTime::none()));
}
}

View file

@ -655,171 +655,6 @@ impl Builder {
}
}
#[cfg(feature = "ser_de")]
pub(crate) mod serde {
use glib;
use glib::ToValue;
use serde::de;
use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
use serde::ser;
use serde::ser::{Serialize, Serializer, SerializeSeq, SerializeTuple};
use std::fmt;
use DateTime;
use Sample;
use value::*;
use value::serde::*;
use Structure;
use StructureRef;
struct FieldSe<'a>(&'a str, &'a glib::SendValue);
impl<'a> Serialize for FieldSe<'a> {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
ser_value!(self.1, |type_, value| {
let mut tup = serializer.serialize_tuple(3)?;
tup.serialize_element(self.0)?;
tup.serialize_element(type_)?;
tup.serialize_element(&value)?;
tup.end()
})
}
}
struct StructureForIter<'a>(&'a StructureRef);
impl<'a> Serialize for StructureForIter<'a> {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let iter = self.0.iter();
let size = iter.size_hint().0;
if size > 0 {
let mut seq = serializer.serialize_seq(Some(size))?;
for field in iter {
seq.serialize_element(&FieldSe(field.0, field.1))?;
}
seq.end()
} else {
let seq = serializer.serialize_seq(None)?;
seq.end()
}
}
}
impl Serialize for StructureRef {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut tup = serializer.serialize_tuple(2)?;
tup.serialize_element(self.get_name())?;
tup.serialize_element(&StructureForIter(self))?;
tup.end()
}
}
impl Serialize for Structure {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.as_ref().serialize(serializer)
}
}
struct FieldDe(String, SendValue);
impl From<FieldDe> for (String, glib::SendValue) {
fn from(field_de: FieldDe) -> Self {
(field_de.0, field_de.1.into())
}
}
struct FieldVisitor;
impl<'de> Visitor<'de> for FieldVisitor {
type Value = FieldDe;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(
"a tuple of 3 elements (name: `String`, type name: `String`, value: `Value`)"
)
}
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
let name = seq.next_element::<String>()?
.ok_or(de::Error::custom("Expected a value for `Value` name, found `None`"))?;
let type_name = seq.next_element::<String>()?
.ok_or(de::Error::custom("Expected a value for `Value` type, found `None`"))?;
Ok(FieldDe(name, de_send_value!(type_name, seq)))
}
}
impl<'de> Deserialize<'de> for FieldDe {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_tuple(3, FieldVisitor)
}
}
// Use `NamelessStructure` to deserialize the `Field`s and
// to add them to the `Structure` at the same time.
struct NamelessStructure(Structure);
impl From<NamelessStructure> for Structure {
fn from(nameless_structure: NamelessStructure) -> Self {
nameless_structure.0
}
}
struct NamelessStructureVisitor;
impl<'de> Visitor<'de> for NamelessStructureVisitor {
type Value = NamelessStructure;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a nameless `Structure` consisting of a sequence of `Field`s)")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
// Can't build a `Structure` with an empty name
let mut structure = Structure::new_empty("None");
while let Some(field) = seq.next_element::<FieldDe>()? {
let (name, value): (String, glib::SendValue) = field.into();
structure.as_mut().set_value(name.as_str(), value);
}
Ok(NamelessStructure(structure))
}
}
impl<'de> Deserialize<'de> for NamelessStructure {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_seq(NamelessStructureVisitor)
}
}
struct StructureVisitor;
impl<'de> Visitor<'de> for StructureVisitor {
type Value = Structure;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a `Structure`: (name: `String`, fields: sequence of `Field`s)")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
let name = seq.next_element::<String>()?
.ok_or(de::Error::custom(
"Expected a name for the `Structure`, found `None`"
))?;
let mut structure: Structure = seq.next_element::<NamelessStructure>()?
.ok_or(de::Error::custom(
"Expected a sequence of `Field`s, found `None`"
))?
.into();
structure.set_name(name.as_str());
Ok(structure)
}
}
impl<'de> Deserialize<'de> for Structure {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_tuple(2, StructureVisitor)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
@ -880,82 +715,4 @@ mod tests {
assert_eq!(a, s.to_string());
}
#[cfg(feature = "ser_de")]
#[test]
fn test_serialize() {
extern crate ron;
use Array;
::init().unwrap();
let s = Structure::builder("test")
.field("f1", &"abc")
.field("f2", &String::from("bcd"))
.field("f3", &123i32)
.field("fraction", &Fraction::new(1, 2))
.field("array", &Array::new(&[&1, &2]))
.build();
// don't use newlines
let mut pretty_config = ron::ser::PrettyConfig::default();
pretty_config.new_line = "".to_string();
let res = ron::ser::to_string_pretty(&s, pretty_config);
assert_eq!(
Ok(
concat!(
"(\"test\", [",
" (\"f1\", \"String\", \"abc\"),",
" (\"f2\", \"String\", \"bcd\"),",
" (\"f3\", \"i32\", 123),",
" (\"fraction\", \"Fraction\", (1, 2)),",
" (\"array\", \"Array\", [",
" (\"i32\", 1),",
" (\"i32\", 2),",
" ]),",
"])"
)
.to_owned()
),
res,
);
}
#[cfg(feature = "ser_de")]
#[test]
fn test_deserialize() {
extern crate ron;
use Array;
::init().unwrap();
let s_ron = r#"
("test", [
("f1", "String", "abc"),
("f2", "String", "bcd"),
("f3", "i32", 123),
("fraction", "Fraction", (1, 2)),
("array", "Array", [
("i32", 1),
("i32", 2),
]),
])"#;
let s: Structure = ron::de::from_str(s_ron).unwrap();
assert_eq!(
s.as_ref(),
Structure::new(
"test",
&[
("f1", &"abc"),
("f2", &"bcd"),
("f3", &123),
("fraction", &Fraction::new(1, 2)),
("array", &Array::new(&[&1, &2])),
],
).as_ref()
);
}
}

View file

@ -0,0 +1,245 @@
// Copyright (C) 2018 François Laignel <fengalin@free.fr>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use glib;
use glib::ToValue;
use serde::de;
use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
use serde::ser;
use serde::ser::{Serialize, Serializer, SerializeSeq, SerializeTuple};
use std::fmt;
use DateTime;
use Sample;
use value::*;
use value_serde::*;
use Structure;
use StructureRef;
struct FieldSe<'a>(&'a str, &'a glib::SendValue);
impl<'a> Serialize for FieldSe<'a> {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
ser_value!(self.1, |type_, value| {
let mut tup = serializer.serialize_tuple(3)?;
tup.serialize_element(self.0)?;
tup.serialize_element(type_)?;
tup.serialize_element(&value)?;
tup.end()
})
}
}
struct StructureForIter<'a>(&'a StructureRef);
impl<'a> Serialize for StructureForIter<'a> {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let iter = self.0.iter();
let size = iter.size_hint().0;
if size > 0 {
let mut seq = serializer.serialize_seq(Some(size))?;
for field in iter {
seq.serialize_element(&FieldSe(field.0, field.1))?;
}
seq.end()
} else {
let seq = serializer.serialize_seq(None)?;
seq.end()
}
}
}
impl Serialize for StructureRef {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut tup = serializer.serialize_tuple(2)?;
tup.serialize_element(self.get_name())?;
tup.serialize_element(&StructureForIter(self))?;
tup.end()
}
}
impl Serialize for Structure {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.as_ref().serialize(serializer)
}
}
struct FieldDe(String, SendValue);
impl From<FieldDe> for (String, glib::SendValue) {
fn from(field_de: FieldDe) -> Self {
(field_de.0, field_de.1.into())
}
}
struct FieldVisitor;
impl<'de> Visitor<'de> for FieldVisitor {
type Value = FieldDe;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(
"a tuple of 3 elements (name: `String`, type name: `String`, value: `Value`)"
)
}
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
let name = seq.next_element::<String>()?
.ok_or(de::Error::custom("Expected a value for `Value` name"))?;
let type_name = seq.next_element::<String>()?
.ok_or(de::Error::custom("Expected a value for `Value` type"))?;
Ok(FieldDe(name, de_send_value!(type_name, seq)))
}
}
impl<'de> Deserialize<'de> for FieldDe {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_tuple(3, FieldVisitor)
}
}
// Use `NamelessStructure` to deserialize the `Field`s and
// to add them to the `Structure` at the same time.
struct NamelessStructure(Structure);
impl From<NamelessStructure> for Structure {
fn from(nameless_structure: NamelessStructure) -> Self {
nameless_structure.0
}
}
struct NamelessStructureVisitor;
impl<'de> Visitor<'de> for NamelessStructureVisitor {
type Value = NamelessStructure;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a nameless `Structure` consisting of a sequence of `Field`s)")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
// Can't build a `Structure` with an empty name
let mut structure = Structure::new_empty("None");
while let Some(field) = seq.next_element::<FieldDe>()? {
let (name, value): (String, glib::SendValue) = field.into();
structure.as_mut().set_value(name.as_str(), value);
}
Ok(NamelessStructure(structure))
}
}
impl<'de> Deserialize<'de> for NamelessStructure {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_seq(NamelessStructureVisitor)
}
}
struct StructureVisitor;
impl<'de> Visitor<'de> for StructureVisitor {
type Value = Structure;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a `Structure`: (name: `String`, fields: sequence of `Field`s)")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
let name = seq.next_element::<String>()?
.ok_or(de::Error::custom("Expected a name for the `Structure`"))?;
let mut structure: Structure = seq.next_element::<NamelessStructure>()?
.ok_or(de::Error::custom("Expected a sequence of `Field`s"))?
.into();
structure.set_name(name.as_str());
Ok(structure)
}
}
impl<'de> Deserialize<'de> for Structure {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_tuple(2, StructureVisitor)
}
}
#[cfg(test)]
mod tests {
extern crate ron;
use Structure;
#[test]
fn test_serialize() {
use Array;
use Fraction;
::init().unwrap();
let s = Structure::builder("test")
.field("f1", &"abc")
.field("f2", &String::from("bcd"))
.field("f3", &123i32)
.field("fraction", &Fraction::new(1, 2))
.field("array", &Array::new(&[&1, &2]))
.build();
let mut pretty_config = ron::ser::PrettyConfig::default();
pretty_config.new_line = "".to_string();
let res = ron::ser::to_string_pretty(&s, pretty_config);
assert_eq!(
Ok(
concat!(
"(\"test\", [",
" (\"f1\", \"String\", \"abc\"),",
" (\"f2\", \"String\", \"bcd\"),",
" (\"f3\", \"i32\", 123),",
" (\"fraction\", \"Fraction\", (1, 2)),",
" (\"array\", \"Array\", [",
" (\"i32\", 1),",
" (\"i32\", 2),",
" ]),",
"])"
)
.to_owned()
),
res,
);
}
#[test]
fn test_deserialize() {
use Array;
use Fraction;
::init().unwrap();
let s_ron = r#"
("test", [
("f1", "String", "abc"),
("f2", "String", "bcd"),
("f3", "i32", 123),
("fraction", "Fraction", (1, 2)),
("array", "Array", [
("i32", 1),
("i32", 2),
]),
])"#;
let s: Structure = ron::de::from_str(s_ron).unwrap();
assert_eq!(
s.as_ref(),
Structure::new(
"test",
&[
("f1", &"abc"),
("f2", &"bcd"),
("f3", &123),
("fraction", &Fraction::new(1, 2)),
("array", &Array::new(&[&1, &2])),
],
).as_ref()
);
}
}

View file

@ -522,232 +522,6 @@ impl StaticType for TagListRef {
}
}
#[cfg(feature = "ser_de")]
mod serde {
use glib::translate::from_glib_none;
use glib::{ToValue, Value};
use gobject_ffi;
use serde::de;
use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
use serde::ser;
use serde::ser::{Serialize, Serializer, SerializeSeq, SerializeTuple};
use super::*;
use std::ffi::CString;
use DateTime;
use Sample;
use value::serde::{DATE_TIME_OTHER_TYPE_ID, SAMPLE_OTHER_TYPE_ID};
struct TagSer<'a>(&'a str, Value);
macro_rules! ser_tag (
($tag_ser:ident, $ser:ident, $t:ty) => (
ser_value!($tag_ser.1, $tag_ser.0, $t, |tag_name, value| {
let mut tup = $ser.serialize_tuple(2)?;
tup.serialize_element(tag_name)?;
tup.serialize_element(&value)?;
tup.end()
})
);
);
impl<'a> Serialize for TagSer<'a> {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
match self.1.type_() {
glib::Type::F64 => ser_tag!(self, serializer, f64),
glib::Type::String => ser_tag!(self, serializer, String),
glib::Type::U32 => ser_tag!(self, serializer, u32),
glib::Type::U64 => ser_tag!(self, serializer, u64),
glib::Type::Other(type_id) => {
if *DATE_TIME_OTHER_TYPE_ID == type_id {
ser_tag!(self, serializer, DateTime)
} else if *SAMPLE_OTHER_TYPE_ID == type_id {
ser_tag!(self, serializer, Sample)
} else {
Err(
ser::Error::custom(
format!("unimplemented Tag serialization for type {}",
glib::Type::Other(type_id),
)
)
)
}
}
type_ => {
Err(
ser::Error::custom(
format!("unimplemented Tag serialization for type {}", type_)
)
)
}
}
}
}
impl Serialize for TagListRef {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let tag_count = unsafe { ffi::gst_tag_list_n_tags(self.as_ptr()) };
if tag_count > 0 {
let mut seq = serializer.serialize_seq(Some(tag_count as usize))?;
for name_index in 0..tag_count {
unsafe {
let tag_name = ffi::gst_tag_list_nth_tag_name(self.as_ptr(), name_index as u32);
let tag_size = ffi::gst_tag_list_get_tag_size(self.as_ptr(), tag_name);
for tag_index in 0..tag_size {
let value = ffi::gst_tag_list_get_value_index(
self.as_ptr(),
tag_name,
tag_index,
);
if !value.is_null() {
let tag_name = CStr::from_ptr(tag_name)
.to_str()
.map_err(|_| {
ser::Error::custom(
format!(
"invalid UTF-8 characters in Tag name {:?}",
tag_name,
)
)
})?;
seq.serialize_element(
&TagSer(
tag_name,
from_glib_none(value as *mut gobject_ffi::GValue),
)
)?
}
}
}
}
seq.end()
} else if tag_count == 0 {
let seq = serializer.serialize_seq(None)?;
seq.end()
} else {
Err(ser::Error::custom("tag count < 0"))
}
}
}
impl Serialize for TagList {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.as_ref().serialize(serializer)
}
}
struct TagDe(CString, Value);
struct TagVisitor;
macro_rules! de_tag_value(
($tag_name:expr, $seq:expr, $t:ty) => (
{
let value = de_value!("Tag", $tag_name, $seq, $t);
TagDe($tag_name, value)
}
);
);
impl<'de> Visitor<'de> for TagVisitor {
type Value = TagDe;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a tuple of 2 elements (name: String, value: Tag value type)")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
let name = CString::new(
seq
.next_element::<String>()
.map_err(|err| de::Error::custom(
format!("Error reading Tag name. {:?}", err)
))?
.ok_or(de::Error::custom("Expected a value for Tag name, found `None`"))?
.as_str()
).unwrap();
unsafe {
let type_: glib::Type = from_glib(ffi::gst_tag_get_type(name.as_ptr() as *const i8));
let tag_de = match type_ {
glib::Type::F64 => de_tag_value!(name, seq, f64),
glib::Type::String => de_tag_value!(name, seq, String),
glib::Type::U32 => de_tag_value!(name, seq, u32),
glib::Type::U64 => de_tag_value!(name, seq, u64),
glib::Type::Other(type_id) => {
if *DATE_TIME_OTHER_TYPE_ID == type_id {
de_tag_value!(name, seq, DateTime)
} else if *SAMPLE_OTHER_TYPE_ID == type_id {
de_tag_value!(name, seq, Sample)
} else {
return Err(
de::Error::custom(
format!(
"unimplemented deserialization for Tag {:?} with type `{}`",
name,
glib::Type::Other(type_id),
),
)
);
}
}
type_ => {
return Err(
de::Error::custom(
format!(
"unimplemented deserialization for Tag {:?} with type `{}`",
name,
type_,
),
)
);
}
};
Ok(tag_de)
}
}
}
impl<'de> Deserialize<'de> for TagDe {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_tuple(2, TagVisitor{}) // 2 items in the tuple: (name, value)
}
}
struct TagListVisitor;
impl<'de> Visitor<'de> for TagListVisitor {
type Value = TagList;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a sequence of Tags")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
let tag_list = TagList::new();
while let Some(tag_de) = seq.next_element::<TagDe>()? {
unsafe {
ffi::gst_tag_list_add_value(
tag_list.as_mut_ptr(),
ffi::GST_TAG_MERGE_APPEND,
tag_de.0.as_ptr(),
tag_de.1.to_glib_none().0,
);
}
}
Ok(tag_list)
}
}
impl<'de> Deserialize<'de> for TagList {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_seq(TagListVisitor)
}
}
}
unsafe impl Sync for TagListRef {}
unsafe impl Send for TagListRef {}
@ -1073,193 +847,4 @@ mod tests {
assert_eq!(first_duration.get(), Some(::SECOND * 120));
assert!(tag_iter.next().is_none());
}
#[cfg(feature = "ser_de")]
#[test]
fn test_serialize() {
extern crate ron;
use Buffer;
use GenericFormattedValue;
::init().unwrap();
let mut tags = TagList::new();
assert_eq!(tags.to_string(), "taglist;");
{
let tags = tags.get_mut().unwrap();
tags.add::<Title>(&"a title", TagMergeMode::Append); // String
tags.add::<Title>(&"another title", TagMergeMode::Append); // String
tags.add::<Duration>(&(::SECOND * 120).into(), TagMergeMode::Append); // u64
tags.add::<Bitrate>(&96_000, TagMergeMode::Append); // u32
tags.add::<TrackGain>(&1f64, TagMergeMode::Append); // f64
tags.add::<DateTime>(
&::DateTime::new(2f32, 2018, 5, 28, 16, 6, 42.841f64),
TagMergeMode::Append,
); // DateTime
let sample = {
let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]).unwrap();
{
let buffer = buffer.get_mut().unwrap();
buffer.set_offset(0);
buffer.set_offset_end(0);
}
Sample::new::<GenericFormattedValue>(
Some(&buffer),
None,
None,
None,
)
};
tags.add::<Image>(&sample, TagMergeMode::Append); // Sample
}
let mut pretty_config = ron::ser::PrettyConfig::default();
pretty_config.new_line = "".to_string();
let res = ron::ser::to_string_pretty(&tags, pretty_config);
assert_eq!(
Ok(
concat!(
"[",
" (\"title\", \"a title\"),",
" (\"title\", \"another title\"),",
" (\"duration\", 120000000000),",
" (\"bitrate\", 96000),",
" (\"replaygain-track-gain\", 1),",
" (\"datetime\", (",
" tz_offset: 2,",
" y: 2018,",
" m: 5,",
" d: 28,",
" h: 16,",
" mn: 6,",
" s: 42,",
" us: 841000,",
" )),",
" (\"image\", (",
" buffer: Some((",
" pts: None,",
" dts: None,",
" duration: None,",
" offset: 0,",
" offset_end: 0,",
" flags: (",
" bits: 0,",
" ),",
" buffer: \"AQIDBA==\",",
" )),",
" buffer_list: None,",
" caps: None,",
" segment: Some((",
" flags: (",
" bits: 0,",
" ),",
" rate: 1,",
" applied_rate: 1,",
" format: Time,",
" base: 0,",
" offset: 0,",
" start: 0,",
" stop: -1,",
" time: 0,",
" position: 0,",
" duration: -1,",
" )),",
" info: None,",
" )),",
"]",
).to_owned()
),
res,
);
}
#[cfg(feature = "ser_de")]
#[test]
fn test_deserialize() {
extern crate ron;
extern crate serde_json;
::init().unwrap();
let tag_list_ron = r#"
[
("title", "a title"),
("title", "another title"),
("duration", 120000000000),
("bitrate", 96000),
("replaygain-track-gain", 1),
("datetime", (
tz_offset: 2,
y: 2018,
m: 5,
d: 28,
h: 16,
mn: 6,
s: 42,
us: 841000,
)),
("image", (
buffer: Some((
pts: None,
dts: None,
duration: None,
offset: 0,
offset_end: 0,
flags: (
bits: 0,
),
buffer: "AQIDBA==",
)),
buffer_list: None,
caps: None,
segment: None,
info: None,
))
]
"#;
let tags: TagList = ron::de::from_str(tag_list_ron).unwrap();
assert_eq!(tags.get_index::<Title>(0).unwrap().get(), Some("a title"));
assert_eq!(tags.get_index::<Title>(1).unwrap().get(), Some("another title"));
assert_eq!(tags.get_index::<Duration>(0).unwrap().get(), Some(::SECOND * 120));
assert_eq!(tags.get_index::<Bitrate>(0).unwrap().get(), Some(96_000));
assert_eq!(tags.get_index::<TrackGain>(0).unwrap().get(), Some(1f64));
let datetime = tags.get_index::<DateTime>(0).unwrap().get().unwrap();
assert_eq!(datetime.get_year(), 2018);
assert_eq!(datetime.get_microsecond(), 841_000);
let sample = tags.get_index::<Image>(0).unwrap().get().unwrap();
let buffer = sample.get_buffer().unwrap();
{
let data = buffer.map_readable().unwrap();
assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
}
let tag_json = r#"
[
["title", "a title"],
["title", "another title"],
["duration", 120000000000],
["bitrate", 96000],
["replaygain-track-gain", 1.0],
["datetime",{"tz_offset":2.0,"y":2018,"m":5,"d":28,"h":16,"mn":6,"s":42,"us":841000}],
["image",{"buffer":{"pts":null,"dts":null,"duration":null,"offset":0,"offset_end":0,"flags":{"bits":0},"buffer":[1,2,3,4]},"buffer_list":null,"caps":null,"segment":null,"info":null}]
]
"#;
let tags: TagList = serde_json::from_str(tag_json).unwrap();
assert_eq!(tags.get_index::<Title>(0).unwrap().get(), Some("a title"));
assert_eq!(tags.get_index::<Title>(1).unwrap().get(), Some("another title"));
assert_eq!(tags.get_index::<Bitrate>(0).unwrap().get(), Some(96_000));
assert_eq!(tags.get_index::<TrackGain>(0).unwrap().get(), Some(1f64));
let datetime = tags.get_index::<DateTime>(0).unwrap().get().unwrap();
assert_eq!(datetime.get_month(), 5);
assert_eq!(datetime.get_hour(), 16);
let sample = tags.get_index::<Image>(0).unwrap().get().unwrap();
let buffer = sample.get_buffer().unwrap();
{
let data = buffer.map_readable().unwrap();
assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
}
}
}

429
gstreamer/src/tags_serde.rs Normal file
View file

@ -0,0 +1,429 @@
// Copyright (C) 2018 François Laignel <fengalin@free.fr>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use ffi;
use glib;
use glib::translate::{ToGlibPtr, from_glib, from_glib_none};
use glib::{ToValue, Value};
use gobject_ffi;
use serde::de;
use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
use serde::ser;
use serde::ser::{Serialize, Serializer, SerializeSeq, SerializeTuple};
use std::ffi::CStr;
use std::ffi::CString;
use std::fmt;
use DateTime;
use Sample;
use miniobject::MiniObject;
use tags::*;
use value_serde::{DATE_TIME_OTHER_TYPE_ID, SAMPLE_OTHER_TYPE_ID};
struct TagSer<'a>(&'a str, Value);
macro_rules! ser_tag (
($tag_ser:ident, $ser:ident, $t:ty) => (
ser_value!($tag_ser.1, $tag_ser.0, $t, |tag_name, value| {
let mut tup = $ser.serialize_tuple(2)?;
tup.serialize_element(tag_name)?;
tup.serialize_element(&value)?;
tup.end()
})
);
);
impl<'a> Serialize for TagSer<'a> {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
match self.1.type_() {
glib::Type::F64 => ser_tag!(self, serializer, f64),
glib::Type::String => ser_tag!(self, serializer, String),
glib::Type::U32 => ser_tag!(self, serializer, u32),
glib::Type::U64 => ser_tag!(self, serializer, u64),
glib::Type::Other(type_id) => {
if *DATE_TIME_OTHER_TYPE_ID == type_id {
ser_tag!(self, serializer, DateTime)
} else if *SAMPLE_OTHER_TYPE_ID == type_id {
ser_tag!(self, serializer, Sample)
} else {
Err(
ser::Error::custom(
format!("unimplemented Tag serialization for type {}",
glib::Type::Other(type_id),
)
)
)
}
}
type_ => {
Err(
ser::Error::custom(
format!("unimplemented Tag serialization for type {}", type_)
)
)
}
}
}
}
impl Serialize for TagListRef {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let tag_count = unsafe { ffi::gst_tag_list_n_tags(self.as_ptr()) };
if tag_count > 0 {
let mut seq = serializer.serialize_seq(Some(tag_count as usize))?;
for name_index in 0..tag_count {
unsafe {
let tag_name = ffi::gst_tag_list_nth_tag_name(self.as_ptr(), name_index as u32);
let tag_size = ffi::gst_tag_list_get_tag_size(self.as_ptr(), tag_name);
for tag_index in 0..tag_size {
let value = ffi::gst_tag_list_get_value_index(
self.as_ptr(),
tag_name,
tag_index,
);
if !value.is_null() {
let tag_name = CStr::from_ptr(tag_name)
.to_str()
.map_err(|_| {
ser::Error::custom(
format!(
"invalid UTF-8 characters in Tag name {:?}",
tag_name,
)
)
})?;
seq.serialize_element(
&TagSer(
tag_name,
from_glib_none(value as *mut gobject_ffi::GValue),
)
)?
}
}
}
}
seq.end()
} else if tag_count == 0 {
let seq = serializer.serialize_seq(None)?;
seq.end()
} else {
Err(ser::Error::custom("tag count < 0"))
}
}
}
impl Serialize for TagList {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.as_ref().serialize(serializer)
}
}
struct TagDe(CString, Value);
struct TagVisitor;
macro_rules! de_tag_value(
($tag_name:expr, $seq:expr, $t:ty) => (
{
let value = de_value!("Tag", $tag_name, $seq, $t);
TagDe($tag_name, value)
}
);
);
impl<'de> Visitor<'de> for TagVisitor {
type Value = TagDe;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a tuple of 2 elements (name: String, value: Tag value type)")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
let name = CString::new(
seq
.next_element::<String>()
.map_err(|err| de::Error::custom(
format!("Error reading Tag name. {:?}", err)
))?
.ok_or(de::Error::custom("Expected a value for Tag name"))?
.as_str()
).unwrap();
unsafe {
let type_: glib::Type = from_glib(ffi::gst_tag_get_type(name.as_ptr() as *const i8));
let tag_de = match type_ {
glib::Type::F64 => de_tag_value!(name, seq, f64),
glib::Type::String => de_tag_value!(name, seq, String),
glib::Type::U32 => de_tag_value!(name, seq, u32),
glib::Type::U64 => de_tag_value!(name, seq, u64),
glib::Type::Other(type_id) => {
if *DATE_TIME_OTHER_TYPE_ID == type_id {
de_tag_value!(name, seq, DateTime)
} else if *SAMPLE_OTHER_TYPE_ID == type_id {
de_tag_value!(name, seq, Sample)
} else {
return Err(
de::Error::custom(
format!(
"unimplemented deserialization for Tag {:?} with type `{}`",
name,
glib::Type::Other(type_id),
),
)
);
}
}
type_ => {
return Err(
de::Error::custom(
format!(
"unimplemented deserialization for Tag {:?} with type `{}`",
name,
type_,
),
)
);
}
};
Ok(tag_de)
}
}
}
impl<'de> Deserialize<'de> for TagDe {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_tuple(2, TagVisitor{}) // 2 items in the tuple: (name, value)
}
}
struct TagListVisitor;
impl<'de> Visitor<'de> for TagListVisitor {
type Value = TagList;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a sequence of Tags")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
let tag_list = TagList::new();
while let Some(tag_de) = seq.next_element::<TagDe>()? {
unsafe {
ffi::gst_tag_list_add_value(
tag_list.as_mut_ptr(),
ffi::GST_TAG_MERGE_APPEND,
tag_de.0.as_ptr(),
tag_de.1.to_glib_none().0,
);
}
}
Ok(tag_list)
}
}
impl<'de> Deserialize<'de> for TagList {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_seq(TagListVisitor)
}
}
#[cfg(test)]
mod tests {
extern crate ron;
use tags::*;
#[test]
fn test_serialize() {
use Buffer;
use GenericFormattedValue;
use TagMergeMode;
use Sample;
::init().unwrap();
let mut tags = TagList::new();
assert_eq!(tags.to_string(), "taglist;");
{
let tags = tags.get_mut().unwrap();
tags.add::<Title>(&"a title", TagMergeMode::Append); // String
tags.add::<Title>(&"another title", TagMergeMode::Append); // String
tags.add::<Duration>(&(::SECOND * 120).into(), TagMergeMode::Append); // u64
tags.add::<Bitrate>(&96_000, TagMergeMode::Append); // u32
tags.add::<TrackGain>(&1f64, TagMergeMode::Append); // f64
tags.add::<DateTime>(
&::DateTime::new(2f32, 2018, 5, 28, 16, 6, 42.841f64),
TagMergeMode::Append,
); // DateTime
let sample = {
let mut buffer = Buffer::from_slice(vec![1, 2, 3, 4]).unwrap();
{
let buffer = buffer.get_mut().unwrap();
buffer.set_offset(0);
buffer.set_offset_end(0);
}
Sample::new::<GenericFormattedValue>(
Some(&buffer),
None,
None,
None,
)
};
tags.add::<Image>(&sample, TagMergeMode::Append); // Sample
}
let mut pretty_config = ron::ser::PrettyConfig::default();
pretty_config.new_line = "".to_string();
let res = ron::ser::to_string_pretty(&tags, pretty_config);
assert_eq!(
Ok(
concat!(
"[",
" (\"title\", \"a title\"),",
" (\"title\", \"another title\"),",
" (\"duration\", 120000000000),",
" (\"bitrate\", 96000),",
" (\"replaygain-track-gain\", 1),",
" (\"datetime\", (",
" tz_offset: 2,",
" y: 2018,",
" m: 5,",
" d: 28,",
" h: 16,",
" mn: 6,",
" s: 42,",
" us: 841000,",
" )),",
" (\"image\", (",
" buffer: Some((",
" pts: None,",
" dts: None,",
" duration: None,",
" offset: 0,",
" offset_end: 0,",
" flags: (",
" bits: 0,",
" ),",
" buffer: \"AQIDBA==\",",
" )),",
" buffer_list: None,",
" caps: None,",
" segment: Some((",
" flags: (",
" bits: 0,",
" ),",
" rate: 1,",
" applied_rate: 1,",
" format: Time,",
" base: 0,",
" offset: 0,",
" start: 0,",
" stop: -1,",
" time: 0,",
" position: 0,",
" duration: -1,",
" )),",
" info: None,",
" )),",
"]",
).to_owned()
),
res,
);
}
#[test]
fn test_deserialize() {
extern crate serde_json;
::init().unwrap();
let tag_list_ron = r#"
[
("title", "a title"),
("title", "another title"),
("duration", 120000000000),
("bitrate", 96000),
("replaygain-track-gain", 1),
("datetime", (
tz_offset: 2,
y: 2018,
m: 5,
d: 28,
h: 16,
mn: 6,
s: 42,
us: 841000,
)),
("image", (
buffer: Some((
pts: None,
dts: None,
duration: None,
offset: 0,
offset_end: 0,
flags: (
bits: 0,
),
buffer: "AQIDBA==",
)),
buffer_list: None,
caps: None,
segment: None,
info: None,
))
]
"#;
let tags: TagList = ron::de::from_str(tag_list_ron).unwrap();
assert_eq!(tags.get_index::<Title>(0).unwrap().get(), Some("a title"));
assert_eq!(tags.get_index::<Title>(1).unwrap().get(), Some("another title"));
assert_eq!(tags.get_index::<Duration>(0).unwrap().get(), Some(::SECOND * 120));
assert_eq!(tags.get_index::<Bitrate>(0).unwrap().get(), Some(96_000));
assert_eq!(tags.get_index::<TrackGain>(0).unwrap().get(), Some(1f64));
let datetime = tags.get_index::<DateTime>(0).unwrap().get().unwrap();
assert_eq!(datetime.get_year(), 2018);
assert_eq!(datetime.get_microsecond(), 841_000);
let sample = tags.get_index::<Image>(0).unwrap().get().unwrap();
let buffer = sample.get_buffer().unwrap();
{
let data = buffer.map_readable().unwrap();
assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
}
let tag_json = r#"
[
["title", "a title"],
["title", "another title"],
["duration", 120000000000],
["bitrate", 96000],
["replaygain-track-gain", 1.0],
["datetime",{"tz_offset":2.0,"y":2018,"m":5,"d":28,"h":16,"mn":6,"s":42,"us":841000}],
["image",{"buffer":{"pts":null,"dts":null,"duration":null,"offset":0,"offset_end":0,"flags":{"bits":0},"buffer":[1,2,3,4]},"buffer_list":null,"caps":null,"segment":null,"info":null}]
]
"#;
let tags: TagList = serde_json::from_str(tag_json).unwrap();
assert_eq!(tags.get_index::<Title>(0).unwrap().get(), Some("a title"));
assert_eq!(tags.get_index::<Title>(1).unwrap().get(), Some("another title"));
assert_eq!(tags.get_index::<Bitrate>(0).unwrap().get(), Some(96_000));
assert_eq!(tags.get_index::<TrackGain>(0).unwrap().get(), Some(1f64));
let datetime = tags.get_index::<DateTime>(0).unwrap().get().unwrap();
assert_eq!(datetime.get_month(), 5);
assert_eq!(datetime.get_hour(), 16);
let sample = tags.get_index::<Image>(0).unwrap().get().unwrap();
let buffer = sample.get_buffer().unwrap();
{
let data = buffer.map_readable().unwrap();
assert_eq!(data.as_slice(), vec![1, 2, 3, 4].as_slice());
}
}
}

View file

@ -263,122 +263,6 @@ impl fmt::Debug for TocEntryRef {
unsafe impl Sync for TocEntryRef {}
unsafe impl Send for TocEntryRef {}
#[cfg(feature = "ser_de")]
mod serde {
use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer, SerializeStruct};
use tags::*;
use super::*;
impl Serialize for TocRef {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut toc = serializer.serialize_struct("Toc", 3)?;
toc.serialize_field("scope", &self.get_scope())?;
toc.serialize_field("tags", &self.get_tags())?;
toc.serialize_field("entries", &self.get_entries())?;
toc.end()
}
}
impl Serialize for Toc {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.as_ref().serialize(serializer)
}
}
impl Serialize for TocEntryRef {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut toc_entry = serializer.serialize_struct("TocEntry", 6)?;
toc_entry.serialize_field("entry_type", &self.get_entry_type())?;
toc_entry.serialize_field("uid", &self.get_uid())?;
toc_entry.serialize_field("start_stop", &self.get_start_stop_times())?;
toc_entry.serialize_field("tags", &self.get_tags())?;
toc_entry.serialize_field("loop_", &self.get_loop())?;
toc_entry.serialize_field("sub_entries", &self.get_sub_entries())?;
toc_entry.end()
}
}
impl Serialize for TocEntry {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.as_ref().serialize(serializer)
}
}
#[derive(Deserialize)]
struct TocDe {
scope: TocScope,
tags: Option<TagList>,
entries: Vec<TocEntry>,
}
impl From<TocDe> for Toc {
fn from(mut toc_de: TocDe) -> Self {
let mut toc = Toc::new(toc_de.scope);
{
let toc = toc.get_mut().unwrap();
if let Some(tags) = toc_de.tags.take() {
toc.set_tags(tags);
}
let entry_iter = toc_de.entries.drain(..);
for entry in entry_iter {
toc.append_entry(entry);
}
}
toc
}
}
impl<'de> Deserialize<'de> for Toc {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
TocDe::deserialize(deserializer)
.and_then(|toc_de| Ok(toc_de.into()))
}
}
#[derive(Deserialize)]
struct TocEntryDe {
entry_type: TocEntryType,
uid: String,
start_stop: Option<(i64, i64)>,
tags: Option<TagList>,
loop_: Option<(TocLoopType, i32)>,
sub_entries: Vec<TocEntry>,
}
impl From<TocEntryDe> for TocEntry {
fn from(mut toc_entry_de: TocEntryDe) -> Self {
let mut toc_entry = TocEntry::new(toc_entry_de.entry_type, toc_entry_de.uid.as_str());
{
let toc_entry = toc_entry.get_mut().unwrap();
if let Some(start_stop) = toc_entry_de.start_stop.take() {
toc_entry.set_start_stop_times(start_stop.0, start_stop.1);
}
if let Some(tags) = toc_entry_de.tags.take() {
toc_entry.set_tags(tags);
}
if let Some(loop_) = toc_entry_de.loop_.take() {
toc_entry.set_loop(loop_.0, loop_.1);
}
let entry_iter = toc_entry_de.sub_entries.drain(..);
for sub_entries in entry_iter {
toc_entry.append_sub_entry(sub_entries);
}
}
toc_entry
}
}
impl<'de> Deserialize<'de> for TocEntry {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
TocEntryDe::deserialize(deserializer)
.and_then(|toc_entry_de| Ok(toc_entry_de.into()))
}
}
}
#[cfg(test)]
mod tests {
use super::*;
@ -427,257 +311,4 @@ mod tests {
assert!(parent.is_some());
assert_eq!(parent.unwrap().get_entry_type(), TocEntryType::Chapter);
}
#[cfg(feature = "ser_de")]
#[test]
fn test_serialize() {
extern crate ron;
use tags::Title;
use super::*;
::init().unwrap();
let mut toc = Toc::new(TocScope::Global);
{
let toc = toc.get_mut().unwrap();
let mut tags = TagList::new();
tags.get_mut().unwrap().add::<Title>(&"toc", TagMergeMode::Append);
toc.set_tags(tags);
let mut toc_edition = TocEntry::new(TocEntryType::Edition, "edition");
{
let toc_edition = toc_edition.get_mut().unwrap();
toc_edition.set_start_stop_times(0, 15);
let mut toc_chap_1 = TocEntry::new(TocEntryType::Chapter, "chapter1");
{
let toc_chap_1 = toc_chap_1.get_mut().unwrap();
toc_chap_1.set_start_stop_times(0, 10);
let mut toc_chap_1_1 = TocEntry::new(TocEntryType::Chapter, "chapter1.1");
{
let toc_chap_1_1 = toc_chap_1_1.get_mut().unwrap();
toc_chap_1_1.set_start_stop_times(0, 4);
let mut tags = TagList::new();
tags.get_mut().unwrap().add::<Title>(&"chapter 1.1", TagMergeMode::Append);
toc_chap_1_1.set_tags(tags);
}
toc_chap_1.append_sub_entry(toc_chap_1_1);
let mut toc_chap_1_2 = TocEntry::new(TocEntryType::Chapter, "chapter1.2");
{
let toc_chap_1_2 = toc_chap_1_2.get_mut().unwrap();
toc_chap_1_2.set_start_stop_times(4, 10);
let mut tags = TagList::new();
tags.get_mut().unwrap().add::<Title>(&"chapter 1.2", TagMergeMode::Append);
toc_chap_1_2.set_tags(tags);
}
toc_chap_1.append_sub_entry(toc_chap_1_2);
}
toc_edition.append_sub_entry(toc_chap_1);
let mut toc_chap_2 = TocEntry::new(TocEntryType::Chapter, "chapter2");
{
let toc_chap_2 = toc_chap_2.get_mut().unwrap();
toc_chap_2.set_start_stop_times(10, 15);
let mut tags = TagList::new();
tags.get_mut().unwrap().add::<Title>(&"chapter 2", TagMergeMode::Append);
toc_chap_2.set_tags(tags);
}
toc_edition.append_sub_entry(toc_chap_2);
}
toc.append_entry(toc_edition);
}
// don't use newlines
let mut pretty_config = ron::ser::PrettyConfig::default();
pretty_config.new_line = "".to_string();
let res = ron::ser::to_string_pretty(&toc, pretty_config);
assert_eq!(
Ok(
concat!(
"(",
" scope: Global,",
" tags: Some([",
" (\"title\", \"toc\"),",
" ]),",
" entries: [",
" (",
" entry_type: Edition,",
" uid: \"edition\",",
" start_stop: Some((0, 15)),",
" tags: None,",
" loop_: Some((None, 0)),",
" sub_entries: [",
" (",
" entry_type: Chapter,",
" uid: \"chapter1\",",
" start_stop: Some((0, 10)),",
" tags: None,",
" loop_: Some((None, 0)),",
" sub_entries: [",
" (",
" entry_type: Chapter,",
" uid: \"chapter1.1\",",
" start_stop: Some((0, 4)),",
" tags: Some([",
" (\"title\", \"chapter 1.1\"),",
" ]),",
" loop_: Some((None, 0)),",
" sub_entries: [",
" ],",
" ),",
" (",
" entry_type: Chapter,",
" uid: \"chapter1.2\",",
" start_stop: Some((4, 10)),",
" tags: Some([",
" (\"title\", \"chapter 1.2\"),",
" ]),",
" loop_: Some((None, 0)),",
" sub_entries: [",
" ],",
" ),",
" ],",
" ),",
" (",
" entry_type: Chapter,",
" uid: \"chapter2\",",
" start_stop: Some((10, 15)),",
" tags: Some([",
" (\"title\", \"chapter 2\"),",
" ]),",
" loop_: Some((None, 0)),",
" sub_entries: [",
" ],",
" ),",
" ],",
" ),",
" ],",
")",
).to_owned()
),
res,
);
}
#[cfg(feature = "ser_de")]
#[test]
fn test_deserialize() {
extern crate ron;
use tags::Title;
::init().unwrap();
let toc_ron = r#"
(
scope: Global,
tags: Some([
("title", "toc"),
]),
entries: [
(
entry_type: Edition,
uid: "edition",
start_stop: Some((0, 15)),
tags: None,
loop_: Some((None, 0)),
sub_entries: [
(
entry_type: Chapter,
uid: "chapter1",
start_stop: Some((0, 10)),
tags: None,
loop_: Some((None, 0)),
sub_entries: [
(
entry_type: Chapter,
uid: "chapter1.1",
start_stop: Some((0, 4)),
tags: Some([
("title", "chapter 1.1"),
]),
loop_: Some((None, 0)),
sub_entries: [
],
),
(
entry_type: Chapter,
uid: "chapter1.2",
start_stop: Some((4, 10)),
tags: Some([
("title", "chapter 1.2"),
]),
loop_: Some((None, 0)),
sub_entries: [
],
),
],
),
(
entry_type: Chapter,
uid: "chapter2",
start_stop: Some((10, 15)),
tags: Some([
("title", "chapter 2"),
]),
loop_: Some((None, 0)),
sub_entries: [
],
),
],
),
],
)
"#;
let toc: Toc = ron::de::from_str(toc_ron).unwrap();
assert_eq!(toc.get_scope(), TocScope::Global);
let entries = toc.get_entries();
assert_eq!(1, entries.len());
let edition = &entries[0];
assert_eq!(TocEntryType::Edition, edition.get_entry_type());
assert_eq!("edition", edition.get_uid());
assert!(edition.get_tags().is_none());
assert_eq!(Some((0, 15)), edition.get_start_stop_times());
let sub_entries = edition.get_sub_entries();
assert_eq!(2, sub_entries.len());
let chapter1 = &sub_entries[0];
assert_eq!(TocEntryType::Chapter, chapter1.get_entry_type());
assert_eq!("chapter1", chapter1.get_uid());
assert!(chapter1.get_tags().is_none());
assert_eq!(Some((0, 10)), chapter1.get_start_stop_times());
let chap1_sub_entries = chapter1.get_sub_entries();
assert_eq!(2, sub_entries.len());
let chapter1_1 = &chap1_sub_entries[0];
assert_eq!(TocEntryType::Chapter, chapter1_1.get_entry_type());
assert_eq!("chapter1.1", chapter1_1.get_uid());
assert_eq!(Some((0, 4)), chapter1_1.get_start_stop_times());
let tags = chapter1_1.get_tags().unwrap();
assert_eq!(Some("chapter 1.1"), tags.get_index::<Title>(0).unwrap().get());
assert_eq!(0, chapter1_1.get_sub_entries().len());
let chapter1_2 = &chap1_sub_entries[1];
assert_eq!(TocEntryType::Chapter, chapter1_2.get_entry_type());
assert_eq!("chapter1.2", chapter1_2.get_uid());
assert_eq!(Some((4, 10)), chapter1_2.get_start_stop_times());
let tags = chapter1_2.get_tags().unwrap();
assert_eq!(Some("chapter 1.2"), tags.get_index::<Title>(0).unwrap().get());
assert_eq!(0, chapter1_2.get_sub_entries().len());
let chapter2 = &sub_entries[1];
assert_eq!(TocEntryType::Chapter, chapter2.get_entry_type());
assert_eq!("chapter2", chapter2.get_uid());
let tags = chapter2.get_tags().unwrap();
assert_eq!(Some("chapter 2"), tags.get_index::<Title>(0).unwrap().get());
assert_eq!(Some((10, 15)), chapter2.get_start_stop_times());
assert_eq!(0, chapter2.get_sub_entries().len());
}
}

379
gstreamer/src/toc_serde.rs Normal file
View file

@ -0,0 +1,379 @@
// Copyright (C) 2018 François Laignel <fengalin@free.fr>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer, SerializeStruct};
use toc::*;
use TagList;
use TocEntryType;
use TocScope;
use TocLoopType;
impl Serialize for TocRef {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut toc = serializer.serialize_struct("Toc", 3)?;
toc.serialize_field("scope", &self.get_scope())?;
toc.serialize_field("tags", &self.get_tags())?;
toc.serialize_field("entries", &self.get_entries())?;
toc.end()
}
}
impl Serialize for Toc {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.as_ref().serialize(serializer)
}
}
impl Serialize for TocEntryRef {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut toc_entry = serializer.serialize_struct("TocEntry", 6)?;
toc_entry.serialize_field("entry_type", &self.get_entry_type())?;
toc_entry.serialize_field("uid", &self.get_uid())?;
toc_entry.serialize_field("start_stop", &self.get_start_stop_times())?;
toc_entry.serialize_field("tags", &self.get_tags())?;
toc_entry.serialize_field("loop_", &self.get_loop())?;
toc_entry.serialize_field("sub_entries", &self.get_sub_entries())?;
toc_entry.end()
}
}
impl Serialize for TocEntry {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.as_ref().serialize(serializer)
}
}
#[derive(Deserialize)]
struct TocDe {
scope: TocScope,
tags: Option<TagList>,
entries: Vec<TocEntry>,
}
impl From<TocDe> for Toc {
fn from(mut toc_de: TocDe) -> Self {
let mut toc = Toc::new(toc_de.scope);
{
let toc = toc.get_mut().unwrap();
if let Some(tags) = toc_de.tags.take() {
toc.set_tags(tags);
}
let entry_iter = toc_de.entries.drain(..);
for entry in entry_iter {
toc.append_entry(entry);
}
}
toc
}
}
impl<'de> Deserialize<'de> for Toc {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
TocDe::deserialize(deserializer)
.and_then(|toc_de| Ok(toc_de.into()))
}
}
#[derive(Deserialize)]
struct TocEntryDe {
entry_type: TocEntryType,
uid: String,
start_stop: Option<(i64, i64)>,
tags: Option<TagList>,
loop_: Option<(TocLoopType, i32)>,
sub_entries: Vec<TocEntry>,
}
impl From<TocEntryDe> for TocEntry {
fn from(mut toc_entry_de: TocEntryDe) -> Self {
let mut toc_entry = TocEntry::new(toc_entry_de.entry_type, toc_entry_de.uid.as_str());
{
let toc_entry = toc_entry.get_mut().unwrap();
if let Some(start_stop) = toc_entry_de.start_stop.take() {
toc_entry.set_start_stop_times(start_stop.0, start_stop.1);
}
if let Some(tags) = toc_entry_de.tags.take() {
toc_entry.set_tags(tags);
}
if let Some(loop_) = toc_entry_de.loop_.take() {
toc_entry.set_loop(loop_.0, loop_.1);
}
let entry_iter = toc_entry_de.sub_entries.drain(..);
for sub_entries in entry_iter {
toc_entry.append_sub_entry(sub_entries);
}
}
toc_entry
}
}
impl<'de> Deserialize<'de> for TocEntry {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
TocEntryDe::deserialize(deserializer)
.and_then(|toc_entry_de| Ok(toc_entry_de.into()))
}
}
#[cfg(test)]
mod tests {
extern crate ron;
use TocEntryType;
use TocScope;
use toc::*;
#[test]
fn test_serialize() {
use TagMergeMode;
use TagList;
use tags::Title;
::init().unwrap();
let mut toc = Toc::new(TocScope::Global);
{
let toc = toc.get_mut().unwrap();
let mut tags = TagList::new();
tags.get_mut().unwrap().add::<Title>(&"toc", TagMergeMode::Append);
toc.set_tags(tags);
let mut toc_edition = TocEntry::new(TocEntryType::Edition, "edition");
{
let toc_edition = toc_edition.get_mut().unwrap();
toc_edition.set_start_stop_times(0, 15);
let mut toc_chap_1 = TocEntry::new(TocEntryType::Chapter, "chapter1");
{
let toc_chap_1 = toc_chap_1.get_mut().unwrap();
toc_chap_1.set_start_stop_times(0, 10);
let mut toc_chap_1_1 = TocEntry::new(TocEntryType::Chapter, "chapter1.1");
{
let toc_chap_1_1 = toc_chap_1_1.get_mut().unwrap();
toc_chap_1_1.set_start_stop_times(0, 4);
let mut tags = TagList::new();
tags.get_mut().unwrap().add::<Title>(&"chapter 1.1", TagMergeMode::Append);
toc_chap_1_1.set_tags(tags);
}
toc_chap_1.append_sub_entry(toc_chap_1_1);
let mut toc_chap_1_2 = TocEntry::new(TocEntryType::Chapter, "chapter1.2");
{
let toc_chap_1_2 = toc_chap_1_2.get_mut().unwrap();
toc_chap_1_2.set_start_stop_times(4, 10);
let mut tags = TagList::new();
tags.get_mut().unwrap().add::<Title>(&"chapter 1.2", TagMergeMode::Append);
toc_chap_1_2.set_tags(tags);
}
toc_chap_1.append_sub_entry(toc_chap_1_2);
}
toc_edition.append_sub_entry(toc_chap_1);
let mut toc_chap_2 = TocEntry::new(TocEntryType::Chapter, "chapter2");
{
let toc_chap_2 = toc_chap_2.get_mut().unwrap();
toc_chap_2.set_start_stop_times(10, 15);
let mut tags = TagList::new();
tags.get_mut().unwrap().add::<Title>(&"chapter 2", TagMergeMode::Append);
toc_chap_2.set_tags(tags);
}
toc_edition.append_sub_entry(toc_chap_2);
}
toc.append_entry(toc_edition);
}
let mut pretty_config = ron::ser::PrettyConfig::default();
pretty_config.new_line = "".to_string();
let res = ron::ser::to_string_pretty(&toc, pretty_config);
assert_eq!(
Ok(
concat!(
"(",
" scope: Global,",
" tags: Some([",
" (\"title\", \"toc\"),",
" ]),",
" entries: [",
" (",
" entry_type: Edition,",
" uid: \"edition\",",
" start_stop: Some((0, 15)),",
" tags: None,",
" loop_: Some((None, 0)),",
" sub_entries: [",
" (",
" entry_type: Chapter,",
" uid: \"chapter1\",",
" start_stop: Some((0, 10)),",
" tags: None,",
" loop_: Some((None, 0)),",
" sub_entries: [",
" (",
" entry_type: Chapter,",
" uid: \"chapter1.1\",",
" start_stop: Some((0, 4)),",
" tags: Some([",
" (\"title\", \"chapter 1.1\"),",
" ]),",
" loop_: Some((None, 0)),",
" sub_entries: [",
" ],",
" ),",
" (",
" entry_type: Chapter,",
" uid: \"chapter1.2\",",
" start_stop: Some((4, 10)),",
" tags: Some([",
" (\"title\", \"chapter 1.2\"),",
" ]),",
" loop_: Some((None, 0)),",
" sub_entries: [",
" ],",
" ),",
" ],",
" ),",
" (",
" entry_type: Chapter,",
" uid: \"chapter2\",",
" start_stop: Some((10, 15)),",
" tags: Some([",
" (\"title\", \"chapter 2\"),",
" ]),",
" loop_: Some((None, 0)),",
" sub_entries: [",
" ],",
" ),",
" ],",
" ),",
" ],",
")",
).to_owned()
),
res,
);
}
#[test]
fn test_deserialize() {
use tags::Title;
::init().unwrap();
let toc_ron = r#"
(
scope: Global,
tags: Some([
("title", "toc"),
]),
entries: [
(
entry_type: Edition,
uid: "edition",
start_stop: Some((0, 15)),
tags: None,
loop_: Some((None, 0)),
sub_entries: [
(
entry_type: Chapter,
uid: "chapter1",
start_stop: Some((0, 10)),
tags: None,
loop_: Some((None, 0)),
sub_entries: [
(
entry_type: Chapter,
uid: "chapter1.1",
start_stop: Some((0, 4)),
tags: Some([
("title", "chapter 1.1"),
]),
loop_: Some((None, 0)),
sub_entries: [
],
),
(
entry_type: Chapter,
uid: "chapter1.2",
start_stop: Some((4, 10)),
tags: Some([
("title", "chapter 1.2"),
]),
loop_: Some((None, 0)),
sub_entries: [
],
),
],
),
(
entry_type: Chapter,
uid: "chapter2",
start_stop: Some((10, 15)),
tags: Some([
("title", "chapter 2"),
]),
loop_: Some((None, 0)),
sub_entries: [
],
),
],
),
],
)
"#;
let toc: Toc = ron::de::from_str(toc_ron).unwrap();
assert_eq!(toc.get_scope(), TocScope::Global);
let entries = toc.get_entries();
assert_eq!(1, entries.len());
let edition = &entries[0];
assert_eq!(TocEntryType::Edition, edition.get_entry_type());
assert_eq!("edition", edition.get_uid());
assert!(edition.get_tags().is_none());
assert_eq!(Some((0, 15)), edition.get_start_stop_times());
let sub_entries = edition.get_sub_entries();
assert_eq!(2, sub_entries.len());
let chapter1 = &sub_entries[0];
assert_eq!(TocEntryType::Chapter, chapter1.get_entry_type());
assert_eq!("chapter1", chapter1.get_uid());
assert!(chapter1.get_tags().is_none());
assert_eq!(Some((0, 10)), chapter1.get_start_stop_times());
let chap1_sub_entries = chapter1.get_sub_entries();
assert_eq!(2, sub_entries.len());
let chapter1_1 = &chap1_sub_entries[0];
assert_eq!(TocEntryType::Chapter, chapter1_1.get_entry_type());
assert_eq!("chapter1.1", chapter1_1.get_uid());
assert_eq!(Some((0, 4)), chapter1_1.get_start_stop_times());
let tags = chapter1_1.get_tags().unwrap();
assert_eq!(Some("chapter 1.1"), tags.get_index::<Title>(0).unwrap().get());
assert_eq!(0, chapter1_1.get_sub_entries().len());
let chapter1_2 = &chap1_sub_entries[1];
assert_eq!(TocEntryType::Chapter, chapter1_2.get_entry_type());
assert_eq!("chapter1.2", chapter1_2.get_uid());
assert_eq!(Some((4, 10)), chapter1_2.get_start_stop_times());
let tags = chapter1_2.get_tags().unwrap();
assert_eq!(Some("chapter 1.2"), tags.get_index::<Title>(0).unwrap().get());
assert_eq!(0, chapter1_2.get_sub_entries().len());
let chapter2 = &sub_entries[1];
assert_eq!(TocEntryType::Chapter, chapter2.get_entry_type());
assert_eq!("chapter2", chapter2.get_uid());
let tags = chapter2.get_tags().unwrap();
assert_eq!(Some("chapter 2"), tags.get_index::<Title>(0).unwrap().get());
assert_eq!(Some((10, 15)), chapter2.get_start_stop_times());
assert_eq!(0, chapter2.get_sub_entries().len());
}
}

View file

@ -529,6 +529,12 @@ impl<'a> Array<'a> {
Array(values.iter().map(|v| v.to_send_value()).collect())
}
pub fn from_owned(values: Vec<glib::SendValue>) -> Self {
assert_initialized_main_thread!();
Array(Cow::Owned(values))
}
pub fn into_owned(self) -> Array<'static> {
Array(self.0.into_owned().into())
}
@ -601,6 +607,12 @@ impl<'a> List<'a> {
List(values.iter().map(|v| v.to_send_value()).collect())
}
pub fn from_owned(values: Vec<glib::SendValue>) -> Self {
assert_initialized_main_thread!();
List(Cow::Owned(values))
}
pub fn into_owned(self) -> List<'static> {
List(self.0.into_owned().into())
}
@ -857,540 +869,3 @@ impl GstValueExt for glib::Value {
}
}
}
#[cfg(feature = "ser_de")]
#[macro_use]
pub(crate) mod serde {
use glib;
use glib::{StaticType, ToValue};
use num_rational::Rational32;
use serde::de;
use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
use serde::ser;
use serde::ser::{Serialize, Serializer, SerializeTuple};
use std::mem;
use DateTime;
use Sample;
use super::*;
pub const ARRAY_TYPE_NAME: &'static str = "Array";
pub const LIST_TYPE_NAME: &'static str = "List";
fn get_other_type_id<T: StaticType>() -> usize {
match T::static_type() {
glib::Type::Other(type_id) => type_id,
type_ => panic!("Expecting `Other` variant, found `{}`", type_),
}
}
lazy_static! {
pub(crate) static ref ARRAY_OTHER_TYPE_ID: usize = get_other_type_id::<Array>();
pub(crate) static ref BITMASK_OTHER_TYPE_ID: usize = get_other_type_id::<Bitmask>();
pub(crate) static ref DATE_TIME_OTHER_TYPE_ID: usize = get_other_type_id::<DateTime>();
pub(crate) static ref FRACTION_OTHER_TYPE_ID: usize = get_other_type_id::<Fraction>();
pub(crate) static ref FRACTION_RANGE_OTHER_TYPE_ID: usize =
get_other_type_id::<FractionRange>();
pub(crate) static ref INT_RANGE_I32_OTHER_TYPE_ID: usize =
get_other_type_id::<IntRange<i32>>();
pub(crate) static ref INT_RANGE_I64_OTHER_TYPE_ID: usize =
get_other_type_id::<IntRange<i64>>();
pub(crate) static ref LIST_OTHER_TYPE_ID: usize = get_other_type_id::<List>();
pub(crate) static ref SAMPLE_OTHER_TYPE_ID: usize = get_other_type_id::<Sample>();
}
impl<'a> Serialize for Fraction {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.0.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for Fraction {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Rational32::deserialize(deserializer)
.and_then(|rational| Ok(Fraction::new(*rational.numer(), *rational.denom())))
}
}
macro_rules! ser_value (
($value:expr, $t_str:expr, $t:ty, $ser_closure:expr) => (
{
let value = $value.get::<$t>().unwrap();
$ser_closure($t_str, value)
}
);
($value:expr, $ser_closure:expr) => (
match $value.type_() {
glib::Type::I8 => ser_value!($value, "i8", i8, $ser_closure),
glib::Type::U8 => ser_value!($value, "ui8", u8, $ser_closure),
glib::Type::Bool => ser_value!($value, "bool", bool, $ser_closure),
glib::Type::I32 => ser_value!($value, "i32", i32, $ser_closure),
glib::Type::U32 => ser_value!($value, "u32", u32, $ser_closure),
glib::Type::ILong => ser_value!($value, "ilong", i32, $ser_closure),
glib::Type::ULong => ser_value!($value, "ulong", u32, $ser_closure),
glib::Type::I64 => ser_value!($value, "i64", i64, $ser_closure),
glib::Type::U64 => ser_value!($value, "u64", u64, $ser_closure),
glib::Type::F32 => ser_value!($value, "f32", f32, $ser_closure),
glib::Type::F64 => ser_value!($value, "f64", f64, $ser_closure),
glib::Type::String => ser_value!($value, "String", String, $ser_closure),
glib::Type::Other(type_id) => {
if *ARRAY_OTHER_TYPE_ID == type_id {
ser_value!($value, ARRAY_TYPE_NAME, Array, $ser_closure)
} else if *BITMASK_OTHER_TYPE_ID == type_id {
ser_value!($value, "Bitmask", Bitmask, $ser_closure)
} else if *DATE_TIME_OTHER_TYPE_ID == type_id {
ser_value!($value, "DateTime", DateTime, $ser_closure)
} else if *FRACTION_OTHER_TYPE_ID == type_id {
ser_value!($value, "Fraction", Fraction, $ser_closure)
} else if *FRACTION_RANGE_OTHER_TYPE_ID == type_id {
ser_value!($value, "FractionRange", FractionRange, $ser_closure)
} else if *INT_RANGE_I32_OTHER_TYPE_ID == type_id {
ser_value!($value, "IntRange<i32>", IntRange<i32>, $ser_closure)
} else if *INT_RANGE_I64_OTHER_TYPE_ID == type_id {
ser_value!($value, "IntRange<i64>", IntRange<i64>, $ser_closure)
} else if *LIST_OTHER_TYPE_ID == type_id {
ser_value!($value, LIST_TYPE_NAME, List, $ser_closure)
} else if *SAMPLE_OTHER_TYPE_ID == type_id {
ser_value!($value, "Sample", Sample, $ser_closure)
} else {
Err(
ser::Error::custom(
format!("unimplemented `Value` serialization for type {}",
glib::Type::Other(type_id),
)
)
)
}
}
type_ => {
Err(
ser::Error::custom(
format!("unimplemented `Value` serialization for type {}", type_)
)
)
}
}
)
);
pub(crate) struct SendValue(glib::SendValue);
impl SendValue {
pub(crate) fn from(send_value: glib::SendValue) -> Self {
SendValue(send_value)
}
}
impl From<SendValue> for glib::SendValue {
fn from(send_value: SendValue) -> Self {
send_value.0
}
}
impl Serialize for SendValue {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
ser_value!(self.0, |type_, value| {
let mut tup = serializer.serialize_tuple(2)?;
tup.serialize_element(type_)?;
tup.serialize_element(&value)?;
tup.end()
})
}
}
macro_rules! impl_ser_send_value_collection (
($t:ident) => (
impl<'a> Serialize for $t<'a> {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let send_value_vec = unsafe {
mem::transmute::<&[glib::SendValue], &[SendValue]>(
self.as_slice()
)
};
send_value_vec.serialize(serializer)
}
}
);
);
impl_ser_send_value_collection!(Array);
impl_ser_send_value_collection!(List);
macro_rules! de_value(
($outer_type:expr, $type_name:expr, $seq:expr, $t:ty) => (
$seq
.next_element::<$t>()?
.ok_or_else(||
de::Error::custom(format!(
"Expected a value for `{}` with type {:?}, found `None`",
$outer_type,
$type_name,
))
)?
.to_value()
);
);
macro_rules! de_send_value(
($type_name:expr, $seq:expr, $t:ty) => (
SendValue::from(
de_value!("Value", $type_name, $seq, $t)
.try_into_send_value::<$t>()
.map_err(|_|
de::Error::custom(format!(
"Failed to convert `Value` with type {:?} to `SendValue`",
$type_name,
))
)?
)
);
($type_name:expr, $seq:expr) => (
match $type_name.as_str() {
"i8" => de_send_value!($type_name, $seq, i8),
"u8" => de_send_value!($type_name, $seq, u8),
"bool" => de_send_value!($type_name, $seq, bool),
"i32" => de_send_value!($type_name, $seq, i32),
"u32" => de_send_value!($type_name, $seq, u32),
"ilong" => de_send_value!($type_name, $seq, i32),
"ulong" => de_send_value!($type_name, $seq, u32),
"i64" => de_send_value!($type_name, $seq, i64),
"u64" => de_send_value!($type_name, $seq, u64),
"f32" => de_send_value!($type_name, $seq, f32),
"f64" => de_send_value!($type_name, $seq, f64),
"String" => de_send_value!($type_name, $seq, String),
"Array" => de_send_value!($type_name, $seq, Array),
"Bitmask" => de_send_value!($type_name, $seq, Bitmask),
"DateTime" => de_send_value!($type_name, $seq, DateTime),
"Fraction" => de_send_value!($type_name, $seq, Fraction),
"FractionRange" => de_send_value!($type_name, $seq, FractionRange),
"IntRange<i32>" => de_send_value!($type_name, $seq, IntRange<i32>),
"IntRange<i64>" => de_send_value!($type_name, $seq, IntRange<i64>),
"Sample" => de_send_value!($type_name, $seq, Sample),
_ => return Err(
de::Error::custom(
format!(
"unimplemented deserialization for `Value` with type `{}`",
$type_name,
),
)
),
}
);
);
struct SendValueVisitor;
impl<'de> Visitor<'de> for SendValueVisitor {
type Value = SendValue;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a tuple of 2 elements (type name: String, value: Value type)")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
let type_name = seq.next_element::<String>()?
.ok_or(de::Error::custom("Expected a value for `Value` type, found `None`"))?;
Ok(de_send_value!(type_name, seq))
}
}
impl<'de> Deserialize<'de> for SendValue {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_tuple(2, SendValueVisitor{})
}
}
macro_rules! impl_de_send_value_collection (
($t:ident) => {
impl<'a, 'de> Deserialize<'de> for $t<'a> {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let send_value_vec = Vec::<SendValue>::deserialize(deserializer)?;
Ok($t(Cow::Owned(unsafe{
mem::transmute::<Vec<SendValue>, Vec<glib::SendValue>>(send_value_vec)
})))
}
}
}
);
impl_de_send_value_collection!(Array);
impl_de_send_value_collection!(List);
}
#[cfg(test)]
mod tests {
#[cfg(feature = "ser_de")]
#[test]
fn test_serialize_simple() {
extern crate ron;
extern crate serde_json;
use Fraction;
use FractionRange;
use IntRange;
use Bitmask;
::init().unwrap();
let mut pretty_config = ron::ser::PrettyConfig::default();
pretty_config.new_line = "".to_string();
// Fraction
let fraction = Fraction::new(1, 3);
let res = ron::ser::to_string_pretty(&fraction, pretty_config.clone());
assert_eq!(Ok("(1, 3)".to_owned()), res);
let res = serde_json::to_string(&fraction).unwrap();
assert_eq!("[1,3]".to_owned(), res);
// FractionRange
let fraction_range = FractionRange::new(Fraction::new(1, 3), Fraction::new(1, 2));
let res = ron::ser::to_string_pretty(&fraction_range, pretty_config.clone());
assert_eq!(
Ok(
concat!(
"(",
" min: (1, 3),",
" max: (1, 2),",
")"
)
.to_owned()
),
res,
);
let res = serde_json::to_string(&fraction_range).unwrap();
assert_eq!("{\"min\":[1,3],\"max\":[1,2]}".to_owned(), res);
// IntRange
let int_range = IntRange::<i32>::new_with_step(0, 42, 21);
let res = ron::ser::to_string_pretty(&int_range, pretty_config.clone());
assert_eq!(
Ok(
concat!(
"(",
" min: 0,",
" max: 42,",
" step: 21,",
")"
)
.to_owned()
),
res,
);
let res = serde_json::to_string(&int_range).unwrap();
assert_eq!("{\"min\":0,\"max\":42,\"step\":21}".to_owned(), res);
// Bitmask
let bitmask = Bitmask::new(1024 + 128 + 32);
let res = ron::ser::to_string_pretty(&bitmask, pretty_config.clone());
assert_eq!(Ok("(1184)".to_owned()), res);
let res = serde_json::to_string(&bitmask).unwrap();
assert_eq!("1184".to_owned(), res);
}
#[cfg(feature = "ser_de")]
#[test]
fn test_serialize_collections() {
extern crate ron;
extern crate serde_json;
use glib::value::ToValue;
use Array;
use Fraction;
use List;
::init().unwrap();
let mut pretty_config = ron::ser::PrettyConfig::default();
pretty_config.new_line = "".to_string();
// Array
let value_13 = Fraction::new(1, 3).to_value();
let send_value_13 = value_13.try_into_send_value::<Fraction>().unwrap();
let value_12 = Fraction::new(1, 2).to_value();
let send_value_12 = value_12.try_into_send_value::<Fraction>().unwrap();
let value_str = "test str".to_value();
let send_value_str = value_str.try_into_send_value::<String>().unwrap();
let array = Array::new(&[&send_value_13, &send_value_12, &send_value_str]);
let res = ron::ser::to_string_pretty(&array, pretty_config.clone());
assert_eq!(
Ok(
concat!(
"[",
" (\"Fraction\", (1, 3)),",
" (\"Fraction\", (1, 2)),",
" (\"String\", \"test str\"),",
"]"
)
.to_owned()
),
res,
);
let res = serde_json::to_string(&array).unwrap();
assert_eq!(
"[[\"Fraction\",[1,3]],[\"Fraction\",[1,2]],[\"String\",\"test str\"]]"
.to_owned(),
res
);
// List
let value_12 = Fraction::new(1, 2).to_value();
let send_value_12 = value_12.try_into_send_value::<Fraction>().unwrap();
let value_str = "test str".to_value();
let send_value_str = value_str.try_into_send_value::<String>().unwrap();
let list = List::new(&[&send_value_12, &send_value_str]);
let res = ron::ser::to_string_pretty(&list, pretty_config.clone());
assert_eq!(
Ok(
concat!(
"[",
" (\"Fraction\", (1, 2)),",
" (\"String\", \"test str\"),",
"]"
)
.to_owned()
),
res,
);
}
#[cfg(feature = "ser_de")]
#[test]
fn test_deserialize_simple() {
extern crate ron;
extern crate serde_json;
use Fraction;
use FractionRange;
use IntRange;
use Bitmask;
::init().unwrap();
// Fraction
let fraction_ron = "(1, 3)";
let fraction: Fraction = ron::de::from_str(fraction_ron).unwrap();
assert_eq!(fraction.0.numer(), &1);
assert_eq!(fraction.0.denom(), &3);
let fraction_json = "[1,3]";
let fraction: Fraction = serde_json::from_str(fraction_json).unwrap();
assert_eq!(fraction.0.numer(), &1);
assert_eq!(fraction.0.denom(), &3);
// FractionRange
let fraction_range_ron = "(min: (1, 3), max: (1, 2))";
let fraction_range: FractionRange = ron::de::from_str(fraction_range_ron).unwrap();
assert_eq!(fraction_range.min().0.denom(), &3);
assert_eq!(fraction_range.max().0.denom(), &2);
let fraction_range_json = "{\"min\":[1,3],\"max\":[1,2]}";
let fraction_range: FractionRange = serde_json::from_str(fraction_range_json).unwrap();
assert_eq!(fraction_range.min().0.denom(), &3);
assert_eq!(fraction_range.max().0.denom(), &2);
// IntRange
let int_range_ron = "(min: 0, max: 42, step: 21)";
let int_range: IntRange<i32> = ron::de::from_str(int_range_ron).unwrap();
assert_eq!(int_range.min(), 0);
assert_eq!(int_range.max(), 42);
assert_eq!(int_range.step(), 21);
let int_range_json = "{\"min\":0,\"max\":42,\"step\":21}";
let int_range: IntRange<i32> = serde_json::from_str(int_range_json).unwrap();
assert_eq!(int_range.min(), 0);
assert_eq!(int_range.max(), 42);
assert_eq!(int_range.step(), 21);
// Bitmask
let bitmask_ref = Bitmask::new(1024 + 128 + 32);
let bitmask_ron = "(1184)";
let bitmask: Bitmask = ron::de::from_str(bitmask_ron).unwrap();
assert_eq!(bitmask_ref, bitmask);
let bitmask_json = "1184";
let bitmask: Bitmask = serde_json::from_str(bitmask_json).unwrap();
assert_eq!(bitmask_ref, bitmask);
}
#[cfg(feature = "ser_de")]
#[test]
fn test_deserialize_collections() {
extern crate ron;
extern crate serde_json;
use Array;
use Fraction;
use List;
::init().unwrap();
// Array
let array_ron =
r#"[
("Fraction", (1, 3)),
("Fraction", (1, 2)),
("String", "test str"),
]"#;
let array: Array = ron::de::from_str(array_ron).unwrap();
assert_eq!(3, array.0.len());
let fraction = array.0[0].get::<Fraction>().unwrap();
assert_eq!(fraction.0.numer(), &1);
assert_eq!(fraction.0.denom(), &3);
let fraction = array.0[1].get::<Fraction>().unwrap();
assert_eq!(fraction.0.numer(), &1);
assert_eq!(fraction.0.denom(), &2);
assert_eq!("test str".to_owned(), array.0[2].get::<String>().unwrap());
let array_json =
r#"[["Fraction",[1,3]],["Fraction",[1,2]],["String","test str"]]"#;
let array: Array = serde_json::from_str(array_json).unwrap();
assert_eq!(3, array.0.len());
let fraction = array.0[0].get::<Fraction>().unwrap();
assert_eq!(fraction.0.numer(), &1);
assert_eq!(fraction.0.denom(), &3);
let fraction = array.0[1].get::<Fraction>().unwrap();
assert_eq!(fraction.0.numer(), &1);
assert_eq!(fraction.0.denom(), &2);
assert_eq!("test str".to_owned(), array.0[2].get::<String>().unwrap());
// List
let list_ron =
r#"[
("Fraction", (1, 2)),
("String", "test str"),
]"#;
let list: List = ron::de::from_str(list_ron).unwrap();
assert_eq!(2, list.0.len());
let fraction = list.0[0].get::<Fraction>().unwrap();
assert_eq!(fraction.0.numer(), &1);
assert_eq!(fraction.0.denom(), &2);
assert_eq!("test str".to_owned(), list.0[1].get::<String>().unwrap());
}
}

View file

@ -0,0 +1,534 @@
// Copyright (C) 2018 François Laignel <fengalin@free.fr>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use glib;
use glib::{StaticType, ToValue};
use num_rational::Rational32;
use serde::de;
use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
use serde::ser;
use serde::ser::{Serialize, Serializer, SerializeTuple};
use std::{fmt, mem};
use DateTime;
use Sample;
use value::*;
pub const ARRAY_TYPE_NAME: &'static str = "Array";
pub const LIST_TYPE_NAME: &'static str = "List";
fn get_other_type_id<T: StaticType>() -> usize {
match T::static_type() {
glib::Type::Other(type_id) => type_id,
type_ => panic!("Expecting `Other` variant, found `{}`", type_),
}
}
lazy_static! {
pub(crate) static ref ARRAY_OTHER_TYPE_ID: usize = get_other_type_id::<Array>();
pub(crate) static ref BITMASK_OTHER_TYPE_ID: usize = get_other_type_id::<Bitmask>();
pub(crate) static ref DATE_TIME_OTHER_TYPE_ID: usize = get_other_type_id::<DateTime>();
pub(crate) static ref FRACTION_OTHER_TYPE_ID: usize = get_other_type_id::<Fraction>();
pub(crate) static ref FRACTION_RANGE_OTHER_TYPE_ID: usize =
get_other_type_id::<FractionRange>();
pub(crate) static ref INT_RANGE_I32_OTHER_TYPE_ID: usize =
get_other_type_id::<IntRange<i32>>();
pub(crate) static ref INT_RANGE_I64_OTHER_TYPE_ID: usize =
get_other_type_id::<IntRange<i64>>();
pub(crate) static ref LIST_OTHER_TYPE_ID: usize = get_other_type_id::<List>();
pub(crate) static ref SAMPLE_OTHER_TYPE_ID: usize = get_other_type_id::<Sample>();
}
impl<'a> Serialize for Fraction {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
self.0.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for Fraction {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
Rational32::deserialize(deserializer)
.and_then(|rational| Ok(Fraction::new(*rational.numer(), *rational.denom())))
}
}
macro_rules! ser_value (
($value:expr, $t_str:expr, $t:ty, $ser_closure:expr) => (
{
let value = $value.get::<$t>().unwrap();
$ser_closure($t_str, value)
}
);
($value:expr, $ser_closure:expr) => (
match $value.type_() {
glib::Type::I8 => ser_value!($value, "i8", i8, $ser_closure),
glib::Type::U8 => ser_value!($value, "ui8", u8, $ser_closure),
glib::Type::Bool => ser_value!($value, "bool", bool, $ser_closure),
glib::Type::I32 => ser_value!($value, "i32", i32, $ser_closure),
glib::Type::U32 => ser_value!($value, "u32", u32, $ser_closure),
glib::Type::I64 => ser_value!($value, "i64", i64, $ser_closure),
glib::Type::U64 => ser_value!($value, "u64", u64, $ser_closure),
glib::Type::F32 => ser_value!($value, "f32", f32, $ser_closure),
glib::Type::F64 => ser_value!($value, "f64", f64, $ser_closure),
glib::Type::String => ser_value!($value, "String", String, $ser_closure),
glib::Type::Other(type_id) => {
if *ARRAY_OTHER_TYPE_ID == type_id {
ser_value!($value, ARRAY_TYPE_NAME, Array, $ser_closure)
} else if *BITMASK_OTHER_TYPE_ID == type_id {
ser_value!($value, "Bitmask", Bitmask, $ser_closure)
} else if *DATE_TIME_OTHER_TYPE_ID == type_id {
ser_value!($value, "DateTime", DateTime, $ser_closure)
} else if *FRACTION_OTHER_TYPE_ID == type_id {
ser_value!($value, "Fraction", Fraction, $ser_closure)
} else if *FRACTION_RANGE_OTHER_TYPE_ID == type_id {
ser_value!($value, "FractionRange", FractionRange, $ser_closure)
} else if *INT_RANGE_I32_OTHER_TYPE_ID == type_id {
ser_value!($value, "IntRange<i32>", IntRange<i32>, $ser_closure)
} else if *INT_RANGE_I64_OTHER_TYPE_ID == type_id {
ser_value!($value, "IntRange<i64>", IntRange<i64>, $ser_closure)
} else if *LIST_OTHER_TYPE_ID == type_id {
ser_value!($value, LIST_TYPE_NAME, List, $ser_closure)
} else if *SAMPLE_OTHER_TYPE_ID == type_id {
ser_value!($value, "Sample", Sample, $ser_closure)
} else {
Err(
ser::Error::custom(
format!("unimplemented `Value` serialization for type {}",
glib::Type::Other(type_id),
)
)
)
}
}
type_ => {
Err(
ser::Error::custom(
format!("unimplemented `Value` serialization for type {}", type_)
)
)
}
}
)
);
pub(crate) struct SendValue(glib::SendValue);
impl SendValue {
pub(crate) fn from(send_value: glib::SendValue) -> Self {
SendValue(send_value)
}
}
impl From<SendValue> for glib::SendValue {
fn from(send_value: SendValue) -> Self {
send_value.0
}
}
impl Serialize for SendValue {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
ser_value!(self.0, |type_, value| {
let mut tup = serializer.serialize_tuple(2)?;
tup.serialize_element(type_)?;
tup.serialize_element(&value)?;
tup.end()
})
}
}
macro_rules! impl_ser_send_value_collection (
($t:ident) => (
impl<'a> Serialize for $t<'a> {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let send_value_vec = unsafe {
mem::transmute::<&[glib::SendValue], &[SendValue]>(
self.as_slice()
)
};
send_value_vec.serialize(serializer)
}
}
);
);
impl_ser_send_value_collection!(Array);
impl_ser_send_value_collection!(List);
macro_rules! de_value(
($outer_type:expr, $type_name:expr, $seq:expr, $t:ty) => (
$seq
.next_element::<$t>()?
.ok_or_else(||
de::Error::custom(format!(
"Expected a value for `{}` with type {:?}",
$outer_type,
$type_name,
))
)?
.to_value()
);
);
macro_rules! de_send_value(
($type_name:expr, $seq:expr, $t:ty) => (
SendValue::from(
de_value!("Value", $type_name, $seq, $t)
.try_into_send_value::<$t>()
.map_err(|_|
de::Error::custom(format!(
"Failed to convert `Value` with type {:?} to `SendValue`",
$type_name,
))
)?
)
);
($type_name:expr, $seq:expr) => (
match $type_name.as_str() {
"i8" => de_send_value!($type_name, $seq, i8),
"u8" => de_send_value!($type_name, $seq, u8),
"bool" => de_send_value!($type_name, $seq, bool),
"i32" => de_send_value!($type_name, $seq, i32),
"u32" => de_send_value!($type_name, $seq, u32),
"i64" => de_send_value!($type_name, $seq, i64),
"u64" => de_send_value!($type_name, $seq, u64),
"f32" => de_send_value!($type_name, $seq, f32),
"f64" => de_send_value!($type_name, $seq, f64),
"String" => de_send_value!($type_name, $seq, String),
"Array" => de_send_value!($type_name, $seq, Array),
"Bitmask" => de_send_value!($type_name, $seq, Bitmask),
"DateTime" => de_send_value!($type_name, $seq, DateTime),
"Fraction" => de_send_value!($type_name, $seq, Fraction),
"FractionRange" => de_send_value!($type_name, $seq, FractionRange),
"IntRange<i32>" => de_send_value!($type_name, $seq, IntRange<i32>),
"IntRange<i64>" => de_send_value!($type_name, $seq, IntRange<i64>),
"Sample" => de_send_value!($type_name, $seq, Sample),
_ => return Err(
de::Error::custom(
format!(
"unimplemented deserialization for `Value` with type `{}`",
$type_name,
),
)
),
}
);
);
struct SendValueVisitor;
impl<'de> Visitor<'de> for SendValueVisitor {
type Value = SendValue;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a tuple: (name, value)")
}
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
let type_name = seq.next_element::<String>()?
.ok_or(de::Error::custom("Expected a value for `Value` type"))?;
Ok(de_send_value!(type_name, seq))
}
}
impl<'de> Deserialize<'de> for SendValue {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_tuple(2, SendValueVisitor{})
}
}
macro_rules! impl_de_send_value_collection (
($t:ident) => {
impl<'a, 'de> Deserialize<'de> for $t<'a> {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let send_value_vec = Vec::<SendValue>::deserialize(deserializer)?;
Ok($t::from_owned(unsafe{
mem::transmute::<Vec<SendValue>, Vec<glib::SendValue>>(send_value_vec)
}))
}
}
}
);
impl_de_send_value_collection!(Array);
impl_de_send_value_collection!(List);
#[cfg(test)]
mod tests {
extern crate ron;
extern crate serde_json;
#[test]
fn test_serialize_simple() {
use Fraction;
use FractionRange;
use IntRange;
use Bitmask;
::init().unwrap();
let mut pretty_config = ron::ser::PrettyConfig::default();
pretty_config.new_line = "".to_string();
// Fraction
let fraction = Fraction::new(1, 3);
let res = ron::ser::to_string_pretty(&fraction, pretty_config.clone());
assert_eq!(Ok("(1, 3)".to_owned()), res);
let res = serde_json::to_string(&fraction).unwrap();
assert_eq!("[1,3]".to_owned(), res);
// FractionRange
let fraction_range = FractionRange::new(Fraction::new(1, 3), Fraction::new(1, 2));
let res = ron::ser::to_string_pretty(&fraction_range, pretty_config.clone());
assert_eq!(
Ok(
concat!(
"(",
" min: (1, 3),",
" max: (1, 2),",
")"
)
.to_owned()
),
res,
);
let res = serde_json::to_string(&fraction_range).unwrap();
assert_eq!("{\"min\":[1,3],\"max\":[1,2]}".to_owned(), res);
// IntRange
let int_range = IntRange::<i32>::new_with_step(0, 42, 21);
let res = ron::ser::to_string_pretty(&int_range, pretty_config.clone());
assert_eq!(
Ok(
concat!(
"(",
" min: 0,",
" max: 42,",
" step: 21,",
")"
)
.to_owned()
),
res,
);
let res = serde_json::to_string(&int_range).unwrap();
assert_eq!("{\"min\":0,\"max\":42,\"step\":21}".to_owned(), res);
// Bitmask
let bitmask = Bitmask::new(1024 + 128 + 32);
let res = ron::ser::to_string_pretty(&bitmask, pretty_config.clone());
assert_eq!(Ok("(1184)".to_owned()), res);
let res = serde_json::to_string(&bitmask).unwrap();
assert_eq!("1184".to_owned(), res);
}
#[test]
fn test_serialize_collections() {
use glib::value::ToValue;
use Array;
use Fraction;
use List;
::init().unwrap();
let mut pretty_config = ron::ser::PrettyConfig::default();
pretty_config.new_line = "".to_string();
// Array
let value_13 = Fraction::new(1, 3).to_value();
let send_value_13 = value_13.try_into_send_value::<Fraction>().unwrap();
let value_12 = Fraction::new(1, 2).to_value();
let send_value_12 = value_12.try_into_send_value::<Fraction>().unwrap();
let value_str = "test str".to_value();
let send_value_str = value_str.try_into_send_value::<String>().unwrap();
let array = Array::new(&[&send_value_13, &send_value_12, &send_value_str]);
let res = ron::ser::to_string_pretty(&array, pretty_config.clone());
assert_eq!(
Ok(
concat!(
"[",
" (\"Fraction\", (1, 3)),",
" (\"Fraction\", (1, 2)),",
" (\"String\", \"test str\"),",
"]"
)
.to_owned()
),
res,
);
let res = serde_json::to_string(&array).unwrap();
assert_eq!(
"[[\"Fraction\",[1,3]],[\"Fraction\",[1,2]],[\"String\",\"test str\"]]"
.to_owned(),
res
);
// List
let value_12 = Fraction::new(1, 2).to_value();
let send_value_12 = value_12.try_into_send_value::<Fraction>().unwrap();
let value_str = "test str".to_value();
let send_value_str = value_str.try_into_send_value::<String>().unwrap();
let list = List::new(&[&send_value_12, &send_value_str]);
let res = ron::ser::to_string_pretty(&list, pretty_config.clone());
assert_eq!(
Ok(
concat!(
"[",
" (\"Fraction\", (1, 2)),",
" (\"String\", \"test str\"),",
"]"
)
.to_owned()
),
res,
);
}
#[cfg(feature = "ser_de")]
#[test]
fn test_deserialize_simple() {
extern crate ron;
extern crate serde_json;
use Fraction;
use FractionRange;
use IntRange;
use Bitmask;
::init().unwrap();
// Fraction
let fraction_ron = "(1, 3)";
let fraction: Fraction = ron::de::from_str(fraction_ron).unwrap();
assert_eq!(fraction.0.numer(), &1);
assert_eq!(fraction.0.denom(), &3);
let fraction_json = "[1,3]";
let fraction: Fraction = serde_json::from_str(fraction_json).unwrap();
assert_eq!(fraction.0.numer(), &1);
assert_eq!(fraction.0.denom(), &3);
// FractionRange
let fraction_range_ron = "(min: (1, 3), max: (1, 2))";
let fraction_range: FractionRange = ron::de::from_str(fraction_range_ron).unwrap();
assert_eq!(fraction_range.min().0.denom(), &3);
assert_eq!(fraction_range.max().0.denom(), &2);
let fraction_range_json = "{\"min\":[1,3],\"max\":[1,2]}";
let fraction_range: FractionRange = serde_json::from_str(fraction_range_json).unwrap();
assert_eq!(fraction_range.min().0.denom(), &3);
assert_eq!(fraction_range.max().0.denom(), &2);
// IntRange
let int_range_ron = "(min: 0, max: 42, step: 21)";
let int_range: IntRange<i32> = ron::de::from_str(int_range_ron).unwrap();
assert_eq!(int_range.min(), 0);
assert_eq!(int_range.max(), 42);
assert_eq!(int_range.step(), 21);
let int_range_json = "{\"min\":0,\"max\":42,\"step\":21}";
let int_range: IntRange<i32> = serde_json::from_str(int_range_json).unwrap();
assert_eq!(int_range.min(), 0);
assert_eq!(int_range.max(), 42);
assert_eq!(int_range.step(), 21);
// Bitmask
let bitmask_ref = Bitmask::new(1024 + 128 + 32);
let bitmask_ron = "(1184)";
let bitmask: Bitmask = ron::de::from_str(bitmask_ron).unwrap();
assert_eq!(bitmask_ref, bitmask);
let bitmask_json = "1184";
let bitmask: Bitmask = serde_json::from_str(bitmask_json).unwrap();
assert_eq!(bitmask_ref, bitmask);
}
#[cfg(feature = "ser_de")]
#[test]
fn test_deserialize_collections() {
extern crate ron;
extern crate serde_json;
use Array;
use Fraction;
use List;
::init().unwrap();
// Array
let array_ron =
r#"[
("Fraction", (1, 3)),
("Fraction", (1, 2)),
("String", "test str"),
]"#;
let array: Array = ron::de::from_str(array_ron).unwrap();
let slice = array.as_slice();
assert_eq!(3, slice.len());
let fraction = slice[0].get::<Fraction>().unwrap();
assert_eq!(fraction.0.numer(), &1);
assert_eq!(fraction.0.denom(), &3);
let fraction = slice[1].get::<Fraction>().unwrap();
assert_eq!(fraction.0.numer(), &1);
assert_eq!(fraction.0.denom(), &2);
assert_eq!("test str".to_owned(), slice[2].get::<String>().unwrap());
let array_json =
r#"[["Fraction",[1,3]],["Fraction",[1,2]],["String","test str"]]"#;
let array: Array = serde_json::from_str(array_json).unwrap();
let slice = array.as_slice();
assert_eq!(3, slice.len());
let fraction = slice[0].get::<Fraction>().unwrap();
assert_eq!(fraction.0.numer(), &1);
assert_eq!(fraction.0.denom(), &3);
let fraction = slice[1].get::<Fraction>().unwrap();
assert_eq!(fraction.0.numer(), &1);
assert_eq!(fraction.0.denom(), &2);
assert_eq!("test str".to_owned(), slice[2].get::<String>().unwrap());
// List
let list_ron =
r#"[
("Fraction", (1, 2)),
("String", "test str"),
]"#;
let list: List = ron::de::from_str(list_ron).unwrap();
let slice = list.as_slice();
assert_eq!(2, slice.len());
let fraction = slice[0].get::<Fraction>().unwrap();
assert_eq!(fraction.0.numer(), &1);
assert_eq!(fraction.0.denom(), &2);
assert_eq!("test str".to_owned(), slice[1].get::<String>().unwrap());
}
}