<commit_before>#![feature(macro_rules)]

//! Strided slices.
//!
//! This library provides two types `Strided` and `MutStrided` as
//! generalised forms of `&[T]` and `&mut [T]` respectively, where the
//! elements are regularly spaced in memory, but not necessarily
//! immediately adjacently.
//!
//! For example, given an underlying array `[1, 2, 3, 4, 5]`, the
//! elements `[1, 3, 5]` are a strided slice with stride 2, and
//! `[1, 4]` has stride 3. Any slice can be regarded as a strided slice
//! with stride 1.
//!
//! This provides functionality through which one can safely and
//! efficiently manipulate every `n`th element of a slice (even a
//! mutable one) as close as possible to it being a conventional
//! slice. This releases one from worries about stride bookkeeping,
//! aliasing of `&mut` or any `unsafe` code.
//!
//! # Quick start
//!
//! The work-horse function is `.substrides(n)`, which returns an
//! iterator across a series of `n` new strided slices, each of which
//! points to every `n`th element, and each of which starts at the
//! next successive offset. For example, the following has `n = 3`.
//!
//! ```rust
//! use strided::MutStrided;
//!
//! let mut v = [1u8, 2, 3, 4, 5];
//! let mut all = MutStrided::new(&mut v);
//!
//! let mut substrides = all.substrides(3);
//!
//! let a = substrides.next().unwrap();
//! let b = substrides.next().unwrap();
//! let c = substrides.next().unwrap();
//! assert!(substrides.next().is_none()); // there was exactly 3.
//!
//! assert_eq!(a, MutStrided::new(&mut [1, 4]));
//! assert_eq!(b, MutStrided::new(&mut [2, 5]));
//! assert_eq!(c, MutStrided::new(&mut [3]));
//! ```
//!
//! The common case of `n = 2` has an abbreviation `substrides2`,
//! which takes the liberty of returns a tuple rather than an iterator
//! to make direct destructuring work. Continuing with the values
//! above, `left` and `right` point to alternate elements, starting at
//! index `0` and `1` of their parent slice respectively.
//!
//! ```rust
//! # use strided::MutStrided;
//! # let mut v = [1u8, 2, 3, 4, 5];
//! # let mut all = MutStrided::new(&mut v);
//! let (left, right) = all.reborrow().substrides2();
//!
//! assert_eq!(left, MutStrided::new(&mut [1, 3, 5]));
//! assert_eq!(right, MutStrided::new(&mut [2, 4]));
//! ```
//!
//! A lot of the conventional slice functionality is available, such
//! as indexing (both sugary and non-panicking), iterators and
//! slicing.
//!
//! ```rust
//! # use strided::MutStrided;
//! # let mut v = [1u8, 2, 3, 4, 5];
//! # let mut all = MutStrided::new(&mut v);
//! let (mut left, right) = all.reborrow().substrides2();
//! assert_eq!(left[2], 5);
//! assert!(right.get(10).is_none()); // out of bounds
//!
//! left[2] += 10;
//! match left.get_mut(0) {
//!     Some(val) => *val -= 3,
//!     None => {}
//! }
//!
//! assert_eq!(right.iter().fold(0, |sum, a| sum + *a), 2 + 4);
//! for val in left.iter_mut() {
//!     *val /= 2
//! }
//! ```
//!
//! Many of the methods of `MutStrided` take `self` by-value and so
//! consume ownership, this makes the `reborrow` method one of the
//! most important. It converts a `&'b mut MutStrided<'a, T>` to a
//! `MutStrided<'b, T>`, that is, allows temporarily viewing a strided
//! slices as one with a shorter lifetime. The temporary can then be
//! used with the consuming methods, and the parent slice can still be
//! used after that borrow has finished. For example, all of the
//! splitting and slicing methods on `MutStrided` consume ownership,
//! and so `reborrow` is necessary there to continue using, in this
//! case, `left`.
//!
//! ```rust
//! # use strided::MutStrided;
//! # let mut v = [1u8, 2, 3, 4, 5];
//! # let mut all = MutStrided::new(&mut v);
//! let (mut left, right) = all.reborrow().substrides2();
//! assert_eq!(left.reborrow().slice(1, 3), MutStrided::new(&mut [3, 5]));
//! assert_eq!(left.reborrow().slice_from(2), MutStrided::new(&mut [5]));
//! assert_eq!(left.reborrow().slice_to(2), MutStrided::new(&mut [1, 3]));
//!
//! assert_eq!(right.split_at(1),
//!            (MutStrided::new(&mut [2]), MutStrided::new(&mut [4])));
//! ```
//!
//! These contortions are necessary to ensure that `&mut`s cannot
//! alias, while still maintaining flexibility: leaving elements with
//! the maximum possible lifetime (i.e. that of the non-strided slices
//! which they lie in). Theoretically they are necessary with
//! `&mut []` too, but the compiler inserts implicit reborrows and so
//! one rarely needs to do them manually.
//!
//! The shared `Strided` is equivalent to `&[]` and only handles `&`
//! references, making ownership transfer and `reborrow` unnecessary,
//! so all its methods act identically to those on `&[]`.
//!
//! # Example
//!
//! The [fast Fourier transform
//! (FFT)](https://en.wikipedia.org/wiki/Fast_Fourier_transform) is a
//! signal processing algorithm that performs a discrete Fourier
//! transform (DFT) of length `n` in `O(n log n)` time. A DFT breaks a
//! waveform into the sum of sines and cosines, and is an important
//! part of many other algorithms due to certain nice properties of
//! the Fourier transform.
//!
//! The first FFT algorithm was the [Cooley-Tukey
//! algorithm](https://en.wikipedia.org/wiki/Cooley-Tukey_FFT_algorithm). The
//! decimation-in-time variant works by computing the FFT of
//! equal-length subarrays of equally spaced elements and then
//! combining these together into the desired result. This sort of
//! spacing is exactly the striding provided by this library, and
//! hence this library can be used to create an FFT algorithm in a
//! very natural way.
//!
//! Below is an implementation of the radix-2 case, that is, when the
//! length `n` is a power of two, in this case, only two strided
//! subarrays are necessary: exactly the alternating ones provided by
//! `substrides2`. Note the use of `reborrow` to allow `start` and
//! `end` to be used for the recursive `fft` calls and then again
//! later in the loop.
//!
//! ```rust
//! extern crate strided;
//! extern crate num; // https://github.com/rust-lang/num
//! use std::num::{Int, Float};
//! use num::complex::{Complex, Complex64};
//! use strided::{MutStrided, Strided};
//!
//! /// Writes the forward DFT of `input` to `output`.
//! fn fft(input: Strided<Complex64>, mut output: MutStrided<Complex64>) {
//!     // check it's a power of two.
//!     assert!(input.len() == output.len() && input.len().count_ones() == 1);
//!
//!     // base case: the DFT of a single element is itself.
//!     if input.len() == 1 {
//!         output[0] = input[0];
//!         return
//!     }
//!
//!     // split the input into two arrays of alternating elements ("decimate in time")
//!     let (evens, odds) = input.substrides2();
//!     // break the output into two halves (front and back, not alternating)
//!     let (mut start, mut end) = output.split_at(input.len() / 2);
//!
//!     // recursively perform two FFTs on alternating elements of the input, writing the
//!     // results into the first and second half of the output array respectively.
//!     fft(evens, start.reborrow());
//!     fft(odds, end.reborrow());
//!
//!     let two_pi: f64 = Float::two_pi();
//!     // exp(-2πi/N)
//!     let twiddle = Complex::from_polar(&1.0, &(-two_pi / input.len() as f64));
//!
//!     let mut factor = Complex::one();
//!
//!     // combine the subFFTs with the relations:
//!     //   X_k = E_k + exp(-2πki/N) * O_k
//!     //   X_{k+N/2} = E_k - exp(-2πki/N) * O_k
//!     for (even, odd) in start.iter_mut().zip(end.iter_mut()) {
//!         let twiddled = factor * *odd;
//!         let e = *even;
//!
//!         *even = e + twiddled;
//!         *odd = e - twiddled;
//!         factor = factor * twiddle;
//!     }
//! }
//!
//! fn main() {
//!     let a = [Complex::new(2., 0.), Complex::new(1., 0.),
//!              Complex::new(2., 0.), Complex::new(1., 0.)];
//!     let mut b = [Complex::new(0., 0.), .. 4];
//!
//!     fft(Strided::new(&a), MutStrided::new(&mut b));
//!     println!("forward: {} -> {}", a.as_slice(), b.as_slice());
//! }
//! ```
//!
//! The above definitely has complexity `O(n log n)`, but it has a
//! much larger constant factor than an optimised library like
//! [FFTW](http://www.fftw.org/).

#[cfg(test)] extern crate test;

pub use base::{Items, MutItems};

pub use mut_::Strided as MutStrided;
pub use mut_::Substrides as MutSubstrides;

pub use imm::Strided as Strided;
pub use imm::Substrides as Substrides;

macro_rules! eq {
    ($stride: expr, $expected: expr) => {
        eq!($stride, $expected, iter)
    };

    ($stride: expr, $expected: expr, $method: ident) => {{
        let e: &[_] = $expected;
        let mut _stride = $stride;
        assert_eq!(_stride.len(), e.len());
        let mut iter = _stride.$method();
        assert_eq!(iter.size_hint(),(e.len(), Some(e.len())));
        let vals = iter.by_ref().map(|s| *s).collect::<Vec<_>>();
        if vals.as_slice() != e {
            panic!("mismatched: {}, {}", vals, e);
        }
        assert_eq!(iter.size_hint(),(0, Some(0)));
    }}
}

mod base;
mod mut_;
mod imm;

#[cfg(test)]
mod bench {
    use super::Strided;
    use test::Bencher as B;
    use test;

    const N: uint = 100;

    #[bench]
    fn iter_slice(b: &mut B) {
        let v = Vec::from_fn(N, |i| i);
        b.iter(|| {
            test::black_box(&v);
            for e in v.iter() { test::black_box(e) }
        })
    }

    #[bench]
    fn iter_step_1(b: &mut B) {
        let v = Vec::from_fn(N, |i| i);
        let s = Strided::new(&*v);
        b.iter(|| {
            test::black_box(&s);
            for e in s.iter() { test::black_box(e) }
        })
    }

    #[bench]
    fn iter_step_13(b: &mut B) {
        let v = Vec::from_fn(N * 13, |i| i);
        let s = Strided::new(&*v);
        let s = s.substrides(13).next().unwrap();
        b.iter(|| {
            test::black_box(&s);
            for e in s.iter() { test::black_box(e) }
        })
    }
}
<commit_msg>Remove superfluous reborrows.<commit_after>#![feature(macro_rules)]

