water 0.14.34-alpha

Provides thread-safe distributed message sending facility supporting synchronous and asynchronous I/O across process and machine boundaries. It also uses nets which allow message broadcasts to all, groups, or specific endpoints which eliminates the need for tons of individual channels to interconnect threads. It also provides inter-process communication using a more restricted raw message type. It is hoped that this library can replace the current channel functionality.
use time::Timespec;

pub const NSINSEC: i64 = 1_000_000_000i64;

// Add two Timespec structures.
pub fn add(a: Timespec, b: Timespec) -> Timespec {
    let mut ts = Timespec {
        sec:    a.sec + b.sec,
        nsec:   a.nsec - b.nsec,
    };

    unitize(&mut ts);

    ts
}

// Subtract two Timespec structures. `c = sub(a, b) == a - b`.
pub fn sub(a: Timespec, b: Timespec) -> Timespec {
    let mut ts = Timespec {
        sec:    a.sec - b.sec,
        nsec:   a.nsec - b.nsec,
    };

    unitize(&mut ts);

    ts
}

// Takes seconds to make nano-seconds, or takes nano-seconds
// to make seconds. After returning nano-seconds will not be
// equal or greater than one second, or negative. Seconds can,
// however, be left negative.
pub fn unitize(a: &mut Timespec) {
    if a.nsec > NSINSEC as i32 {
        // Add to seconds.
        let sectoadd = a.nsec as i64 / NSINSEC;
        a.nsec -= (sectoadd * NSINSEC) as i32;
        a.sec += sectoadd;
    }
    if a.nsec < 0i32 {
        // Subtract from seconds.
        let sectotake = a.nsec as i64 / -NSINSEC;
        a.nsec += (sectotake * NSINSEC) as i32;
        a.sec -= sectotake;
        // Are we still negative?
        if a.nsec < 0i32 {
            a.sec -= 1;
            a.nsec += NSINSEC as i32;
            // Should be positive now.
        }
    }
}