brcode/
emit.rs

1use crate::parse::Data;
2
3pub(crate) fn emit(code: &[(usize, Data)]) -> String {
4    code.iter()
5        .map(|e| match &e.1 {
6            Data::Single(s) => format!("{:02}{:02}{}", e.0, s.len(), s),
7            Data::Vector(v) => {
8                let inner = v
9                    .iter()
10                    .map(|ve| match &ve.1 {
11                        Data::Single(vs) => (vs.len(), format!("{:02}{:02}{}", ve.0, vs.len(), vs)),
12                        _ => (0, String::new()),
13                    })
14                    .fold((0usize, String::new()), |acc, e| {
15                        (acc.0 + e.0 + 4, acc.1 + &e.1)
16                    });
17                format!("{:02}{:02}{}", e.0, inner.0, inner.1)
18            }
19        })
20        .collect::<String>()
21}
22
23#[cfg(test)]
24mod test {
25    use super::emit;
26    use crate::from_str;
27
28    #[test]
29    fn emits_same_data_as_receives() {
30        let code = "00020104141234567890123426580014BR.GOV.BCB.PIX0136123e4567-e12b-12d1-a456-42665544000027300012BR.COM.OUTRO011001234567895204000053039865406123.455802BR5917NOME DO RECEBEDOR6008BRASILIA61087007490062190515RP12345678-201980390012BR.COM.OUTRO01190123.ABCD.3456.WXYZ6304AD38";
31        let parsed_data = from_str(code);
32        let emited = emit(&parsed_data);
33
34        assert_eq!(code, emited);
35    }
36
37    #[test]
38    fn helloworld_in_tag_00() {
39        let code = "26062602oi";
40        let parsed_data = from_str(code);
41        let emited = emit(&parsed_data);
42
43        assert_eq!(code, emited);
44    }
45}