toe_beans/v4/message/
sname.rs1use crate::v4::error::Result;
2use std::{
3 cmp::Ordering,
4 ffi::{CStr, CString},
5};
6
7#[derive(Debug, PartialEq)]
17pub struct SName([u8; 64]);
18
19impl SName {
20 pub fn new(name: &CStr) -> Result<Self> {
23 let bytes = name.to_bytes_with_nul();
24 match bytes.len().cmp(&64) {
25 Ordering::Less => {
26 let mut padding = [0u8; 64];
27 bytes
28 .iter()
29 .enumerate()
30 .for_each(|(i, byte)| padding[i] = *byte);
31 Ok(Self(padding))
32 }
33 Ordering::Equal => Ok(Self(bytes.try_into().unwrap())),
34 Ordering::Greater => Err("SName does not fit in a 64 byte array"),
35 }
36 }
37
38 pub fn from_slice_unchecked(name: &[u8]) -> Self {
45 Self(name.try_into().unwrap())
46 }
47
48 pub const EMPTY: Self = Self([0; 64]);
52
53 pub fn to_string(&self) -> CString {
56 CStr::from_bytes_until_nul(&self.0).unwrap().to_owned()
57 }
58
59 pub fn len(&self) -> usize {
65 64
66 }
67}
68
69impl From<&SName> for [u8; 64] {
70 fn from(sname: &SName) -> Self {
71 sname.0
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78
79 #[test]
80 fn test_new_sname_below_length() {
81 let sname = SName::new(c"12345");
82 assert!(sname.is_ok());
83 }
84
85 #[test]
86 fn test_new_sname_at_length() {
87 let sname = SName::new(c"123451234512345123451234512345123451234512345123451234512345123");
89 assert!(sname.is_ok());
90 }
91
92 #[test]
93 fn test_new_sname_above_length() {
94 let sname = SName::new(c"1234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345123451234512345");
95 assert!(sname.is_err());
96 }
97
98 #[test]
99 fn test_empty() {
100 let sname = SName::EMPTY;
101 assert_eq!(sname.0, [0; 64]);
102 }
103}