//! Strided slices.
//!
//! This library provides two types `Strided` and `MutStrided` as
//! generalised forms of `&[T]` and `&mut [T]` respectively, where the
//! elements are regularly spaced in memory, but not necessarily
//! immediately adjacently.
//!
//! For example, given an underlying array `[1, 2, 3, 4, 5]`, the
//! elements `[1, 3, 5]` are a strided slice with stride 2, and
//! `[1, 4]` has stride 3. Any slice can be regarded as a strided slice
//! with stride 1.
//!
//! This provides functionality through which one can safely and
//! efficiently manipulate every `n`th element of a slice (even a
//! mutable one) as close as possible to it being a conventional
//! slice. This releases one from worries about stride bookkeeping,
//! aliasing of `&mut` or any `unsafe` code.
//!
//! # Quick start
//!
//! The work-horse function is `.substrides(n)`, which returns an
//! iterator across a series of `n` new strided slices, each of which
//! points to every `n`th element, and each of which starts at the
//! next successive offset. For example, the following has `n = 3`.
//!
//! ```rust
//! use strided::MutStrided;
//!
//! let mut v = [1u8, 2, 3, 4, 5];
//! let mut all = MutStrided::new(&mut v);
//!
//! let mut substrides = all.substrides(3);
//!
//! let a = substrides.next().unwrap();
//! let b = substrides.next().unwrap();
//! let c = substrides.next().unwrap();
//! assert!(substrides.next().is_none()); // there was exactly 3.
//!
//! assert_eq!(a, MutStrided::new(&mut [1, 4]));
//! assert_eq!(b, MutStrided::new(&mut [2, 5]));
//! assert_eq!(c, MutStrided::new(&mut [3]));
//! ```
//!
//! The common case of `n = 2` has an abbreviation `substrides2`,
//! which takes the liberty of returns a tuple rather than an iterator
//! to make direct destructuring work. Continuing with the values
//! above, `left` and `right` point to alternate elements, starting at
//! index `0` and `1` of their parent slice respectively.
//!
//! ```rust
//! # use strided::MutStrided;
//! # let mut v = [1u8, 2, 3, 4, 5];
//! # let mut all = MutStrided::new(&mut v);
//! let (left, right) = all.substrides2();
//!
//! assert_eq!(left, MutStrided::new(&mut [1, 3, 5]));
//! assert_eq!(right, MutStrided::new(&mut [2, 4]));
//! ```
//!
//! A lot of the conventional slice functionality is available, such
//! as indexing (both sugary and non-panicking), iterators and
//! slicing.
//!
//! ```rust
//! # use strided::MutStrided;
//! # let mut v = [1u8, 2, 3, 4, 5];
//! # let mut all = MutStrided::new(&mut v);
//! let (mut left, right) = all.substrides2();
//! assert_eq!(left[2], 5);
//! assert!(right.get(10).is_none()); // out of bounds
//!
//! left[2] += 10;
//! match left.get_mut(0) {
//!     Some(val) => *val -= 3,
//!     None => {}
//! }
//!
//! assert_eq!(right.iter().fold(0, |sum, a| sum + *a), 2 + 4);
//! for val in left.iter_mut() {
//!     *val /= 2
//! }
//! ```
//!
//! Many of the methods of `MutStrided` take `self` by-value and so
//! consume ownership, this makes the `reborrow` method one of the
//! most important. It converts a `&'b mut MutStrided<'a, T>` to a
//! `MutStrided<'b, T>`, that is, allows temporarily viewing a strided
//! slices as one with a shorter lifetime. The temporary can then be
//! used with the consuming methods, and the parent slice can still be
//! used after that borrow has finished. For example, all of the
//! splitting and slicing methods on `MutStrided` consume ownership,
//! and so `reborrow` is necessary there to continue using, in this
//! case, `left`.
//!
//! ```rust
//! # use strided::MutStrided;
//! # let mut v = [1u8, 2, 3, 4, 5];
//! # let mut all = MutStrided::new(&mut v);
//! let (mut left, right) = all.reborrow().substrides2();
//! assert_eq!(left.reborrow().slice(1, 3), MutStrided::new(&mut [3, 5]));
//! assert_eq!(left.reborrow().slice_from(2), MutStrided::new(&mut [5]));
//! assert_eq!(left.reborrow().slice_to(2), MutStrided::new(&mut [1, 3]));
//!
//! assert_eq!(right.split_at(1),
//!            (MutStrided::new(&mut [2]), MutStrided::new(&mut [4])));
//! ```
//!
//! These contortions are necessary to ensure that `&mut`s cannot
//! alias, while still maintaining flexibility: leaving elements with
//! the maximum possible lifetime (i.e. that of the non-strided slices
//! which they lie in). Theoretically they are necessary with
//! `&mut []` too, but the compiler inserts implicit reborrows and so
//! one rarely needs to do them manually.
//!
//! The shared `Strided` is equivalent to `&[]` and only handles `&`
//! references, making ownership transfer and `reborrow` unnecessary,
//! so all its methods act identically to those on `&[]`.
//!
//! # Example
//!
//! The [fast Fourier transform
//! (FFT)](https://en.wikipedia.org/wiki/Fast_Fourier_transform) is a
//! signal processing algorithm that performs a discrete Fourier
//! transform (DFT) of length `n` in `O(n log n)` time. A DFT breaks a
//! waveform into the sum of sines and cosines, and is an important
//! part of many other algorithms due to certain nice properties of
//! the Fourier transform.
//!
//! The first FFT algorithm was the [Cooley-Tukey
//! algorithm](https://en.wikipedia.org/wiki/Cooley-Tukey_FFT_algorithm). The
//! decimation-in-time variant works by computing the FFT of
//! equal-length subarrays of equally spaced elements and then
//! combining these together into the desired result. This sort of
//! spacing is exactly the striding provided by this library, and
//! hence this library can be used to create an FFT algorithm in a
//! very natural way.
//!
//! Below is an implementation of the radix-2 case, that is, when the
//! length `n` is a power of two, in this case, only two strided
//! subarrays are necessary: exactly the alternating ones provided by
//! `substrides2`. Note the use of `reborrow` to allow `start` and
//! `end` to be used for the recursive `fft` calls and then again
//! later in the loop.
//!
//! ```rust
//! extern crate strided;
//! extern crate num; // https://github.com/rust-lang/num
//! use std::num::{Int, Float};
//! use num::complex::{Complex, Complex64};
//! use strided::{MutStrided, Strided};
//!
//! /// Writes the forward DFT of `input` to `output`.
//! fn fft(input: Strided<Complex64>, mut output: MutStrided<Complex64>) {
//!     // check it's a power of two.
//!     assert!(input.len() == output.len() && input.len().count_ones() == 1);
//!
//!     // base case: the DFT of a single element is itself.
//!     if input.len() == 1 {
//!         output[0] = input[0];
//!         return
//!     }
//!
//!     // split the input into two arrays of alternating elements ("decimate in time")
//!     let (evens, odds) = input.substrides2();
//!     // break the output into two halves (front and back, not alternating)
//!     let (mut start, mut end) = output.split_at(input.len() / 2);
//!
//!     // recursively perform two FFTs on alternating elements of the input, writing the
//!     // results into the first and second half of the output array respectively.
//!     fft(evens, start.reborrow());
//!     fft(odds, end.reborrow());
//!
//!     let two_pi: f64 = Float::two_pi();
//!     // exp(-2πi/N)
//!     let twiddle = Complex::from_polar(&1.0, &(-two_pi / input.len() as f64));
//!
//!     let mut factor = Complex::one();
//!
//!     // combine the subFFTs with the relations:
//!     //   X_k = E_k + exp(-2πki/N) * O_k
//!     //   X_{k+N/2} = E_k - exp(-2πki/N) * O_k
//!     for (even, odd) in start.iter_mut().zip(end.iter_mut()) {
//!         let twiddled = factor * *odd;
//!         let e = *even;
//!
//!         *even = e + twiddled;
//!         *odd = e - twiddled;
//!         factor = factor * twiddle;
//!     }
//! }
//!
//! fn main() {
//!     let a = [Complex::new(2., 0.), Complex::new(1., 0.),
//!              Complex::new(2., 0.), Complex::new(1., 0.)];
//!     let mut b = [Complex::new(0., 0.), .. 4];
//!
//!     fft(Strided::new(&a), MutStrided::new(&mut b));
//!     println!("forward: {} -> {}", a.as_slice(), b.as_slice());
//! }
//! ```
//!
//! The above definitely has complexity `O(n log n)`, but it has a
//! much larger constant factor than an optimised library like
//! [FFTW](http://www.fftw.org/).

#[cfg(test)] extern crate test;

pub use base::{Items, MutItems};

pub use mut_::Strided as MutStrided;
pub use mut_::Substrides as MutSubstrides;

pub use imm::Strided as Strided;
pub use imm::Substrides as Substrides;

macro_rules! eq {
    ($stride: expr, $expected: expr) => {
        eq!($stride, $expected, iter)
    };

    ($stride: expr, $expected: expr, $method: ident) => {{
        let e: &[_] = $expected;
        let mut _stride = $stride;
        assert_eq!(_stride.len(), e.len());
        let mut iter = _stride.$method();
        assert_eq!(iter.size_hint(),(e.len(), Some(e.len())));
        let vals = iter.by_ref().map(|s| *s).collect::<Vec<_>>();
        if vals.as_slice() != e {
            panic!("mismatched: {}, {}", vals, e);
        }
        assert_eq!(iter.size_hint(),(0, Some(0)));
    }}
}

mod base;
mod mut_;
mod imm;

#[cfg(test)]
mod bench {
    use super::Strided;
    use test::Bencher as B;
    use test;

    const N: uint = 100;

    #[bench]
    fn iter_slice(b: &mut B) {
        let v = Vec::from_fn(N, |i| i);
        b.iter(|| {
            test::black_box(&v);
            for e in v.iter() { test::black_box(e) }
        })
    }

    #[bench]
    fn iter_step_1(b: &mut B) {
        let v = Vec::from_fn(N, |i| i);
        let s = Strided::new(&*v);
        b.iter(|| {
            test::black_box(&s);
            for e in s.iter() { test::black_box(e) }
        })
    }

    #[bench]
    fn iter_step_13(b: &mut B) {
        let v = Vec::from_fn(N * 13, |i| i);
        let s = Strided::new(&*v);
        let s = s.substrides(13).next().unwrap();
        b.iter(|| {
            test::black_box(&s);
            for e in s.iter() { test::black_box(e) }
        })
    }
}
<|endoftext|>


<commit_before>#![recursion_limit = "1024"]
#[macro_use]

extern crate error_chain;

pub mod config;
mod errors;

use std::process::Command;

use config::Config;
use errors::*;

#[derive(Clone, Debug, PartialEq)]
pub struct Author {
  pub name: String,
  pub email: String,
}

pub struct GitTogether<C> {
  pub config: C,
}

impl<C: Config> GitTogether<C> {
  pub fn set_active(&self, inits: &[&str]) -> Result<()> {
    self.get_authors(inits)
      .and_then(|_| self.config.set("active", &inits.join("+")))
  }

  pub fn signoff<'a>(&self, cmd: &'a mut Command) -> Result<&'a mut Command> {
    let active = try!(self.config.get("active"));
    let inits: Vec<_> = active.split('+').collect();
    let authors = try!(self.get_authors(&inits));

    let cmd = match authors.get(0) {
      Some(author) => {
        cmd.env("GIT_AUTHOR_NAME", author.name.clone())
          .env("GIT_AUTHOR_EMAIL", author.email.clone())
      }
      _ => cmd,
    };

    let cmd = match authors.get(1) {
      Some(committer) => {
        cmd.env("GIT_COMMITTER_NAME", committer.name.clone())
          .env("GIT_COMMITTER_EMAIL", committer.email.clone())
          .arg("--signoff")
      }
      _ => cmd,
    };

    Ok(cmd)
  }

  fn get_active(&self) -> Result<Vec<String>> {
    self.config
      .get("active")
      .map(|active| active.split('+').map(|s| s.into()).collect())
  }

  pub fn rotate_active(&self) -> Result<()> {
    self.get_active().and_then(|active| {
      let mut inits: Vec<_> = active.iter().map(String::as_ref).collect();
      if !inits.is_empty() {
        let author = inits.remove(0);
        inits.push(author);
      }
      self.set_active(&inits[..])
    })
  }

  fn get_authors(&self, inits: &[&str]) -> Result<Vec<Author>> {
    let domain = try!(self.config.get("domain"));
    inits.iter()
      .map(|&init| {
        self.config
          .get(&format!("authors.{}", init))
          .chain_err(|| ErrorKind::AuthorNotFound(init.into()))
          .and_then(|raw| {
            if raw.is_empty() {
              return Err(ErrorKind::InvalidAuthor(raw).into());
            }

            let mut split = raw.split(';');
            let name = try!(split.next()
                .ok_or(ErrorKind::InvalidAuthor(raw.clone())))
              .trim();
            let username = try!(split.next()
                .ok_or(ErrorKind::InvalidAuthor(raw.clone())))
              .trim();
            let email = format!("{}@{}", username, domain);

            Ok(Author {
              name: name.into(),
              email: email,
            })
          })
      })
      .collect()
  }
}

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

  use std::cell::RefCell;
  use std::collections::HashMap;

  use config::Config;
  use errors::*;

  #[test]
  fn get_authors_no_domain() {
    let config = MockConfig::new(&[("authors.jh", "James Holden; jholden")]);
    let gt = GitTogether { config: config };

    assert!(gt.get_authors(&["jh"]).is_err());
  }

  #[test]
  fn get_authors() {
    let config = MockConfig::new(&[("domain", "rocinante.com"),
                                   ("authors.jh", ""),
                                   ("authors.nn", "Naomi Nagata"),
                                   ("authors.ab", "Amos Burton; aburton"),
                                   ("authors.ak", "Alex Kamal; akamal") /* ("authors.ca", "Chrisjen Avasarala;"),
                                                                         * ("authors.bd", "Bobbie Draper; bdraper@mars.mil"),
                                                                         * ("authors.jm", "Joe Miller; jmiller@starhelix.com"), */]);
    let gt = GitTogether { config: config };

    assert!(gt.get_authors(&["jh"]).is_err());
    assert!(gt.get_authors(&["nn"]).is_err());
    // assert!(gt.get_authors(&["ca"]).is_err());
    // assert!(gt.get_authors(&["jh", "bd"]).is_err());

    assert_eq!(gt.get_authors(&["ab", "ak"]).unwrap(),
               vec![
               Author { name: "Amos Burton".into(), email: "aburton@rocinante.com".into() },
               Author { name: "Alex Kamal".into(), email: "akamal@rocinante.com".into() },
               ]);
    // assert_eq!(gt.get_authors(&["ab", "bd", "jm"]).unwrap(),
    //            vec![Author { name: "Amos Burton".into(), email: "aburton@rocinante.com".into() },
    // Author { name: "Bobbie Draper".into(), email: "bdraper@mars.mil".into() },
    // Author { name: "Joe Miller".into(), email: "jmiller@starhelix.com".into() },
    // ]);
  }

  #[test]
  fn set_active() {
    let config = MockConfig::new(&[("domain", "rocinante.com"),
                                   ("authors.jh", "James Holden; jholden"),
                                   ("authors.nn", "Naomi Nagata; nnagata")]);
    let gt = GitTogether { config: config };

    gt.set_active(&["jh"]).unwrap();
    assert_eq!(gt.get_active().unwrap(), vec!["jh"]);

    gt.set_active(&["jh", "nn"]).unwrap();
    assert_eq!(gt.get_active().unwrap(), vec!["jh", "nn"]);
  }

  #[test]
  fn rotate_active() {
    let config = MockConfig::new(&[("active", "jh+nn"),
                                   ("domain", "rocinante.com"),
                                   ("authors.jh", "James Holden; jholden"),
                                   ("authors.nn", "Naomi Nagata; nnagata")]);
    let gt = GitTogether { config: config };

    gt.rotate_active().unwrap();
    assert_eq!(gt.get_active().unwrap(), vec!["nn", "jh"]);
  }

  struct MockConfig {
    data: RefCell<HashMap<String, String>>,
  }

  impl MockConfig {
    fn new(data: &[(&str, &str)]) -> MockConfig {
      let data = data.iter()
        .map(|&(k, v)| (k.into(), v.into()))
        .collect();
      MockConfig { data: RefCell::new(data) }
    }
  }

  impl Config for MockConfig {
    fn get(&self, name: &str) -> Result<String> {
      self.data.borrow().get(name.into()).cloned().ok_or("".into())
    }

    fn set(&self, name: &str, value: &str) -> Result<()> {
      self.data.borrow_mut().insert(name.into(), value.into());
      Ok(())
    }
  }
}
<commit_msg>better errors in the mock config<commit_after>#![recursion_limit = "1024"]
#[macro_use]

