#![allow(clippy::print_stdout, reason = "Examples are intended to print walkthrough output")]
use srcmap_codec::{DecodeError, Segment, decode, encode};
fn main() {
let mappings_str = "AAAA,IAAA;EACEC;IAEE;;A";
println!("=== Source Map Codec Roundtrip ===\n");
println!("Input mappings: {mappings_str:?}\n");
let mappings = decode(mappings_str).expect("valid mappings string");
println!("Decoded {} lines:\n", mappings.len());
for (line_idx, line) in mappings.iter().enumerate() {
if line.is_empty() {
println!(" Line {line_idx}: (empty)");
continue;
}
println!(" Line {line_idx}: {} segment(s)", line.len());
for (seg_idx, segment) in line.iter().enumerate() {
match segment.len() {
1 => {
println!(" [{seg_idx}] 1-field: generated_col={}", segment[0],);
}
4 => {
println!(
" [{seg_idx}] 4-field: generated_col={}, source={}, orig_line={}, orig_col={}",
segment[0], segment[1], segment[2], segment[3],
);
}
5 => {
println!(
" [{seg_idx}] 5-field: generated_col={}, source={}, orig_line={}, orig_col={}, name={}",
segment[0], segment[1], segment[2], segment[3], segment[4],
);
}
other => {
println!(" [{seg_idx}] unexpected {other}-field segment");
}
}
}
}
println!("\n--- Shifting all generated columns by +4 ---\n");
let shifted: Vec<Vec<Segment>> = mappings
.iter()
.map(|line| {
line.iter()
.map(|seg| match seg.len() {
1 => Segment::one(seg[0] + 4),
4 => Segment::four(seg[0] + 4, seg[1], seg[2], seg[3]),
5 => Segment::five(seg[0] + 4, seg[1], seg[2], seg[3], seg[4]),
_ => *seg,
})
.collect()
})
.collect();
let encoded_original = encode(&mappings);
let encoded_shifted = encode(&shifted);
println!("Original re-encoded: {encoded_original:?}");
println!("Shifted re-encoded: {encoded_shifted:?}\n");
assert_eq!(encoded_original, mappings_str, "roundtrip must produce identical output");
println!("Roundtrip verified: original encodes back to the same string.");
let re_decoded = decode(&encoded_shifted).expect("shifted mappings should be valid");
for (line_idx, (orig_line, shifted_line)) in mappings.iter().zip(re_decoded.iter()).enumerate()
{
assert_eq!(orig_line.len(), shifted_line.len(), "line {line_idx} segment count must match");
for (seg_idx, (orig_seg, shifted_seg)) in
orig_line.iter().zip(shifted_line.iter()).enumerate()
{
assert_eq!(
shifted_seg[0],
orig_seg[0] + 4,
"line {line_idx} segment {seg_idx}: generated column must be shifted by 4"
);
}
}
println!("Shift verified: all generated columns increased by 4.\n");
println!("--- Error handling ---\n");
match decode("AA!A") {
Err(DecodeError::InvalidBase64 { byte, offset }) => {
println!(
"InvalidBase64: byte 0x{byte:02x} ({:?}) at offset {offset}",
char::from(byte),
);
}
other => panic!("expected InvalidBase64, got {other:?}"),
}
match decode("g") {
Err(DecodeError::UnexpectedEof { offset }) => {
println!("UnexpectedEof: at offset {offset}");
}
other => panic!("expected UnexpectedEof, got {other:?}"),
}
match decode("AC") {
Err(DecodeError::InvalidSegmentLength { fields, offset }) => {
println!("InvalidSegmentLength: {fields} fields at offset {offset}");
}
other => panic!("expected InvalidSegmentLength, got {other:?}"),
}
match decode("gggggggggggggg") {
Err(DecodeError::VlqOverflow { offset }) => {
println!("VlqOverflow: at offset {offset}");
}
other => panic!("expected VlqOverflow, got {other:?}"),
}
println!("\nAll assertions passed.");
}