1use crate::vlq::vlq_decode;
2use crate::{DecodeError, Line, Segment, SourceMapMappings};
3
4pub fn decode(input: &str) -> Result<SourceMapMappings, DecodeError> {
20 if input.is_empty() {
21 return Ok(Vec::new());
22 }
23
24 let bytes = input.as_bytes();
25 let len = bytes.len();
26
27 let line_count = bytes.iter().filter(|&&b| b == b';').count() + 1;
29 let mut mappings: SourceMapMappings = Vec::with_capacity(line_count);
30
31 let mut source_index: i64 = 0;
33 let mut original_line: i64 = 0;
34 let mut original_column: i64 = 0;
35 let mut name_index: i64 = 0;
36
37 let mut pos: usize = 0;
38
39 loop {
40 let mut generated_column: i64 = 0;
42 let mut line: Line = Vec::new();
43 let mut saw_semicolon = false;
44
45 while pos < len {
46 let byte = bytes[pos];
47
48 if byte == b';' {
49 pos += 1;
50 saw_semicolon = true;
51 break;
52 }
53
54 if byte == b',' {
55 pos += 1;
56 continue;
57 }
58
59 let mut segment: Segment = Vec::with_capacity(5);
61
62 let (delta, consumed) = vlq_decode(bytes, pos)?;
64 generated_column += delta;
65 segment.push(generated_column);
66 pos += consumed;
67
68 if pos < len && bytes[pos] != b',' && bytes[pos] != b';' {
70 let (delta, consumed) = vlq_decode(bytes, pos)?;
72 source_index += delta;
73 segment.push(source_index);
74 pos += consumed;
75
76 let (delta, consumed) = vlq_decode(bytes, pos)?;
78 original_line += delta;
79 segment.push(original_line);
80 pos += consumed;
81
82 let (delta, consumed) = vlq_decode(bytes, pos)?;
84 original_column += delta;
85 segment.push(original_column);
86 pos += consumed;
87
88 if pos < len && bytes[pos] != b',' && bytes[pos] != b';' {
90 let (delta, consumed) = vlq_decode(bytes, pos)?;
91 name_index += delta;
92 segment.push(name_index);
93 pos += consumed;
94 }
95 }
96
97 debug_assert!(
98 segment.len() == 1 || segment.len() == 4 || segment.len() == 5,
99 "invalid segment length {}",
100 segment.len()
101 );
102
103 line.push(segment);
104 }
105
106 mappings.push(line);
107
108 if !saw_semicolon {
109 break;
110 }
111 }
112
113 Ok(mappings)
114}