extern crate error_chain;

pub mod config;
mod errors;

use std::process::Command;

use config::Config;
use errors::*;

#[derive(Clone, Debug, PartialEq)]
pub struct Author {
  pub name: String,
  pub email: String,
}

pub struct GitTogether<C> {
  pub config: C,
}

impl<C: Config> GitTogether<C> {
  pub fn set_active(&self, inits: &[&str]) -> Result<()> {
    self.get_authors(inits)
      .and_then(|_| self.config.set("active", &inits.join("+")))
  }

  pub fn signoff<'a>(&self, cmd: &'a mut Command) -> Result<&'a mut Command> {
    let active = try!(self.config.get("active"));
    let inits: Vec<_> = active.split('+').collect();
    let authors = try!(self.get_authors(&inits));

    let cmd = match authors.get(0) {
      Some(author) => {
        cmd.env("GIT_AUTHOR_NAME", author.name.clone())
          .env("GIT_AUTHOR_EMAIL", author.email.clone())
      }
      _ => cmd,
    };

    let cmd = match authors.get(1) {
      Some(committer) => {
        cmd.env("GIT_COMMITTER_NAME", committer.name.clone())
          .env("GIT_COMMITTER_EMAIL", committer.email.clone())
          .arg("--signoff")
      }
      _ => cmd,
    };

    Ok(cmd)
  }

  fn get_active(&self) -> Result<Vec<String>> {
    self.config
      .get("active")
      .map(|active| active.split('+').map(|s| s.into()).collect())
  }

  pub fn rotate_active(&self) -> Result<()> {
    self.get_active().and_then(|active| {
      let mut inits: Vec<_> = active.iter().map(String::as_ref).collect();
      if !inits.is_empty() {
        let author = inits.remove(0);
        inits.push(author);
      }
      self.set_active(&inits[..])
    })
  }

  fn get_authors(&self, inits: &[&str]) -> Result<Vec<Author>> {
    let domain = try!(self.config.get("domain"));
    inits.iter()
      .map(|&init| {
        self.config
          .get(&format!("authors.{}", init))
          .chain_err(|| ErrorKind::AuthorNotFound(init.into()))
          .and_then(|raw| {
            if raw.is_empty() {
              return Err(ErrorKind::InvalidAuthor(raw).into());
            }

            let mut split = raw.split(';');
            let name = try!(split.next()
                .ok_or(ErrorKind::InvalidAuthor(raw.clone())))
              .trim();
            let username = try!(split.next()
                .ok_or(ErrorKind::InvalidAuthor(raw.clone())))
              .trim();
            let email = format!("{}@{}", username, domain);

            Ok(Author {
              name: name.into(),
              email: email,
            })
          })
      })
      .collect()
  }
}

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

  use std::cell::RefCell;
  use std::collections::HashMap;

  use config::Config;
  use errors::*;

  #[test]
  fn get_authors_no_domain() {
    let config = MockConfig::new(&[("authors.jh", "James Holden; jholden")]);
    let gt = GitTogether { config: config };

    assert!(gt.get_authors(&["jh"]).is_err());
  }

  #[test]
  fn get_authors() {
    let config = MockConfig::new(&[("domain", "rocinante.com"),
                                   ("authors.jh", ""),
                                   ("authors.nn", "Naomi Nagata"),
                                   ("authors.ab", "Amos Burton; aburton"),
                                   ("authors.ak", "Alex Kamal; akamal") /* ("authors.ca", "Chrisjen Avasarala;"),
                                                                         * ("authors.bd", "Bobbie Draper; bdraper@mars.mil"),
                                                                         * ("authors.jm", "Joe Miller; jmiller@starhelix.com"), */]);
    let gt = GitTogether { config: config };

    assert!(gt.get_authors(&["jh"]).is_err());
    assert!(gt.get_authors(&["nn"]).is_err());
    // assert!(gt.get_authors(&["ca"]).is_err());
    // assert!(gt.get_authors(&["jh", "bd"]).is_err());

    assert_eq!(gt.get_authors(&["ab", "ak"]).unwrap(),
               vec![
               Author { name: "Amos Burton".into(), email: "aburton@rocinante.com".into() },
               Author { name: "Alex Kamal".into(), email: "akamal@rocinante.com".into() },
               ]);
    // assert_eq!(gt.get_authors(&["ab", "bd", "jm"]).unwrap(),
    //            vec![Author { name: "Amos Burton".into(), email: "aburton@rocinante.com".into() },
    // Author { name: "Bobbie Draper".into(), email: "bdraper@mars.mil".into() },
    // Author { name: "Joe Miller".into(), email: "jmiller@starhelix.com".into() },
    // ]);
  }

  #[test]
  fn set_active() {
    let config = MockConfig::new(&[("domain", "rocinante.com"),
                                   ("authors.jh", "James Holden; jholden"),
                                   ("authors.nn", "Naomi Nagata; nnagata")]);
    let gt = GitTogether { config: config };

    gt.set_active(&["jh"]).unwrap();
    assert_eq!(gt.get_active().unwrap(), vec!["jh"]);

    gt.set_active(&["jh", "nn"]).unwrap();
    assert_eq!(gt.get_active().unwrap(), vec!["jh", "nn"]);
  }

  #[test]
  fn rotate_active() {
    let config = MockConfig::new(&[("active", "jh+nn"),
                                   ("domain", "rocinante.com"),
                                   ("authors.jh", "James Holden; jholden"),
                                   ("authors.nn", "Naomi Nagata; nnagata")]);
    let gt = GitTogether { config: config };

    gt.rotate_active().unwrap();
    assert_eq!(gt.get_active().unwrap(), vec!["nn", "jh"]);
  }

  struct MockConfig {
    data: RefCell<HashMap<String, String>>,
  }

  impl MockConfig {
    fn new(data: &[(&str, &str)]) -> MockConfig {
      let data = data.iter()
        .map(|&(k, v)| (k.into(), v.into()))
        .collect();
      MockConfig { data: RefCell::new(data) }
    }
  }

  impl Config for MockConfig {
    fn get(&self, name: &str) -> Result<String> {
      self.data
        .borrow()
        .get(name.into())
        .cloned()
        .ok_or(format!("name not found: '{}'", name).into())
    }

    fn set(&self, name: &str, value: &str) -> Result<()> {
      self.data.borrow_mut().insert(name.into(), value.into());
      Ok(())
    }
  }
}
<|endoftext|>


<commit_before>#![feature(libc)]

extern crate libc;
use std::ffi::CString;
use std::slice;
use std::ptr;

mod ffi;

#[derive(Debug, Copy, Clone)]
pub struct Env {
    env: ffi::Voidptr
}

#[derive(Debug, Copy, Clone)]
pub struct Db {
    db: ffi::Voidptr
}

// XXX: Use Arc
unsafe impl Sync for Db {}
unsafe impl Send for Db {}
unsafe impl Sync for Env {}
unsafe impl Send for Env {}

use std::marker::PhantomData;

#[macro_export]
macro_rules! obj {
    (
        $db:ident ;
        $(
            $name:ident : $x:expr
        ),*
    ) => {{
        let mut obj = $db.obj();
        $(
            obj.$name($x)
        );*
        ;obj
    }}
}

#[derive(Debug)]
pub struct DbObject<'a> {
    o: ffi::Voidptr,
    phantom: PhantomData<&'a ()>,
}

impl<'a> DbObject<'a> {
    // We name it attr(), to not mix it up with the set() method.
    pub fn attr<'b>(&'b mut self, path: &str, data: &'b[u8]) {
        let path = CString::new(path).unwrap();
        unsafe {ffi::setstring(self.o, path.as_bytes(), data); }
    }

    // Shortcut for attr("key", ...)
    pub fn key<'b>(&'b mut self, data: &'b[u8]) {
        unsafe {ffi::setstring(self.o, "key\0".as_bytes(), data); }
    }

    // Shortcut for attr("value", ...)
    pub fn value<'b>(&'b mut self, data: &'b[u8]) {
        unsafe {ffi::setstring(self.o, "value\0".as_bytes(), data); }
    }

    // Shortcut for attr("val", ...)
    pub fn val<'b>(&'b mut self, data: &'b[u8]) {
        self.value(data)
    }

    // Shortcut for attr("order", ...)
    pub fn order<'b>(&'b mut self, data: &'b[u8]) {
        unsafe {ffi::setstring(self.o, "order\0".as_bytes(), data); }
    }

    // Shortcut for attr("prefix", ...)
    pub fn prefix<'b>(&'b mut self, data: &'b[u8]) {
        unsafe {ffi::setstring(self.o, "prefix\0".as_bytes(), data); }
    }
}

impl<'a> Drop for DbObject<'a> {
    fn drop(&mut self) {
        if !self.o.is_null() {
            unsafe {ffi::sp_destroy(self.o)};
        }
    }
}

#[derive(Debug)]
pub struct DbResultObject<'a> {
    o: ffi::Voidptr,
    phantom: PhantomData<&'a ()>,
}

impl<'a> DbResultObject<'a> {
    fn get_<'b>(&'b self, key: &'b [u8]) -> Option<&'b[u8]> {
        unsafe {
            let mut sz = 0;
            let valptr = ffi::sp_getstring(self.o, key.as_ptr(), &mut sz);

            // XXX: what if we stored an empty value?
            if valptr.is_null() {
                return None;
            }

            let s = slice::from_raw_parts(valptr as *const u8, sz as usize);
            return Some(s);
        }

    }
    pub fn get_value<'b>(&'b self) -> Option<&'b[u8]> {
        self.get_(b"value\0")
    }

    pub fn get_key<'b>(&'b self) -> Option<&'b[u8]> {
        self.get_(b"key\0")
    }
}

impl<'a> Drop for DbResultObject<'a> {
    fn drop(&mut self) {
        if !self.o.is_null() {
            unsafe {ffi::sp_destroy(self.o)};
        }
    }
}

#[derive(Debug)]
pub struct Transaction<'a> {
    tx: ffi::Voidptr,
    phantom: PhantomData<&'a ()>
}

impl<'a> Drop for Transaction<'a> {
    // Unless commit() is called, this will roll back the transaction
    fn drop(&mut self) {
        if !self.tx.is_null() {
            unsafe {ffi::sp_destroy(self.tx);}
        }
    }
}

pub struct Cursor<'a> {
    obj: ffi::Voidptr,
    phantom: PhantomData<&'a ()>
}

