<commit_before>extern crate gcd;

use gcd::Gcd;

fn insertion_point<T, F>(value: &T, buffer: &[T], before: F) -> Option<usize>
    where
        F: Fn(&T, &T) -> bool
{
    // Find the insertion point where the value would fit
    // All elements to the left of the insertion point are "before" the value
    // and the value is "before" all elements to the right of the insertion point.
    // The "before" function returns true if it's first argument is "before" the second.
    // Typically, this will be PartialOrd::lt to insert the value before equal values
    // or PartialOrd::le to insert the value after other equal values.
    // The function performs a binary search, but is biased to look for values before or after
    // all the values in the slice.  It starts with the mid-point. Depending on that test, it
    // then tests whether the value is before slice, or value is after slice. It then bisects
    // the half identified by the first two comparisons.
    // Returns index to first element in the slice that is not before the value. If there is no
    // element, it returns None (rather than slice length). This ensures that the caller
    // special-cases that event, to avoid using an element that is not in the slice.
    // TODO - could support a RANDOM flag that uses normal binary search instead of biased
    // to allow user to flag whether data is truly random
    if buffer.is_empty() {
        return None
    }
    let mut lo = 0;   // lowest candidate
    let mut hi = buffer.len() - 1; // highest candidate
    let trial = hi / 2;
    if before(&buffer[trial], value) {
        if trial == hi || before(&buffer[hi], value) {
            return None
        }
        lo = trial + 1;
    } else {
        if trial == lo || !before(&buffer[lo], value) {
            return Some(lo)
        }
        lo = lo + 1;
        hi = trial;
    }
    let mut trial = (hi - lo) / 2 + lo;  // (hi + lo) / 2 is more prone to overflow (however unlikely)
    while hi > lo {
        if before(&buffer[trial], value) {
            lo = trial + 1
        } else {
            hi = trial
        }
        trial = (hi - lo) / 2 + lo;
    }
    debug_assert!(lo == hi);
    return Some(lo)
}

fn swap_sequence<T>(s: &mut [T], a: usize, b: usize, k: usize) {
    for i in 0..k {
        s.swap(a + i, b + i)
    }
}

fn rotate<T>(s: &mut [T], k: usize) {
    // Rotate the last k elements to the front of the slice.
    // given a slice of 0..n, move n-k..n to front and 0..n-k to end
    // for i = 0..k, add size of second section: new position = (i + k) % n
    // for i = k..n, subtract size of first section: new position = (i - n + k) % n = (i + k) % n
    // so all elements need to have the same move applied
    // There are gcd(k, n-k) cycles
    // TODO - possibly there is a speed-up by running the for loop inside the while. This will
    // access data more linearly, which may improve CPU caching
    // TODO - we can use unchecked gets to possibly improve performance, since indexes are
    // constrained by modulo
    let n = s.len();
    if k == 0 || k == n {
        return
    }
    assert!(n > k);
    let c = k.gcd(n - k);
    for i in 0 .. c {
        let mut j = (i + k) % n;
        while j != i {
            s.swap(i, j);
            j = (j + k) % n;
        }
    }
}

fn merge<T, F>(mut s: &mut [T], split: usize, lt: F, le: F)
    where
        T: Ord,
        F: Fn(&T, &T) -> bool
{
    // The slice to be sorted is divided into S0 | L | M | R | S1
    // The indexes into the slice are l0, l1, r0, r1
    let mut l0 = 0;
    let mut l1 = split;
    let mut r0 = split;
    let mut r1 = s.len();
    while l1 - l0 > 1 && r1 - r0 > 1 {
        assert!(l1 == r0);  // M is empty
        // Find r0 in L
        match insertion_point(&s[r0], &s[l0 .. l1], &le) {
            None => {
                // r0 > lmax - done
                return
            }
            Some(pos) => {
                // swap values, and add r0 into M
                let ins = l0 + pos;
                s.swap(ins, r0);
                l0 = ins + 1;
                r0 += 1;
            }
        }
        while l0 < l1 && l1 < r0 && r0 < r1 {
            // While L, M, and R exist, find insertion point of M[0] in R
            match insertion_point(&s[l1], &s[r0 .. r1], &lt) {
                None => {
                    // R < M < L
                    // LMR -> RML
                    // first, swap min(|L|,|R|) to make:
                    // S(from Ra)-Lb-Ma-Mb(from La)-Rb, one of Lb or Rb is empty
                    // then, if Lb is empty, rotate Ma-Mb-Rb to Rb-Ma-Mb, return
                    // else rotate Lb-Ma-Mb to Ma-Mb-Lb, return
                    let llen = l1 - l0;
                    let rlen = r1 - r0;
                    // TODO - remove if with:
                    // let maxlen = max(llen, rlen);
                    // let minlen = min(llen, rlen);
                    // swap_sequence(&mut s, l0, r0, minlen);
                    // l0 += minlen;
                    // r0 += minlen;
                    // rotate(&mut s[l0 .. r1], maxlen - minlen);
                    if llen < rlen {
                        swap_sequence(&mut s, l0, r0, llen);
                        l0 += llen;
                        // r0 += llen;
                        rotate(&mut s[l0 .. r1], rlen - llen);
                    } else {
                        swap_sequence(&mut s, l0, r0, rlen);
                        l0 += rlen;
                        // r0 += rlen;
                        rotate(&mut s[l0 .. r1], llen - rlen)
                    }
                    return
                }
                Some(pos) => {
                    // L-M-R0..pos-Rpos..
                    //swap L/R to min |L|, pos
                    // R0-L1-M-L0-R0x-R1, either L1 is empty or R0x is empty
                    // if L1 is empty, rotate M-L0-R0x to R0x-M-L0, R0-R0x-M[0] => S, M->L
                    // else R0-L1-M-L0-R1
                    let llen = l1 - l0;
                    if llen < pos {
                        swap_sequence(&mut s, l0, r0, llen);
                        // L is empty
                        rotate(&mut s[l1 .. r0 + pos], pos - llen);
                        l0 += pos + 1; // Ra + M0
                        l1 = r0 + pos;
                        r0 = l1;
                    } else {
                        swap_sequence(&mut s, l0, r0, pos);
                        // find where R0 goes in M-L0. If None, then rotate L1-M-L0 -> M-L0-L1
                        // else rotate L1 and M < R0. Then swap R0 and L1,0.
                        // or insertion sort R0 into M
                    }
                }
            }
            // match insertion_point(&s[r0], &s[l1 .. r0], le) {
            //     None => {
            //         // all of M goes before R
            //         // if |L| < |M|, rotate L-M, no more M
            //         // else
            //         // swap L-M, keep M
            //     }
            //     Some(pos) => {
            //         // L0-L1-M0-M1-R
            //         // if |L| < |M0|, rotate L-M0 to M0-L, no more M
            //         // else swap L0/M0, keep M, assert R[0] < M[0]
            //     }
            // }
        }
        // if M exists, but L doesn't, L=M
    }
    if l1 - l0 == 1 {
        // |L| = 1: Just insert it into R
        match insertion_point(&s[l0], &s[r0 .. r1], lt) {
            None => rotate(&mut s[l0 .. r1], r1 - r0),
            Some(pos) if pos != 0 => rotate(&mut s[l0 .. r0 + pos], pos),
            _ => {
                // already in position
            },
        }
    } else if r1 - r0 == 1 {
        // |R| = 1: Just insert it into L
        match insertion_point(&s[r0], &s[l0 .. l1], le) {
            None => {
                // already in position
            }
            Some(pos) => rotate(&mut s[l0 + pos .. r1], 1),
        }
    } // at least one of |L| and |R| == 0
}

#[cfg(not(test))]
fn main() {
    let mut a = vec![2, 4, 6, 1, 3, 5];
    merge(&mut a, 3, i32::lt, i32::le)
}

#[cfg(test)]
mod tests {
    #[test]
    fn bisect0() {
        assert!(super::insertion_point(&3, &[], i32::lt) == None)
    }

    #[test]
    fn bisect1_before() {
        assert!(super::insertion_point(&1, &[2], i32::lt) == Some(0))
    }
    #[test]
    fn bisect1_after() {
        assert!(super::insertion_point(&3, &[2], i32::lt) == None)
    }

    #[test]
    fn bisect2_before() {
        assert!(super::insertion_point(&1, &[2, 4], i32::lt) == Some(0))
    }
    #[test]
    fn bisect2_middle() {
        assert!(super::insertion_point(&3, &[2, 4], i32::lt) == Some(1))
    }
    #[test]
    fn bisect2_after() {
        assert!(super::insertion_point(&5, &[2, 4], i32::lt) == None)
    }

    #[test]
    fn bisect3_before() {
        assert!(super::insertion_point(&1, &[2, 4, 6], i32::lt) == Some(0))
    }
    #[test]
    fn bisect3_lt() {
        // Use less-than if the value should be inserted before equal values
        assert!(super::insertion_point(&4, &[2, 4, 6], i32::lt) == Some(1))
    }
    #[test]
    fn bisect3_le() {
        // Use less-than-or-equal if value should be inserted after equal values
        assert!(super::insertion_point(&4, &[2, 4, 6], i32::le) == Some(2))
    }
    #[test]
    fn bisect3_after() {
        assert!(super::insertion_point(&7, &[2, 4, 6], i32::lt) == None)
    }

    #[test]
    fn swap_sequence_adjacent() {
        let mut buf = [1, 2, 3, 4, 5, 6];
        super::swap_sequence(&mut buf, 0, 3, 3);
        assert_eq!(buf, [4, 5, 6, 1, 2, 3]);
    }

    #[test]
    fn swap_sequence_disjoint() {
        let mut buf = [1, 2, 3, 4, 5, 6];
        super::swap_sequence(&mut buf, 1, 4, 2);
        assert_eq!(buf, [1, 5, 6, 4, 2, 3]);
    }

    #[test]
    fn swap_sequence_zero() {
        let mut buf = [1, 2, 3, 4, 5, 6];
        super::swap_sequence(&mut buf, 0, 3, 0);
        assert_eq!(buf, [1, 2, 3, 4, 5, 6]);
    }

    #[test]
    fn rotate0_0() {
        let mut buf: [i32; 0] = [];
        super::rotate(&mut buf, 0);
        assert_eq!(buf, []);
    }

    #[test]
    fn rotate0_1() {
        let mut buf = [4];
        super::rotate(&mut buf, 0);
        assert_eq!(buf, [4]);
    }

    #[test]
    fn rotate1_0() {
        let mut buf = [4];
        super::rotate(&mut buf, 1);
        assert_eq!(buf, [4]);
    }

    #[test]
    fn rotate1_1() {
        let mut buf = [5, 4];
        super::rotate(&mut buf, 1);
        assert_eq!(buf, [4, 5]);
    }

    #[test]
    fn rotate_gcd_1() {
        let mut buf = [5, 4, 3, 2, 1];
        super::rotate(&mut buf, 2);
        assert_eq!(buf, [2, 1, 5, 4, 3]);
    }

