vize_l1 0.523.0

L1 - the lossless Vue-template surface tree (codename Sinopia, Davinci P2-7)
Documentation
use vize_l0::{Allocator, Span};

use super::{DecodeSegmentKind, EmbedSource, SourceError, prepare_attribute_value};

#[test]
fn identity_slices_borrow_exact_utf8_and_preserve_file_offsets_without_allocating() {
    let allocator = Allocator::default();
    let source = EmbedSource::authored("zzαβγzz", Span::new(2, 8)).unwrap();
    let allocated = allocator.allocated_bytes();
    let piece = source.slice_in(&allocator, Span::new(2, 4)).unwrap();
    assert_eq!(piece.text(), "β");
    assert_eq!(piece.span(), Span::new(4, 6));
    assert!(piece.decode_map().is_none());
    assert_eq!(
        piece.text().as_ptr(),
        source.text().get(2..4).unwrap().as_ptr()
    );
    assert_eq!(piece.authored_span(Span::new(0, 2)), Ok(Span::new(4, 6)));
    assert_eq!(allocator.allocated_bytes(), allocated);
}

#[test]
fn derived_map_shortens_identity_segments_and_keeps_complete_entity_atoms() {
    let allocator = Allocator::default();
    let source =
        prepare_attribute_value(&allocator, "zzabfjc∾̳dezz", Span::new(2, 19)).unwrap();
    let piece = source.slice_in(&allocator, Span::new(1, 11)).unwrap();
    assert_eq!(piece.text(), "bfjc∾̳d");
    assert_eq!(piece.span(), Span::new(3, 18));
    let map = piece.decode_map().unwrap();
    let expected = [
        (
            Span::new(0, 1),
            Span::new(3, 4),
            DecodeSegmentKind::Identity,
        ),
        (Span::new(1, 3), Span::new(4, 11), DecodeSegmentKind::Entity),
        (
            Span::new(3, 4),
            Span::new(11, 12),
            DecodeSegmentKind::Identity,
        ),
        (
            Span::new(4, 9),
            Span::new(12, 17),
            DecodeSegmentKind::Entity,
        ),
        (
            Span::new(9, 10),
            Span::new(17, 18),
            DecodeSegmentKind::Identity,
        ),
    ];
    assert_eq!(map.segments().len(), expected.len());
    for (segment, (decoded, authored, kind)) in map.segments().iter().zip(expected) {
        assert_eq!(segment.decoded(), decoded);
        assert_eq!(segment.authored(), authored);
        assert_eq!(segment.kind(), kind);
    }
    let nested = piece.slice_in(&allocator, Span::new(1, 9)).unwrap();
    assert_eq!(nested.text(), "fjc∾̳");
    assert_eq!(nested.span(), Span::new(4, 17));
    assert_eq!(nested.authored_span(Span::new(0, 2)), Ok(Span::new(4, 11)));
    assert_eq!(nested.authored_span(Span::new(3, 8)), Ok(Span::new(12, 17)));
}

#[test]
fn full_map_and_identity_only_or_empty_pieces_avoid_new_storage() {
    let allocator = Allocator::default();
    let source =
        prepare_attribute_value(&allocator, "zzabcfjdefzz", Span::new(2, 15)).unwrap();
    let allocated = allocator.allocated_bytes();
    let full = source.slice_in(&allocator, Span::new(0, 8)).unwrap();
    assert_eq!(
        full.decode_map().unwrap().segments().as_ptr(),
        source.decode_map().unwrap().segments().as_ptr()
    );
    let identity = source.slice_in(&allocator, Span::new(1, 3)).unwrap();
    assert_eq!(identity.text(), "bc");
    assert_eq!(identity.span(), Span::new(3, 5));
    assert!(identity.decode_map().is_none());
    let empty = source.slice_in(&allocator, Span::new(3, 3)).unwrap();
    assert_eq!(empty.text(), "");
    assert_eq!(empty.span(), Span::new(5, 5));
    assert!(empty.decode_map().is_none());
    assert_eq!(allocator.allocated_bytes(), allocated);
}

#[test]
fn cuts_reject_partial_entities_and_invalid_utf8_ranges() {
    let allocator = Allocator::default();
    let source = prepare_attribute_value(&allocator, "zzfjzz", Span::new(2, 9)).unwrap();
    for span in [Span::new(0, 1), Span::new(1, 1), Span::new(1, 2)] {
        assert_eq!(
            source.slice_in(&allocator, span).unwrap_err(),
            SourceError::PartialEntityBoundary
        );
    }
    for span in [Span::new(2, 1), Span::new(0, u32::MAX)] {
        assert_eq!(
            source.slice_in(&allocator, span).unwrap_err(),
            SourceError::InvalidDecodedSpan
        );
    }
    let unicode = prepare_attribute_value(&allocator, "zz∾̳zz", Span::new(2, 7)).unwrap();
    assert_eq!(
        unicode.slice_in(&allocator, Span::new(1, 2)).unwrap_err(),
        SourceError::InvalidDecodedSpan
    );
    assert_eq!(
        unicode.slice_in(&allocator, Span::new(3, 3)).unwrap_err(),
        SourceError::PartialEntityBoundary
    );
    assert_eq!(
        unicode.slice_in(&allocator, Span::new(0, 3)).unwrap_err(),
        SourceError::PartialEntityBoundary
    );
}

#[test]
fn a_piece_never_decodes_a_previously_decoded_reference_again() {
    let allocator = Allocator::default();
    let source = prepare_attribute_value(&allocator, "zza&bzz", Span::new(2, 13)).unwrap();
    let piece = source.slice_in(&allocator, Span::new(1, 6)).unwrap();
    assert_eq!(piece.text(), "&");
    assert_eq!(piece.span(), Span::new(3, 12));
    assert_eq!(piece.authored_span(Span::new(0, 1)), Ok(Span::new(3, 8)));
    assert_eq!(piece.authored_span(Span::new(1, 5)), Ok(Span::new(8, 12)));
}

#[test]
fn every_piece_utf8_range_preserves_parent_exact_and_covering_projections() {
    let allocator = Allocator::default();
    let source =
        prepare_attribute_value(&allocator, "zzafjb∾̳czz", Span::new(2, 17)).unwrap();
    let piece = source.slice_in(&allocator, Span::new(1, 9)).unwrap();
    for start in 0..=piece.text().len() {
        for end in start..=piece.text().len() {
            let child = Span::new(start as u32, end as u32);
            let parent = Span::new(start as u32 + 1, end as u32 + 1);
            assert_eq!(piece.authored_span(child), source.authored_span(parent));
            assert_eq!(
                piece.authored_covering_span(child),
                source.authored_covering_span(parent)
            );
        }
    }
}