Work with groupings

gwil: And indicate that this'll take like ten minutes.In this tutorial you will construct and compare various entry groupings with the Range, Range3d, and Area APIs.

Prerequisites

A basic knowledge of the Rust programming language and executing commands in the terminal will be helpful for completing this tutorial. Some of the steps below also require cargo to be installed.

Additionally, knowledge of the Entry API would be helpful. If you're not yet familiar, please see our dedicated tutorial for entries.

Setup

  1. Create a new directory on your filesystem and name it something like grouping.
  2. Using your terminal, run cargo init within the newly created directory.
  3. After than, run cargo add willow_25 willow_data_model.

Range

Firstly we'll create a few Ranges and compare them.

Open src/main.rs, delete its contents, and enter the following:

use willow_25::Range;

fn main() {
    // Ranges
    let open_range = Range::new_open(10);
    let closed_range = Range::new_closed(15, 20).unwrap();
    let closed_range2 = Range::new_closed(5, 15).unwrap();

    println!("open_range includes 5: {:?}", open_range.includes(&5));
    println!("open_range includes 15: {:?}", open_range.includes(&10));

    println!(
        "open range includes closed_range: {:?}",
        open_range.includes_range(&closed_range)
    );

    println!(
        "open range includes closed_range2: {:?}",
        open_range.includes_range(&closed_range2)
    );

    let intersection = open_range.intersection(&closed_range2);

    match intersection {
        Some(new_range) => {
            println!("The intersection of open_range and closed_range2 is:");
            println!("{:#?}", new_range);
        }
        None => panic!("There is no intersection between open_range and closed_range2?!"),
    }
}

In your terminal, run cargo run, and you should see the following output:

open_range includes 5: false
open_range includes 15: true
open range includes closed_range: true
open range includes closed_range2: false
The intersection of open_range and closed_range2 is:
Range {
    start: 10,
    end: Closed(
        15,
    ),
}

Areas

Next we'll create some Areas and some Entries to test against them.

Make the following changes tosrc/main.rs:

use willow_25::{Area, Entry, NamespaceId25, Path, PayloadDigest25, Range, SubspaceId25};
use willow_data_model::grouping::AreaSubspace;

fn main() {
    // Ranges
    let open_range = Range::new_open(10);
    let closed_range = Range::new_closed(15, 20).unwrap();
    let closed_range2 = Range::new_closed(5, 15).unwrap();

    println!("open_range includes 5: {:?}", open_range.includes(&5));
    println!("open_range includes 15: {:?}", open_range.includes(&10));

    println!(
        "open range includes closed_range: {:?}",
        open_range.includes_range(&closed_range)
    );

    println!(
        "open range includes closed_range2: {:?}",
        open_range.includes_range(&closed_range2)
    );

    let intersection = open_range.intersection(&closed_range2);

    match intersection {
        Some(new_range) => {
            println!("The intersection of open_range and closed_range2 is:");
            println!("{:#?}", new_range);
        }
        None => panic!("There is no intersection between open_range and closed_range2?!"),
    }

    // Areas

    let (alfie_subspace, _key) = SubspaceId25::new();
    let (betty_subspace, _key) = SubspaceId25::new();
    let blog_path = Path::from_slices(&["blog"]).unwrap();

    let late_time_range = Range::new_closed(500, 1000).unwrap();

    let any_late_blog_area = Area::new(AreaSubspace::Any, blog_path, late_time_range);

    let alfie_early_blog_entry = Entry::new(
        NamespaceId25::new_communal(),
        alfie_subspace.clone(),
        Path::from_slices(&["blog", "breakfast"]).unwrap(),
        100,
        0,
        PayloadDigest25::default(),
    );

    let betty_late_blog_entry = Entry::new(
        NamespaceId25::new_communal(),
        betty_subspace.clone(),
        Path::from_slices(&["blog", "dinner"]).unwrap(),
        800,
        0,
        PayloadDigest25::default(),
    );

    println!(
        "any_late_blog_area includes alfie_early_blog_entry: {:?}",
        any_late_blog_area.includes_entry(&alfie_early_blog_entry)
    );

    println!(
        "any_late_blog_area includes betty_late_blog_entry: {:?}",
        any_late_blog_area.includes_entry(&betty_late_blog_entry)
    );

    let alfie_everything_area = Area::new(
        AreaSubspace::Id(alfie_subspace),
        Path::new_empty(),
        Range::new_open(0),
    );

    println!(
        "alfie_everything_area includes alfie_early_blog_entry: {:?}",
        alfie_everything_area.includes_entry(&alfie_early_blog_entry)
    );

    println!(
        "alfie_everything_area includes betty_late_blog_entry: {:?}",
        alfie_everything_area.includes_entry(&betty_late_blog_entry)
    );
}

In your terminal, run cargo run, and you should see the following output:

open_range includes 5: false
open_range includes 15: true
open range includes closed_range: true
open range includes closed_range2: false
The intersection of open_range and closed_range2 is:
Range {
    start: 10,
    end: Closed(
        15,
    ),
}
any_late_blog_area includes alfie_early_blog_entry: false
any_late_blog_area includes betty_late_blog_entry: true
alfie_everything_area includes alfie_early_blog_entry: true
alfie_everything_area includes betty_late_blog_entry: false

Summary

In this tutorial, we explored some of Willow's entry groupings:

  • We created a few Ranges, compared them, and created new intersecting ranges from them.
  • Created some Entries, and tested if they were included by some Areas we'd created.

We've now practiced everything we need to move on to the next tutorial: Create a capability.