seq_marked/marked/
impl_try_from_meta_bytes.rs

1use std::io;
2
3use crate::Marked;
4
5impl<M> TryFrom<Marked<(Option<M>, Vec<u8>)>> for Marked<(Option<M>, String)> {
6    type Error = io::Error;
7
8    fn try_from(marked: Marked<(Option<M>, Vec<u8>)>) -> Result<Self, Self::Error> {
9        match marked {
10            Marked::TombStone => Ok(Marked::TombStone),
11            Marked::Normal((meta, value)) => {
12                let s = String::from_utf8(value).map_err(|e| {
13                    io::Error::new(
14                        io::ErrorKind::InvalidData,
15                        format!("fail to convert Vec<u8> to String: {}", e),
16                    )
17                })?;
18
19                Ok(Marked::Normal((meta, s)))
20            }
21        }
22    }
23}
24
25impl<M> From<Marked<(Option<M>, String)>> for Marked<(Option<M>, Vec<u8>)> {
26    /// Convert `Marked<String>` to `Marked<Vec<u8>>`
27    fn from(value: Marked<(Option<M>, String)>) -> Self {
28        match value {
29            Marked::TombStone => Marked::TombStone,
30            Marked::Normal((meta, value)) => {
31                let v = value.into_bytes();
32                Marked::Normal((meta, v))
33            }
34        }
35    }
36}
37
38#[cfg(test)]
39mod tests {
40    use super::*;
41
42    #[test]
43    fn test_try_from_bytes_to_string_success() {
44        let marked = Marked::Normal((Some("metadata"), "hello".as_bytes().to_vec()));
45        let result: Result<Marked<(Option<&str>, String)>, _> = marked.try_into();
46
47        assert!(result.is_ok());
48        let converted = result.unwrap();
49        assert_eq!(
50            converted,
51            Marked::Normal((Some("metadata"), "hello".to_string()))
52        );
53    }
54
55    #[test]
56    fn test_try_from_bytes_to_string_without_meta() {
57        let marked = Marked::Normal((None::<String>, "world".as_bytes().to_vec()));
58        let result: Result<Marked<(Option<String>, String)>, _> = marked.try_into();
59
60        assert!(result.is_ok());
61        let converted = result.unwrap();
62        assert_eq!(converted, Marked::Normal((None, "world".to_string())));
63    }
64
65    #[test]
66    fn test_try_from_bytes_to_string_tombstone() {
67        let marked = Marked::<(Option<String>, Vec<u8>)>::TombStone;
68        let result: Result<Marked<(Option<String>, String)>, _> = marked.try_into();
69
70        assert!(result.is_ok());
71        let converted = result.unwrap();
72        assert_eq!(converted, Marked::TombStone);
73    }
74
75    #[test]
76    fn test_try_from_bytes_to_string_invalid_utf8() {
77        let invalid_bytes = vec![0xFF, 0xFE, 0xFD];
78        let marked = Marked::Normal((Some("test"), invalid_bytes));
79        let result: Result<Marked<(Option<&str>, String)>, _> = marked.try_into();
80
81        assert!(result.is_err());
82        let error = result.unwrap_err();
83        assert_eq!(error.kind(), io::ErrorKind::InvalidData);
84        assert!(error.to_string().contains("fail to convert Vec<u8> to String"));
85    }
86
87    #[test]
88    fn test_from_string_to_bytes() {
89        let marked = Marked::Normal((Some("metadata"), "hello".to_string()));
90        let converted: Marked<(Option<&str>, Vec<u8>)> = marked.into();
91
92        assert_eq!(
93            converted,
94            Marked::Normal((Some("metadata"), "hello".as_bytes().to_vec()))
95        );
96    }
97
98    #[test]
99    fn test_from_string_to_bytes_without_meta() {
100        let marked = Marked::Normal((None::<String>, "world".to_string()));
101        let converted: Marked<(Option<String>, Vec<u8>)> = marked.into();
102
103        assert_eq!(
104            converted,
105            Marked::Normal((None, "world".as_bytes().to_vec()))
106        );
107    }
108
109    #[test]
110    fn test_from_string_to_bytes_tombstone() {
111        let marked = Marked::<(Option<String>, String)>::TombStone;
112        let converted: Marked<(Option<String>, Vec<u8>)> = marked.into();
113
114        assert_eq!(converted, Marked::TombStone);
115    }
116}