impl<'a> Drop for Cursor<'a> {
    fn drop(&mut self) {
        unsafe {ffi::sp_destroy(self.obj);}
    }
}

impl<'a> Cursor<'a> {
    pub fn next<'b>(&'b self) -> Option<DbResultObject<'b>> {
        let res = unsafe { ffi::sp_get(self.obj, ptr::null_mut()) };
        if res.is_null() {
            None
        }
        else {
            Some(DbResultObject{o: res, phantom: PhantomData})
        }
    }
}

pub trait SetGetOps {
    fn backend(&self) -> ffi::Voidptr;

    // Consumes the DbObject
    fn set<'a>(&self, obj: DbObject<'a>) {
        let mut obj = obj;
        unsafe {ffi::sp_set(self.backend(), obj.o)}; // XXX: Check error code
        obj.o = ptr::null_mut(); // sp_set drops it
    }

    // XXX: Make sure self.db == dbobject.db
    fn get<'a, 'b>(&'a self, pattern: DbObject<'b>) -> Option<DbResultObject<'a>> {
        unsafe {
            let res = ffi::sp_get(self.backend(), pattern.o);
            if res.is_null() {
                return None;
            }
            let n = DbResultObject {
                o: pattern.o,
                phantom: PhantomData
            };
            let mut pattern = pattern;
            pattern.o = ptr::null_mut();
            return Some(n);
        }
    }

    fn cursor<'a, 'b>(&'a self, pattern: DbObject<'b>) -> Cursor<'a> {
        unsafe {
            let cursor = ffi::sp_cursor(self.backend(), pattern.o);
            assert!(!cursor.is_null());

            // pattern is freed as part of the Cursor
            let mut pattern = pattern;
            pattern.o = ptr::null_mut();

            Cursor {obj: cursor, phantom: PhantomData}
        }
    }
}

impl<'a> Transaction<'a> {
    pub fn commit(mut self) -> i32 {
        let rc = unsafe{ffi::sp_commit(self.tx)};
        self.tx = ptr::null_mut();
        rc as i32
    }
}

impl<'a> SetGetOps for Transaction<'a> {
    fn backend(&self) -> ffi::Voidptr { self.tx }
}

impl Env {
    pub fn new() -> Env {
        Env {env: unsafe{ffi::sp_env()}}
    }

    pub fn destroy(self) {
        unsafe{ffi::sp_destroy(self.env)};
    }

    pub fn db(&mut self, dbname: &str) {
        // XXX: is dbname copied?
        let dbname = CString::new(dbname).unwrap();
        unsafe {ffi::setstring(self.env, "db\0".as_bytes(), dbname.as_bytes()) };
    }

    pub fn open(&mut self) {
        unsafe {ffi::sp_open(self.env)};
    }

    pub fn begin<'a>(&'a self) -> Transaction<'a> {
        let tx = unsafe{ffi::sp_begin(self.env)};
        assert!(!tx.is_null());
        Transaction {
            tx: tx,
            phantom: PhantomData
        }
    }

    pub fn get_db(&self, dbname: &str) -> Option<Db> {
        let dbstr = "db.".to_string() + dbname;
        let attr = CString::new(&dbstr[..]).unwrap();
        unsafe {
            let obj = ffi::sp_getobject(self.env, attr.as_ptr() as *const u8);
            if obj.is_null() {
                None
            }
            else {
                Some(Db {db: obj})
            }
        }
    }

    pub fn setattr(&mut self, key: &str, val: &str) {
        let key = CString::new(key).unwrap();
        let val = CString::new(val).unwrap();
        unsafe {ffi::setstring(self.env, key.as_bytes(), val.as_bytes()) };
    }

    pub fn setintattr(&mut self, key: &str, val: i64) {
        let key = CString::new(key).unwrap();
        unsafe {ffi::sp_setint(self.env, key.as_ptr(), val) };
    }
}

impl SetGetOps for Db {
    fn backend(&self) -> ffi::Voidptr { self.db }
}

impl Db {
    pub fn obj<'a>(&'a self) -> DbObject<'a> {
        let obj = unsafe { ffi::sp_object(self.db) };
        assert!(!obj.is_null());
        DbObject{o: obj, phantom: PhantomData}
    }

}
<commit_msg>Add secondary key 'key_b' support<commit_after>#![feature(libc)]

extern crate libc;
use std::ffi::CString;
use std::slice;
use std::ptr;

mod ffi;

#[derive(Debug, Copy, Clone)]
pub struct Env {
    env: ffi::Voidptr
}

#[derive(Debug, Copy, Clone)]
pub struct Db {
    db: ffi::Voidptr
}

// XXX: Use Arc
unsafe impl Sync for Db {}
unsafe impl Send for Db {}
unsafe impl Sync for Env {}
unsafe impl Send for Env {}

use std::marker::PhantomData;

#[macro_export]
macro_rules! obj {
    (
        $db:ident ;
        $(
            $name:ident : $x:expr
        ),*
    ) => {{
        let mut obj = $db.obj();
        $(
            obj.$name($x)
        );*
        ;obj
    }}
}

#[derive(Debug)]
pub struct DbObject<'a> {
    o: ffi::Voidptr,
    phantom: PhantomData<&'a ()>,
}

impl<'a> DbObject<'a> {
    // We name it attr(), to not mix it up with the set() method.
    pub fn attr<'b>(&'b mut self, path: &str, data: &'b[u8]) {
        let path = CString::new(path).unwrap();
        unsafe {ffi::setstring(self.o, path.as_bytes(), data); }
    }

    // Shortcut for attr("key", ...)
    pub fn key<'b>(&'b mut self, data: &'b[u8]) {
        unsafe {ffi::setstring(self.o, "key\0".as_bytes(), data); }
    }

    // Shortcut for attr("key_b", ...)
    // This allows setting a secondary key.
    pub fn key_b<'b>(&'b mut self, data: &'b[u8]) {
        unsafe {ffi::setstring(self.o, "key_b\0".as_bytes(), data); }
    }

    // Shortcut for attr("value", ...)
    pub fn value<'b>(&'b mut self, data: &'b[u8]) {
        unsafe {ffi::setstring(self.o, "value\0".as_bytes(), data); }
    }

    // Shortcut for attr("val", ...)
    pub fn val<'b>(&'b mut self, data: &'b[u8]) {
        self.value(data)
    }

    // Shortcut for attr("order", ...)
    pub fn order<'b>(&'b mut self, data: &'b[u8]) {
        unsafe {ffi::setstring(self.o, "order\0".as_bytes(), data); }
    }

    // Shortcut for attr("prefix", ...)
    pub fn prefix<'b>(&'b mut self, data: &'b[u8]) {
        unsafe {ffi::setstring(self.o, "prefix\0".as_bytes(), data); }
    }
}

impl<'a> Drop for DbObject<'a> {
    fn drop(&mut self) {
        if !self.o.is_null() {
            unsafe {ffi::sp_destroy(self.o)};
        }
    }
}

#[derive(Debug)]
pub struct DbResultObject<'a> {
    o: ffi::Voidptr,
    phantom: PhantomData<&'a ()>,
}

impl<'a> DbResultObject<'a> {
    fn get_<'b>(&'b self, key: &'b [u8]) -> Option<&'b[u8]> {
        unsafe {
            let mut sz = 0;
            let valptr = ffi::sp_getstring(self.o, key.as_ptr(), &mut sz);

            // XXX: what if we stored an empty value?
            if valptr.is_null() {
                return None;
            }

            let s = slice::from_raw_parts(valptr as *const u8, sz as usize);
            return Some(s);
        }

    }
    pub fn get_value<'b>(&'b self) -> Option<&'b[u8]> {
        self.get_(b"value\0")
    }

    pub fn get_key<'b>(&'b self) -> Option<&'b[u8]> {
        self.get_(b"key\0")
    }

    pub fn get_key_b<'b>(&'b self) -> Option<&'b[u8]> {
        self.get_(b"key_b\0")
    }
}

impl<'a> Drop for DbResultObject<'a> {
    fn drop(&mut self) {
        if !self.o.is_null() {
            unsafe {ffi::sp_destroy(self.o)};
        }
    }
}

#[derive(Debug)]
pub struct Transaction<'a> {
    tx: ffi::Voidptr,
    phantom: PhantomData<&'a ()>
}

impl<'a> Drop for Transaction<'a> {
    // Unless commit() is called, this will roll back the transaction
    fn drop(&mut self) {
        if !self.tx.is_null() {
            unsafe {ffi::sp_destroy(self.tx);}
        }
    }
}

pub struct Cursor<'a> {
    obj: ffi::Voidptr,
    phantom: PhantomData<&'a ()>
}

impl<'a> Drop for Cursor<'a> {
    fn drop(&mut self) {
        unsafe {ffi::sp_destroy(self.obj);}
    }
}

impl<'a> Cursor<'a> {
    pub fn next<'b>(&'b self) -> Option<DbResultObject<'b>> {
        let res = unsafe { ffi::sp_get(self.obj, ptr::null_mut()) };
        if res.is_null() {
            None
        }
        else {
            Some(DbResultObject{o: res, phantom: PhantomData})
        }
    }
}

pub trait SetGetOps {
    fn backend(&self) -> ffi::Voidptr;

    // Consumes the DbObject
    fn set<'a>(&self, obj: DbObject<'a>) {
        let mut obj = obj;
        unsafe {ffi::sp_set(self.backend(), obj.o)}; // XXX: Check error code
        obj.o = ptr::null_mut(); // sp_set drops it
    }

    // XXX: Make sure self.db == dbobject.db
    fn get<'a, 'b>(&'a self, pattern: DbObject<'b>) -> Option<DbResultObject<'a>> {
        unsafe {
            let res = ffi::sp_get(self.backend(), pattern.o);
            if res.is_null() {
                return None;
            }
            let n = DbResultObject {
                o: pattern.o,
                phantom: PhantomData
            };
            let mut pattern = pattern;
            pattern.o = ptr::null_mut();
            return Some(n);
        }
    }

    fn cursor<'a, 'b>(&'a self, pattern: DbObject<'b>) -> Cursor<'a> {
        unsafe {
            let cursor = ffi::sp_cursor(self.backend(), pattern.o);
            assert!(!cursor.is_null());

            // pattern is freed as part of the Cursor
            let mut pattern = pattern;
            pattern.o = ptr::null_mut();

            Cursor {obj: cursor, phantom: PhantomData}
        }
    }
}

impl<'a> Transaction<'a> {
    pub fn commit(mut self) -> i32 {
        let rc = unsafe{ffi::sp_commit(self.tx)};
        self.tx = ptr::null_mut();
        rc as i32
    }
}

impl<'a> SetGetOps for Transaction<'a> {
    fn backend(&self) -> ffi::Voidptr { self.tx }
}

impl Env {
    pub fn new() -> Env {
        Env {env: unsafe{ffi::sp_env()}}
    }

    pub fn destroy(self) {
        unsafe{ffi::sp_destroy(self.env)};
    }

    pub fn db(&mut self, dbname: &str) {
        // XXX: is dbname copied?
        let dbname = CString::new(dbname).unwrap();
        unsafe {ffi::setstring(self.env, "db\0".as_bytes(), dbname.as_bytes()) };
    }

    pub fn open(&mut self) {
        unsafe {ffi::sp_open(self.env)};
    }

    pub fn begin<'a>(&'a self) -> Transaction<'a> {
        let tx = unsafe{ffi::sp_begin(self.env)};
        assert!(!tx.is_null());
        Transaction {
            tx: tx,
            phantom: PhantomData
        }
    }

    pub fn get_db(&self, dbname: &str) -> Option<Db> {
        let dbstr = "db.".to_string() + dbname;
        let attr = CString::new(&dbstr[..]).unwrap();
        unsafe {
            let obj = ffi::sp_getobject(self.env, attr.as_ptr() as *const u8);
            if obj.is_null() {
                None
            }
            else {
                Some(Db {db: obj})
            }
        }
    }

    pub fn setattr(&mut self, key: &str, val: &str) {
        let key = CString::new(key).unwrap();
        let val = CString::new(val).unwrap();
        unsafe {ffi::setstring(self.env, key.as_bytes(), val.as_bytes()) };
    }

    pub fn setintattr(&mut self, key: &str, val: i64) {
        let key = CString::new(key).unwrap();
        unsafe {ffi::sp_setint(self.env, key.as_ptr(), val) };
    }
}

impl SetGetOps for Db {
    fn backend(&self) -> ffi::Voidptr { self.db }
}

impl Db {
    pub fn obj<'a>(&'a self) -> DbObject<'a> {
        let obj = unsafe { ffi::sp_object(self.db) };
        assert!(!obj.is_null());
        DbObject{o: obj, phantom: PhantomData}
    }

}
<|endoftext|>


