forked from mirrors/gstreamer-rs
279 lines
10 KiB
Rust
279 lines
10 KiB
Rust
// Take a look at the license at the top of the repository in the LICENSE file.
|
|
|
|
use serde::{
|
|
de,
|
|
de::{Deserialize, Deserializer},
|
|
ser::{Serialize, Serializer},
|
|
};
|
|
|
|
use crate::{
|
|
format::{FormattedValue, FormattedValueIntrinsic, SpecificFormattedValueIntrinsic},
|
|
Format, FormattedSegment, GenericFormattedValue, Segment, SegmentFlags,
|
|
};
|
|
|
|
#[derive(serde::Serialize, serde::Deserialize)]
|
|
struct FormattedSegmentSerde {
|
|
flags: SegmentFlags,
|
|
rate: f64,
|
|
applied_rate: f64,
|
|
format: Format,
|
|
base: i64,
|
|
offset: i64,
|
|
start: i64,
|
|
stop: i64,
|
|
time: i64,
|
|
position: i64,
|
|
duration: i64,
|
|
}
|
|
|
|
impl<T: FormattedValueIntrinsic> Serialize for FormattedSegment<T> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let fmt_seg = unsafe {
|
|
FormattedSegmentSerde {
|
|
flags: self.flags(),
|
|
rate: self.rate(),
|
|
applied_rate: self.applied_rate(),
|
|
format: self.format(),
|
|
base: self.base().into_raw_value(),
|
|
offset: self.offset().into_raw_value(),
|
|
start: self.start().into_raw_value(),
|
|
stop: self.stop().into_raw_value(),
|
|
time: self.time().into_raw_value(),
|
|
position: self.position().into_raw_value(),
|
|
duration: self.duration().into_raw_value(),
|
|
}
|
|
};
|
|
fmt_seg.serialize(serializer)
|
|
}
|
|
}
|
|
|
|
impl<'de> Deserialize<'de> for Segment {
|
|
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
|
skip_assert_initialized!();
|
|
FormattedSegmentSerde::deserialize(deserializer).map(|fmt_seg_de| {
|
|
let mut segment = Self::new();
|
|
segment.set_flags(fmt_seg_de.flags);
|
|
segment.set_rate(fmt_seg_de.rate);
|
|
segment.set_applied_rate(fmt_seg_de.applied_rate);
|
|
segment.set_format(fmt_seg_de.format);
|
|
segment.set_base(GenericFormattedValue::new(
|
|
fmt_seg_de.format,
|
|
fmt_seg_de.base,
|
|
));
|
|
segment.set_offset(GenericFormattedValue::new(
|
|
fmt_seg_de.format,
|
|
fmt_seg_de.offset,
|
|
));
|
|
segment.set_start(GenericFormattedValue::new(
|
|
fmt_seg_de.format,
|
|
fmt_seg_de.start,
|
|
));
|
|
segment.set_stop(GenericFormattedValue::new(
|
|
fmt_seg_de.format,
|
|
fmt_seg_de.stop,
|
|
));
|
|
segment.set_time(GenericFormattedValue::new(
|
|
fmt_seg_de.format,
|
|
fmt_seg_de.time,
|
|
));
|
|
segment.set_position(GenericFormattedValue::new(
|
|
fmt_seg_de.format,
|
|
fmt_seg_de.position,
|
|
));
|
|
segment.set_duration(GenericFormattedValue::new(
|
|
fmt_seg_de.format,
|
|
fmt_seg_de.duration,
|
|
));
|
|
|
|
segment
|
|
})
|
|
}
|
|
}
|
|
|
|
impl<'de, T: SpecificFormattedValueIntrinsic> Deserialize<'de> for FormattedSegment<T> {
|
|
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
|
skip_assert_initialized!();
|
|
Segment::deserialize(deserializer).and_then(|segment| {
|
|
segment.downcast::<T>().map_err(|segment| {
|
|
de::Error::custom(format!(
|
|
"failed to convert segment with format {:?} to {:?}",
|
|
segment.format(),
|
|
T::default_format(),
|
|
))
|
|
})
|
|
})
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use crate::{ClockTime, Format, GenericFormattedValue, Segment, SegmentFlags};
|
|
|
|
#[test]
|
|
fn test_serialize() {
|
|
crate::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::from(ClockTime::from_nseconds(123)));
|
|
segment.set_offset(GenericFormattedValue::from(ClockTime::from_nseconds(42)));
|
|
segment.set_start(GenericFormattedValue::from(ClockTime::from_nseconds(1024)));
|
|
segment.set_stop(GenericFormattedValue::from(ClockTime::from_nseconds(2048)));
|
|
segment.set_time(GenericFormattedValue::from(ClockTime::from_nseconds(1042)));
|
|
segment.set_position(GenericFormattedValue::from(ClockTime::from_nseconds(256)));
|
|
segment.set_duration(GenericFormattedValue::from(ClockTime::NONE));
|
|
|
|
let pretty_config = ron::ser::PrettyConfig::new().new_line("".to_string());
|
|
|
|
let res = ron::ser::to_string_pretty(&segment, pretty_config);
|
|
assert_eq!(
|
|
Ok(concat!(
|
|
"(",
|
|
" flags: \"reset+segment\",",
|
|
" rate: 1.0,",
|
|
" 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_segment() {
|
|
crate::init().unwrap();
|
|
|
|
let segment_ron = r#"
|
|
(
|
|
flags: "reset+segment",
|
|
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.flags(), SegmentFlags::RESET | SegmentFlags::SEGMENT);
|
|
assert!((segment.rate() - 1f64).abs() < std::f64::EPSILON);
|
|
assert!((segment.applied_rate() - 0.9f64).abs() < std::f64::EPSILON);
|
|
assert_eq!(segment.format(), Format::Time);
|
|
assert_eq!(segment.flags(), SegmentFlags::RESET | SegmentFlags::SEGMENT);
|
|
assert!((segment.rate() - 1f64).abs() < std::f64::EPSILON);
|
|
assert!((segment.applied_rate() - 0.9f64).abs() < std::f64::EPSILON);
|
|
assert_eq!(segment.format(), Format::Time);
|
|
assert_eq!(
|
|
segment.base(),
|
|
GenericFormattedValue::from(ClockTime::from_nseconds(123)),
|
|
);
|
|
assert_eq!(
|
|
segment.offset(),
|
|
GenericFormattedValue::from(ClockTime::from_nseconds(42)),
|
|
);
|
|
assert_eq!(
|
|
segment.start(),
|
|
GenericFormattedValue::from(ClockTime::from_nseconds(1024)),
|
|
);
|
|
assert_eq!(
|
|
segment.stop(),
|
|
GenericFormattedValue::from(ClockTime::from_nseconds(2048)),
|
|
);
|
|
assert_eq!(
|
|
segment.time(),
|
|
GenericFormattedValue::from(ClockTime::from_nseconds(1042)),
|
|
);
|
|
assert_eq!(
|
|
segment.position(),
|
|
GenericFormattedValue::from(ClockTime::from_nseconds(256)),
|
|
);
|
|
assert_eq!(
|
|
segment.duration(),
|
|
GenericFormattedValue::from(ClockTime::NONE),
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_deserialize_formatted() {
|
|
use crate::{format::Time, FormattedSegment};
|
|
|
|
crate::init().unwrap();
|
|
|
|
let segment_ron = r#"
|
|
(
|
|
flags: "reset+segment",
|
|
rate: 1,
|
|
applied_rate: 0.9,
|
|
format: Time,
|
|
base: 123,
|
|
offset: 42,
|
|
start: 1024,
|
|
stop: 2048,
|
|
time: 1042,
|
|
position: 256,
|
|
duration: -1,
|
|
)
|
|
"#;
|
|
|
|
let fmt_seg: FormattedSegment<Time> = ron::de::from_str(segment_ron).unwrap();
|
|
assert_eq!(fmt_seg.flags(), SegmentFlags::RESET | SegmentFlags::SEGMENT);
|
|
assert!((fmt_seg.rate() - 1f64).abs() < std::f64::EPSILON);
|
|
assert!((fmt_seg.applied_rate() - 0.9f64).abs() < std::f64::EPSILON);
|
|
assert_eq!(fmt_seg.format(), Format::Time);
|
|
assert_eq!(fmt_seg.base(), Some(ClockTime::from_nseconds(123)));
|
|
assert_eq!(fmt_seg.offset(), Some(ClockTime::from_nseconds(42)));
|
|
assert_eq!(fmt_seg.start(), Some(ClockTime::from_nseconds(1024)));
|
|
assert_eq!(fmt_seg.stop(), Some(ClockTime::from_nseconds(2048)));
|
|
assert_eq!(fmt_seg.time(), Some(ClockTime::from_nseconds(1042)));
|
|
assert_eq!(fmt_seg.position(), Some(ClockTime::from_nseconds(256)));
|
|
assert_eq!(fmt_seg.duration(), ClockTime::NONE);
|
|
}
|
|
|
|
#[test]
|
|
fn test_serde_roundtrip() {
|
|
crate::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::from(ClockTime::from_nseconds(123)));
|
|
segment.set_offset(GenericFormattedValue::from(ClockTime::from_nseconds(42)));
|
|
segment.set_start(GenericFormattedValue::from(ClockTime::from_nseconds(1024)));
|
|
segment.set_stop(GenericFormattedValue::from(ClockTime::from_nseconds(2048)));
|
|
segment.set_time(GenericFormattedValue::from(ClockTime::from_nseconds(1042)));
|
|
segment.set_position(GenericFormattedValue::from(ClockTime::from_nseconds(256)));
|
|
segment.set_duration(GenericFormattedValue::from(ClockTime::NONE));
|
|
let segment_se = ron::ser::to_string(&segment).unwrap();
|
|
|
|
let segment_de: Segment = ron::de::from_str(segment_se.as_str()).unwrap();
|
|
assert_eq!(segment_de.flags(), segment.flags());
|
|
assert!((segment_de.rate() - segment.rate()).abs() < std::f64::EPSILON);
|
|
assert!((segment_de.applied_rate() - segment.applied_rate()).abs() < std::f64::EPSILON);
|
|
assert_eq!(segment_de.format(), segment.format());
|
|
assert_eq!(segment_de.base(), segment.base());
|
|
assert_eq!(segment_de.offset(), segment.offset());
|
|
assert_eq!(segment_de.start(), segment.start());
|
|
assert_eq!(segment_de.stop(), segment.stop());
|
|
assert_eq!(segment_de.time(), segment.time());
|
|
assert_eq!(segment_de.position(), segment.position());
|
|
assert_eq!(segment_de.duration(), segment.duration());
|
|
}
|
|
}
|