    #[test]
    fn rotate_gcd_3() {
        let mut buf = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21];
        super::rotate(&mut buf, 6);
        assert_eq!(buf, [16, 17, 18, 19, 20, 21, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
    }

}<commit_msg>Added insertion point tests for longer sequences<commit_after>extern crate gcd;

use gcd::Gcd;

fn insertion_point<T, F>(value: &T, buffer: &[T], before: &mut F) -> Option<usize>
    where
        F: FnMut(&T, &T) -> bool
{
    // Find the insertion point where the value would fit
    // All elements to the left of the insertion point are "before" the value
    // and the value is "before" all elements to the right of the insertion point.
    // The "before" function returns true if it's first argument is "before" the second.
    // Typically, this will be PartialOrd::lt to insert the value before equal values
    // or PartialOrd::le to insert the value after other equal values.
    // The function performs a binary search, but is biased to look for values before or after
    // all the values in the slice.  It starts with the mid-point. Depending on that test, it
    // then tests whether the value is before slice, or value is after slice. It then bisects
    // the half identified by the first two comparisons.
    // Returns index to first element in the slice that is not before the value. If there is no
    // element, it returns None (rather than slice length). This ensures that the caller
    // special-cases that event, to avoid using an element that is not in the slice.
    // TODO - could support a RANDOM flag that uses normal binary search instead of biased
    // to allow user to flag whether data is truly random
    if buffer.is_empty() {
        return None
    }
    let mut lo = 0;   // lowest candidate
    let mut hi = buffer.len() - 1; // highest candidate
    let trial = hi / 2;
    if before(&buffer[trial], value) {
        if trial == hi || before(&buffer[hi], value) {
            return None
        }
        lo = trial + 1;
    } else {
        if trial == lo || !before(&buffer[lo], value) {
            return Some(lo)
        }
        lo = lo + 1;
        hi = trial;
    }
    while hi > lo {
        let trial = (hi - lo) / 2 + lo;  // (hi+lo)/2 is more prone to overflow (however unlikely)
        if before(&buffer[trial], value) {
            lo = trial + 1
        } else {
            hi = trial
        }
    }
    debug_assert!(lo == hi);
    return Some(lo)
}

fn swap_sequence<T>(s: &mut [T], a: usize, b: usize, k: usize) {
    for i in 0..k {
        s.swap(a + i, b + i)
    }
}

fn rotate<T>(s: &mut [T], k: usize) {
    // Rotate the last k elements to the front of the slice.
    // given a slice of 0..n, move n-k..n to front and 0..n-k to end
    // for i = 0..k, add size of second section: new position = (i + k) % n
    // for i = k..n, subtract size of first section: new position = (i - n + k) % n = (i + k) % n
    // so all elements need to have the same move applied
    // There are gcd(k, n-k) cycles
    // TODO - possibly there is a speed-up by running the for loop inside the while. This will
    // access data more linearly, which may improve CPU caching
    // TODO - we can use unchecked gets to possibly improve performance, since indexes are
    // constrained by modulo
    let n = s.len();
    if k == 0 || k == n {
        return
    }
    assert!(n > k);
    let c = k.gcd(n - k);
    for i in 0 .. c {
        let mut j = (i + k) % n;
        while j != i {
            s.swap(i, j);
            j = (j + k) % n;
        }
    }
}

fn merge<T, F>(mut s: &mut [T], split: usize, mut lt: F, mut le: F)
    where
        T: Ord,
        F: FnMut(&T, &T) -> bool
{
    // The slice to be sorted is divided into S0 | L | M | R | S1
    // The indexes into the slice are l0, l1, r0, r1
    let mut l0 = 0;
    let mut l1 = split;
    let mut r0 = split;
    let mut r1 = s.len();
    while l1 - l0 > 1 && r1 - r0 > 1 {
        assert!(l1 == r0);  // M is empty
        // Find r0 in L
        match insertion_point(&s[r0], &s[l0 .. l1], &mut le) {
            None => {
                // r0 > lmax - done
                return
            }
            Some(pos) => {
                // swap values, and add r0 into M
                let ins = l0 + pos;
                s.swap(ins, r0);
                l0 = ins + 1;
                r0 += 1;
            }
        }
        while l0 < l1 && l1 < r0 && r0 < r1 {
            // While L, M, and R exist, find insertion point of M[0] in R
            match insertion_point(&s[l1], &s[r0 .. r1], &mut lt) {
                None => {
                    // R < M < L
                    // LMR -> RML
                    // first, swap min(|L|,|R|) to make:
                    // S(from Ra)-Lb-Ma-Mb(from La)-Rb, one of Lb or Rb is empty
                    // then, if Lb is empty, rotate Ma-Mb-Rb to Rb-Ma-Mb, return
                    // else rotate Lb-Ma-Mb to Ma-Mb-Lb, return
                    let llen = l1 - l0;
                    let rlen = r1 - r0;
                    // TODO - remove if with:
                    // let maxlen = max(llen, rlen);
                    // let minlen = min(llen, rlen);
                    // swap_sequence(&mut s, l0, r0, minlen);
                    // l0 += minlen;
                    // r0 += minlen;
                    // rotate(&mut s[l0 .. r1], maxlen - minlen);
                    if llen < rlen {
                        swap_sequence(&mut s, l0, r0, llen);
                        l0 += llen;
                        // r0 += llen;
                        rotate(&mut s[l0 .. r1], rlen - llen);
                    } else {
                        swap_sequence(&mut s, l0, r0, rlen);
                        l0 += rlen;
                        // r0 += rlen;
                        rotate(&mut s[l0 .. r1], llen - rlen)
                    }
                    return
                }
                Some(pos) => {
                    // L-M-R0..pos-Rpos..
                    //swap L/R to min |L|, pos
                    // R0-L1-M-L0-R0x-R1, either L1 is empty or R0x is empty
                    // if L1 is empty, rotate M-L0-R0x to R0x-M-L0, R0-R0x-M[0] => S, M->L
                    // else R0-L1-M-L0-R1
                    let llen = l1 - l0;
                    if llen < pos {
                        swap_sequence(&mut s, l0, r0, llen);
                        // L is empty
                        rotate(&mut s[l1 .. r0 + pos], pos - llen);
                        l0 += pos + 1; // Ra + M0
                        l1 = r0 + pos;
                        r0 = l1;
                    } else {
                        swap_sequence(&mut s, l0, r0, pos);
                        // find where R0 goes in M-L0. If None, then rotate L1-M-L0 -> M-L0-L1
                        // else rotate L1 and M < R0. Then swap R0 and L1,0.
                        // or insertion sort R0 into M
                    }
                }
            }
            // match insertion_point(&s[r0], &s[l1 .. r0], le) {
            //     None => {
            //         // all of M goes before R
            //         // if |L| < |M|, rotate L-M, no more M
            //         // else
            //         // swap L-M, keep M
            //     }
            //     Some(pos) => {
            //         // L0-L1-M0-M1-R
            //         // if |L| < |M0|, rotate L-M0 to M0-L, no more M
            //         // else swap L0/M0, keep M, assert R[0] < M[0]
            //     }
            // }
        }
        // if M exists, but L doesn't, L=M
    }
    if l1 - l0 == 1 {
        // |L| = 1: Just insert it into R
        match insertion_point(&s[l0], &s[r0 .. r1], &mut lt) {
            None => rotate(&mut s[l0 .. r1], r1 - r0),
            Some(pos) if pos != 0 => rotate(&mut s[l0 .. r0 + pos], pos),
            _ => {
                // already in position
            },
        }
    } else if r1 - r0 == 1 {
        // |R| = 1: Just insert it into L
        match insertion_point(&s[r0], &s[l0 .. l1], &mut le) {
            None => {
                // already in position
            }
            Some(pos) => rotate(&mut s[l0 + pos .. r1], 1),
        }
    } // at least one of |L| and |R| == 0
}

#[cfg(not(test))]
fn main() {
    let mut a = vec![2, 4, 6, 1, 3, 5];
    merge(&mut a, 3, &mut i32::lt, &mut i32::le)
}

#[cfg(test)]
mod tests {
    #[test]
    fn bisect0() {
        assert_eq!(super::insertion_point(&3, &[], &mut i32::lt), None)
    }

    #[test]
    fn bisect1_before() {
        assert_eq!(super::insertion_point(&1, &[2], &mut i32::lt), Some(0))
    }
    #[test]
    fn bisect1_after() {
        assert_eq!(super::insertion_point(&3, &[2], &mut i32::lt), None)
    }

    #[test]
    fn bisect2_before() {
        assert_eq!(super::insertion_point(&1, &[2, 4], &mut i32::lt), Some(0))
    }
    #[test]
    fn bisect2_middle() {
        assert_eq!(super::insertion_point(&3, &[2, 4], &mut i32::lt), Some(1))
    }
    #[test]
    fn bisect2_after() {
        assert_eq!(super::insertion_point(&5, &[2, 4], &mut i32::lt), None)
    }

    #[test]
    fn bisect3_before() {
        assert_eq!(super::insertion_point(&1, &[2, 4, 6], &mut i32::lt), Some(0))
    }
    #[test]
    fn bisect3_lt() {
        // Use less-than if the value should be inserted before equal values
        assert_eq!(super::insertion_point(&4, &[2, 4, 6], &mut i32::lt), Some(1))
    }
    #[test]
    fn bisect3_le() {
        // Use less-than-or-equal if value should be inserted after equal values
        assert_eq!(super::insertion_point(&4, &[2, 4, 6], &mut i32::le), Some(2))
    }
    #[test]
    fn bisect3_after() {
        assert_eq!(super::insertion_point(&7, &[2, 4, 6], &mut i32::lt), None)
    }

    #[test]
    fn bisect3_even() {
        let s = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
        let mut profile = Vec::new();
        for v in 1 .. 18 {
            let mut count = 0;
            {
                super::insertion_point(&v, &s, &mut |&a, &b|{count += 1; a < b});
            }
            profile.push(count);
        }
        assert_eq!(profile, vec![2, 5, 5, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5, 5, 5, 5, 2])
    }

    #[test]
    fn bisect3_odd() {
        let s = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
        let mut profile = Vec::new();
        for v in 1 .. 17 {
            let mut count = 0;
            {
                super::insertion_point(&v, &s, &mut |&a, &b|{count += 1; a < b});
            }
            profile.push(count);
        }
        assert_eq!(profile, vec![2, 5, 5, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5, 5, 4, 2])
    }

    #[test]
    fn swap_sequence_adjacent() {
        let mut buf = [1, 2, 3, 4, 5, 6];
        super::swap_sequence(&mut buf, 0, 3, 3);
        assert_eq!(buf, [4, 5, 6, 1, 2, 3]);
    }

    #[test]
    fn swap_sequence_disjoint() {
        let mut buf = [1, 2, 3, 4, 5, 6];
        super::swap_sequence(&mut buf, 1, 4, 2);
        assert_eq!(buf, [1, 5, 6, 4, 2, 3]);
    }

    #[test]
    fn swap_sequence_zero() {
        let mut buf = [1, 2, 3, 4, 5, 6];
        super::swap_sequence(&mut buf, 0, 3, 0);
        assert_eq!(buf, [1, 2, 3, 4, 5, 6]);
    }

    #[test]
    fn rotate0_0() {
        let mut buf: [i32; 0] = [];
        super::rotate(&mut buf, 0);
        assert_eq!(buf, []);
    }

    #[test]
    fn rotate0_1() {
        let mut buf = [4];
        super::rotate(&mut buf, 0);
        assert_eq!(buf, [4]);
    }

    #[test]
    fn rotate1_0() {
        let mut buf = [4];
        super::rotate(&mut buf, 1);
        assert_eq!(buf, [4]);
    }

    #[test]
    fn rotate1_1() {
        let mut buf = [5, 4];
        super::rotate(&mut buf, 1);
        assert_eq!(buf, [4, 5]);
    }

    #[test]
    fn rotate_gcd_1() {
        let mut buf = [5, 4, 3, 2, 1];
        super::rotate(&mut buf, 2);
        assert_eq!(buf, [2, 1, 5, 4, 3]);
    }

