toe_beans/v4/message/options/
file.rs

1use crate::v4::error::Result;
2use serde::{Deserialize, Serialize};
3use std::ffi::{CStr, CString};
4
5/// Similar to the File struct, used for the fixed-length Message file field,
6/// but is a variable-length option used for the Message options field.
7///
8/// A null-terminated string with min-length 1.
9#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
10pub struct FileOption(CString);
11
12impl FileOption {
13    /// Construct a valid file field.
14    pub fn new(name: &CStr) -> Result<Self> {
15        if name.count_bytes() + 1 >= 255 {
16            return Err("Larger than 255 octets for a single option");
17        }
18
19        Ok(Self(name.to_owned()))
20    }
21
22    /// Get the `CString` that this type wraps.
23    pub fn to_string(self) -> CString {
24        self.0
25    }
26
27    /// Get the length of FileOption (WITH the null byte).
28    pub fn len(&self) -> usize {
29        self.0.count_bytes() + 1
30    }
31
32    #[inline]
33    /// Used to encode the variable-length option.
34    pub fn extend_into(&self, bytes: &mut Vec<u8>, tag: u8) {
35        bytes.push(tag); // tag
36        bytes.push(self.len() as u8); // length
37        bytes.extend_from_slice(self.0.to_bytes_with_nul()); // value
38    }
39}
40
41impl From<&[u8]> for FileOption {
42    fn from(value: &[u8]) -> Self {
43        Self(CStr::from_bytes_with_nul(value).unwrap().to_owned())
44    }
45}