From 6b1387515040b0c8c46ef7ccdc51c25a6cee9c0a Mon Sep 17 00:00:00 2001 From: Rafael Caricio Date: Tue, 10 May 2022 23:05:48 +0200 Subject: [PATCH] Use Deku crate for serialization Using the Deku library we can implement a `no_std` compatible read and write structs/enums. We don't need to write manually encoding code and rely completely on the Deku derive macros to do the right job. I've implemented the SpliceTime part of the spec as a proof of concept of the use of Deku. It worked great for this small structure. --- Cargo.toml | 4 ++- src/data.rs | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + src/time.rs | 27 ++++++++++++++++++++ 4 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 src/data.rs diff --git a/Cargo.toml b/Cargo.toml index a07bf62..c125c01 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,8 +7,9 @@ edition = "2021" license = "MIT" [dependencies] -base64 = "0.13" +base64 = { version = "0.13", default-features = false, features = ["alloc"] } bitstream-io = "1.3" +deku = { version = "0.13", default-features = false, features = ["alloc"] } crc = "3.0" thiserror = "1" serde = { version = "1", features = ["derive"], optional = true } @@ -19,3 +20,4 @@ ascii = "1" [dev-dependencies] serde_json = "1" assert-json-diff = "2" +hexlit = "0.5" diff --git a/src/data.rs b/src/data.rs new file mode 100644 index 0000000..09af197 --- /dev/null +++ b/src/data.rs @@ -0,0 +1,71 @@ +use deku::prelude::*; + +#[derive(Debug, Clone, PartialEq, DekuRead, DekuWrite)] +#[deku(endian = "big", type="u8", bits = "1")] +pub(crate) enum SpliceTime { + + #[deku(id = "1")] + TimeSpecified { + + #[deku(bits = "6", assert_eq = "0x3f")] + reserved: u8, + + #[deku(bits = "33")] + pts_time: u64, + + }, + + #[deku(id = "0")] + NoTimeSpecified { + + #[deku(bits = "7", assert_eq = "0x7f")] + reserved: u8, + + } +} + +impl Default for SpliceTime { + fn default() -> Self { + Self::NoTimeSpecified { + reserved: 0x7f + } + } +} + +impl SpliceTime { + fn new(pts_time: u64) -> Self { + Self::TimeSpecified { + reserved: 0x3f, + pts_time + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn write_splice_time() { + let st = SpliceTime::default(); + let data: Vec = st.try_into().unwrap(); + + assert_eq!(hex::encode(data.as_slice()), "7f"); + } + + #[test] + fn write_splice_time_with_pts_time() { + let st = SpliceTime::new(0x072bd0050); + let encoded: Vec = st.try_into().unwrap(); + + assert_eq!(hex::encode(encoded.as_slice()), "fe72bd0050"); + } + + #[test] + fn read_splice_time_with_pts_time() { + let data = hex::decode("fe72bd0050").unwrap(); + let st = SpliceTime::try_from(data.as_slice()).unwrap(); + + assert_eq!(st, SpliceTime::new(0x072bd0050)); + } +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 73cbca3..20b6374 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,6 +4,7 @@ use std::time::Duration; use thiserror::Error; mod commands; +mod data; mod descriptors; mod info; mod time; diff --git a/src/time.rs b/src/time.rs index e56fe9d..7f48633 100644 --- a/src/time.rs +++ b/src/time.rs @@ -80,3 +80,30 @@ where t } } + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn encode_time_signal() { + + let mut st = SpliceTime::default(); + + let mut data = Vec::new(); + st.write_to(&mut data).unwrap(); + + assert_eq!(hex::encode(data.as_slice()), "7f") + } + + #[test] + fn encode_time_signal_with_time() { + + let mut st = SpliceTime::from(0x072bd0050); + + let mut data = Vec::new(); + st.write_to(&mut data).unwrap(); + + assert_eq!(hex::encode(data.as_slice()), "fe72bd0050") + } +} \ No newline at end of file