    #[test]
    fn rotate_gcd_3() {
        let mut buf = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21];
        super::rotate(&mut buf, 6);
        assert_eq!(buf, [16, 17, 18, 19, 20, 21, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
    }

}<|endoftext|>


<commit_before>//
// Copyright (c) 2016, Boris Popov <popov@whitekefir.ru>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//

#![allow(non_snake_case)]

mod forker;
mod worker;
mod logger;
mod program;
mod env;
mod mounter;
mod executor;

fn main() {

    let forker = forker::Forker::new();
    forker.spawn();
}
<commit_msg>fix mod section<commit_after>//
// Copyright (c) 2016, Boris Popov <popov@whitekefir.ru>
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//

#![allow(non_snake_case)]

mod forker;
mod worker;
mod logger;
mod program;
mod env;
mod mounter;
mod executor;
mod blkid;

fn main() {

    let forker = forker::Forker::new();
    forker.spawn();
}
<|endoftext|>


<commit_before>#![deny(missing_docs)]

//! A library for range addressing

/// A representation of a range
///
/// The type parameter is used to wrap data related to the range.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct Range<T = ()> {
    /// The range offset
    pub offset: usize,
    /// The range length
    pub length: usize,
    /// The data described within the range.
    pub data: T,
}

impl Range {
    /// Creates a new `Range`
    #[inline(always)]
    pub fn new(offset: usize, length: usize) -> Range {
        Range {
            offset: offset,
            length: length,
            data: (),
        }
    }

    /// Wraps some data in the range.
    #[inline(always)]
    pub fn wrap<T>(self, data: T) -> Range<T> {
        Range {
            offset: self.offset,
            length: self.length,
            data: data,
        }
    }

    /// Creates an empty range with an offset.
    #[inline(always)]
    pub fn empty(offset: usize) -> Range {
        Range {
            offset: offset,
            length: 0,
            data: (),
        }
    }

    /// Shrinks range at both ends with `n` items.
    #[inline(always)]
    pub fn shrink_n(&self, n: usize) -> Option<Range> {
        if self.length < 2 * n {
            None
        } else {
            Some(Range::new(self.offset + n, self.length - 2 * n))
        }
    }

    /// Shrinks range at both ends with 1 item.
    #[inline(always)]
    pub fn shrink(&self) -> Option<Range> {
        self.shrink_n(1)
    }

    /// Intersects a range with another, where ends are excluded.
    pub fn intersect(&self, other: &Range) -> Option<Range> {
        use std::cmp::{ min, max };

        if other.next_offset() <= self.offset ||
           other.offset >= self.next_offset() {
            None
        } else {
            let offset = max(self.offset, other.offset);
            let length = min(self.next_offset(), other.next_offset())
                - offset;
            Some(Range::new(offset, length))
        }
    }

    /// Intersects a range with another, where ends are included.
    pub fn ends_intersect(&self, other: &Range) -> Option<Range> {
        use std::cmp::{ min, max };

        if other.next_offset() < self.offset ||
           other.offset > self.next_offset() {
            None
        } else {
            let offset = max(self.offset, other.offset);
            let length = min(self.next_offset(), other.next_offset())
                - offset;
            Some(Range::new(offset, length))
        }
    }
}

impl<T> Range<T> {
    /// Returns true if range is empty
    #[inline(always)]
    pub fn is_empty(&self) -> bool {
        self.length == 0
    }

    /// Returns the next offset
    #[inline(always)]
    pub fn next_offset(&self) -> usize {
        self.offset + self.length
    }

    /// Returns a range iterator.
    #[inline(always)]
    pub fn iter(&self) -> std::ops::Range<usize> {
        self.offset..self.offset + self.length
    }

    /// Unwraps the data.
    #[inline(always)]
    pub fn unwrap(self) -> T {
        self.data
    }

    /// Decouples range and data.
    #[inline(always)]
    pub fn decouple(self) -> (Range, T) {
        (Range { offset: self.offset, length: self.length, data: () },
         self.data)
    }
}

impl<T> From<(Range, T)> for Range<T> {
    #[inline(always)]
    fn from((r, d): (Range, T)) -> Range<T> {
        Range {
            offset: r.offset,
            length: r.length,
            data: d
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn intersect() {
        let a: Range = Range::new(2, 5);
        let b = Range::new(5, 3);
        let c = a.intersect(&b);
        assert_eq!(c, Some(Range::new(5, 2)));
    }

    #[test]
    fn ends_intersect() {
        let a: Range = Range::new(2, 3);
        let b = Range::new(5, 3);
        let c = a.ends_intersect(&b);
        assert_eq!(c, Some(Range::new(5, 0)));
        let c = b.ends_intersect(&a);
        assert_eq!(c, Some(Range::new(5, 0)));
    }
}
<commit_msg>Added `Range<T>::map`<commit_after>#![deny(missing_docs)]

//! A library for range addressing

/// A representation of a range
///
/// The type parameter is used to wrap data related to the range.
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct Range<T = ()> {
    /// The range offset
    pub offset: usize,
    /// The range length
    pub length: usize,
    /// The data described within the range.
    pub data: T,
}

impl Range {
    /// Creates a new `Range`
    #[inline(always)]
    pub fn new(offset: usize, length: usize) -> Range {
        Range {
            offset: offset,
            length: length,
            data: (),
        }
    }

    /// Wraps some data in the range.
    #[inline(always)]
    pub fn wrap<T>(self, data: T) -> Range<T> {
        Range {
            offset: self.offset,
            length: self.length,
            data: data,
        }
    }

    /// Creates an empty range with an offset.
    #[inline(always)]
    pub fn empty(offset: usize) -> Range {
        Range {
            offset: offset,
            length: 0,
            data: (),
        }
    }

    /// Shrinks range at both ends with `n` items.
    #[inline(always)]
    pub fn shrink_n(&self, n: usize) -> Option<Range> {
        if self.length < 2 * n {
            None
        } else {
            Some(Range::new(self.offset + n, self.length - 2 * n))
        }
    }

    /// Shrinks range at both ends with 1 item.
    #[inline(always)]
    pub fn shrink(&self) -> Option<Range> {
        self.shrink_n(1)
    }

    /// Intersects a range with another, where ends are excluded.
    pub fn intersect(&self, other: &Range) -> Option<Range> {
        use std::cmp::{ min, max };

        if other.next_offset() <= self.offset ||
           other.offset >= self.next_offset() {
            None
        } else {
            let offset = max(self.offset, other.offset);
            let length = min(self.next_offset(), other.next_offset())
                - offset;
            Some(Range::new(offset, length))
        }
    }

    /// Intersects a range with another, where ends are included.
    pub fn ends_intersect(&self, other: &Range) -> Option<Range> {
        use std::cmp::{ min, max };

        if other.next_offset() < self.offset ||
           other.offset > self.next_offset() {
            None
        } else {
            let offset = max(self.offset, other.offset);
            let length = min(self.next_offset(), other.next_offset())
                - offset;
            Some(Range::new(offset, length))
        }
    }
}

impl<T> Range<T> {
    /// Returns true if range is empty
    #[inline(always)]
    pub fn is_empty(&self) -> bool {
        self.length == 0
    }

    /// Returns the next offset
    #[inline(always)]
    pub fn next_offset(&self) -> usize {
        self.offset + self.length
    }

    /// Returns a range iterator.
    #[inline(always)]
    pub fn iter(&self) -> std::ops::Range<usize> {
        self.offset..self.offset + self.length
    }

    /// Maps from some data to another.
    #[inline(always)]
    pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Range<U> {
        Range {
            offset: self.offset,
            length: self.length,
            data: f(self.data)
        }
    }

    /// Unwraps the data.
    #[inline(always)]
    pub fn unwrap(self) -> T {
        self.data
    }

    /// Decouples range and data.
    #[inline(always)]
    pub fn decouple(self) -> (Range, T) {
        (Range { offset: self.offset, length: self.length, data: () },
         self.data)
    }
}

impl<T> From<(Range, T)> for Range<T> {
    #[inline(always)]
    fn from((r, d): (Range, T)) -> Range<T> {
        Range {
            offset: r.offset,
            length: r.length,
            data: d
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn intersect() {
        let a: Range = Range::new(2, 5);
        let b = Range::new(5, 3);
        let c = a.intersect(&b);
        assert_eq!(c, Some(Range::new(5, 2)));
    }

    #[test]
    fn ends_intersect() {
        let a: Range = Range::new(2, 3);
        let b = Range::new(5, 3);
        let c = a.ends_intersect(&b);
        assert_eq!(c, Some(Range::new(5, 0)));
        let c = b.ends_intersect(&a);
        assert_eq!(c, Some(Range::new(5, 0)));
    }
}
<|endoftext|>


<commit_before>#![feature(box_syntax)]
extern crate curl;
extern crate serde;
extern crate num_cpus;
extern crate serde_json;
extern crate getopts;
extern crate crossbeam;
extern crate define;
use define::dictionaries::{Dictionary, Definition, wordnik};
use define::thesaureses::Thesaurus;
use std::collections::HashMap;
use std::sync::Arc;
use std::env;
use std::sync::mpsc;
use getopts::{Matches, Options};

static KEY: &'static str = "a2a73e7b926c924fad7001ca3111acd55af2ffabf50eb4ae5";
static UKEY: &'static str = "ub2JDDg9Iumsh1HfdO3a3HQbZi0up1qe8LkjsnWQvyVvQLFn1q";
//const THREAD_ENABLED: bool = true;
struct Config {
    max_definitions: i16,
}

fn parse_args() -> (Options, Matches) {
    let argv: Vec<String> = { let mut args: Vec<String> = env::args().collect(); args.dedup(); args };
    let mut parser = Options::new();
    parser.optflag("t", "thesaurus", "Finds synonyms for word");
    parser.optflag("u", "urban", "Urban Dictionary");
    parser.optopt("", "source", "Set dictionary source", "SOURCE");
    parser.optopt("",
                  "thesaurus-source",
                  "Set thesaurus source (not functional yet)",
                  "SOURCE");
    let parsed = parser.parse(&argv[1..]).unwrap();
    (parser, parsed)
}

fn get_sources()
    -> (HashMap<String, Box<Dictionary + Send>>,
        HashMap<String, Box<Thesaurus>>)
{
    // insert your dictionaries here
    let mut dictionaries: HashMap<String, Box<Dictionary + Send>> = HashMap::new();
    let wordnik = wordnik::Wordnik::new(KEY);
    dictionaries.insert(String::from("wordnik"), box wordnik.clone());
    dictionaries.insert(String::from("example"),
                        box define::dictionaries::example::ExampleDictionary);
    dictionaries.insert(String::from("urban"),
                        box define::dictionaries::urban::Urban::new(UKEY));
    let mut thesaureses: HashMap<String, Box<Thesaurus>> = HashMap::new();
    thesaureses.insert(String::from("wordnik"), box wordnik.clone());
    (dictionaries, thesaureses)
}

fn print_definition<'a, T: Dictionary + ?Sized>(dict: &'a mut Box<T>,
                                                word: &str,
                                                max_definitions: Option<usize>)
                                                -> Result<(), &'a str> {
    let definitions = try!(dict.get_definitions(word));
    let max_definitions = max_definitions.unwrap_or(1);
    if max_definitions > 1 {
        for (wordnumber, word) in definitions.iter().take(max_definitions).enumerate() {
            println!("{}. {}", wordnumber + 1, word.text);
        }
    } else {
        println!("{}", definitions[0].text);
    }
    Ok(())
}

fn print_synonyms<'a, T: Thesaurus + ?Sized>(thes: &'a mut Box<T>,
                                             word: &str)
                                             -> Result<(), &'a str> {
    let synonyms = try!(thes.get_synonyms(word));
    println!("{}", synonyms.join(", "));
    Ok(())
}

fn get_source<'a, T: Dictionary + ?Sized, K: Thesaurus + ?Sized>
    (dictionaries: &'a mut HashMap<String, Box<T>>,
     thesaureses: &'a mut HashMap<String, Box<K>>,
     args: &Matches)
     -> (&'a mut Box<T>, &'a mut Box<K>) {

    let mut source: String = "wordnik".to_owned();
    let tsource: String;
    tsource = args.opt_str("thesaurus-source").unwrap_or("wordnik".to_owned()).to_owned();
    if !args.opt_present("source") {
        for dictionary_source in dictionaries.keys() {
            if args.opt_defined(&dictionary_source) && args.opt_present(&dictionary_source) {
                source = dictionary_source.clone();
            }
        }
    }
    else if args.opt_present("source") {
        source = args.opt_str("source").unwrap_or("wordnik".to_owned()).to_owned();
    }
    let dict: Option<&mut Box<T>> = dictionaries.get_mut(&source);
    let thes: Option<&mut Box<K>> = thesaureses.get_mut(&tsource);
    (dict.unwrap(), thes.unwrap())
}

fn main() {
    let (mut dictionaries, mut thesaureses) = get_sources();
    let (opts, args) = parse_args(); //we needs opts too for printing brief description
    let (dictionary, thesaurus) = get_source(&mut dictionaries, &mut thesaureses, &args);
    if args.free.is_empty() {
        println!("{}", opts.usage("USAGE: define WORD"));
    }
    for word in &args.free {
        println!("{}:", word.to_uppercase());
        print_definition(dictionary, &word.to_lowercase(), Some(3)).unwrap_or_else(|err| println!("{}", err));
        if args.opt_present("t") {
            println!("SYNONYMS:");
            print_synonyms(thesaurus, word).unwrap_or_else(|err| println!("{}", err));
        }
    }
}
<commit_msg>Remove num_cpus and crossbeam<commit_after>#![feature(box_syntax)]
extern crate curl;
extern crate serde;
extern crate serde_json;
extern crate getopts;
extern crate define;
use define::dictionaries::{Dictionary, Definition, wordnik};
use define::thesaureses::Thesaurus;
use std::collections::HashMap;
use std::sync::Arc;
use std::env;
use std::sync::mpsc;
use getopts::{Matches, Options};

static KEY: &'static str = "a2a73e7b926c924fad7001ca3111acd55af2ffabf50eb4ae5";
static UKEY: &'static str = "ub2JDDg9Iumsh1HfdO3a3HQbZi0up1qe8LkjsnWQvyVvQLFn1q";
//const THREAD_ENABLED: bool = true;
struct Config {
    max_definitions: i16,
}

fn parse_args() -> (Options, Matches) {
    let argv: Vec<String> = { let mut args: Vec<String> = env::args().collect(); args.dedup(); args };
    let mut parser = Options::new();
    parser.optflag("t", "thesaurus", "Finds synonyms for word");
    parser.optflag("u", "urban", "Urban Dictionary");
    parser.optopt("", "source", "Set dictionary source", "SOURCE");
    parser.optopt("",
                  "thesaurus-source",
                  "Set thesaurus source (not functional yet)",
                  "SOURCE");
    let parsed = parser.parse(&argv[1..]).unwrap();
    (parser, parsed)
}

fn get_sources()
    -> (HashMap<String, Box<Dictionary + Send>>,
        HashMap<String, Box<Thesaurus>>)
{
    // insert your dictionaries here
    let mut dictionaries: HashMap<String, Box<Dictionary + Send>> = HashMap::new();
    let wordnik = wordnik::Wordnik::new(KEY);
    dictionaries.insert(String::from("wordnik"), box wordnik.clone());
    dictionaries.insert(String::from("example"),
                        box define::dictionaries::example::ExampleDictionary);
    dictionaries.insert(String::from("urban"),
                        box define::dictionaries::urban::Urban::new(UKEY));
    let mut thesaureses: HashMap<String, Box<Thesaurus>> = HashMap::new();
    thesaureses.insert(String::from("wordnik"), box wordnik.clone());
    (dictionaries, thesaureses)
}

fn print_definition<'a, T: Dictionary + ?Sized>(dict: &'a mut Box<T>,
                                                word: &str,
                                                max_definitions: Option<usize>)
                                                -> Result<(), &'a str> {
    let definitions = try!(dict.get_definitions(word));
    let max_definitions = max_definitions.unwrap_or(1);
    if max_definitions > 1 {
        for (wordnumber, word) in definitions.iter().take(max_definitions).enumerate() {
            println!("{}. {}", wordnumber + 1, word.text);
        }
    } else {
        println!("{}", definitions[0].text);
    }
    Ok(())
}

