byte_style_encoder/
lib.rs

1use std::fmt::{Display, Formatter};
2
3use bitvec::order::Msb0;
4use bitvec::vec::BitVec;
5use nom::{Finish, IResult};
6use nom::bits::complete::tag as bit_tag;
7use nom::branch::alt;
8use nom::bytes::complete::tag as byte_tag;
9use nom::character::complete::multispace0;
10use nom::combinator::map;
11use nom::multi::many0;
12use nom::sequence::preceded;
13
14use crate::error::{ByteStyleError, ByteStyleResult};
15
16pub mod error;
17
18const BYTE_STYLE_A: &str = "追求极致";
19const BYTE_STYLE_B: &str = "务实敢为";
20const BYTE_STYLE_C: &str = "开放谦逊";
21const BYTE_STYLE_D: &str = "始终创业";
22const BYTE_STYLE_E: &str = "多元兼容";
23
24pub fn encode_to_byte_style(input: &str) -> ByteStyleResult<String> {
25    Ok(Words::parse_from_bits((input.as_bytes(), 0)).finish().map_err(
26        |e| ByteStyleError::Parse(format!("unable to parse from bit: {:?}", e))
27    )?.1.to_string())
28}
29
30pub fn decode_from_byte_style(input: &str) -> ByteStyleResult<String> {
31    let decoded_bytes = Words::parse_from_byte_style(input).finish().map_err(
32        |e| ByteStyleError::Parse(format!("unable to parse from byte style: {:?}", e))
33    )?.1.to_bytes();
34    let decoded = String::from_utf8(decoded_bytes)?;
35    Ok(decoded)
36}
37
38#[derive(Debug)]
39struct Word(&'static str);
40
41impl Word {
42    fn parse_from_bits(input: (&[u8], usize)) -> IResult<(&[u8], usize), Self> {
43        alt((
44            map(bit_tag(0b000_u8, 3_u8), |_| Self(BYTE_STYLE_A)),
45            map(bit_tag(0b001_u8, 3_u8), |_| Self(BYTE_STYLE_B)),
46            map(bit_tag(0b00_u8, 2_u8), |_| Self(BYTE_STYLE_A)),
47            map(bit_tag(0b01_u8, 2_u8), |_| Self(BYTE_STYLE_C)),
48            map(bit_tag(0b10_u8, 2_u8), |_| Self(BYTE_STYLE_D)),
49            map(bit_tag(0b11_u8, 2_u8), |_| Self(BYTE_STYLE_E)),
50            map(bit_tag(0b0_u8, 1_u8), |_| Self(BYTE_STYLE_C)),
51            map(bit_tag(0b1_u8, 1_u8), |_| Self(BYTE_STYLE_D)),
52        ))(input)
53    }
54
55    fn parse_from_byte_style(input: &str) -> IResult<&str, Self> {
56        alt((
57            map(byte_tag(BYTE_STYLE_A), |_| Self(BYTE_STYLE_A)),
58            map(byte_tag(BYTE_STYLE_B), |_| Self(BYTE_STYLE_B)),
59            map(byte_tag(BYTE_STYLE_C), |_| Self(BYTE_STYLE_C)),
60            map(byte_tag(BYTE_STYLE_D), |_| Self(BYTE_STYLE_D)),
61            map(byte_tag(BYTE_STYLE_E), |_| Self(BYTE_STYLE_E)),
62        ))(input)
63    }
64}
65
66impl ToString for Word {
67    fn to_string(&self) -> String {
68        self.0.to_string()
69    }
70}
71
72#[derive(Debug)]
73struct Words(pub Vec<Word>);
74
75impl Words {
76    fn parse_from_bits(input: (&[u8], usize)) -> IResult<(&[u8], usize), Self> {
77        map(many0(Word::parse_from_bits), Self)(input)
78    }
79
80    fn parse_from_byte_style(input: &str) -> IResult<&str, Self> {
81        map(many0(preceded(multispace0, Word::parse_from_byte_style)), Self)(input)
82    }
83
84    fn to_bytes(&self) -> Vec<u8> {
85        let mut bit_vec: BitVec<Msb0, u8> = BitVec::with_capacity(self.0.len() * 3);
86        self.0.iter().for_each(|w| match w.0 {
87            BYTE_STYLE_A => bit_vec.extend([false, false, false]),
88            BYTE_STYLE_B => bit_vec.extend([false, false, true]),
89            BYTE_STYLE_C => bit_vec.extend([false, true]),
90            BYTE_STYLE_D => bit_vec.extend([true, false]),
91            BYTE_STYLE_E => bit_vec.extend([true, true]),
92            _ => { unreachable!() }
93        });
94        for _ in 0..(bit_vec.len() % 8) {
95            bit_vec.pop();
96        }
97        bit_vec.into_vec()
98    }
99}
100
101impl Display for Words {
102    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
103        let vec = self.0.iter().map(|word| word.to_string()).collect::<Vec<_>>();
104        write!(f, "{}", vec.join(" "))
105    }
106}
107
108#[cfg(test)]
109mod tests {
110    use nom::Finish;
111
112    use super::*;
113
114    #[test]
115    fn test_encode() {
116        let bytes = "已删除".as_bytes();
117        let encoded = Words::parse_from_bits((bytes, 0)).finish().unwrap().1.to_string();
118        assert_eq!(encoded, "多元兼容 始终创业 开放谦逊 开放谦逊 始终创业 多元兼容 开放谦逊 多元兼容 始终创业 多元兼容 务实敢为 开放谦逊 多元兼容 务实敢为 开放谦逊 始终创业 务实敢为 追求极致 始终创业 始终创业 追求极致 开放谦逊 多元兼容 开放谦逊 务实敢为 始终创业 开放谦逊 始终创业 开放谦逊 始终创业 始终创业 开放谦逊 追求极致");
119    }
120
121    #[test]
122    fn test_decode() {
123        println!("{:?}", "已删除".as_bytes());
124        let words = "多元兼容 始终创业 开放谦逊 开放谦逊 始终创业 多元兼容 开放谦逊 多元兼容 始终创业 多元兼容 务实敢为 开放谦逊 多元兼容 务实敢为 开放谦逊 始终创业 务实敢为 追求极致 始终创业 始终创业 追求极致 开放谦逊 多元兼容 开放谦逊 务实敢为 始终创业 开放谦逊 始终创业 开放谦逊 始终创业 始终创业 开放谦逊 追求极致";
125        let decoded_bytes = Words::parse_from_byte_style(words).finish().unwrap().1.to_bytes();
126        let decoded = String::from_utf8(decoded_bytes).unwrap();
127        assert_eq!(decoded, "已删除");
128    }
129}