1use crate::text::BLANK_CHAR;
2use crate::text_prob::TextProb;
3use modular_bitfield_msb::prelude::*;
4
5pub const MAX_RADIOTEXT_LEN: usize = 64;
6pub const END_OF_MESSAGE_CHAR: u8 = 0x0d;
7
8#[derive(Debug, Clone, PartialEq, Eq)]
10pub struct Radiotext {
11 pub display: [u8; MAX_RADIOTEXT_LEN],
13 pvt: TextProb<MAX_RADIOTEXT_LEN>,
14}
15
16impl Default for Radiotext {
17 fn default() -> Self {
18 Self {
19 display: [BLANK_CHAR; MAX_RADIOTEXT_LEN],
20 pvt: TextProb::default(),
21 }
22 }
23}
24
25#[derive(BitfieldSpecifier, Debug, Default, Clone, Copy, PartialEq, Eq)]
27#[bits = 1]
28pub enum RtVariant {
29 #[default]
30 A,
31 B,
32}
33
34#[derive(Debug, Default, Clone, PartialEq, Eq)]
35pub struct RtData {
36 pub a: Radiotext, pub b: Radiotext, pub decode_rt: RtVariant, }
40
41impl Radiotext {
42 pub fn reset(&mut self) {
43 self.display.fill(BLANK_CHAR);
44 }
45
46 pub fn update_rt_simple(&mut self, addr: usize, char_pairs: &[Option<[u8; 2]>]) {
50 let mut idx = addr;
51
52 let mut add_pair = |pair: &Option<[u8; 2]>| -> bool {
55 if pair.is_none() {
56 return false;
57 }
58 for ch in pair.unwrap() {
59 if ch == END_OF_MESSAGE_CHAR {
60 self.display[idx..].fill(BLANK_CHAR);
61 return true;
62 }
63 self.display[idx] = ch;
64 idx += 1;
65 }
66 false
67 };
68
69 let eom = add_pair(&char_pairs[0]);
70 if !eom && char_pairs.len() > 1 {
71 add_pair(&char_pairs[1]);
72 }
73 }
74
75 pub fn update_rt_advance(&mut self, addr: usize, char_pairs: &[Option<[u8; 2]>]) {
76 let mut idx = addr;
77
78 let mut add_pair = |pair: &Option<[u8; 2]>| {
79 if pair.is_none() {
80 return;
81 }
82 for ch in pair.unwrap() {
83 self.pvt.update(idx, ch);
84 idx += 1;
85 }
86 };
87
88 add_pair(&char_pairs[0]);
89 if char_pairs.len() > 1 {
90 add_pair(&char_pairs[1]);
91 }
92 if !self.pvt.is_complete() {
93 return;
94 }
95 self.display.copy_from_slice(&self.pvt.hi_prob);
96 }
97
98 pub fn bump_rt_validation_count(&mut self) {
99 self.pvt.bump_rt_validation_count();
100 }
101}