fn print_synonyms<'a, T: Thesaurus + ?Sized>(thes: &'a mut Box<T>,
                                             word: &str)
                                             -> Result<(), &'a str> {
    let synonyms = try!(thes.get_synonyms(word));
    println!("{}", synonyms.join(", "));
    Ok(())
}

fn get_source<'a, T: Dictionary + ?Sized, K: Thesaurus + ?Sized>
    (dictionaries: &'a mut HashMap<String, Box<T>>,
     thesaureses: &'a mut HashMap<String, Box<K>>,
     args: &Matches)
     -> (&'a mut Box<T>, &'a mut Box<K>) {

    let mut source: String = "wordnik".to_owned();
    let tsource: String;
    tsource = args.opt_str("thesaurus-source").unwrap_or("wordnik".to_owned()).to_owned();
    if !args.opt_present("source") {
        for dictionary_source in dictionaries.keys() {
            if args.opt_defined(&dictionary_source) && args.opt_present(&dictionary_source) {
                source = dictionary_source.clone();
            }
        }
    }
    else if args.opt_present("source") {
        source = args.opt_str("source").unwrap_or("wordnik".to_owned()).to_owned();
    }
    let dict: Option<&mut Box<T>> = dictionaries.get_mut(&source);
    let thes: Option<&mut Box<K>> = thesaureses.get_mut(&tsource);
    (dict.unwrap(), thes.unwrap())
}

fn main() {
    let (mut dictionaries, mut thesaureses) = get_sources();
    let (opts, args) = parse_args(); //we needs opts too for printing brief description
    let (dictionary, thesaurus) = get_source(&mut dictionaries, &mut thesaureses, &args);
    if args.free.is_empty() {
        println!("{}", opts.usage("USAGE: define WORD"));
    }
    for word in &args.free {
        println!("{}:", word.to_uppercase());
        print_definition(dictionary, &word.to_lowercase(), Some(3)).unwrap_or_else(|err| println!("{}", err));
        if args.opt_present("t") {
            println!("SYNONYMS:");
            print_synonyms(thesaurus, word).unwrap_or_else(|err| println!("{}", err));
        }
    }
}
<|endoftext|>


<commit_before>//! High level bindings to [libxdo](http://www.semicomplete.com/files/xdotool/docs/html/)

#![warn(missing_docs)]

extern crate libxdo_sys as sys;
extern crate libc;

use std::ffi::{CString, NulError};
use std::convert::From;
use libc::c_int;
use std::ptr::null;

/// An XDo instance
pub struct XDo {
    handle: *mut sys::xdo_t,
}

/// An error that can happen when trying to create an XDo instance.
#[derive(Debug)]
pub enum XDoCreationError {
    /// The parameter passed in contained a nul character.
    NulError(NulError),
    /// Unknown error
    Unknown,
}

impl From<NulError> for XDoCreationError {
    fn from(err: NulError) -> XDoCreationError {
        XDoCreationError::NulError(err)
    }
}

#[derive(Debug)]
enum XDoOperationErrorKind {
    NulError(NulError),
    OperationFailed,
}

/// An error originating from an XDo operation.
#[derive(Debug)]
struct XDoOperationError {
    kind: XDoOperationErrorKind,
}

impl From<NulError> for XDoOperationError {
    fn from(err: NulError) -> XDoOperationError {
        XDoOperationError { kind: XDoOperationErrorKind::NulError(err) }
    }
}

/// Result of an XDo operation.
pub type OpResult = Result<(), XDoOperationError>;

macro_rules! xdo (
    ($fncall: expr) => {
        unsafe {
            match $fncall {
                0 => Ok(()),
                _ => Err(XDoOperationError{ kind: XDoOperationErrorKind::OperationFailed })
            }
        }
    }
);

impl XDo {
    /// Creates a new XDo instance.
    ///
    /// # Parameters
    ///
    /// display - An optional string display name, such as ":0". If None, uses the environment
    /// DISPLAY.
    ///
    /// # Returns
    ///
    /// Returns a new XDo instance, or an XDoCreationError on error.
    pub fn new(display: Option<&str>) -> Result<XDo, XDoCreationError> {
        let display = match display {
            Some(display) => {
                let cstr = try!(CString::new(display));
                cstr.as_ptr()
            }
            None => null(),
        };
        let handle = unsafe { sys::xdo_new(display) };
        if handle.is_null() {
            return Err(XDoCreationError::Unknown);
        }
        Ok(XDo { handle: handle })
    }
    /// Moves the mouse to the specified position.
    pub fn move_mouse(&self, x: i32, y: i32, screen: i32) -> OpResult {
        xdo!(sys::xdo_move_mouse(self.handle, x as c_int, y as c_int, screen as c_int))
    }
    /// Moves the mouse relative to the current position.
    pub fn move_mouse_relative(&self, x: i32, y: i32) -> OpResult {
        xdo!(sys::xdo_move_mouse_relative(self.handle, x as c_int, y as c_int))
    }
    /// Does a mouse click.
    pub fn click(&self, button: i32) -> OpResult {
        xdo!(sys::xdo_click_window(self.handle, sys::CURRENTWINDOW, button as c_int))
    }
    /// Holds a mouse button down.
    pub fn mouse_down(&self, button: i32) -> OpResult {
        xdo!(sys::xdo_mouse_down(self.handle, sys::CURRENTWINDOW, button as c_int))
    }
    /// Releases a mouse button.
    pub fn mouse_up(&self, button: i32) -> OpResult {
        xdo!(sys::xdo_mouse_up(self.handle, sys::CURRENTWINDOW, button as c_int))
    }
    /// Types the specified text.
    pub fn enter_text(&self, text: &str, delay_microsecs: u32) -> OpResult {
        let string = try!(CString::new(text));
        xdo!(sys::xdo_enter_text_window(self.handle,
                                        sys::CURRENTWINDOW,
                                        string.as_ptr(),
                                        delay_microsecs))
    }
    /// Does the specified key sequence.
    pub fn send_keysequence(&self, sequence: &str, delay_microsecs: u32) -> OpResult {
        let string = try!(CString::new(sequence));
        xdo!(sys::xdo_send_keysequence_window(self.handle,
                                              sys::CURRENTWINDOW,
                                              string.as_ptr(),
                                              delay_microsecs))
    }
    /// Releases the specified key sequence.
    pub fn send_keysequence_up(&self, sequence: &str, delay_microsecs: u32) -> OpResult {
        let string = try!(CString::new(sequence));
        xdo!(sys::xdo_send_keysequence_window_up(self.handle,
                                                 sys::CURRENTWINDOW,
                                                 string.as_ptr(),
                                                 delay_microsecs))
    }
    /// Presses the specified key sequence down.
    pub fn send_keysequence_down(&self, sequence: &str, delay_microsecs: u32) -> OpResult {
        let string = try!(CString::new(sequence));
        xdo!(sys::xdo_send_keysequence_window_down(self.handle,
                                                   sys::CURRENTWINDOW,
                                                   string.as_ptr(),
                                                   delay_microsecs))
    }
}

