kenwood_thd75/types/
voice.rs1#[derive(Debug, Clone, PartialEq, Eq, Hash)]
34pub struct VoiceMessage {
35 pub channel: VoiceChannel,
37 pub name: VoiceMessageName,
39 pub duration_secs: u8,
41 pub repeat: bool,
43 pub repeat_interval: RepeatInterval,
45}
46
47impl Default for VoiceMessage {
48 fn default() -> Self {
49 Self {
50 channel: VoiceChannel::Ch1,
51 name: VoiceMessageName::default(),
52 duration_secs: 0,
53 repeat: false,
54 repeat_interval: RepeatInterval::default(),
55 }
56 }
57}
58
59#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
61pub enum VoiceChannel {
62 Ch1,
64 Ch2,
66 Ch3,
68 Ch4,
70}
71
72impl VoiceChannel {
73 #[must_use]
75 pub const fn number(self) -> u8 {
76 match self {
77 Self::Ch1 => 1,
78 Self::Ch2 => 2,
79 Self::Ch3 => 3,
80 Self::Ch4 => 4,
81 }
82 }
83
84 #[must_use]
86 pub const fn max_duration_secs(self) -> u8 {
87 match self {
88 Self::Ch1 => 30,
89 Self::Ch2 | Self::Ch3 | Self::Ch4 => 15,
90 }
91 }
92}
93
94#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
96pub struct VoiceMessageName(String);
97
98impl VoiceMessageName {
99 pub const MAX_LEN: usize = 8;
101
102 #[must_use]
108 pub fn new(text: &str) -> Option<Self> {
109 if text.len() <= Self::MAX_LEN {
110 Some(Self(text.to_owned()))
111 } else {
112 None
113 }
114 }
115
116 #[must_use]
118 pub fn as_str(&self) -> &str {
119 &self.0
120 }
121}
122
123#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
128pub struct RepeatInterval(u8);
129
130impl RepeatInterval {
131 pub const MAX: u8 = 60;
133
134 #[must_use]
140 pub const fn new(seconds: u8) -> Option<Self> {
141 if seconds <= Self::MAX {
142 Some(Self(seconds))
143 } else {
144 None
145 }
146 }
147
148 #[must_use]
150 pub const fn seconds(self) -> u8 {
151 self.0
152 }
153}
154
155#[cfg(test)]
160mod tests {
161 use super::*;
162
163 #[test]
164 fn voice_channel_numbers() {
165 assert_eq!(VoiceChannel::Ch1.number(), 1);
166 assert_eq!(VoiceChannel::Ch2.number(), 2);
167 assert_eq!(VoiceChannel::Ch3.number(), 3);
168 assert_eq!(VoiceChannel::Ch4.number(), 4);
169 }
170
171 #[test]
172 fn voice_channel_max_durations() {
173 assert_eq!(VoiceChannel::Ch1.max_duration_secs(), 30);
174 assert_eq!(VoiceChannel::Ch2.max_duration_secs(), 15);
175 assert_eq!(VoiceChannel::Ch3.max_duration_secs(), 15);
176 assert_eq!(VoiceChannel::Ch4.max_duration_secs(), 15);
177 }
178
179 #[test]
180 fn voice_message_default() {
181 let msg = VoiceMessage::default();
182 assert_eq!(msg.channel, VoiceChannel::Ch1);
183 assert_eq!(msg.duration_secs, 0);
184 assert!(!msg.repeat);
185 }
186
187 #[test]
188 fn voice_message_name_valid() {
189 let name = VoiceMessageName::new("CQ Call").unwrap();
190 assert_eq!(name.as_str(), "CQ Call");
191 }
192
193 #[test]
194 fn voice_message_name_max_length() {
195 let name = VoiceMessageName::new("12345678").unwrap();
196 assert_eq!(name.as_str().len(), 8);
197 }
198
199 #[test]
200 fn voice_message_name_too_long() {
201 assert!(VoiceMessageName::new("123456789").is_none());
202 }
203
204 #[test]
205 fn repeat_interval_valid_range() {
206 assert!(RepeatInterval::new(0).is_some());
207 assert!(RepeatInterval::new(30).is_some());
208 assert!(RepeatInterval::new(60).is_some());
209 }
210
211 #[test]
212 fn repeat_interval_invalid() {
213 assert!(RepeatInterval::new(61).is_none());
214 }
215
216 #[test]
217 fn repeat_interval_value() {
218 let interval = RepeatInterval::new(45).unwrap();
219 assert_eq!(interval.seconds(), 45);
220 }
221
222 #[test]
223 fn repeat_interval_default() {
224 let interval = RepeatInterval::default();
225 assert_eq!(interval.seconds(), 0);
226 }
227}