<commit_before>/*!

# GraphQL

[GraphQL][1] is a data query language developed by Facebook intended to serve
mobile and web application frontends. A server provides a schema, containing
types and fields that applications can query. Queries are hierarchical,
composable, and statically typed. Schemas are introspective, which lets clients
statically verify their queries against a server without actually executing
them.

This library provides data types and traits to expose Rust types in a GraphQL
schema, as well as an optional integration into the [Iron framework][2]. It
tries to keep the number of dynamic operations to a minimum, and give you as the
schema developer the control of the query execution path.

## Exposing data types

The `GraphQLType` trait is the primary interface towards application developers.
By deriving this trait, you can expose your types as either objects, enums,
interfaces, unions, or scalars.

However, due to the dynamic nature of GraphQL's type system, deriving this trait
manually is a bit tedious, especially in order to do it in a fully type safe
manner. To help with this task, this library provides a couple of macros; the
most common one being `graphql_object!`. Use this macro to expose your already
existing object types as GraphQL objects:

```rust
#[macro_use] extern crate juniper;
# use std::collections::HashMap;
use juniper::FieldResult;

struct User { id: String, name: String, friend_ids: Vec<String>  }
struct QueryRoot;
struct Database { users: HashMap<String, User> }

// GraphQL objects can access a "context object" during execution. Use this
// object to provide e.g. database access to the field accessors.
//
// In this example, we use the Database struct as our context.
graphql_object!(User: Database as "User" |&self| {

    // Expose a simple field as a GraphQL string.
    field id() -> &String {
        &self.id
    }

    field name() -> &String {
        &self.name
    }

    // FieldResult<T> is an alias for Result<T, String> - simply return
    // a string from this method and it will be correctly inserted into
    // the execution response.
    field secret() -> FieldResult<&String> {
        Err("Can't touch this".to_owned())
    }

    // Field accessors can optionally take an "executor" as their first
    // argument. This object can help guide query execution and provides
    // access to the context instance.
    //
    // In this example, the context is used to convert the friend_ids array
    // into actual User objects.
    field friends(&mut executor) -> Vec<&User> {
        self.friend_ids.iter()
            .filter_map(|id| executor.context().users.get(id))
            .collect()
    }
});

// The context object is passed down to all referenced types - all your exposed
// types need to have the same context type.
graphql_object!(QueryRoot: Database as "Query" |&self| {

    // Arguments work just like they do on functions.
    field user(&mut executor, id: String) -> Option<&User> {
        executor.context().users.get(&id)
    }
});

# fn main() { }
```

Adding per type, field, and argument documentation is possible directly from
this macro. For more in-depth information on how to expose fields and types, see
the [`graphql_object!`][3] macro.

## Integrating with Iron

The most obvious usecase is to expose the GraphQL schema over an HTTP endpoint.
To support this, the library provides an optional and customizable Iron handler.

For example, continuing from the schema created above:

```rust,no_run
extern crate iron;
# #[macro_use] extern crate juniper;
# use std::collections::HashMap;

use iron::prelude::*;
use juniper::iron_handlers::GraphQLHandler;

# use juniper::FieldResult;
#
# struct User { id: String, name: String, friend_ids: Vec<String>  }
# struct QueryRoot;
# struct Database { users: HashMap<String, User> }
#
# graphql_object!(User: Database as "User" |&self| {
#     field id() -> FieldResult<&String> {
#         Ok(&self.id)
#     }
#
#     field name() -> FieldResult<&String> {
#         Ok(&self.name)
#     }
#
#     field friends(&mut executor) -> FieldResult<Vec<&User>> {
#         Ok(self.friend_ids.iter()
#             .filter_map(|id| executor.context().users.get(id))
#             .collect())
#     }
# });
#
# graphql_object!(QueryRoot: Database as "Query" |&self| {
#     field user(&mut executor, id: String) -> FieldResult<Option<&User>> {
#         Ok(executor.context().users.get(&id))
#     }
# });

// This function is executed for every request. Here, we would realistically
// provide a database connection or similar. For this example, we'll be
// creating the database from scratch.
fn context_factory(_: &mut Request) -> Database {
    Database {
        users: vec![
            ( "1000".to_owned(), User {
                id: "1000".to_owned(), name: "Robin".to_owned(),
                friend_ids: vec!["1001".to_owned()] } ),
            ( "1001".to_owned(), User {
                id: "1001".to_owned(), name: "Max".to_owned(),
                friend_ids: vec!["1000".to_owned()] } ),
        ].into_iter().collect()
    }
}

fn main() {
    // GraphQLHandler takes a context factory function, the root object,
    // and the mutation object. If we don't have any mutations to expose, we
    // can use the empty tuple () to indicate absence.
    let graphql_endpoint = GraphQLHandler::new(context_factory, QueryRoot, ());

    // Start serving the schema at the root on port 8080.
    Iron::new(graphql_endpoint).http("localhost:8080").unwrap();
}

```

See the [`iron_handlers`][4] module and the [`GraphQLHandler`][5] documentation
for more information on what request methods are supported. There's also a
built-in [GraphiQL][6] handler included.

[1]: http://graphql.org
[2]: http://ironframework.io
[3]: macro.graphql_object!.html
[4]: iron_handlers/index.html
[5]: iron_handlers/struct.GraphQLHandler.html
[6]: https://github.com/graphql/graphiql

*/

#![cfg_attr(feature="nightly", feature(test))]
#![warn(missing_docs)]

extern crate rustc_serialize;

#[cfg(feature="nightly")] extern crate test;
#[cfg(feature="iron-handlers")] #[macro_use(itry, iexpect)] extern crate iron;
#[cfg(test)] extern crate iron_test;

#[macro_use] mod macros;
mod ast;
pub mod parser;
mod value;
mod types;
mod schema;
pub mod validation;
mod executor;
mod integrations;

#[cfg(all(test, not(feature="expose-test-schema")))] mod tests;
#[cfg(feature="expose-test-schema")] pub mod tests;

#[cfg(test)] mod executor_tests;

use std::collections::HashMap;

use rustc_serialize::json::{ToJson, Json};

use parser::{parse_document_source, ParseError, Spanning, SourcePosition};
use validation::{RuleError, ValidatorContext, visit_all_rules};
use executor::execute_validated_query;

pub use ast::{ToInputValue, FromInputValue, InputValue, Type, Selection};
pub use value::Value;
pub use types::base::{Arguments, GraphQLType, TypeKind};
pub use executor::{
    Executor, Registry, ExecutionResult, ExecutionError, FieldResult, IntoFieldResult,
};
pub use types::scalars::ID;
pub use schema::model::RootNode;

pub use schema::meta;

#[cfg(feature="iron-handlers")] pub use integrations::iron_handlers;

/// An error that prevented query execution
#[derive(Debug, PartialEq)]
#[allow(missing_docs)]
pub enum GraphQLError<'a> {
    ParseError(Spanning<ParseError<'a>>),
    ValidationError(Vec<RuleError>),
}

/// Execute a query in a provided schema
pub fn execute<'a, CtxT, QueryT, MutationT>(
    document_source: &'a str,
    operation_name: Option<&str>,
    root_node: &RootNode<CtxT, QueryT, MutationT>,
    variables: &HashMap<String, InputValue>,
    context: &CtxT,
)
    -> Result<(Value, Vec<ExecutionError>), GraphQLError<'a>>
    where QueryT: GraphQLType<CtxT>,
          MutationT: GraphQLType<CtxT>,
{
    let document = try!(parse_document_source(document_source));

    {
        let mut ctx = ValidatorContext::new(&root_node.schema, &document);
        visit_all_rules(&mut ctx, &document);

        let errors = ctx.into_errors();
        if !errors.is_empty() {
            return Err(GraphQLError::ValidationError(errors));
        }
    }

    Ok(execute_validated_query(document, operation_name, root_node, variables, context))
}

impl<'a> From<Spanning<ParseError<'a>>> for GraphQLError<'a> {
    fn from(f: Spanning<ParseError<'a>>) -> GraphQLError<'a> {
        GraphQLError::ParseError(f)
    }
}

impl<'a> ToJson for GraphQLError<'a> {
    fn to_json(&self) -> Json {
        let errs = match *self {
            GraphQLError::ParseError(ref err) => parse_error_to_json(err),
            GraphQLError::ValidationError(ref errs) => errs.to_json(),
        };

        Json::Object(vec![
            ("errors".to_owned(), errs),
        ].into_iter().collect())
    }
}

fn parse_error_to_json(err: &Spanning<ParseError>) -> Json {
    Json::Array(vec![
        Json::Object(vec![
            ("message".to_owned(), format!("{}", err.item).to_json()),
            ("locations".to_owned(), vec![
                Json::Object(vec![
                    ("line".to_owned(), (err.start.line() + 1).to_json()),
                    ("column".to_owned(), (err.start.column() + 1).to_json())
                ].into_iter().collect()),
            ].to_json()),
        ].into_iter().collect()),
    ])
}

impl ToJson for RuleError {
    fn to_json(&self) -> Json {
        Json::Object(vec![
            ("message".to_owned(), self.message().to_json()),
            ("locations".to_owned(), self.locations().to_json()),
        ].into_iter().collect())
    }
}

impl ToJson for SourcePosition {
    fn to_json(&self) -> Json {
        Json::Object(vec![
            ("line".to_owned(), (self.line() + 1).to_json()),
            ("column".to_owned(), (self.column() + 1).to_json()),
        ].into_iter().collect())
    }
}

impl ToJson for ExecutionError {
    fn to_json(&self) -> Json {
        Json::Object(vec![
            ("message".to_owned(), self.message().to_json()),
            ("locations".to_owned(), vec![self.location().clone()].to_json()),
            ("path".to_owned(), self.path().to_json()),
        ].into_iter().collect())
    }
}

#[doc(hidden)]
pub fn to_snake_case(s: &str) -> String {
    let mut dest = String::new();

    for (i, part) in s.split('_').enumerate() {
        if i > 0 && part.len() == 1 {
            dest.push_str(&part.to_uppercase());
        }
        else if i > 0 && part.len() > 1 {
            let first = part.chars().next().unwrap().to_uppercase().collect::<String>();
            let second = &part[1..];

            dest.push_str(&first);
            dest.push_str(second);
        }
        else if i == 0 {
            dest.push_str(part);
        }
    }

    dest
}