impl Drop for XDo {
    fn drop(&mut self) {
        unsafe {
            sys::xdo_free(self.handle);
        }
    }
}
<commit_msg>Fix a private-in-public error<commit_after>//! High level bindings to [libxdo](http://www.semicomplete.com/files/xdotool/docs/html/)

#![warn(missing_docs)]

extern crate libxdo_sys as sys;
extern crate libc;

use std::ffi::{CString, NulError};
use std::convert::From;
use libc::c_int;
use std::ptr::null;

/// An XDo instance
pub struct XDo {
    handle: *mut sys::xdo_t,
}

/// An error that can happen when trying to create an XDo instance.
#[derive(Debug)]
pub enum XDoCreationError {
    /// The parameter passed in contained a nul character.
    NulError(NulError),
    /// Unknown error
    Unknown,
}

impl From<NulError> for XDoCreationError {
    fn from(err: NulError) -> XDoCreationError {
        XDoCreationError::NulError(err)
    }
}

#[derive(Debug)]
enum XDoOperationErrorKind {
    NulError(NulError),
    OperationFailed,
}

/// An error originating from an XDo operation.
#[derive(Debug)]
pub struct XDoOperationError {
    kind: XDoOperationErrorKind,
}

impl From<NulError> for XDoOperationError {
    fn from(err: NulError) -> XDoOperationError {
        XDoOperationError { kind: XDoOperationErrorKind::NulError(err) }
    }
}

/// Result of an XDo operation.
pub type OpResult = Result<(), XDoOperationError>;

macro_rules! xdo (
    ($fncall: expr) => {
        unsafe {
            match $fncall {
                0 => Ok(()),
                _ => Err(XDoOperationError{ kind: XDoOperationErrorKind::OperationFailed })
            }
        }
    }
);

impl XDo {
    /// Creates a new XDo instance.
    ///
    /// # Parameters
    ///
    /// display - An optional string display name, such as ":0". If None, uses the environment
    /// DISPLAY.
    ///
    /// # Returns
    ///
    /// Returns a new XDo instance, or an XDoCreationError on error.
    pub fn new(display: Option<&str>) -> Result<XDo, XDoCreationError> {
        let display = match display {
            Some(display) => {
                let cstr = try!(CString::new(display));
                cstr.as_ptr()
            }
            None => null(),
        };
        let handle = unsafe { sys::xdo_new(display) };
        if handle.is_null() {
            return Err(XDoCreationError::Unknown);
        }
        Ok(XDo { handle: handle })
    }
    /// Moves the mouse to the specified position.
    pub fn move_mouse(&self, x: i32, y: i32, screen: i32) -> OpResult {
        xdo!(sys::xdo_move_mouse(self.handle, x as c_int, y as c_int, screen as c_int))
    }
    /// Moves the mouse relative to the current position.
    pub fn move_mouse_relative(&self, x: i32, y: i32) -> OpResult {
        xdo!(sys::xdo_move_mouse_relative(self.handle, x as c_int, y as c_int))
    }
    /// Does a mouse click.
    pub fn click(&self, button: i32) -> OpResult {
        xdo!(sys::xdo_click_window(self.handle, sys::CURRENTWINDOW, button as c_int))
    }
    /// Holds a mouse button down.
    pub fn mouse_down(&self, button: i32) -> OpResult {
        xdo!(sys::xdo_mouse_down(self.handle, sys::CURRENTWINDOW, button as c_int))
    }
    /// Releases a mouse button.
    pub fn mouse_up(&self, button: i32) -> OpResult {
        xdo!(sys::xdo_mouse_up(self.handle, sys::CURRENTWINDOW, button as c_int))
    }
    /// Types the specified text.
    pub fn enter_text(&self, text: &str, delay_microsecs: u32) -> OpResult {
        let string = try!(CString::new(text));
        xdo!(sys::xdo_enter_text_window(self.handle,
                                        sys::CURRENTWINDOW,
                                        string.as_ptr(),
                                        delay_microsecs))
    }
    /// Does the specified key sequence.
    pub fn send_keysequence(&self, sequence: &str, delay_microsecs: u32) -> OpResult {
        let string = try!(CString::new(sequence));
        xdo!(sys::xdo_send_keysequence_window(self.handle,
                                              sys::CURRENTWINDOW,
                                              string.as_ptr(),
                                              delay_microsecs))
    }
    /// Releases the specified key sequence.
    pub fn send_keysequence_up(&self, sequence: &str, delay_microsecs: u32) -> OpResult {
        let string = try!(CString::new(sequence));
        xdo!(sys::xdo_send_keysequence_window_up(self.handle,
                                                 sys::CURRENTWINDOW,
                                                 string.as_ptr(),
                                                 delay_microsecs))
    }
    /// Presses the specified key sequence down.
    pub fn send_keysequence_down(&self, sequence: &str, delay_microsecs: u32) -> OpResult {
        let string = try!(CString::new(sequence));
        xdo!(sys::xdo_send_keysequence_window_down(self.handle,
                                                   sys::CURRENTWINDOW,
                                                   string.as_ptr(),
                                                   delay_microsecs))
    }
}

impl Drop for XDo {
    fn drop(&mut self) {
        unsafe {
            sys::xdo_free(self.handle);
        }
    }
}
<|endoftext|>


<commit_before>// Hound -- A WAV encoding library in Rust
// Copyright (C) 2015 Ruud van Asseldonk
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 3 of the License only.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

//! Hound, a WAV encoding library.
//!
//! TODO: Add some introductory text here.
//!
//! The following example renders a 440 Hz sine wave, and stores it as as a
//! mono wav file with a sample rate of 44.1 kHz and 16 bits per sample.
//!
//! ```
//! use std::fs;
//! use std::f32::consts::PI;
//! use std::i16;
//! use hound;
//!
//! let spec = hound::WavSpec {
//!     channels: 1,
//!     sample_rate: 44100,
//!     bits_per_sample: 16
//! };
//! // TODO: ensure that the type can be inferred.
//! let writer_res = hound::WavWriter::<fs::File>::create("sine.wav", spec);
//! let mut writer = writer_res.ok().unwrap();
//! for t in (0 .. 44100).map(|x| x as f32 / 44100.0) {
//!     let sample = (t * 440.0 * 2.0 * PI).sin();
//!     let amplitude: i16 = i16::MAX;
//!     writer.write_sample((sample * amplitude as f32) as i16).ok().unwrap();
//! }
//! writer.finalize().ok().unwrap();
//! ```

#![warn(missing_docs)]

use std::fs;
use std::io;
use std::io::{Seek, Write};
use std::path;

/// Extends the functionality of `io::Write` with additional methods.
///
/// The methods may be used on any type that implements `io::Write`.
trait WriteExt: io::Write {
    /// Writes an unsigned 16-bit integer in little endian format.
    fn write_le_u16(&mut self, x: u16) -> io::Result<()>;

    /// Writes an unsigned 32-bit integer in little endian format.
    fn write_le_u32(&mut self, x: u32) -> io::Result<()>;
}

impl<W> WriteExt for W where W: io::Write {

    fn write_le_u16(&mut self, x: u16) -> io::Result<()> {
        let mut buf = [0u8; 2];
        buf[0] = (x & 0xff) as u8;
        buf[1] = (x >> 8) as u8;
        self.write_all(&buf)
    }

    fn write_le_u32(&mut self, x: u32) -> io::Result<()> {
        let mut buf = [0u8; 4];
        buf[0] = ((x >> 00) & 0xff) as u8;
        buf[1] = ((x >> 08) & 0xff) as u8;
        buf[2] = ((x >> 16) & 0xff) as u8;
        buf[3] = ((x >> 24) & 0xff) as u8;
        self.write_all(&buf)
    }
}

/// A type that can be used to represent audio samples.
pub trait Sample {
    /// Writes the audio sample to the WAVE data section.
    fn write<W: io::Write>(self, writer: &mut W, bits: u32) -> io::Result<()>;
}

impl Sample for u16 {
    fn write<W: io::Write>(self, writer: &mut W, bits: u32) -> io::Result<()> {
        writer.write_le_u16(self)
        // TODO: take bits into account
    }
}

impl Sample for i16 {
    fn write<W: io::Write>(self, writer: &mut W, bits: u32) -> io::Result<()> {
        writer.write_le_u16(self as u16)
        // TODO: take bits into account
    }
}

/// Generates a bitmask with `channels` ones in the least significant bits.
fn channel_mask(channels: u16) -> u32 {
    (0 .. channels).map(|c| 1 << c).fold(0, |a, c| a | c)
}

#[test]
fn verify_channel_mask()
{
    assert_eq!(channel_mask(0), 0);
    assert_eq!(channel_mask(1), 1);
    assert_eq!(channel_mask(2), 3);
    assert_eq!(channel_mask(3), 7);
    assert_eq!(channel_mask(4), 15);
}

/// Specifies properties of the audio data.
#[derive(Clone, Copy)]
pub struct WavSpec {
    /// The number of channels.
    pub channels: u16,

    /// The number of samples per second.
    ///
    /// A common value is 44100, this is 44.1 kHz which is used for CD audio.
    pub sample_rate: u32,

    /// The number of bits per sample.
    ///
    /// A common value is 16 bits per sample, which is used for CD audio.
    pub bits_per_sample: u32
}

/// A writer that accepts samples and writes the WAVE format.
///
/// TODO: add example.
///
/// After all samples have been written, the file must be finalized. This can
/// be done by calling `finalize`. If `finalize` is not called, the file will
/// be finalized upon drop. However, finalization involves IO that may fail,
/// and without calling `finalize`, such a failure cannot be observed.
pub struct WavWriter<W> where W: io::Write + io::Seek {
    /// Specifies properties of the audio data.
    spec: WavSpec,

    /// The (container) bytes per sample. This is the bit rate / 8 rounded up.
    bytes_per_sample: u32,

    /// Whether the header has been written already.
    wrote_header: bool,

    /// The writer that will be written to.
    writer: io::BufWriter<W>,

    /// The number of bytes written to the data section.
    ///
    /// This is an `u32` because WAVE cannot accomodate more data.
    data_bytes_written: u32,

    /// Whether `finalize_internal` has been called.
    finalized: bool
}

impl<W> WavWriter<W> where W: io::Write + io::Seek {
    /// Creates a writer that writes the WAVE format to the underlying writer.
    ///
    /// The underlying writer is assumed to be at offset 0. `WavWriter` employs
    /// buffering internally to avoid too many `write` calls to the underlying
    /// writer.
    pub fn new(writer: W, spec: WavSpec) -> WavWriter<W> {
        WavWriter {
            spec: spec,
            bytes_per_sample: (spec.bits_per_sample as f32 / 8.0).ceil() as u32,
            wrote_header: false,
            writer: io::BufWriter::new(writer),
            data_bytes_written: 0,
            finalized: false
        }
    }

    /// Creates a writer that writes the WAVE format to a file.
    ///
    /// The file will be overwritten if it exists.
    pub fn create<P: AsRef<path::Path>>(filename: P, spec: WavSpec)
           -> io::Result<WavWriter<fs::File>> {
        let file = try!(fs::File::create(filename));
        Ok(WavWriter::new(file, spec))
    }

