flexcell 0.1.0-alpha.1

A flexible cell that allows safe circumvention of double borrow issues.
Documentation
use flexcell::FlexCell;

#[derive(Debug)]
struct Node {
    value: i32,
    next: Option<Box<Node>>,
}

impl Node {
    fn new(value: i32) -> Self {
        Node { value, next: None }
    }
}

// Recursively creates and links nodes with values from start to end-1 for the head node (i.e., the node wrapped in FlexCell).
fn recursive_build(head: &FlexCell<Node>, start: i32, end: i32) {
    if start >= end {
        return;
    }

    // Prepare a new node externally.
    let mut new_node = Node::new(start);

    // Use lend to temporarily make head point to new_node,
    // and proceed with the recursive call in that state.
    head.lend(&mut new_node, || {
        recursive_build(head, start + 1, end);
    });

    // After exiting the lend closure, head is restored to the original node.
    // Then, link the newly created new_node to the next of head.
    head.with_mut(|head_node| {
        head_node.next = Some(Box::new(new_node));
    });
}

fn main() {
    // Create a FlexCell containing the first node
    let head = FlexCell::new(Node::new(0));

    // Recursively add nodes with values from 1 to 3
    recursive_build(&head, 1, 4);

    // Traverse the entire linked list and verify the values
    head.with(|node| {
        let mut current = Some(node);
        let mut expected = 0;

        // Traverse and check if the values are in the order 0, 1, 2, 3
        while let Some(n) = current {
            assert_eq!(n.value, expected);
            expected += 1;
            current = n.next.as_deref();
        }
        // Finally, expected should be 4 (confirming the values 0..4)
        assert_eq!(expected, 4);
    });
}