intervalmap 0.1.1

An interval set/map library inspired by Boost.Icl
Documentation
//! Basic usage examples for the intervalmap library.

use intervalmap::{interval_map, interval_map::Entry, interval_set, IntervalMap, IntervalSet};

fn main() {
    println!("=== IntervalSet Examples ===\n");
    interval_set_examples();

    println!("\n=== IntervalMap Examples ===\n");
    interval_map_examples();

    println!("\n=== Macro Examples ===\n");
    macro_examples();

    println!("\n=== Different Index Types ===\n");
    different_index_types();

    println!("\n=== Utility Methods ===\n");
    utility_methods_examples();
}

fn interval_set_examples() {
    // Create an empty interval set
    let mut set: IntervalSet<u32> = IntervalSet::new();
    println!("Created empty IntervalSet: len = {}", set.len());

    // Insert intervals - overlapping ones are automatically merged
    set.insert(0..10);
    set.insert(5..15); // Merges with [0, 10) to form [0, 15)
    println!("After inserting 0..10 and 5..15: len = {}", set.len());

    // Query containment
    println!("Contains 7: {}", set.contains(7));
    println!("Contains 20: {}", set.contains(20));

    // Get the interval containing a point
    if let Some(interval) = set.get_interval(7) {
        println!("Interval containing 7: {:?}", interval);
    }

    // Insert a non-adjacent interval
    set.insert(30..40);
    println!("After inserting 30..40: len = {}", set.len());

    // Remove a portion
    set.remove(5..10);
    println!("After removing 5..10: len = {}", set.len());

    // Iterate over intervals
    print!("Current intervals: ");
    for interval in set.iter() {
        print!("{:?} ", interval);
    }
    println!();
}

fn interval_map_examples() {
    // Create an interval map
    let mut map: IntervalMap<u32, &str> = IntervalMap::new();

    // Insert intervals with values
    map.insert(0..10, "first");
    map.insert(20..30, "second");
    println!("After inserting two intervals: len = {}", map.len());

    // Query values at points
    println!("Value at 5: {:?}", map.get(5));
    println!("Value at 15: {:?}", map.get(15));
    println!("Value at 25: {:?}", map.get(25));

    // Overlapping inserts split existing intervals
    map.insert(5..15, "middle");
    println!("\nAfter inserting 5..15 -> 'middle': len = {}", map.len());
    println!("Value at 3: {:?}", map.get(3)); // "first" (from [0, 5))
    println!("Value at 7: {:?}", map.get(7)); // "middle" (from [5, 15))

    // Get interval and value together
    if let Some((interval, value)) = map.get_interval(7) {
        println!("Interval containing 7: {:?} -> {}", interval, value);
    }

    // Iterate over all entries
    println!("\nAll entries:");
    for (interval, value) in map.iter() {
        println!("  {:?} -> {}", interval, value);
    }

    // Entry API for conditional insertion
    let mut scores: IntervalMap<u32, i32> = IntervalMap::new();

    // Insert only if vacant
    match scores.entry(50) {
        Entry::Vacant(e) => {
            e.insert(40..60, 100);
            println!("\nInserted score 100 for range 40..60");
        }
        Entry::Occupied(e) => {
            println!("Point 50 already has score: {}", e.get());
        }
    }

    // or_insert pattern
    let score = scores.entry(50).or_insert(40..60, 200);
    println!("Score at 50 (unchanged): {}", score);

    // Modify existing value
    match scores.entry(50) {
        Entry::Occupied(mut e) => {
            *e.get_mut() += 50;
            println!("Updated score to: {}", e.get());
        }
        Entry::Vacant(_) => {}
    }
}

fn macro_examples() {
    // Create an interval set with the macro
    let set = interval_set! { 0..10, 20..30, 40..50 };
    println!("interval_set! with 3 ranges: len = {}", set.len());
    println!("Contains 5: {}", set.contains(5));
    println!("Contains 25: {}", set.contains(25));
    println!("Contains 35: {}", set.contains(35));

    // Empty set
    let empty: IntervalSet<u32> = interval_set! {};
    println!("Empty interval_set!: is_empty = {}", empty.is_empty());

    // Create an interval map with the macro
    let map = interval_map! {
        0..10 => "zero to ten",
        20..30 => "twenty to thirty",
    };
    println!("\ninterval_map! with 2 entries: len = {}", map.len());
    println!("Value at 5: {:?}", map.get(5));
    println!("Value at 25: {:?}", map.get(25));
}