    /// Writes the RIFF WAVE header
    fn write_header(&mut self) -> io::Result<()> {
        // Useful links:
        // https://msdn.microsoft.com/en-us/library/ms713462.aspx
        // https://msdn.microsoft.com/en-us/library/ms713497.aspx

        let mut header = [0u8; 68];
        let spec = &self.spec;

        // Write the header in-memory first.
        {
            let mut buffer: io::Cursor<&mut [u8]> = io::Cursor::new(&mut header);
            try!(buffer.write_all("RIFF".as_bytes()));

            // Skip 4 bytes that will be filled with the file size afterwards.
            try!(buffer.write_le_u32(0));

            try!(buffer.write_all("WAVE".as_bytes()));
            try!(buffer.write_all("fmt ".as_bytes()));
            try!(buffer.write_le_u32(40)); // Size of the WAVE header chunk.

            // The following is based on the WAVEFORMATEXTENSIBLE struct as
            // documented on MSDN.

            // The field wFormatTag, value 1 means WAVE_FORMAT_PCM, but we use
            // the slightly more sophisticated WAVE_FORMAT_EXTENSIBLE.
            try!(buffer.write_le_u16(0xfffe));
            // The field nChannels.
            try!(buffer.write_le_u16(spec.channels));
            // The field nSamplesPerSec.
            try!(buffer.write_le_u32(spec.sample_rate));
            let bytes_per_sec = spec.sample_rate
                              * self.bytes_per_sample
                              * spec.channels as u32;
            // The field nAvgBytesPerSec;
            try!(buffer.write_le_u32(bytes_per_sec));
            // The field nBlockAlign. Block align * sample rate = bytes per sec.
            try!(buffer.write_le_u16((bytes_per_sec / spec.sample_rate) as u16));
            // The field wBitsPerSample. This is actually the size of the
            // container, so this is a multiple of 8.
            try!(buffer.write_le_u16(self.bytes_per_sample as u16 * 8));
            // The field cbSize, the number of remaining bytes in the struct.
            try!(buffer.write_le_u16(22));
            // The field wValidBitsPerSample, the real number of bits per sample.
            try!(buffer.write_le_u16(self.spec.bits_per_sample as u16));
            // The field dwChannelMask.
            // TODO: add the option to specify the channel mask. For now, use
            // the default assignment.
            try!(buffer.write_le_u32(channel_mask(self.spec.channels)));
            // The field SubFormat. We use KSDATAFORMAT_SUBTYPE_PCM. The
            // following GUIDS are defined:
            // - PCM:        00000001-0000-0010-8000-00aa00389b71
            // - IEEE_FLOAT: 00000003-0000-0010-8000-00aa00389b71
            // The byte order of a GUID is native for the first three sections,
            // which is assumed to be little endian, and big endian for the
            // last 8-byte section (which does contain a hyphen, for reasons
            // unknown to me).
            try!(buffer.write_all(&[0x01, 0x00, 0x00, 0x00,
                                    0x00, 0x00, 0x10, 0x00,
                                    0x80, 0x00, 0x00, 0xaa,
                                    0x00, 0x38, 0x9b, 0x71]));

            // So far the "fmt " section, now comes the "data" section. We will
            // only write the header here, actual data are the samples. The
            // number of bytes that this will take is not known at this point.
            // The 0 will be overwritten later.
            try!(buffer.write_all("data".as_bytes()));
            try!(buffer.write_le_u32(0));
        }

        // Then write the entire header at once.
        try!(self.writer.write_all(&header));

        Ok(())
    }

    /// Writes a single sample for one channel.
    ///
    /// WAVE interleaves channel data, so the channel that this writes the
    /// sample to depends on previous writes.
    pub fn write_sample<S: Sample>(&mut self, sample: S) -> io::Result<()> {
        if !self.wrote_header {
            try!(self.write_header());
            self.wrote_header = true;
        }

        // TODO: do we need bits per sample? Is the padding at the obvious side?
        try!(sample.write(&mut self.writer, self.bytes_per_sample));
        self.data_bytes_written += self.bytes_per_sample;
        Ok(())
    }

    /// Performs finalization. After calling this, the writer should be destructed.
    fn finalize_internal(&mut self) -> io::Result<()> {
        self.finalized = true;

        // Flush remaining samples via the BufWriter.
        try!(self.writer.flush());

        // Extract the underlying writer and rewind it to the start, to update
        // the header fields of which we now know the value.
        let mut writer = self.writer.get_mut();

        // The header minus magic and 32-bit filesize is 60 bytes long.
        let file_size = self.data_bytes_written + 60;
        try!(writer.seek(io::SeekFrom::Start(4)));
        try!(writer.write_le_u32(file_size));
        try!(writer.seek(io::SeekFrom::Start(64)));
        try!(writer.write_le_u32(self.data_bytes_written));

        Ok(())
    }

    /// Writes the parts of the WAVE format that require knowing all samples.
    ///
    /// This method must be called after all samples have been written. If it
    /// is not called, the destructor will finalize the file, but any IO errors
    /// that occur in the process cannot be observed in that manner.
    pub fn finalize(mut self) -> io::Result<()> {
        self.finalize_internal()
    }
}

impl<W> Drop for WavWriter<W> where W: io::Write + io::Seek {
    fn drop(&mut self) {
        // `finalize_internal` must be called only once. If that is done via
        // `finalize`, then this method is a no-op. If the user did not
        // finalize explicitly, then we should do it now. This can fail, but
        // drop should not panic, so a failure is ignored silently here.
        if !self.finalized {
            let _r = self.finalize_internal();
        }
    }
}

// TODO: Add benchmark for write speed.
<commit_msg>remove unused import<commit_after>// Hound -- A WAV encoding library in Rust
// Copyright (C) 2015 Ruud van Asseldonk
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 3 of the License only.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

//! Hound, a WAV encoding library.
//!
//! TODO: Add some introductory text here.
//!
//! The following example renders a 440 Hz sine wave, and stores it as as a
//! mono wav file with a sample rate of 44.1 kHz and 16 bits per sample.
//!
//! ```
//! use std::fs;
//! use std::f32::consts::PI;
//! use std::i16;
//! use hound;
//!
//! let spec = hound::WavSpec {
//!     channels: 1,
//!     sample_rate: 44100,
//!     bits_per_sample: 16
//! };
//! // TODO: ensure that the type can be inferred.
//! let writer_res = hound::WavWriter::<fs::File>::create("sine.wav", spec);
//! let mut writer = writer_res.ok().unwrap();
//! for t in (0 .. 44100).map(|x| x as f32 / 44100.0) {
//!     let sample = (t * 440.0 * 2.0 * PI).sin();
//!     let amplitude: i16 = i16::MAX;
//!     writer.write_sample((sample * amplitude as f32) as i16).ok().unwrap();
//! }
//! writer.finalize().ok().unwrap();
//! ```

#![warn(missing_docs)]

use std::fs;
use std::io;
use std::io::Write;
use std::path;

/// Extends the functionality of `io::Write` with additional methods.
///
/// The methods may be used on any type that implements `io::Write`.
trait WriteExt: io::Write {
    /// Writes an unsigned 16-bit integer in little endian format.
    fn write_le_u16(&mut self, x: u16) -> io::Result<()>;

    /// Writes an unsigned 32-bit integer in little endian format.
    fn write_le_u32(&mut self, x: u32) -> io::Result<()>;
}

impl<W> WriteExt for W where W: io::Write {

    fn write_le_u16(&mut self, x: u16) -> io::Result<()> {
        let mut buf = [0u8; 2];
        buf[0] = (x & 0xff) as u8;
        buf[1] = (x >> 8) as u8;
        self.write_all(&buf)
    }

    fn write_le_u32(&mut self, x: u32) -> io::Result<()> {
        let mut buf = [0u8; 4];
        buf[0] = ((x >> 00) & 0xff) as u8;
        buf[1] = ((x >> 08) & 0xff) as u8;
        buf[2] = ((x >> 16) & 0xff) as u8;
        buf[3] = ((x >> 24) & 0xff) as u8;
        self.write_all(&buf)
    }
}

/// A type that can be used to represent audio samples.
pub trait Sample {
    /// Writes the audio sample to the WAVE data section.
    fn write<W: io::Write>(self, writer: &mut W, bits: u32) -> io::Result<()>;
}

impl Sample for u16 {
    fn write<W: io::Write>(self, writer: &mut W, bits: u32) -> io::Result<()> {
        writer.write_le_u16(self)
        // TODO: take bits into account
    }
}

impl Sample for i16 {
    fn write<W: io::Write>(self, writer: &mut W, bits: u32) -> io::Result<()> {
        writer.write_le_u16(self as u16)
        // TODO: take bits into account
    }
}

/// Generates a bitmask with `channels` ones in the least significant bits.
fn channel_mask(channels: u16) -> u32 {
    (0 .. channels).map(|c| 1 << c).fold(0, |a, c| a | c)
}

#[test]
fn verify_channel_mask()
{
    assert_eq!(channel_mask(0), 0);
    assert_eq!(channel_mask(1), 1);
    assert_eq!(channel_mask(2), 3);
    assert_eq!(channel_mask(3), 7);
    assert_eq!(channel_mask(4), 15);
}

/// Specifies properties of the audio data.
#[derive(Clone, Copy)]
pub struct WavSpec {
    /// The number of channels.
    pub channels: u16,

    /// The number of samples per second.
    ///
    /// A common value is 44100, this is 44.1 kHz which is used for CD audio.
    pub sample_rate: u32,

    /// The number of bits per sample.
    ///
    /// A common value is 16 bits per sample, which is used for CD audio.
    pub bits_per_sample: u32
}

/// A writer that accepts samples and writes the WAVE format.
///
/// TODO: add example.
///
/// After all samples have been written, the file must be finalized. This can
/// be done by calling `finalize`. If `finalize` is not called, the file will
/// be finalized upon drop. However, finalization involves IO that may fail,
/// and without calling `finalize`, such a failure cannot be observed.
pub struct WavWriter<W> where W: io::Write + io::Seek {
    /// Specifies properties of the audio data.
    spec: WavSpec,

    /// The (container) bytes per sample. This is the bit rate / 8 rounded up.
    bytes_per_sample: u32,

    /// Whether the header has been written already.
    wrote_header: bool,

    /// The writer that will be written to.
    writer: io::BufWriter<W>,

    /// The number of bytes written to the data section.
    ///
    /// This is an `u32` because WAVE cannot accomodate more data.
    data_bytes_written: u32,

    /// Whether `finalize_internal` has been called.
    finalized: bool
}

impl<W> WavWriter<W> where W: io::Write + io::Seek {
    /// Creates a writer that writes the WAVE format to the underlying writer.
    ///
    /// The underlying writer is assumed to be at offset 0. `WavWriter` employs
    /// buffering internally to avoid too many `write` calls to the underlying
    /// writer.
    pub fn new(writer: W, spec: WavSpec) -> WavWriter<W> {
        WavWriter {
            spec: spec,
            bytes_per_sample: (spec.bits_per_sample as f32 / 8.0).ceil() as u32,
            wrote_header: false,
            writer: io::BufWriter::new(writer),
            data_bytes_written: 0,
            finalized: false
        }
    }

    /// Creates a writer that writes the WAVE format to a file.
    ///
    /// The file will be overwritten if it exists.
    pub fn create<P: AsRef<path::Path>>(filename: P, spec: WavSpec)
           -> io::Result<WavWriter<fs::File>> {
        let file = try!(fs::File::create(filename));
        Ok(WavWriter::new(file, spec))
    }