#[test]
fn test_to_snake_case() {
    assert_eq!(&to_snake_case("test")[..], "test");
    assert_eq!(&to_snake_case("_test")[..], "Test");
    assert_eq!(&to_snake_case("first_second")[..], "firstSecond");
    assert_eq!(&to_snake_case("first_")[..], "first");
    assert_eq!(&to_snake_case("a_b_c")[..], "aBC");
    assert_eq!(&to_snake_case("a_bc")[..], "aBc");
    assert_eq!(&to_snake_case("a_b")[..], "aB");
    assert_eq!(&to_snake_case("a")[..], "a");
    assert_eq!(&to_snake_case("")[..], "");
}
<commit_msg>Add dependency note to crate doc<commit_after>/*!

# GraphQL

[GraphQL][1] is a data query language developed by Facebook intended to serve
mobile and web application frontends. A server provides a schema, containing
types and fields that applications can query. Queries are hierarchical,
composable, and statically typed. Schemas are introspective, which lets clients
statically verify their queries against a server without actually executing
them.

This library provides data types and traits to expose Rust types in a GraphQL
schema, as well as an optional integration into the [Iron framework][2]. It
tries to keep the number of dynamic operations to a minimum, and give you as the
schema developer the control of the query execution path.

Juniper only depends on `rustc-serialize` by default, making it lightweight and
easy to drop into any project. Through the `iron-handlers` feature, it also
depends on Iron.

## Exposing data types

The `GraphQLType` trait is the primary interface towards application developers.
By deriving this trait, you can expose your types as either objects, enums,
interfaces, unions, or scalars.

However, due to the dynamic nature of GraphQL's type system, deriving this trait
manually is a bit tedious, especially in order to do it in a fully type safe
manner. To help with this task, this library provides a couple of macros; the
most common one being `graphql_object!`. Use this macro to expose your already
existing object types as GraphQL objects:

```rust
#[macro_use] extern crate juniper;
# use std::collections::HashMap;
use juniper::FieldResult;

struct User { id: String, name: String, friend_ids: Vec<String>  }
struct QueryRoot;
struct Database { users: HashMap<String, User> }

// GraphQL objects can access a "context object" during execution. Use this
// object to provide e.g. database access to the field accessors.
//
// In this example, we use the Database struct as our context.
graphql_object!(User: Database as "User" |&self| {

    // Expose a simple field as a GraphQL string.
    field id() -> &String {
        &self.id
    }

    field name() -> &String {
        &self.name
    }

    // FieldResult<T> is an alias for Result<T, String> - simply return
    // a string from this method and it will be correctly inserted into
    // the execution response.
    field secret() -> FieldResult<&String> {
        Err("Can't touch this".to_owned())
    }

    // Field accessors can optionally take an "executor" as their first
    // argument. This object can help guide query execution and provides
    // access to the context instance.
    //
    // In this example, the context is used to convert the friend_ids array
    // into actual User objects.
    field friends(&mut executor) -> Vec<&User> {
        self.friend_ids.iter()
            .filter_map(|id| executor.context().users.get(id))
            .collect()
    }
});

// The context object is passed down to all referenced types - all your exposed
// types need to have the same context type.
graphql_object!(QueryRoot: Database as "Query" |&self| {

    // Arguments work just like they do on functions.
    field user(&mut executor, id: String) -> Option<&User> {
        executor.context().users.get(&id)
    }
});

# fn main() { }
```

Adding per type, field, and argument documentation is possible directly from
this macro. For more in-depth information on how to expose fields and types, see
the [`graphql_object!`][3] macro.

## Integrating with Iron

The most obvious usecase is to expose the GraphQL schema over an HTTP endpoint.
To support this, the library provides an optional and customizable Iron handler.

For example, continuing from the schema created above:

```rust,no_run
extern crate iron;
# #[macro_use] extern crate juniper;
# use std::collections::HashMap;

use iron::prelude::*;
use juniper::iron_handlers::GraphQLHandler;

# use juniper::FieldResult;
#
# struct User { id: String, name: String, friend_ids: Vec<String>  }
# struct QueryRoot;
# struct Database { users: HashMap<String, User> }
#
# graphql_object!(User: Database as "User" |&self| {
#     field id() -> FieldResult<&String> {
#         Ok(&self.id)
#     }
#
#     field name() -> FieldResult<&String> {
#         Ok(&self.name)
#     }
#
#     field friends(&mut executor) -> FieldResult<Vec<&User>> {
#         Ok(self.friend_ids.iter()
#             .filter_map(|id| executor.context().users.get(id))
#             .collect())
#     }
# });
#
# graphql_object!(QueryRoot: Database as "Query" |&self| {
#     field user(&mut executor, id: String) -> FieldResult<Option<&User>> {
#         Ok(executor.context().users.get(&id))
#     }
# });

// This function is executed for every request. Here, we would realistically
// provide a database connection or similar. For this example, we'll be
// creating the database from scratch.
fn context_factory(_: &mut Request) -> Database {
    Database {
        users: vec![
            ( "1000".to_owned(), User {
                id: "1000".to_owned(), name: "Robin".to_owned(),
                friend_ids: vec!["1001".to_owned()] } ),
            ( "1001".to_owned(), User {
                id: "1001".to_owned(), name: "Max".to_owned(),
                friend_ids: vec!["1000".to_owned()] } ),
        ].into_iter().collect()
    }
}

fn main() {
    // GraphQLHandler takes a context factory function, the root object,
    // and the mutation object. If we don't have any mutations to expose, we
    // can use the empty tuple () to indicate absence.
    let graphql_endpoint = GraphQLHandler::new(context_factory, QueryRoot, ());

    // Start serving the schema at the root on port 8080.
    Iron::new(graphql_endpoint).http("localhost:8080").unwrap();
}

```

See the [`iron_handlers`][4] module and the [`GraphQLHandler`][5] documentation
for more information on what request methods are supported. There's also a
built-in [GraphiQL][6] handler included.

[1]: http://graphql.org
[2]: http://ironframework.io
[3]: macro.graphql_object!.html
[4]: iron_handlers/index.html
[5]: iron_handlers/struct.GraphQLHandler.html
[6]: https://github.com/graphql/graphiql

*/

#![cfg_attr(feature="nightly", feature(test))]
#![warn(missing_docs)]

extern crate rustc_serialize;

#[cfg(feature="nightly")] extern crate test;
#[cfg(feature="iron-handlers")] #[macro_use(itry, iexpect)] extern crate iron;
#[cfg(test)] extern crate iron_test;

#[macro_use] mod macros;
mod ast;
pub mod parser;
mod value;
mod types;
mod schema;
pub mod validation;
mod executor;
mod integrations;

#[cfg(all(test, not(feature="expose-test-schema")))] mod tests;
#[cfg(feature="expose-test-schema")] pub mod tests;

#[cfg(test)] mod executor_tests;

use std::collections::HashMap;

use rustc_serialize::json::{ToJson, Json};

use parser::{parse_document_source, ParseError, Spanning, SourcePosition};
use validation::{RuleError, ValidatorContext, visit_all_rules};
use executor::execute_validated_query;

pub use ast::{ToInputValue, FromInputValue, InputValue, Type, Selection};
pub use value::Value;
pub use types::base::{Arguments, GraphQLType, TypeKind};
pub use executor::{
    Executor, Registry, ExecutionResult, ExecutionError, FieldResult, IntoFieldResult,
};
pub use types::scalars::ID;
pub use schema::model::RootNode;

pub use schema::meta;

#[cfg(feature="iron-handlers")] pub use integrations::iron_handlers;

/// An error that prevented query execution
#[derive(Debug, PartialEq)]
#[allow(missing_docs)]
pub enum GraphQLError<'a> {
    ParseError(Spanning<ParseError<'a>>),
    ValidationError(Vec<RuleError>),
}

/// Execute a query in a provided schema
pub fn execute<'a, CtxT, QueryT, MutationT>(
    document_source: &'a str,
    operation_name: Option<&str>,
    root_node: &RootNode<CtxT, QueryT, MutationT>,
    variables: &HashMap<String, InputValue>,
    context: &CtxT,
)
    -> Result<(Value, Vec<ExecutionError>), GraphQLError<'a>>
    where QueryT: GraphQLType<CtxT>,
          MutationT: GraphQLType<CtxT>,
{
    let document = try!(parse_document_source(document_source));

    {
        let mut ctx = ValidatorContext::new(&root_node.schema, &document);
        visit_all_rules(&mut ctx, &document);

        let errors = ctx.into_errors();
        if !errors.is_empty() {
            return Err(GraphQLError::ValidationError(errors));
        }
    }

    Ok(execute_validated_query(document, operation_name, root_node, variables, context))
}

impl<'a> From<Spanning<ParseError<'a>>> for GraphQLError<'a> {
    fn from(f: Spanning<ParseError<'a>>) -> GraphQLError<'a> {
        GraphQLError::ParseError(f)
    }
}

impl<'a> ToJson for GraphQLError<'a> {
    fn to_json(&self) -> Json {
        let errs = match *self {
            GraphQLError::ParseError(ref err) => parse_error_to_json(err),
            GraphQLError::ValidationError(ref errs) => errs.to_json(),
        };

        Json::Object(vec![
            ("errors".to_owned(), errs),
        ].into_iter().collect())
    }
}

fn parse_error_to_json(err: &Spanning<ParseError>) -> Json {
    Json::Array(vec![
        Json::Object(vec![
            ("message".to_owned(), format!("{}", err.item).to_json()),
            ("locations".to_owned(), vec![
                Json::Object(vec![
                    ("line".to_owned(), (err.start.line() + 1).to_json()),
                    ("column".to_owned(), (err.start.column() + 1).to_json())
                ].into_iter().collect()),
            ].to_json()),
        ].into_iter().collect()),
    ])
}

impl ToJson for RuleError {
    fn to_json(&self) -> Json {
        Json::Object(vec![
            ("message".to_owned(), self.message().to_json()),
            ("locations".to_owned(), self.locations().to_json()),
        ].into_iter().collect())
    }
}

impl ToJson for SourcePosition {
    fn to_json(&self) -> Json {
        Json::Object(vec![
            ("line".to_owned(), (self.line() + 1).to_json()),
            ("column".to_owned(), (self.column() + 1).to_json()),
        ].into_iter().collect())
    }
}

impl ToJson for ExecutionError {
    fn to_json(&self) -> Json {
        Json::Object(vec![
            ("message".to_owned(), self.message().to_json()),
            ("locations".to_owned(), vec![self.location().clone()].to_json()),
            ("path".to_owned(), self.path().to_json()),
        ].into_iter().collect())
    }
}

#[doc(hidden)]
pub fn to_snake_case(s: &str) -> String {
    let mut dest = String::new();

    for (i, part) in s.split('_').enumerate() {
        if i > 0 && part.len() == 1 {
            dest.push_str(&part.to_uppercase());
        }
        else if i > 0 && part.len() > 1 {
            let first = part.chars().next().unwrap().to_uppercase().collect::<String>();
            let second = &part[1..];

            dest.push_str(&first);
            dest.push_str(second);
        }
        else if i == 0 {
            dest.push_str(part);
        }
    }

    dest
}

#[test]
fn test_to_snake_case() {
    assert_eq!(&to_snake_case("test")[..], "test");
    assert_eq!(&to_snake_case("_test")[..], "Test");
    assert_eq!(&to_snake_case("first_second")[..], "firstSecond");
    assert_eq!(&to_snake_case("first_")[..], "first");
    assert_eq!(&to_snake_case("a_b_c")[..], "aBC");
    assert_eq!(&to_snake_case("a_bc")[..], "aBc");
    assert_eq!(&to_snake_case("a_b")[..], "aB");
    assert_eq!(&to_snake_case("a")[..], "a");
    assert_eq!(&to_snake_case("")[..], "");
}
<|endoftext|>


<commit_before>extern crate rustc_serialize;
extern crate websocket;
extern crate crossbeam;
extern crate rand;

pub mod client;
mod options;
mod transport;

use std::result;
use websocket::result::WebSocketError;
use std::sync::mpsc::SendError;

#[derive(Debug)]
pub enum WampError {
    InvalidURL,
    WebSocketError(WebSocketError),
    InternalThreadError,
}

//impl From<ParseError> for WampError {
//    fn from(err: ParseError) -> WampError{
//        WampError::InvalidURL(err)
//    }
//}

impl <T> From<SendError<T>> for WampError {
    fn from(err: SendError<T>) -> WampError {
        WampError::InternalThreadError
    }
}

impl From<WebSocketError> for WampError {
    fn from(err: WebSocketError) -> WampError{
        WampError::WebSocketError(err)
    }
}

impl <T> From<SendError<T>> for WampError {
    fn from(err: SendError<T>) -> WampError {
        WampError::InternalThreadError
    }
}

pub type WampResult<T> = result::Result<T, WampError>;
<commit_msg>continued merging. my git-fu is gaining power<commit_after>extern crate rustc_serialize;
extern crate websocket;
extern crate crossbeam;
extern crate rand;

pub mod client;
mod options;
mod transport;

use std::result;
use websocket::result::WebSocketError;
use std::sync::mpsc::SendError;

#[derive(Debug)]
pub enum WampError {
    InvalidURL,
    WebSocketError(WebSocketError),
    InternalThreadError,
}

//impl From<ParseError> for WampError {
//    fn from(err: ParseError) -> WampError{
//        WampError::InvalidURL(err)
//    }
//}

impl <T> From<SendError<T>> for WampError {
    fn from(err: SendError<T>) -> WampError {
        WampError::InternalThreadError
    }
}

impl From<WebSocketError> for WampError {
    fn from(err: WebSocketError) -> WampError{
        WampError::WebSocketError(err)
    }
}

pub type WampResult<T> = result::Result<T, WampError>;
<|endoftext|>


<commit_before>use std::ops::{Add, Sub};

#[derive(Debug,PartialEq,Eq)]
pub struct LimitVal {
    Val : u8,
    Max : u8,
    Min : u8,
    //Fix : Fn(u8) -> u8 //This caused wierd issues, ignore for now.
}

impl Add for LimitVal {
    type Output = LimitVal;

    fn add(self, other: LimitVal) -> LimitVal {
        let mut result: LimitVal = LimitVal::new().Min(0).Max(0).Val(0).finalize(); //hack
        result.Val = self.Val + other.Val;
        result.Max = if(self.Max > other.Max){
                        other.Max // choose the smallest one
                    }else{
                        self.Max
                    };
        result.Min = if(self.Min > other.Min){
                        self.Min // choose the biggest one
                    }else{
                        other.Min
                    };
        result
    }
}