fn different_index_types() {
    // Using i64 for signed intervals
    let mut signed_set: IntervalSet<i64> = IntervalSet::new();
    signed_set.insert(-100..0);
    signed_set.insert(0..100);
    println!("i64 IntervalSet:");
    println!("  Contains -50: {}", signed_set.contains(-50));
    println!("  Contains 50: {}", signed_set.contains(50));
    println!("  Len (merged): {}", signed_set.len());

    // Using u64 for large ranges
    let mut large_set: IntervalSet<u64> = IntervalSet::new();
    large_set.insert(0..1_000_000);
    large_set.insert(1_000_000_000..2_000_000_000);
    println!("\nu64 IntervalSet:");
    println!("  Contains 500_000: {}", large_set.contains(500_000));
    println!(
        "  Contains 1_500_000_000: {}",
        large_set.contains(1_500_000_000)
    );

    // Type annotation can be used with macros
    let typed_set: IntervalSet<i32> = interval_set! { -10..0, 0..10 };
    println!("\ni32 interval_set!: len = {}", typed_set.len());
}

fn utility_methods_examples() {
    // Create a set with multiple intervals
    let set = interval_set! { 0u32..10, 20..30, 40..50 };
    println!("Initial set: {:?}", set.iter().collect::<Vec<_>>());

    // -------------------------------------------------------------------------
    // Query Methods: first(), last(), span()
    // -------------------------------------------------------------------------
    println!("\n--- Query Methods ---");

    // first() - O(log n) access to first interval
    println!("first(): {:?}", set.first());

    // last() - O(log n) access to last interval
    println!("last(): {:?}", set.last());

    // span() - bounding interval from min to max
    println!("span(): {:?}", set.span());

    // -------------------------------------------------------------------------
    // Overlap and Coverage Checks
    // -------------------------------------------------------------------------
    println!("\n--- Overlap and Coverage ---");

    // overlaps() - check if any interval overlaps a range
    println!("overlaps(15..25): {}", set.overlaps(15..25)); // true - overlaps [20,30)
    println!("overlaps(10..20): {}", set.overlaps(10..20)); // false - gap between intervals
    println!("overlaps(35..45): {}", set.overlaps(35..45)); // true - overlaps [40,50)

    // covers() - check if entire range is covered
    println!("covers(22..28): {}", set.covers(22..28)); // true - fully within [20,30)
    println!("covers(0..50): {}", set.covers(0..50)); // false - gaps exist
    println!("covers(0..10): {}", set.covers(0..10)); // true - exactly [0,10)

    // -------------------------------------------------------------------------
    // Iteration Helpers
    // -------------------------------------------------------------------------
    println!("\n--- Iteration Helpers ---");

    // gaps() - iterate over gaps between intervals
    print!("gaps(): ");
    for gap in set.gaps() {
        print!("{:?} ", gap);
    }
    println!();

    // iter_overlapping() - iterate only over intervals that overlap a range
    print!("iter_overlapping(15..45): ");
    for interval in set.iter_overlapping(15..45) {
        print!("{:?} ", interval);
    }
    println!();

    // -------------------------------------------------------------------------
    // Modification Methods
    // -------------------------------------------------------------------------
    println!("\n--- Modification Methods ---");

    // retain() - keep only intervals matching a predicate
    let mut filtered = set.clone();
    filtered.retain(|r| r.start >= 20);
    println!(
        "After retain(start >= 20): {:?}",
        filtered.iter().collect::<Vec<_>>()
    );

    // split_at() - split intervals at a point
    let mut split = interval_set! { 0u32..30 };
    println!(
        "Before split_at(15): {:?}",
        split.iter().collect::<Vec<_>>()
    );
    split.split_at(15);
    println!("After split_at(15): {:?}", split.iter().collect::<Vec<_>>());

    // Multiple splits
    let mut multi_split = interval_set! { 0u32..100 };
    multi_split.split_at(25);
    multi_split.split_at(50);
    multi_split.split_at(75);
    println!(
        "After multiple splits: {:?}",
        multi_split.iter().collect::<Vec<_>>()
    );

    // -------------------------------------------------------------------------
    // IntervalMap also has these methods
    // -------------------------------------------------------------------------
    println!("\n--- IntervalMap Utility Methods ---");

    let map = interval_map! {
        0u32..10 => "a",
        20..30 => "b",
        40..50 => "c",
    };

    println!("Map first(): {:?}", map.first());
    println!("Map last(): {:?}", map.last());
    println!("Map span(): {:?}", map.span());
    println!("Map overlaps(25..35): {}", map.overlaps(25..35));
    println!("Map covers(22..28): {}", map.covers(22..28));
}