    /// Writes the RIFF WAVE header
    fn write_header(&mut self) -> io::Result<()> {
        // Useful links:
        // https://msdn.microsoft.com/en-us/library/ms713462.aspx
        // https://msdn.microsoft.com/en-us/library/ms713497.aspx

        let mut header = [0u8; 68];
        let spec = &self.spec;

        // Write the header in-memory first.
        {
            let mut buffer: io::Cursor<&mut [u8]> = io::Cursor::new(&mut header);
            try!(buffer.write_all("RIFF".as_bytes()));

            // Skip 4 bytes that will be filled with the file size afterwards.
            try!(buffer.write_le_u32(0));

            try!(buffer.write_all("WAVE".as_bytes()));
            try!(buffer.write_all("fmt ".as_bytes()));
            try!(buffer.write_le_u32(40)); // Size of the WAVE header chunk.

            // The following is based on the WAVEFORMATEXTENSIBLE struct as
            // documented on MSDN.

            // The field wFormatTag, value 1 means WAVE_FORMAT_PCM, but we use
            // the slightly more sophisticated WAVE_FORMAT_EXTENSIBLE.
            try!(buffer.write_le_u16(0xfffe));
            // The field nChannels.
            try!(buffer.write_le_u16(spec.channels));
            // The field nSamplesPerSec.
            try!(buffer.write_le_u32(spec.sample_rate));
            let bytes_per_sec = spec.sample_rate
                              * self.bytes_per_sample
                              * spec.channels as u32;
            // The field nAvgBytesPerSec;
            try!(buffer.write_le_u32(bytes_per_sec));
            // The field nBlockAlign. Block align * sample rate = bytes per sec.
            try!(buffer.write_le_u16((bytes_per_sec / spec.sample_rate) as u16));
            // The field wBitsPerSample. This is actually the size of the
            // container, so this is a multiple of 8.
            try!(buffer.write_le_u16(self.bytes_per_sample as u16 * 8));
            // The field cbSize, the number of remaining bytes in the struct.
            try!(buffer.write_le_u16(22));
            // The field wValidBitsPerSample, the real number of bits per sample.
            try!(buffer.write_le_u16(self.spec.bits_per_sample as u16));
            // The field dwChannelMask.
            // TODO: add the option to specify the channel mask. For now, use
            // the default assignment.
            try!(buffer.write_le_u32(channel_mask(self.spec.channels)));
            // The field SubFormat. We use KSDATAFORMAT_SUBTYPE_PCM. The
            // following GUIDS are defined:
            // - PCM:        00000001-0000-0010-8000-00aa00389b71
            // - IEEE_FLOAT: 00000003-0000-0010-8000-00aa00389b71
            // The byte order of a GUID is native for the first three sections,
            // which is assumed to be little endian, and big endian for the
            // last 8-byte section (which does contain a hyphen, for reasons
            // unknown to me).
            try!(buffer.write_all(&[0x01, 0x00, 0x00, 0x00,
                                    0x00, 0x00, 0x10, 0x00,
                                    0x80, 0x00, 0x00, 0xaa,
                                    0x00, 0x38, 0x9b, 0x71]));

            // So far the "fmt " section, now comes the "data" section. We will
            // only write the header here, actual data are the samples. The
            // number of bytes that this will take is not known at this point.
            // The 0 will be overwritten later.
            try!(buffer.write_all("data".as_bytes()));
            try!(buffer.write_le_u32(0));
        }

        // Then write the entire header at once.
        try!(self.writer.write_all(&header));

        Ok(())
    }

    /// Writes a single sample for one channel.
    ///
    /// WAVE interleaves channel data, so the channel that this writes the
    /// sample to depends on previous writes.
    pub fn write_sample<S: Sample>(&mut self, sample: S) -> io::Result<()> {
        if !self.wrote_header {
            try!(self.write_header());
            self.wrote_header = true;
        }

        // TODO: do we need bits per sample? Is the padding at the obvious side?
        try!(sample.write(&mut self.writer, self.bytes_per_sample));
        self.data_bytes_written += self.bytes_per_sample;
        Ok(())
    }

    /// Performs finalization. After calling this, the writer should be destructed.
    fn finalize_internal(&mut self) -> io::Result<()> {
        self.finalized = true;

        // Flush remaining samples via the BufWriter.
        try!(self.writer.flush());

        // Extract the underlying writer and rewind it to the start, to update
        // the header fields of which we now know the value.
        let mut writer = self.writer.get_mut();

        // The header minus magic and 32-bit filesize is 60 bytes long.
        let file_size = self.data_bytes_written + 60;
        try!(writer.seek(io::SeekFrom::Start(4)));
        try!(writer.write_le_u32(file_size));
        try!(writer.seek(io::SeekFrom::Start(64)));
        try!(writer.write_le_u32(self.data_bytes_written));

        Ok(())
    }

    /// Writes the parts of the WAVE format that require knowing all samples.
    ///
    /// This method must be called after all samples have been written. If it
    /// is not called, the destructor will finalize the file, but any IO errors
    /// that occur in the process cannot be observed in that manner.
    pub fn finalize(mut self) -> io::Result<()> {
        self.finalize_internal()
    }
}

impl<W> Drop for WavWriter<W> where W: io::Write + io::Seek {
    fn drop(&mut self) {
        // `finalize_internal` must be called only once. If that is done via
        // `finalize`, then this method is a no-op. If the user did not
        // finalize explicitly, then we should do it now. This can fail, but
        // drop should not panic, so a failure is ignored silently here.
        if !self.finalized {
            let _r = self.finalize_internal();
        }
    }
}

// TODO: Add benchmark for write speed.
<|endoftext|>


<commit_before>extern crate curl;

use std::str;
use std::error::Error;
// use std::thread;
// use std::sync::Arc;
use curl::http;

mod util;

pub struct Firebase {
    base_uri: String,
}

impl Firebase {
    pub fn new(base_uri: &str) -> Self {
        Firebase {
            base_uri: base_uri.to_string(),
        }
    }

    pub fn authed(base_uri: &str, auth_token: &str) -> Self {
        let uri = util::trim_right(base_uri, "/");
        Firebase {
            base_uri: format!("{}?auth={}", uri, auth_token),
        }
    }

    pub fn at(&self, path: &str) -> Self {
        let mut components = self.base_uri.split('?');

        let base = components.next().unwrap();
        let base = util::trim_right(base, ".json");
        let path = util::trim_right(path, "/");
        let path = util::add_right(path, ".json");
        let url  = util::join(base, &path, "/");

        let url = if let Some(args) = components.next() {
            url + "?" + args
        } else {
            url
        };

        Firebase {
            base_uri: url,
        }
    }

    pub fn get(&self) -> Result<Response, Box<Error>> {
        self.request(Method::GET, None)
    }

    // pub fn get_async<F>(&self, done: &F) where F: Fn(Result<Response, Box<Error>>) {
    //     let callback = Arc::new(done).clone();
    //
    //     thread::spawn(move || {
    //         callback(self.get());
    //     });
    // }

    pub fn set(&self, data: &str) -> Result<Response, Box<Error>> {
        self.request(Method::PUT, Some(data))
    }

    pub fn push(&self, data: &str) -> Result<Response, Box<Error>> {
        self.request(Method::POST, Some(data))
    }

    pub fn update(&self, data: &str) -> Result<Response, Box<Error>> {
        self.request(Method::PATCH, Some(data))
    }

    pub fn remove(&self) -> Result<Response, Box<Error>> {
        self.request(Method::DELETE, None)
    }

    fn request(&self, method: Method, data: Option<&str>) -> Result<Response, Box<Error>> {
        Firebase::request_url(&self.base_uri, method, data)
    }

    fn request_url(url: &str, method: Method, data: Option<&str>) -> Result<Response, Box<Error>> {
        let mut handler = http::handle();

        let req = match method {
            Method::GET     => handler.get(url),
            Method::POST    => handler.post(url, data.unwrap()),
            Method::PUT     => handler.put(url, data.unwrap()),
            Method::PATCH   => handler.patch(url, data.unwrap()),
            Method::DELETE  => handler.delete(url)
        };
        let res = try!(req.exec());

        let body = try!(str::from_utf8(res.get_body()));

        Ok(Response {
            body: body.to_string(),
            code: res.get_code(),
        })
    }

    pub fn get_url(&self) -> &str {
        return &self.base_uri;
    }

    pub fn order_by(&self, key: &str) -> ParamsRequest {
        self.params_request(order_by_str(key))
    }

    pub fn limit_to_first(&self, count: u32) -> ParamsRequest {
        self.params_request(limit_to_first_str(count))
    }

    pub fn limit_to_last(&self, count: u32) -> ParamsRequest {
        self.params_request(limit_to_last_str(count))
    }

    pub fn start_at(&self, index: u32) -> ParamsRequest {
        self.params_request(start_at_str(index))
    }

    pub fn end_at(&self, index: u32) -> ParamsRequest {
        self.params_request(end_at_str(index))
    }

    pub fn equal_to(&self, value: u32) -> ParamsRequest {
        self.params_request(equal_to_str(value))
    }

    pub fn shallow(&self, flag: bool) -> ParamsRequest {
        self.params_request(shallow_str(flag))
    }

    fn params_request(&self, param: String) -> ParamsRequest {
        ParamsRequest {
            firebase: &self,
            params: vec![param],
        }
    }
}

pub struct ParamsRequest<'l> {
    firebase: &'l Firebase,
    params: Vec<String>,
}

impl<'l> ParamsRequest<'l> {
    pub fn order_by(mut self, key: &str) -> Self {
        self.params.push(order_by_str(key));
        self
    }

    pub fn limit_to_first(mut self, count: u32) -> Self {
        self.params.push(limit_to_first_str(count));
        self
    }

    pub fn limit_to_last(mut self, count: u32) -> Self {
        self.params.push(limit_to_last_str(count));
        self
    }

    pub fn start_at(mut self, index: u32) -> Self {
        self.params.push(start_at_str(index));
        self
    }

    pub fn end_at(mut self, index: u32) -> Self {
        self.params.push(end_at_str(index));
        self
    }

    pub fn equal_to(mut self, value: u32) -> Self {
        self.params.push(equal_to_str(value));
        self
    }

    pub fn shallow(mut self, flag: bool) -> Self {
        self.params.push(shallow_str(flag));
        self
    }

    pub fn get(&self) -> Result<Response, Box<Error>> {
        Firebase::request_url(&self.get_url(), Method::GET, None)
    }

    pub fn get_url(&self) -> String {
        let params = self.params.connect("&");

        if self.firebase.base_uri.find("?").is_some() {
            format!("{}&{}", &self.firebase.base_uri, params)
        } else {
            format!("{}?{}", &self.firebase.base_uri, params)
        }
    }
}

fn order_by_str(key: &str) -> String {
    format!("orderBy={}", key)
}

fn limit_to_first_str(count: u32) -> String {
    format!("limitToFirst={}", count)
}

fn limit_to_last_str(count: u32) -> String {
    format!("limitToLast={}", count)
}

fn start_at_str(index: u32) -> String {
    format!("startAt={}", index)
}

fn end_at_str(index: u32) -> String {
    format!("endAt={}", index)
}

fn equal_to_str(value: u32) -> String {
    format!("equalTo={}", value)
}

fn shallow_str(flag: bool) -> String {
    format!("shallow={}", flag)
}

enum Method {
    GET,
    POST,
    PUT,
    PATCH,
    DELETE,
}

pub struct Response {
    pub body: String,
    pub code: u32,
}

impl Response {
    pub fn is_success(&self) -> bool {
        self.code < 400
    }
}
<commit_msg>First go at async features to the library<commit_after>extern crate curl;

use std::str;
use std::error::Error;
use std::thread;
use std::thread::JoinHandle;
use std::sync::Arc;
use curl::http;

mod util;

pub type FbResult = Result<Response, Box<Error>>;

#[derive(Clone)]
pub struct Firebase {
    base_uri: String,
}

impl Firebase {
    pub fn new(base_uri: &str) -> Self {
        Firebase {
            base_uri: base_uri.to_string(),
        }
    }