impl LimitVal {
    fn new() -> LimitVal {
            LimitVal{Val: 0, Max: 0, Min: 0}
        }
    fn Max(&mut self , val:u8) -> &mut LimitVal{
        self.Max  = val;
        self
    }
    fn Min(&mut self , val:u8) -> &mut LimitVal{
        self.Min  = val;
        self
    }
    fn Val(&mut self , val:u8) -> &mut LimitVal{
        self.Val  = val;
        self
    }
    fn finalize(&self) -> LimitVal{
        LimitVal{Max: self.Max, Min: self.Min, Val: self.Val}
    }

}

#[cfg(test)]
mod tests {
    /*
    Can always put in own file, then would need:
    extern crate adder; (or whatever)
    and then namespace:: the functions.
    */
    use super::*;

    #[test]
    fn test_add() {
        let x: LimitVal = LimitVal::new().Min(10).Max(0).Val(2).finalize();
        let y: LimitVal = LimitVal::new().Min(10).Max(0).Val(3).finalize();

        let z = x + y;
        assert_eq!(z.Val,5);
    }
}
<commit_msg>More changes.<commit_after>use std::ops::{Add, Sub};

pub struct LimitVal {
    val : u8,
    max : u8,
    min : u8,
    //Fix : Fn(u8) -> u8 //This causes issue with size not being implemented?
}

impl LimitVal {
    fn new() -> LimitVal {
            LimitVal{val: 0, max: 0, min: 0}
        }
    fn max(&mut self , val:u8) -> &mut LimitVal{
        self.max  = val;
        self
    }
    fn min(&mut self , val:u8) -> &mut LimitVal{
        self.min  = val;
        self
    }
    fn val(&mut self , val:u8) -> &mut LimitVal{
        self.val  = val;
        self
    }
    fn finalize(&self) -> LimitVal{
        LimitVal{max: self.max, min: self.min, val: self.val}
    }

}

impl Add for LimitVal {
    type Output = LimitVal;

    fn add(self, other: LimitVal) -> LimitVal {
        let mut result: LimitVal = LimitVal::new().min(0).max(0).val(0).finalize(); //hack
        result.val = self.val + other.val;
        result.max = if(self.max > other.max){
                        other.max // choose the smallest one
                    }else{
                        self.max
                    };
        result.min = if(self.min > other.min){
                        self.min // choose the biggest one
                    }else{
                        other.min
                    };
        result
    }
}

#[cfg(test)]
mod tests {
    /*
    Can always put in own file, then would need:
    extern crate adder; (or whatever)
    and then namespace:: the functions.
    */
    use super::*;

    #[test]
    fn test_add() {
        let x: LimitVal = LimitVal::new().min(10).max(0).val(2).finalize();
        let y: LimitVal = LimitVal::new().min(10).max(0).val(3).finalize();

        let z = x + y;
        assert_eq!(z.val,5);
    }
}
<|endoftext|>


<commit_before>//! This crate implements a structure that can be used as a generic array type.use
//! Core Rust array types `[T; N]` can't be used generically with respect to `N`, so for example this:
//!
//! ```{should_fail}
//! struct Foo<T, N> {
//!     data: [T; N]
//! }
//! ```
//!
//! won't work.
//!
//! **generic-array** exports a `GenericArray<T,N>` type, which lets the above be implemented as:
//!
//! ```
//!# use generic_array::{ArrayLength, GenericArray};
//! struct Foo<T, N: ArrayLength<T>> {
//!     data: GenericArray<T,N>
//! }
//! ```
//!
//! The `ArrayLength<T>` trait is implemented by default for [unsigned integer types](../typenum/uint/index.html) from [typenum](../typenum/index.html).
extern crate typenum;
use typenum::uint::{Unsigned, UTerm, UInt};
use typenum::bit::{B0, B1};
use std::marker::PhantomData;
use std::mem;
use std::ops::{Deref, DerefMut};
use std::slice;

/// Trait making GenericArray work, marking types to be used as length of an array
pub unsafe trait ArrayLength<T> : Unsigned {
    /// Associated type representing the array type for the number
    type ArrayType;
}

unsafe impl<T> ArrayLength<T> for UTerm {
    type ArrayType = ();
}

/// Internal type used to generate a struct of appropriate size
#[allow(dead_code)]
#[repr(C)]
pub struct GenericArrayImplEven<T, U> {
    parent1: U,
    parent2: U,
    _marker: PhantomData<T>
}

/// Internal type used to generate a struct of appropriate size
#[allow(dead_code)]
#[repr(C)]
pub struct GenericArrayImplOdd<T, U> {
    parent1: U,
    parent2: U,
    data: T
}

unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B0> {
    type ArrayType = GenericArrayImplEven<T, N::ArrayType>;
}

unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B1> {
    type ArrayType = GenericArrayImplOdd<T, N::ArrayType>;
}

/// Struct representing a generic array - GenericArray<T, N> works like [T; N]
#[allow(dead_code)]
pub struct GenericArray<T, U: ArrayLength<T>> {
    data: U::ArrayType
}

impl<T, N> Deref for GenericArray<T, N> where N: ArrayLength<T> {
    type Target = [T];

    fn deref(&self) -> &[T] {
        unsafe {
            slice::from_raw_parts(self as *const Self as *const T, N::to_usize())
        }
    }
}

impl<T, N> DerefMut for GenericArray<T, N> where N: ArrayLength<T> {
    fn deref_mut(&mut self) -> &mut [T] {
        unsafe {
            slice::from_raw_parts_mut(self as *mut Self as *mut T, N::to_usize())
        }
    }
}

impl<T: Default, N> GenericArray<T, N> where N: ArrayLength<T> {

    /// Function constructing an array filled with default values
    pub fn new() -> GenericArray<T, N> {
        let mut res: GenericArray<T, N> = unsafe { mem::zeroed() };
        for r in res.iter_mut() { *r = T::default(); }
        res
    }

}

impl<T: Clone, N> GenericArray<T, N> where N: ArrayLength<T> {

    /// Function constructing an array from a slice; the length of the slice must be equal to the length of the array
    pub fn from_slice(list: &[T]) -> GenericArray<T, N> {
        assert_eq!(list.len(), N::to_usize());
        let mut res: GenericArray<T, N> = unsafe { mem::zeroed() };
        for i in 0..N::to_usize() {
            res[i] = list[i].clone();
        }
        res
    }

}
<commit_msg>Implemented Clone and Copy for GenericArray (where appropriate)<commit_after>//! This crate implements a structure that can be used as a generic array type.use
//! Core Rust array types `[T; N]` can't be used generically with respect to `N`, so for example this:
//!
//! ```{should_fail}
//! struct Foo<T, N> {
//!     data: [T; N]
//! }
//! ```
//!
//! won't work.
//!
//! **generic-array** exports a `GenericArray<T,N>` type, which lets the above be implemented as:
//!
//! ```
//!# use generic_array::{ArrayLength, GenericArray};
//! struct Foo<T, N: ArrayLength<T>> {
//!     data: GenericArray<T,N>
//! }
//! ```
//!
//! The `ArrayLength<T>` trait is implemented by default for [unsigned integer types](../typenum/uint/index.html) from [typenum](../typenum/index.html).
extern crate typenum;
use typenum::uint::{Unsigned, UTerm, UInt};
use typenum::bit::{B0, B1};
use std::marker::PhantomData;
use std::mem;
use std::ops::{Deref, DerefMut};
use std::slice;

/// Trait making GenericArray work, marking types to be used as length of an array
pub unsafe trait ArrayLength<T> : Unsigned {
    /// Associated type representing the array type for the number
    type ArrayType;
}

unsafe impl<T> ArrayLength<T> for UTerm {
    type ArrayType = ();
}

/// Internal type used to generate a struct of appropriate size
#[allow(dead_code)]
#[repr(C)]
pub struct GenericArrayImplEven<T, U> {
    parent1: U,
    parent2: U,
    _marker: PhantomData<T>
}

impl<T: Clone, U: Clone> Clone for GenericArrayImplEven<T, U> {
    fn clone(&self) -> GenericArrayImplEven<T, U> {
        GenericArrayImplEven {
            parent1: self.parent1.clone(),
            parent2: self.parent2.clone(),
            _marker: PhantomData
        }
    }
}

impl<T: Copy, U: Copy> Copy for GenericArrayImplEven<T, U> {}

/// Internal type used to generate a struct of appropriate size
#[allow(dead_code)]
#[repr(C)]
pub struct GenericArrayImplOdd<T, U> {
    parent1: U,
    parent2: U,
    data: T
}

impl<T: Clone, U: Clone> Clone for GenericArrayImplOdd<T, U> {
    fn clone(&self) -> GenericArrayImplOdd<T, U> {
        GenericArrayImplOdd {
            parent1: self.parent1.clone(),
            parent2: self.parent2.clone(),
            data: self.data.clone()
        }
    }
}

impl<T: Copy, U: Copy> Copy for GenericArrayImplOdd<T, U> {}

unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B0> {
    type ArrayType = GenericArrayImplEven<T, N::ArrayType>;
}

unsafe impl<T, N: ArrayLength<T>> ArrayLength<T> for UInt<N, B1> {
    type ArrayType = GenericArrayImplOdd<T, N::ArrayType>;
}

/// Struct representing a generic array - GenericArray<T, N> works like [T; N]
#[allow(dead_code)]
pub struct GenericArray<T, U: ArrayLength<T>> {
    data: U::ArrayType
}

impl<T, N> Deref for GenericArray<T, N> where N: ArrayLength<T> {
    type Target = [T];

    fn deref(&self) -> &[T] {
        unsafe {
            slice::from_raw_parts(self as *const Self as *const T, N::to_usize())
        }
    }
}

impl<T, N> DerefMut for GenericArray<T, N> where N: ArrayLength<T> {
    fn deref_mut(&mut self) -> &mut [T] {
        unsafe {
            slice::from_raw_parts_mut(self as *mut Self as *mut T, N::to_usize())
        }
    }
}

impl<T: Default, N> GenericArray<T, N> where N: ArrayLength<T> {

    /// Function constructing an array filled with default values
    pub fn new() -> GenericArray<T, N> {
        let mut res: GenericArray<T, N> = unsafe { mem::zeroed() };
        for r in res.iter_mut() { *r = T::default(); }
        res
    }

}

impl<T: Clone, N> GenericArray<T, N> where N: ArrayLength<T> {

    /// Function constructing an array from a slice; the length of the slice must be equal to the length of the array
    pub fn from_slice(list: &[T]) -> GenericArray<T, N> {
        assert_eq!(list.len(), N::to_usize());
        let mut res: GenericArray<T, N> = unsafe { mem::zeroed() };
        for i in 0..N::to_usize() {
            res[i] = list[i].clone();
        }
        res
    }

}

impl<T: Clone, N> Clone for GenericArray<T, N> where N: ArrayLength<T> {
    fn clone(&self) -> GenericArray<T, N> {
        let mut res: GenericArray<T, N> = unsafe { mem::zeroed() };
        for i in 0..N::to_usize() { res[i] = self[i].clone(); }
        res
    }
}
impl<T: Copy, N> Copy for GenericArray<T, N> where N: ArrayLength<T>, N::ArrayType: Copy {}
<|endoftext|>


<commit_before>#![doc(html_root_url = "https://docs.rs/rayon/1.0")]
#![deny(missing_debug_implementations)]
#![deny(missing_docs)]

