[][src]Struct contrail::Trail

pub struct Trail { /* fields omitted */ }

The trail itself.

Backtrackable and non-backtrackable memory

The trail consists of backtrackable memory and non-backtrackable memory. Both types of storage can be used with Value and Array. Whenever trail.new_level() is called, a clone of the backtrackable memory is made and appended to an internal stack. Conversely, whenever trail.backtrack() is called, the current backtrackable memory is replaced with the most recent clone from the internal stack. Non-backtrackable memory is unaffected by these methods.

When designing data structures using the trail, try to store as much as possible in non-backtrackable storage. This will make calls to new_level() and backtrack() more efficient as less data will need to be cloned.

Examples

The following example illustrates the differences between Backtrackable and NonBacktrackable storage:

use contrail::{BacktrackableValue, NonBacktrackableValue, TrailBuilder};

let mut builder = TrailBuilder::new();
let backtrackable_counter = BacktrackableValue::new(&mut builder, 0);
let non_backtrackable_counter = NonBacktrackableValue::new(&mut builder, 0);
let mut trail = builder.finish();

assert_eq!(backtrackable_counter.get(&trail), 0);
assert_eq!(non_backtrackable_counter.get(&trail), 0);

trail.new_level();

backtrackable_counter.update(&mut trail, |x| x + 1);
non_backtrackable_counter.update(&mut trail, |x| x + 1);

assert_eq!(backtrackable_counter.get(&trail), 1);
assert_eq!(non_backtrackable_counter.get(&trail), 1);

trail.backtrack();

assert_eq!(backtrackable_counter.get(&trail), 0);
assert_eq!(non_backtrackable_counter.get(&trail), 1);

Another example that backtracks multiple times:

use contrail::{BacktrackableValue, TrailBuilder};

let mut builder = TrailBuilder::new();
let countdown = BacktrackableValue::new(&mut builder, 3);
let mut trail = builder.finish();

println!("Counting down from {}:", countdown.get(&trail));

while countdown.get(&trail) > 0 {
    trail.new_level();
    println!("{}...", countdown.get(&trail));
    countdown.update(&mut trail, |x| x - 1);
}

println!("{}!", countdown.get(&trail));

println!("Counting back up:");

while !trail.is_trail_empty() {
    trail.backtrack();
    println!("{}", countdown.get(&trail));
}

This produces the following output:

Counting down from 3:
3...
2...
1...
0!
Counting back up:
1
2
3

Methods

impl Trail[src]

pub fn new_level(&mut self)[src]

Adds a new level to the trail.

When this method is called, a clone of the trail's backtrackable memory at that point in time is added to an internal stack of memory. These memory snapshots can be recalled in FILO order using backtrack().

Examples

use contrail::{BacktrackableValue, TrailBuilder};

let mut builder = TrailBuilder::new();
let value = BacktrackableValue::new(&mut builder, 0);
let mut trail = builder.finish();

value.set(&mut trail, 1);
trail.new_level();
value.set(&mut trail, 2);
trail.backtrack();
assert_eq!(value.get(&trail), 1);

pub fn backtrack(&mut self)[src]

Backtracks the trail to the most recent level.

When this method is called, the most recent backtrackable memory stored in the trail's internal stack is removed from the stack and set as the current backtrackable memory. If the trail is empty, this method has no effect.

Examples

use contrail::{BacktrackableValue, TrailBuilder};

let mut builder = TrailBuilder::new();
let value = BacktrackableValue::new(&mut builder, 0);
let mut trail = builder.finish();

value.set(&mut trail, 1);
trail.new_level();
value.set(&mut trail, 2);
trail.backtrack();
assert_eq!(value.get(&trail), 1);

pub fn trail_len(&self) -> usize[src]

Returns the length of the trail.

The length of the trail is increased whenever a level is added, and decreased whenever a backtrack occurs.

Examples

use contrail::TrailBuilder;

let mut trail = TrailBuilder::new().finish();

assert_eq!(trail.trail_len(), 0);

trail.new_level();
assert_eq!(trail.trail_len(), 1);

trail.backtrack();
assert_eq!(trail.trail_len(), 0);

pub fn is_trail_empty(&self) -> bool[src]

Checks if the trail's length is 0.

Examples

use contrail::TrailBuilder;

let mut trail = TrailBuilder::new().finish();

assert!(trail.is_trail_empty());

trail.new_level();
assert!(!trail.is_trail_empty());

trail.backtrack();
assert!(trail.is_trail_empty());

Auto Trait Implementations

impl Send for Trail

impl Sync for Trail

Blanket Implementations

impl<T> From for T[src]

impl<T, U> Into for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom for T where
    U: Into<T>, 
[src]

type Error = !

🔬 This is a nightly-only experimental API. (try_from)

The type returned in the event of a conversion error.

impl<T> Borrow for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> BorrowMut for T where
    T: ?Sized
[src]

impl<T, U> TryInto for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

🔬 This is a nightly-only experimental API. (try_from)

The type returned in the event of a conversion error.