    pub fn authed(base_uri: &str, auth_token: &str) -> Self {
        let uri = util::trim_right(base_uri, "/");
        Firebase {
            base_uri: format!("{}?auth={}", uri, auth_token),
        }
    }

    pub fn at(&self, path: &str) -> Self {
        let mut components = self.base_uri.split('?');

        let base = components.next().unwrap();
        let base = util::trim_right(base, ".json");
        let path = util::trim_right(path, "/");
        let path = util::add_right(path, ".json");
        let url  = util::join(base, &path, "/");

        let url = if let Some(args) = components.next() {
            url + "?" + args
        } else {
            url
        };

        Firebase {
            base_uri: url,
        }
    }

    pub fn get(&self) -> FbResult {
        self.request(Method::GET, None)
    }

    pub fn get_async<F>(&self, callback: F) -> JoinHandle<()>
            where F: Fn(FbResult) + Send + Sync + 'static {
        self.request_async(Method::GET, None, callback)
    }

    pub fn set(&self, data: &str) -> FbResult {
        self.request(Method::PUT, Some(data))
    }

    pub fn set_async<F>(&self, data: &str, callback: F) -> JoinHandle<()>
            where F: Fn(FbResult) + Send + Sync + 'static {
        self.request_async(Method::PUT, Some(data), callback)
    }

    pub fn push(&self, data: &str) -> FbResult {
        self.request(Method::POST, Some(data))
    }

    pub fn push_async<F>(&self, data: &str, callback: F) -> JoinHandle<()>
            where F: Fn(FbResult) + Send + Sync + 'static {
        self.request_async(Method::POST, Some(data), callback)
    }

    pub fn update(&self, data: &str) -> FbResult {
        self.request(Method::PATCH, Some(data))
    }

    pub fn update_async<F>(&self, data: &str, callback: F) -> JoinHandle<()>
            where F: Fn(FbResult) + Send + Sync + 'static {
        self.request_async(Method::PATCH, Some(data), callback)
    }

    pub fn remove(&self) -> FbResult {
        self.request(Method::DELETE, None)
    }

    pub fn remove_async<F>(&self, callback: F) -> JoinHandle<()>
            where F: Fn(FbResult) + Send + Sync + 'static {
        self.request_async(Method::DELETE, None, callback)
    }

    fn request(&self, method: Method, data: Option<&str>) -> FbResult {
        Firebase::request_url(&self.base_uri, method, data)
    }

    fn request_url(url: &str, method: Method, data: Option<&str>) -> FbResult {
        let mut handler = http::handle();

        let req = match method {
            Method::GET     => handler.get(url),
            Method::POST    => handler.post(url, data.unwrap()),
            Method::PUT     => handler.put(url, data.unwrap()),
            Method::PATCH   => handler.patch(url, data.unwrap()),
            Method::DELETE  => handler.delete(url)
        };
        let res = try!(req.exec());

        let body = try!(str::from_utf8(res.get_body()));

        Ok(Response {
            body: body.to_string(),
            code: res.get_code(),
        })
    }

    fn request_async<F>(&self, method: Method, data: Option<&str>, callback: F) -> JoinHandle<()>
            where F: Fn(FbResult) + Send + Sync + 'static {
        let done = Arc::new(callback).clone();
        let me   = Arc::new(self.clone());

        if let Some(d) = data {
            let data = Arc::new(d.to_string()).clone();
            thread::spawn(move || {
                done(me.request(method, Some(&*data)));
            })
        } else {
            thread::spawn(move || {
                done(me.request(method, None));
            })
        }
    }

    pub fn get_url(&self) -> &str {
        return &self.base_uri;
    }

    pub fn order_by(&self, key: &str) -> ParamsRequest {
        self.params_request(order_by_str(key))
    }

    pub fn limit_to_first(&self, count: u32) -> ParamsRequest {
        self.params_request(limit_to_first_str(count))
    }

    pub fn limit_to_last(&self, count: u32) -> ParamsRequest {
        self.params_request(limit_to_last_str(count))
    }

    pub fn start_at(&self, index: u32) -> ParamsRequest {
        self.params_request(start_at_str(index))
    }

    pub fn end_at(&self, index: u32) -> ParamsRequest {
        self.params_request(end_at_str(index))
    }

    pub fn equal_to(&self, value: u32) -> ParamsRequest {
        self.params_request(equal_to_str(value))
    }

    pub fn shallow(&self, flag: bool) -> ParamsRequest {
        self.params_request(shallow_str(flag))
    }

    fn params_request(&self, param: String) -> ParamsRequest {
        ParamsRequest {
            firebase: &self,
            params: vec![param],
        }
    }
}

pub struct ParamsRequest<'l> {
    firebase: &'l Firebase,
    params: Vec<String>,
}

impl<'l> ParamsRequest<'l> {
    pub fn order_by(mut self, key: &str) -> Self {
        self.params.push(order_by_str(key));
        self
    }

    pub fn limit_to_first(mut self, count: u32) -> Self {
        self.params.push(limit_to_first_str(count));
        self
    }

    pub fn limit_to_last(mut self, count: u32) -> Self {
        self.params.push(limit_to_last_str(count));
        self
    }

    pub fn start_at(mut self, index: u32) -> Self {
        self.params.push(start_at_str(index));
        self
    }

    pub fn end_at(mut self, index: u32) -> Self {
        self.params.push(end_at_str(index));
        self
    }

    pub fn equal_to(mut self, value: u32) -> Self {
        self.params.push(equal_to_str(value));
        self
    }

    pub fn shallow(mut self, flag: bool) -> Self {
        self.params.push(shallow_str(flag));
        self
    }

    pub fn get(&self) -> FbResult {
        Firebase::request_url(&self.get_url(), Method::GET, None)
    }

    // TODO: Make async call here. Need to restructure.

    pub fn get_url(&self) -> String {
        let params = self.params.connect("&");

        if self.firebase.base_uri.find("?").is_some() {
            format!("{}&{}", &self.firebase.base_uri, params)
        } else {
            format!("{}?{}", &self.firebase.base_uri, params)
        }
    }
}

fn order_by_str(key: &str) -> String {
    format!("orderBy={}", key)
}

fn limit_to_first_str(count: u32) -> String {
    format!("limitToFirst={}", count)
}

fn limit_to_last_str(count: u32) -> String {
    format!("limitToLast={}", count)
}

fn start_at_str(index: u32) -> String {
    format!("startAt={}", index)
}

fn end_at_str(index: u32) -> String {
    format!("endAt={}", index)
}

fn equal_to_str(value: u32) -> String {
    format!("equalTo={}", value)
}

fn shallow_str(flag: bool) -> String {
    format!("shallow={}", flag)
}

enum Method {
    GET,
    POST,
    PUT,
    PATCH,
    DELETE,
}

pub struct Response {
    pub body: String,
    pub code: u32,
}

impl Response {
    pub fn is_success(&self) -> bool {
        self.code < 400
    }
}
<|endoftext|>


<commit_before>#![warn(bad_style, missing_docs,
        unused, unused_extern_crates, unused_import_braces,
        unused_qualifications, unused_results, unused_typecasts)]

extern crate "oauth-client" as oauth;

use std::borrow::IntoCow;
use std::collections::HashMap;
use std::str::CowString;
use oauth::Token;

mod api {
    pub const REQUEST_TOKEN: &'static str   = "https://api.twitter.com/oauth/request_token";
    pub const AUTHORIZE: &'static str       = "https://api.twitter.com/oauth/authorize";
    pub const ACCESS_TOKEN: &'static str    = "https://api.twitter.com/oauth/access_token";
    pub const STATUSES_UPDATE: &'static str = "https://api.twitter.com/1.1/statuses/update.json";
}

fn split_query<'a>(query: &'a str) -> HashMap<CowString<'a>, CowString<'a>> {
    let mut param = HashMap::new();
    for q in query.split('&') {
        let mut s = q.splitn(2, '=');
        let k = s.next().unwrap();
        let v = s.next().unwrap();
        let _ = param.insert(k.into_cow(), v.into_cow());
    }
    param
}

pub fn get_request_token(consumer: &Token) -> Token<'static> {
    let resp = oauth::get(api::REQUEST_TOKEN, consumer, None, None);
    let param = split_query(resp.as_slice());
    Token::new(param.get("oauth_token").unwrap().to_string(),
               param.get("oauth_token_secret").unwrap().to_string())
}

pub fn get_authorize_url(request: &Token) -> String {
    format!("{}?oauth_token={}", api::AUTHORIZE, request.key)
}

pub fn get_access_token(consumer: &Token, request: &Token, pin: &str) -> Token<'static> {
    let mut param = HashMap::new();
    let _ = param.insert("oauth_verifier".into_cow(), pin.into_cow());
    let resp = oauth::get(api::ACCESS_TOKEN, consumer, Some(request), Some(&param));
    let param = split_query(resp.as_slice());
    Token::new(param.get("oauth_token").unwrap().to_string(),
               param.get("oauth_token_secret").unwrap().to_string())
}

pub fn tweet(consumer: &Token, access: &Token, status: &str) {
    let mut param = HashMap::new();
    let _ = param.insert("status".into_cow(), status.into_cow());
    let _ = oauth::post(api::STATUSES_UPDATE, consumer, Some(access), Some(&param));
}
<commit_msg>Update to rust master<commit_after>#![warn(bad_style, missing_docs,
        unused, unused_extern_crates, unused_import_braces,
        unused_qualifications, unused_results, unused_typecasts)]

extern crate "oauth-client" as oauth;

use std::borrow::IntoCow;
use std::collections::HashMap;
use std::string::CowString;
use oauth::Token;

mod api {
    pub const REQUEST_TOKEN: &'static str   = "https://api.twitter.com/oauth/request_token";
    pub const AUTHORIZE: &'static str       = "https://api.twitter.com/oauth/authorize";
    pub const ACCESS_TOKEN: &'static str    = "https://api.twitter.com/oauth/access_token";
    pub const STATUSES_UPDATE: &'static str = "https://api.twitter.com/1.1/statuses/update.json";
}

fn split_query<'a>(query: &'a str) -> HashMap<CowString<'a>, CowString<'a>> {
    let mut param = HashMap::new();
    for q in query.split('&') {
        let mut s = q.splitn(2, '=');
        let k = s.next().unwrap();
        let v = s.next().unwrap();
        let _ = param.insert(k.into_cow(), v.into_cow());
    }
    param
}

pub fn get_request_token(consumer: &Token) -> Token<'static> {
    let resp = oauth::get(api::REQUEST_TOKEN, consumer, None, None);
    let param = split_query(resp.as_slice());
    Token::new(param.get("oauth_token").unwrap().to_string(),
               param.get("oauth_token_secret").unwrap().to_string())
}

pub fn get_authorize_url(request: &Token) -> String {
    format!("{}?oauth_token={}", api::AUTHORIZE, request.key)
}

pub fn get_access_token(consumer: &Token, request: &Token, pin: &str) -> Token<'static> {
    let mut param = HashMap::new();
    let _ = param.insert("oauth_verifier".into_cow(), pin.into_cow());
    let resp = oauth::get(api::ACCESS_TOKEN, consumer, Some(request), Some(&param));
    let param = split_query(resp.as_slice());
    Token::new(param.get("oauth_token").unwrap().to_string(),
               param.get("oauth_token_secret").unwrap().to_string())
}

pub fn tweet(consumer: &Token, access: &Token, status: &str) {
    let mut param = HashMap::new();
    let _ = param.insert("status".into_cow(), status.into_cow());
    let _ = oauth::post(api::STATUSES_UPDATE, consumer, Some(access), Some(&param));
}
<|endoftext|>