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.
This commit is contained in:
Rafael Caricio 2022-05-10 23:05:48 +02:00
parent 501e060979
commit 6b13875150
Signed by: rafaelcaricio
GPG key ID: 3C86DBCE8E93C947
4 changed files with 102 additions and 1 deletions

View file

@ -7,8 +7,9 @@ edition = "2021"
license = "MIT" license = "MIT"
[dependencies] [dependencies]
base64 = "0.13" base64 = { version = "0.13", default-features = false, features = ["alloc"] }
bitstream-io = "1.3" bitstream-io = "1.3"
deku = { version = "0.13", default-features = false, features = ["alloc"] }
crc = "3.0" crc = "3.0"
thiserror = "1" thiserror = "1"
serde = { version = "1", features = ["derive"], optional = true } serde = { version = "1", features = ["derive"], optional = true }
@ -19,3 +20,4 @@ ascii = "1"
[dev-dependencies] [dev-dependencies]
serde_json = "1" serde_json = "1"
assert-json-diff = "2" assert-json-diff = "2"
hexlit = "0.5"

71
src/data.rs Normal file
View file

@ -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<u8> = 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<u8> = 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));
}
}

View file

@ -4,6 +4,7 @@ use std::time::Duration;
use thiserror::Error; use thiserror::Error;
mod commands; mod commands;
mod data;
mod descriptors; mod descriptors;
mod info; mod info;
mod time; mod time;

View file

@ -80,3 +80,30 @@ where
t 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")
}
}