gcd_rs/record/
text.rs

1use byteorder::ByteOrder;
2use serde::{Deserialize, Serialize};
3use std::fmt::{Display, Formatter};
4use std::io::Result;
5
6use crate::RecordHeader;
7
8#[derive(Debug, PartialEq, Hash, Eq, Clone, Serialize, Deserialize)]
9pub enum TextRecord {
10    Simple(String),
11    Blob(Vec<u8>),
12}
13
14impl Display for TextRecord {
15    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
16        match self {
17            TextRecord::Simple(x) => write!(f, "TextRecord:Simple({})", x),
18            TextRecord::Blob(x) => {
19                write!(f, "TextRecord:Blob(len: {})", x.len())
20            }
21        }
22    }
23}
24
25pub const ID: u16 = 5;
26
27impl TextRecord {
28    pub fn new<F: std::io::Read>(file: &mut F, lenght: u16) -> Result<Self> {
29        let mut data = vec![0; lenght as usize];
30        file.read_exact(&mut data)?;
31        match core::str::from_utf8(&data) {
32            Ok(_) => Ok(TextRecord::Simple(unsafe {
33                //allowed because the check was done on "core::str::from_utf8"
34                String::from_utf8_unchecked(data)
35            })),
36            Err(_) => Ok(TextRecord::Blob(data)),
37        }
38    }
39    pub fn len(&self) -> u16 {
40        match self {
41            TextRecord::Simple(data) => data.len() as u16,
42            TextRecord::Blob(data) => data.len() as u16,
43        }
44    }
45    pub fn value(&self) -> &[u8] {
46        match self {
47            TextRecord::Simple(x) => x.as_bytes(),
48            TextRecord::Blob(x) => &x,
49        }
50    }
51    pub fn record_to_raw<B: ByteOrder>(&self, data: &mut [u8]) -> Result<()> {
52        //write header
53        let next = RecordHeader::Text(self.len()).to_raw::<B>(data)?;
54        next[..self.len() as usize].copy_from_slice(self.value());
55        Ok(())
56    }
57}