1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// SPDX-FileCopyrightText: 2025 The vita49-rs Authors
//
// SPDX-License-Identifier: MIT OR Apache-2.0
use deku::prelude::*;
use crate::packet_header::PacketHeader;
use crate::payload::Payload;
use crate::VitaError;
/// Base signal data structure.
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default, DekuRead, DekuWrite)]
#[deku(
endian = "endian",
ctx = "endian: deku::ctx::Endian, packet_header: &PacketHeader"
)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SignalData {
#[deku(count = "packet_header.payload_size_words()")]
data: Vec<u32>,
}
impl TryFrom<Payload> for SignalData {
type Error = Payload;
fn try_from(value: Payload) -> Result<Self, Self::Error> {
match value {
Payload::SignalData(c) => Ok(c),
a => Err(a),
}
}
}
impl SignalData {
/// Create a new, empty signal data packet.
pub fn new() -> SignalData {
SignalData::default()
}
/// Create a new signal data packet from an input slice of bytes.
///
/// # Errors
/// Internally, the payload is represented as a vector of 32-bit integers.
/// If you pass a payload of bytes with a length indivisible by 4, the call
/// will return an error.
/// # Example
/// ```
/// # use std::io;
/// use vita49::prelude::*;
/// # fn main() -> Result<(), VitaError> {
/// let mut packet = Vrt::new_signal_data_packet();
/// *packet.payload_mut() = Payload::SignalData(SignalData::from_bytes(&vec![1, 2, 3, 4, 5, 6, 7, 8])?);
/// assert_eq!(packet.signal_payload()?, vec![1, 2, 3, 4, 5, 6, 7, 8]);
/// # Ok(())
/// # }
/// ```
pub fn from_bytes(bytes: &[u8]) -> Result<SignalData, VitaError> {
let mut ret = SignalData::new();
ret.set_payload(bytes)?;
Ok(ret)
}
/// Get the data payload as a vector of bytes.
pub fn payload(&self) -> Vec<u8> {
self.data.iter().flat_map(|&v| v.to_be_bytes()).collect()
}
/// Set the packet payload to some raw bytes.
///
/// # Errors
/// Internally, the payload is represented as a vector of 32-bit integers.
/// If you pass a payload of bytes with a length indivisible by 4, the call
/// will return an error.
///
/// # Example
/// ```
/// # use std::io;
/// use vita49::prelude::*;
/// # fn main() -> Result<(), VitaError> {
/// let mut packet = Vrt::new_signal_data_packet();
/// let sig_data = packet.payload_mut().signal_data_mut()?;
/// sig_data.set_payload(&vec![1, 2, 3, 4, 5, 6, 7, 8])?;
/// assert_eq!(packet.signal_payload()?, vec![1, 2, 3, 4, 5, 6, 7, 8]);
/// # Ok(())
/// # }
/// ```
pub fn set_payload(&mut self, bytes: &[u8]) -> Result<(), VitaError> {
let packed_payload: Vec<u32> = bytes
.chunks(4)
.map(|chunk| {
chunk
.try_into()
.map(u32::from_be_bytes)
.map_err(|_| VitaError::PayloadUneven32BitWords)
})
.collect::<Result<Vec<u32>, VitaError>>()?;
self.data = packed_payload.to_vec();
Ok(())
}
/// Gets the size of the payload in 32-bit words.
pub fn size_words(&self) -> u16 {
self.data.len() as u16
}
/// Gets the size of the payload in bytes.
pub fn payload_size_bytes(&self) -> usize {
self.data.len() * 4
}
}