1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
use std::str::Chars; #[derive(Debug, PartialEq, Clone)] pub enum Data { Single(String), Vector(Vec<(usize, Data)>), } impl Data { pub fn to_str(&self) -> String { match self { Data::Single(s) => String::from(&s[..]), _ => String::new(), } } pub fn to_vec(&self) -> Vec<(usize, Data)> { match self { Data::Vector(v) => (*v).to_vec(), _ => Vec::new(), } } } pub(crate) fn parse(code: &str, max: usize) -> Vec<(usize, Data)> { let mut chars = code.chars(); (0usize..=max) .filter_map(|_| parse_code(&mut chars)) .map(|code| match code.0 { 26..=51 => (code.0, Data::Vector(inner_parse(&code.1, 99))), 80..=99 => (code.0, Data::Vector(inner_parse(&code.1, 99))), 62 => (code.0, Data::Vector(inner_parse(&code.1, 25))), _ => (code.0, Data::Single(code.1)), }) .collect() } pub(crate) fn inner_parse(code: &str, max: usize) -> Vec<(usize, Data)> { let mut chars = code.chars(); (0usize..=max) .filter_map(|_| parse_code(&mut chars)) .map(|code| (code.0, Data::Single(code.1))) .collect() } fn parse_code(chars: &mut Chars) -> Option<(usize, String)> { match ( chars.take(2).collect::<String>().parse(), chars.take(2).collect::<String>().parse(), ) { (Ok(id), Ok(len)) => { let value: String = chars.take(len).collect(); Some((id, value)) } _ => None, } } #[cfg(test)] mod test { use super::{parse, Data}; #[test] fn helloworld_in_tag_00() { let code = "0011hello-world"; let expected = vec![(0usize, Data::Single(String::from("hello-world")))]; assert_eq!(parse(code, 99), expected); } #[test] fn code_with_inner_values() { let code = "00020104141234567890123426580014BR.GOV.BCB.PIX0136123e4567-e12b-12d1-a456-426655440000"; let expected = vec![ (0usize, Data::Single("01".to_string())), (4usize, Data::Single("12345678901234".to_string())), ( 26, Data::Vector(vec![ (0usize, Data::Single("BR.GOV.BCB.PIX".to_string())), ( 1usize, Data::Single("123e4567-e12b-12d1-a456-426655440000".to_string()), ), ]), ), ]; assert_eq!(parse(code, 99), expected); } }