1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
extern crate rand;
extern crate uuid;

use rand::Rng;
use uuid::Builder;

pub struct Linked<T> {
    value: T,               // what does this variable contain?
    links: Vec<uuid::Uuid>, // what variables are linked with this one?
    identifier: uuid::Uuid, // what is this variable's identifier?
}

impl<T> Linked<T> {
    fn new(val: T) -> Linked<T> {
        let rb = rand::thread_rng().gen::<[u8; 16]>();
        let id = Builder::from_bytes(rb).build();

        return Linked::<T> {
            value: val,
            links: vec![],
            identifier: id,
        };
    }
}

pub fn link<T1, T2>(mut x: Linked<T1>, mut y: Linked<T2>) -> (Linked<T1>, Linked<T2>) {
    // no accidental clones!
    if x.identifier == y.identifier {
        return (x, y);
    };
    // no self-references!
    if x.links.contains(&x.identifier) || y.links.contains(&y.identifier) {
        return (x, y);
    };
    // link y with x
    if !x.links.contains(&y.identifier) {
        x.links.push(y.identifier);
    };
    // link x with y
    if !y.links.contains(&x.identifier) {
        y.links.push(x.identifier);
    };

    return (x, y);
}