//! Data-parallelism library that makes it easy to convert sequential
//! computations into parallel
//!
//! Rayon is lightweight and convenient for introducing parallelism into existing
//! code. It guarantees data-race free executions and takes advantage of
//! parallelism when sensible, based on work-load at runtime.
//!
//! # How to use Rayon
//!
//! There are two ways to use Rayon:
//!
//! - **High-level parallel constructs** are the simplest way to use Rayon and also
//!   typically the most efficient.
//!   - [Parallel iterators][iter module] make it easy to convert a sequential iterator to
//!     execute in parallel.
//!   - The [`par_sort`] method sorts `&mut [T]` slices (or vectors) in parallel.
//!   - [`par_extend`] can be used to efficiently grow collections with items produced
//!     by a parallel iterator.
//! - **Custom tasks** let you divide your work into parallel tasks yourself.
//!   - [`join`] is used to subdivide a task into two pieces.
//!   - [`scope`] creates a scope within which you can create any number of parallel tasks.
//!   - [`ThreadPoolBuilder`] can be used to create your own thread pools or customize
//!     the global one.
//!
//! [iter module]: iter/index.html
//! [`join`]: fn.join.html
//! [`scope`]: fn.scope.html
//! [`par_sort`]: slice/trait.ParallelSliceMut.html#method.par_sort
//! [`par_extend`]: iter/trait.ParallelExtend.html#tymethod.par_extend
//! [`ThreadPoolBuilder`]: struct.ThreadPoolBuilder.html
//!
//! # Basic usage and the Rayon prelude
//!
//! First, you will need to add `rayon` to your `Cargo.toml` and put
//! `extern crate rayon` in your main file (`lib.rs`, `main.rs`).
//!
//! Next, to use parallel iterators or the other high-level methods,
//! you need to import several traits. Those traits are bundled into
//! the module [`rayon::prelude`]. It is recommended that you import
//! all of these traits at once by adding `use rayon::prelude::*` at
//! the top of each module that uses Rayon methods.
//!
//! These traits give you access to the `par_iter` method which provides
//! parallel implementations of many iterative functions such as [`map`],
//! [`for_each`], [`filter`], [`fold`], and [more].
//!
//! [`rayon::prelude`]: prelude/index.html
//! [`map`]: iter/trait.ParallelIterator.html#method.map
//! [`for_each`]: iter/trait.ParallelIterator.html#method.for_each
//! [`filter`]: iter/trait.ParallelIterator.html#method.filter
//! [`fold`]: iter/trait.ParallelIterator.html#method.fold
//! [more]: iter/trait.ParallelIterator.html#provided-methods
//!
//! # Crate Layout
//!
//! Rayon extends many of the types found in the standard library with
//! parallel iterator implementations. The modules in the `rayon`
//! crate mirror [`std`] itself: so, e.g., the `option` module in
//! Rayon contains parallel iterators for the `Option` type, which is
//! found in [the `option` module of `std`]. Similarly, the
//! `collections` module in Rayon offers parallel iterator types for
//! [the `collections` from `std`]. You will rarely need to access
//! these submodules unless you need to name iterator types
//! explicitly.
//!
//! [the `option` module of `std`]: https://doc.rust-lang.org/std/option/index.html
//! [the `collections` from `std`]: https://doc.rust-lang.org/std/collections/index.html
//! [`std`]: https://doc.rust-lang.org/std/
//!
//! # Other questions?
//!
//! See [the Rayon FAQ][faq].
//!
//! [faq]: https://github.com/rayon-rs/rayon/blob/master/FAQ.md

extern crate crossbeam_deque;
extern crate either;
extern crate rayon_core;

#[cfg(test)]
extern crate rand;
#[cfg(test)]
extern crate rand_xorshift;

#[macro_use]
mod delegate;

#[macro_use]
mod private;

mod split_producer;

pub mod collections;
pub mod iter;
pub mod option;
pub mod prelude;
pub mod range;
pub mod result;
pub mod slice;
pub mod str;
pub mod vec;

mod math;
mod par_either;

mod compile_fail;

pub use rayon_core::current_num_threads;
pub use rayon_core::FnContext;
pub use rayon_core::ThreadPool;
pub use rayon_core::ThreadPoolBuildError;
pub use rayon_core::ThreadPoolBuilder;
pub use rayon_core::{join, join_context};
pub use rayon_core::{scope, Scope};
pub use rayon_core::{scope_fifo, ScopeFifo};
pub use rayon_core::{spawn, spawn_fifo};
<commit_msg>Reexport current_thread_index function<commit_after>#![doc(html_root_url = "https://docs.rs/rayon/1.0")]
#![deny(missing_debug_implementations)]
#![deny(missing_docs)]

//! Data-parallelism library that makes it easy to convert sequential
//! computations into parallel
//!
//! Rayon is lightweight and convenient for introducing parallelism into existing
//! code. It guarantees data-race free executions and takes advantage of
//! parallelism when sensible, based on work-load at runtime.
//!
//! # How to use Rayon
//!
//! There are two ways to use Rayon:
//!
//! - **High-level parallel constructs** are the simplest way to use Rayon and also
//!   typically the most efficient.
//!   - [Parallel iterators][iter module] make it easy to convert a sequential iterator to
//!     execute in parallel.
//!   - The [`par_sort`] method sorts `&mut [T]` slices (or vectors) in parallel.
//!   - [`par_extend`] can be used to efficiently grow collections with items produced
//!     by a parallel iterator.
//! - **Custom tasks** let you divide your work into parallel tasks yourself.
//!   - [`join`] is used to subdivide a task into two pieces.
//!   - [`scope`] creates a scope within which you can create any number of parallel tasks.
//!   - [`ThreadPoolBuilder`] can be used to create your own thread pools or customize
//!     the global one.
//!
//! [iter module]: iter/index.html
//! [`join`]: fn.join.html
//! [`scope`]: fn.scope.html
//! [`par_sort`]: slice/trait.ParallelSliceMut.html#method.par_sort
//! [`par_extend`]: iter/trait.ParallelExtend.html#tymethod.par_extend
//! [`ThreadPoolBuilder`]: struct.ThreadPoolBuilder.html
//!
//! # Basic usage and the Rayon prelude
//!
//! First, you will need to add `rayon` to your `Cargo.toml` and put
//! `extern crate rayon` in your main file (`lib.rs`, `main.rs`).
//!
//! Next, to use parallel iterators or the other high-level methods,
//! you need to import several traits. Those traits are bundled into
//! the module [`rayon::prelude`]. It is recommended that you import
//! all of these traits at once by adding `use rayon::prelude::*` at
//! the top of each module that uses Rayon methods.
//!
//! These traits give you access to the `par_iter` method which provides
//! parallel implementations of many iterative functions such as [`map`],
//! [`for_each`], [`filter`], [`fold`], and [more].
//!
//! [`rayon::prelude`]: prelude/index.html
//! [`map`]: iter/trait.ParallelIterator.html#method.map
//! [`for_each`]: iter/trait.ParallelIterator.html#method.for_each
//! [`filter`]: iter/trait.ParallelIterator.html#method.filter
//! [`fold`]: iter/trait.ParallelIterator.html#method.fold
//! [more]: iter/trait.ParallelIterator.html#provided-methods
//!
//! # Crate Layout
//!
//! Rayon extends many of the types found in the standard library with
//! parallel iterator implementations. The modules in the `rayon`
//! crate mirror [`std`] itself: so, e.g., the `option` module in
//! Rayon contains parallel iterators for the `Option` type, which is
//! found in [the `option` module of `std`]. Similarly, the
//! `collections` module in Rayon offers parallel iterator types for
//! [the `collections` from `std`]. You will rarely need to access
//! these submodules unless you need to name iterator types
//! explicitly.
//!
//! [the `option` module of `std`]: https://doc.rust-lang.org/std/option/index.html
//! [the `collections` from `std`]: https://doc.rust-lang.org/std/collections/index.html
//! [`std`]: https://doc.rust-lang.org/std/
//!
//! # Other questions?
//!
//! See [the Rayon FAQ][faq].
//!
//! [faq]: https://github.com/rayon-rs/rayon/blob/master/FAQ.md

extern crate crossbeam_deque;
extern crate either;
extern crate rayon_core;

#[cfg(test)]
extern crate rand;
#[cfg(test)]
extern crate rand_xorshift;

#[macro_use]
mod delegate;

#[macro_use]
mod private;

mod split_producer;

pub mod collections;
pub mod iter;
pub mod option;
pub mod prelude;
pub mod range;
pub mod result;
pub mod slice;
pub mod str;
pub mod vec;

mod math;
mod par_either;

mod compile_fail;

pub use rayon_core::{current_num_threads, current_thread_index};
pub use rayon_core::FnContext;
pub use rayon_core::ThreadPool;
pub use rayon_core::ThreadPoolBuildError;
pub use rayon_core::ThreadPoolBuilder;
pub use rayon_core::{join, join_context};
pub use rayon_core::{scope, Scope};
pub use rayon_core::{scope_fifo, ScopeFifo};
pub use rayon_core::{spawn, spawn_fifo};
<|endoftext|>


<commit_before>use std::io::Command;
use std::os;
use std::str;

pub struct Options {
    pub statik: bool,
}

pub fn find_library(name: &str) -> Result<(), String> {
    find_library_opts(name, &default_options(name))
}

pub fn find_library_opts(name: &str, options: &Options) -> Result<(), String> {
    if os::getenv(format!("{}_NO_PKG_CONFIG", envify(name)).as_slice()).is_some() {
        return Err(format!("pkg-config requested to be aborted for {}", name))
    }
    let mut cmd = Command::new("pkg-config");
    if options.statik {
        cmd.arg("--static");
    }
    cmd.arg("--libs")
       .env("PKG_CONFIG_ALLOW_SYSTEM_LIBS", "1")
       .arg(name);
    let out = try!(cmd.output().map_err(|e| {
        format!("failed to run `{}`: {}", cmd, e)
    }));
    let stdout = str::from_utf8(out.output.as_slice()).unwrap();
    let stderr = str::from_utf8(out.error.as_slice()).unwrap();
    if !out.status.success() {
        let mut msg = format!("`{}` did not exit successfully: {}", cmd,
                              out.status);
        if stdout.len() > 0 {
            msg.push_str("\n--- stdout\n");
            msg.push_str(stdout);
        }
        if stderr.len() > 0 {
            msg.push_str("\n--- stderr\n");
            msg.push_str(stderr);
        }
        return Err(msg)
    }

    for arg in stdout.split(' ').filter(|l| !l.is_empty() && l.len() > 2) {
        let val = arg.slice_from(2);
        if arg.starts_with("-l") {
            if options.statik {
                println!("cargo:rustc-args=-l {}:static", val);
            } else {
                println!("cargo:rustc-args=-l {}", val);
            }
        } else if arg.starts_with("-L") {
            println!("cargo:rustc-args=-L {}", val);
        }
    }
    Ok(())
}

pub fn default_options(name: &str) -> Options {
    let name = envify(name);
    let statik = if os::getenv(format!("{}_STATIC", name).as_slice()).is_some() {
        true
    } else if os::getenv(format!("{}_DYNAMIC", name).as_slice()).is_some() {
        false
    } else if os::getenv("PKG_CONFIG_ALL_STATIC").is_some() {
        true
    } else if os::getenv("PKG_CONFIG_ALL_DYNAMIC").is_some() {
        false
    } else {
        true
    };
    Options { statik: statik }
}

fn envify(name: &str) -> String {
    name.chars().map(|c| c.to_uppercase()).map(|c| if c == '-' {'_'} else {c})
        .collect()
}
<commit_msg>More typos<commit_after>use std::io::Command;
use std::os;
use std::str;

pub struct Options {
    pub statik: bool,
}

pub fn find_library(name: &str) -> Result<(), String> {
    find_library_opts(name, &default_options(name))
}

pub fn find_library_opts(name: &str, options: &Options) -> Result<(), String> {
    if os::getenv(format!("{}_NO_PKG_CONFIG", envify(name)).as_slice()).is_some() {
        return Err(format!("pkg-config requested to be aborted for {}", name))
    }
    let mut cmd = Command::new("pkg-config");
    if options.statik {
        cmd.arg("--static");
    }
    cmd.arg("--libs")
       .env("PKG_CONFIG_ALLOW_SYSTEM_LIBS", "1")
       .arg(name);
    let out = try!(cmd.output().map_err(|e| {
        format!("failed to run `{}`: {}", cmd, e)
    }));
    let stdout = str::from_utf8(out.output.as_slice()).unwrap();
    let stderr = str::from_utf8(out.error.as_slice()).unwrap();
    if !out.status.success() {
        let mut msg = format!("`{}` did not exit successfully: {}", cmd,
                              out.status);
        if stdout.len() > 0 {
            msg.push_str("\n--- stdout\n");
            msg.push_str(stdout);
        }
        if stderr.len() > 0 {
            msg.push_str("\n--- stderr\n");
            msg.push_str(stderr);
        }
        return Err(msg)
    }

    for arg in stdout.split(' ').filter(|l| !l.is_empty() && l.len() > 2) {
        let val = arg.slice_from(2);
        if arg.starts_with("-l") {
            if options.statik {
                println!("cargo:rustc-flags=-l {}:static", val);
            } else {
                println!("cargo:rustc-flags=-l {}", val);
            }
        } else if arg.starts_with("-L") {
            println!("cargo:rustc-flags=-L {}", val);
        }
    }
    Ok(())
}

pub fn default_options(name: &str) -> Options {
    let name = envify(name);
    let statik = if os::getenv(format!("{}_STATIC", name).as_slice()).is_some() {
        true
    } else if os::getenv(format!("{}_DYNAMIC", name).as_slice()).is_some() {
        false
    } else if os::getenv("PKG_CONFIG_ALL_STATIC").is_some() {
        true
    } else if os::getenv("PKG_CONFIG_ALL_DYNAMIC").is_some() {
        false
    } else {
        false
    };
    Options { statik: statik }
}

fn envify(name: &str) -> String {
    name.chars().map(|c| c.to_uppercase()).map(|c| if c == '-' {'_'} else {c})
        .collect()
}
<|endoftext|>