<commit_before>//! Defines the BSDF which acts as a container for composing the various BRDFs
//! and BTDFs that describe the surface's properties

use std::vec::Vec;
use std::cmp;
use collect::enum_set::EnumSet;

use linalg;
use linalg::{Normal, Vector, Point};
use film::Colorf;
use geometry::DifferentialGeometry;
use bxdf::{BxDF, BxDFType};

/// The BSDF contains the various BRDFs and BTDFs that describe the surface's properties
/// at some point. It also transforms incident and outgoing light directions into
/// shading space to make the BxDFs easier to implement.
/// TODO: We really need the memory pool. Each time we get the bsdf from a
/// material we need to allocate a decent amount of stuff since they each need
/// their own tangent, bitangent and differential geometry reference.
pub struct BSDF<'a> {
    /// The hit point
    pub p: Point,
    /// Shading normal, may be perturbed by bump mapping
    pub n: Normal,
    /// The actual geometry normal
    pub ng: Normal,
    /// Tangent vector for the surface
    pub tan: Vector,
    /// Bitangent vector for the surface
    pub bitan: Vector,
    /// Refractive index of the geometry
    pub eta: f32,
    /// TODO: Currently a Vec is safe to use but once in the memory pool it
    /// will leak since it won't be dropped. This would also migrate our BxDFs
    /// from Box<BxDF> to &BxDF. When unboxed traits land we can move to unboxed
    /// BxDFs here though.
    bxdfs: &'a Vec<Box<BxDF + Send + Sync>>,
}

impl<'a> BSDF<'a> {
    /// Create a new BSDF using the BxDFs passed to shade the differential geometry with
    /// refractive index `eta`
    pub fn new(bxdfs: &'a Vec<Box<BxDF + Send + Sync>>, eta: f32,
               dg: &DifferentialGeometry<'a>)
               -> BSDF<'a> {
        let n = dg.n.normalized();
        let bitan = dg.dp_du.normalized();
        let tan = linalg::cross(&n, &bitan);
        BSDF { p: dg.p, n: n, ng: dg.ng, tan: tan, bitan: bitan, bxdfs: bxdfs, eta: eta }
    }
    /// Return the total number of BxDFs
    pub fn num_bxdfs(&self) -> usize { self.bxdfs.len() }
    /// Return the number of BxDFs matching the flags
    pub fn num_matching(&self, flags: EnumSet<BxDFType>) -> usize {
        self.bxdfs.iter().filter(|ref x| x.matches(flags)).count()
    }
    /// Transform the vector from world space to shading space
    pub fn to_shading(&self, v: &Vector) -> Vector {
        Vector::new(linalg::dot(v, &self.bitan), linalg::dot(v, &self.tan),
                    linalg::dot(v, &self.n))
    }
    /// Transform the vectro from shading space to world space
    pub fn from_shading(&self, v: &Vector) -> Vector {
        Vector::new(self.bitan.x * v.x + self.tan.x * v.y + self.n.x * v.z,
                    self.bitan.y * v.x + self.tan.y * v.y + self.n.y * v.z,
                    self.bitan.z * v.x + self.tan.z * v.y + self.n.z * v.z)
    }
    /// Evaluate the BSDF for the outgoing and incident light directions
    /// `w_o` and `w_i` in world space, sampling the desired subset of BxDFs
    /// selected by the flags passed. `wo_world` and `wi_world` should point from
    /// the hit point in the outgoing and incident light directions respectively.
    pub fn eval(&self, wo_world: &Vector, wi_world: &Vector, mut flags: EnumSet<BxDFType>) -> Colorf {
        let w_o = self.to_shading(wo_world);
        let w_i = self.to_shading(wi_world);
        // Determine if we should evaluate reflection or transmission based on the
        // geometry normal and the light directions
        if linalg::dot(wo_world, &self.n) * linalg::dot(wi_world, &self.n) > 0.0 {
            flags.remove(&BxDFType::Transmission);
        } else {
            flags.remove(&BxDFType::Reflection);
        }
        // Find all matching BxDFs and add their contribution to the material's color
        self.bxdfs.iter().filter_map(|ref x| if x.matches(flags) { Some(x.eval(&w_o, &w_i)) } else { None })
            .fold(Colorf::broadcast(0.0), |x, y| x + y)
    }
    /// Sample a component of the BSDF to get an incident light direction for light
    /// leaving the surface along `w_o`.
    /// `samples` are the 3 random values to use when sampling a component of the BSDF
    /// and a the chosen BSDF
    /// Returns the color, direction, pdf and the type of BxDF that was sampled.
    pub fn sample(&self, wo_world: &Vector, flags: EnumSet<BxDFType>, samples: &[f32])
        -> (Colorf, Vector, f32, EnumSet<BxDFType>) {
        // TODO: Is there a better way to accept slices but require they be of some length?
        assert!(samples.len() > 2);

        let n_matching = self.num_matching(flags);
        if n_matching == 0 {
            return (Colorf::broadcast(0.0), Vector::broadcast(0.0), 0.0, EnumSet::new());
        }
        let comp = cmp::min((samples[0] * n_matching as f32) as usize, n_matching - 1);
        let bxdf = self.matching_at(comp, flags);
        let w_o = self.to_shading(wo_world);
        let (f, w_i, pdf) = bxdf.sample(&w_o, &samples[1..]);
        let wi_world = self.from_shading(&w_i);

        if n_matching > 1 {
            if !bxdf.bxdf_type().contains(&BxDFType::Specular) {
                (self.eval(wo_world, &wi_world, flags), wi_world,
                self.pdf(wo_world, &wi_world, flags), bxdf.bxdf_type())
            } else {
                (f, wi_world, pdf / n_matching as f32, bxdf.bxdf_type())
            }
        } else {
            (f, wi_world, pdf, bxdf.bxdf_type())
        }
    }
    /// Compute the pdf for sampling the pair of incident and outgoing light directions for
    /// the BxDFs matching the flags set
    pub fn pdf(&self, wo_world: &Vector, wi_world: &Vector, flags: EnumSet<BxDFType>) -> f32 {
        let w_o = self.to_shading(wo_world);
        let w_i = self.to_shading(wi_world);
        let (pdf_val, n_comps) = self.bxdfs.iter()
            .filter_map(|ref x| if x.matches(flags) { Some(x.pdf(&w_o, &w_i)) } else { None })
            .fold((0.0, 0), |(p, n), y| (p + y, n + 1));
        if n_comps > 0 {
            pdf_val / n_comps as f32
        } else {
            0.0
        }
    }
    /// Get the `i`th BxDF that matches the flags passed. There should not be fewer than i
    /// BxDFs that match the flags
    fn matching_at(&self, i: usize, flags: EnumSet<BxDFType>) -> &Box<BxDF + Send + Sync> {
        let mut it = self.bxdfs.iter().filter(|ref x| x.matches(flags)).skip(i);
        match it.next() {
            Some(b) => b,
            None => panic!("Out of bounds index for BxDF type {:?}", flags)
        }
    }
}

<commit_msg>Should use ng there<commit_after>//! Defines the BSDF which acts as a container for composing the various BRDFs
//! and BTDFs that describe the surface's properties

use std::vec::Vec;
use std::cmp;
use collect::enum_set::EnumSet;

use linalg;
use linalg::{Normal, Vector, Point};
use film::Colorf;
use geometry::DifferentialGeometry;
use bxdf::{BxDF, BxDFType};

/// The BSDF contains the various BRDFs and BTDFs that describe the surface's properties
/// at some point. It also transforms incident and outgoing light directions into
/// shading space to make the BxDFs easier to implement.
/// TODO: We really need the memory pool. Each time we get the bsdf from a
/// material we need to allocate a decent amount of stuff since they each need
/// their own tangent, bitangent and differential geometry reference.
pub struct BSDF<'a> {
    /// The hit point
    pub p: Point,
    /// Shading normal, may be perturbed by bump mapping
    pub n: Normal,
    /// The actual geometry normal
    pub ng: Normal,
    /// Tangent vector for the surface
    pub tan: Vector,
    /// Bitangent vector for the surface
    pub bitan: Vector,
    /// Refractive index of the geometry
    pub eta: f32,
    /// TODO: Currently a Vec is safe to use but once in the memory pool it
    /// will leak since it won't be dropped. This would also migrate our BxDFs
    /// from Box<BxDF> to &BxDF. When unboxed traits land we can move to unboxed
    /// BxDFs here though.
    bxdfs: &'a Vec<Box<BxDF + Send + Sync>>,
}

impl<'a> BSDF<'a> {
    /// Create a new BSDF using the BxDFs passed to shade the differential geometry with
    /// refractive index `eta`
    pub fn new(bxdfs: &'a Vec<Box<BxDF + Send + Sync>>, eta: f32,
               dg: &DifferentialGeometry<'a>)
               -> BSDF<'a> {
        let n = dg.n.normalized();
        let bitan = dg.dp_du.normalized();
        let tan = linalg::cross(&n, &bitan);
        BSDF { p: dg.p, n: n, ng: dg.ng, tan: tan, bitan: bitan, bxdfs: bxdfs, eta: eta }
    }
    /// Return the total number of BxDFs
    pub fn num_bxdfs(&self) -> usize { self.bxdfs.len() }
    /// Return the number of BxDFs matching the flags
    pub fn num_matching(&self, flags: EnumSet<BxDFType>) -> usize {
        self.bxdfs.iter().filter(|ref x| x.matches(flags)).count()
    }
    /// Transform the vector from world space to shading space
    pub fn to_shading(&self, v: &Vector) -> Vector {
        Vector::new(linalg::dot(v, &self.bitan), linalg::dot(v, &self.tan),
                    linalg::dot(v, &self.n))
    }
    /// Transform the vectro from shading space to world space
    pub fn from_shading(&self, v: &Vector) -> Vector {
        Vector::new(self.bitan.x * v.x + self.tan.x * v.y + self.n.x * v.z,
                    self.bitan.y * v.x + self.tan.y * v.y + self.n.y * v.z,
                    self.bitan.z * v.x + self.tan.z * v.y + self.n.z * v.z)
    }
    /// Evaluate the BSDF for the outgoing and incident light directions
    /// `w_o` and `w_i` in world space, sampling the desired subset of BxDFs
    /// selected by the flags passed. `wo_world` and `wi_world` should point from
    /// the hit point in the outgoing and incident light directions respectively.
    pub fn eval(&self, wo_world: &Vector, wi_world: &Vector, mut flags: EnumSet<BxDFType>) -> Colorf {
        let w_o = self.to_shading(wo_world);
        let w_i = self.to_shading(wi_world);
        // Determine if we should evaluate reflection or transmission based on the
        // geometry normal and the light directions
        if linalg::dot(wo_world, &self.ng) * linalg::dot(wi_world, &self.ng) > 0.0 {
            flags.remove(&BxDFType::Transmission);
        } else {
            flags.remove(&BxDFType::Reflection);
        }
        // Find all matching BxDFs and add their contribution to the material's color
        self.bxdfs.iter().filter_map(|ref x| if x.matches(flags) { Some(x.eval(&w_o, &w_i)) } else { None })
            .fold(Colorf::broadcast(0.0), |x, y| x + y)
    }
    /// Sample a component of the BSDF to get an incident light direction for light
    /// leaving the surface along `w_o`.
    /// `samples` are the 3 random values to use when sampling a component of the BSDF
    /// and a the chosen BSDF
    /// Returns the color, direction, pdf and the type of BxDF that was sampled.
    pub fn sample(&self, wo_world: &Vector, flags: EnumSet<BxDFType>, samples: &[f32])
        -> (Colorf, Vector, f32, EnumSet<BxDFType>) {
        // TODO: Is there a better way to accept slices but require they be of some length?
        assert!(samples.len() > 2);

        let n_matching = self.num_matching(flags);
        if n_matching == 0 {
            return (Colorf::broadcast(0.0), Vector::broadcast(0.0), 0.0, EnumSet::new());
        }
        let comp = cmp::min((samples[0] * n_matching as f32) as usize, n_matching - 1);
        let bxdf = self.matching_at(comp, flags);
        let w_o = self.to_shading(wo_world);
        let (f, w_i, pdf) = bxdf.sample(&w_o, &samples[1..]);
        let wi_world = self.from_shading(&w_i);

        if n_matching > 1 {
            if !bxdf.bxdf_type().contains(&BxDFType::Specular) {
                (self.eval(wo_world, &wi_world, flags), wi_world,
                self.pdf(wo_world, &wi_world, flags), bxdf.bxdf_type())
            } else {
                (f, wi_world, pdf / n_matching as f32, bxdf.bxdf_type())
            }
        } else {
            (f, wi_world, pdf, bxdf.bxdf_type())
        }
    }
    /// Compute the pdf for sampling the pair of incident and outgoing light directions for
    /// the BxDFs matching the flags set
    pub fn pdf(&self, wo_world: &Vector, wi_world: &Vector, flags: EnumSet<BxDFType>) -> f32 {
        let w_o = self.to_shading(wo_world);
        let w_i = self.to_shading(wi_world);
        let (pdf_val, n_comps) = self.bxdfs.iter()
            .filter_map(|ref x| if x.matches(flags) { Some(x.pdf(&w_o, &w_i)) } else { None })
            .fold((0.0, 0), |(p, n), y| (p + y, n + 1));
        if n_comps > 0 {
            pdf_val / n_comps as f32
        } else {
            0.0
        }
    }
    /// Get the `i`th BxDF that matches the flags passed. There should not be fewer than i
    /// BxDFs that match the flags
    fn matching_at(&self, i: usize, flags: EnumSet<BxDFType>) -> &Box<BxDF + Send + Sync> {
        let mut it = self.bxdfs.iter().filter(|ref x| x.matches(flags)).skip(i);
        match it.next() {
            Some(b) => b,
            None => panic!("Out of bounds index for BxDF type {:?}", flags)
        }
    }
}

<|endoftext|>


<commit_before>/// Character level parsers

use internal::{IResult,Needed};
use traits::{AsChar,InputIter,InputLength,Slice};
use std::ops::RangeFrom;

/// matches one of the provided characters
///
/// # Example
/// ```
/// # #[macro_use] extern crate nom;
/// # use nom::IResult;
/// # fn main() {
/// named!(simple<char>, one_of!(&b"abc"[..]));
/// assert_eq!(simple(b"a123"), IResult::Done(&b"123"[..], 'a'));
///
/// named!(a_or_b<&str, char>, one_of!("ab汉"));
/// assert_eq!(a_or_b("汉jiosfe"), IResult::Done("jiosfe", '汉'));
/// # }
/// ```
#[macro_export]
macro_rules! one_of (
  ($i:expr, $inp: expr) => (
    {
      use $crate::Slice;
      use $crate::AsChar;
      use $crate::FindToken;
      use $crate::InputIter;

      match ($i).iter_elements().next().map(|c| {
        (c, c.find_token($inp))
      }) {
        None             => $crate::IResult::Incomplete::<_, _>($crate::Needed::Size(1)),
        Some((_, false)) => $crate::IResult::Error(error_position!($crate::ErrorKind::OneOf, $i)),
        //the unwrap should be safe here
        Some((c, true))  => $crate::IResult::Done($i.slice(c.len()..), $i.iter_elements().next().unwrap().as_char())
      }
    }
  );
);

/// matches anything but the provided characters
///
/// # Example
/// ```
/// # #[macro_use] extern crate nom;
/// # use nom::IResult;
/// # fn main() {
/// named!(no_letter_a<char>, none_of!(&b"abc"[..]));
/// assert_eq!(no_letter_a(b"123"), IResult::Done(&b"23"[..], '1'));
///
/// named!(err_on_single_quote<char>, none_of!(&b"'"[..]));
/// assert_eq!(err_on_single_quote(b"'jios'fe"), IResult::Error(nom::ErrorKind::NoneOf));
/// # }
/// ```
#[macro_export]
macro_rules! none_of (
  ($i:expr, $inp: expr) => (
    {
      use $crate::Slice;
      use $crate::AsChar;
      use $crate::FindToken;
      use $crate::InputIter;

      match ($i).iter_elements().next().map(|c| {
        (c, !c.find_token($inp))
      }) {
        None             => $crate::IResult::Incomplete::<_, _>($crate::Needed::Size(1)),
        Some((_, false)) => $crate::IResult::Error(error_position!($crate::ErrorKind::NoneOf, $i)),
        //the unwrap should be safe here
        Some((c, true))  => $crate::IResult::Done($i.slice(c.len()..), $i.iter_elements().next().unwrap().as_char())
      }
    }
  );
);

/// matches one character: `char!(char) => &[u8] -> IResult<&[u8], char>
#[macro_export]
macro_rules! char (
  ($i:expr, $c: expr) => (
    {
      use $crate::Slice;
      use $crate::AsChar;
      use $crate::InputIter;

      match ($i).iter_elements().next().map(|c| {
        (c, c.as_char() == $c)
      }) {
        None             => $crate::IResult::Incomplete::<_, _>($crate::Needed::Size(1)),
        Some((_, false)) => $crate::IResult::Error(error_position!($crate::ErrorKind::Char, $i)),
        //the unwrap should be safe here
        Some((c, true))  => $crate::IResult::Done($i.slice(c.len()..), $i.iter_elements().next().unwrap().as_char())
      }
    }
  );
);

named!(#[doc="Matches a newline character '\\n'"], pub newline<char>, char!('\n'));

named!(#[doc="Matches a tab character '\\t'"], pub tab<char>, char!('\t'));

pub fn anychar<T>(input: T) -> IResult<T, char> where
  T: InputIter+InputLength+Slice<RangeFrom<usize>>,
  <T as InputIter>::Item: AsChar {
  if input.input_len() == 0 {
    IResult::Incomplete(Needed::Size(1))
  } else {
    IResult::Done(input.slice(1..), input.iter_elements().next().expect("slice should contain at least one element").as_char())
  }
}

#[cfg(test)]
mod tests {
  use internal::IResult::*;
  use util::ErrorKind;

  #[test]
  fn one_of() {
    named!(f<char>, one_of!("ab"));

    let a = &b"abcd"[..];
    assert_eq!(f(a), Done(&b"bcd"[..], 'a'));

    let b = &b"cde"[..];
    assert_eq!(f(b), Error(error_position!(ErrorKind::OneOf, b)));

    named!(utf8(&str) -> char,
      one_of!("+\u{FF0B}"));

    assert!(utf8("+").is_done());
    assert!(utf8("\u{FF0B}").is_done());
  }

  #[test]
  fn none_of() {
    named!(f<char>, none_of!("ab"));

    let a = &b"abcd"[..];
    assert_eq!(f(a), Error(error_position!(ErrorKind::NoneOf, a)));

    let b = &b"cde"[..];
    assert_eq!(f(b), Done(&b"de"[..], 'c'));
  }

  #[test]
  fn char() {
    named!(f<char>, char!('c'));

    let a = &b"abcd"[..];
    assert_eq!(f(a), Error(error_position!(ErrorKind::Char, a)));

    let b = &b"cde"[..];
    assert_eq!(f(b), Done(&b"de"[..], 'c'));
  }

}
<commit_msg>Add doc comments for character.rs<commit_after>/// Character level parsers

use internal::{IResult,Needed};
use traits::{AsChar,InputIter,InputLength,Slice};
use std::ops::RangeFrom;

/// matches one of the provided characters
///
/// # Example
/// ```
/// # #[macro_use] extern crate nom;
/// # use nom::IResult;
/// # fn main() {
/// named!(simple<char>, one_of!(&b"abc"[..]));
/// assert_eq!(simple(b"a123"), IResult::Done(&b"123"[..], 'a'));
///
/// named!(a_or_b<&str, char>, one_of!("ab汉"));
/// assert_eq!(a_or_b("汉jiosfe"), IResult::Done("jiosfe", '汉'));
/// # }
/// ```
#[macro_export]
macro_rules! one_of (
  ($i:expr, $inp: expr) => (
    {
      use $crate::Slice;
      use $crate::AsChar;
      use $crate::FindToken;
      use $crate::InputIter;

      match ($i).iter_elements().next().map(|c| {
        (c, c.find_token($inp))
      }) {
        None             => $crate::IResult::Incomplete::<_, _>($crate::Needed::Size(1)),
        Some((_, false)) => $crate::IResult::Error(error_position!($crate::ErrorKind::OneOf, $i)),
        //the unwrap should be safe here
        Some((c, true))  => $crate::IResult::Done($i.slice(c.len()..), $i.iter_elements().next().unwrap().as_char())
      }
    }
  );
);

/// matches anything but the provided characters
///
/// # Example
/// ```
/// # #[macro_use] extern crate nom;
/// # use nom::IResult;
/// # fn main() {
/// named!(no_letter_a<char>, none_of!(&b"abc"[..]));
/// assert_eq!(no_letter_a(b"123"), IResult::Done(&b"23"[..], '1'));
///
/// named!(err_on_single_quote<char>, none_of!(&b"'"[..]));
/// assert_eq!(err_on_single_quote(b"'jiosfe"), IResult::Error(nom::ErrorKind::NoneOf));
/// # }
/// ```
#[macro_export]
macro_rules! none_of (
  ($i:expr, $inp: expr) => (
    {
      use $crate::Slice;
      use $crate::AsChar;
      use $crate::FindToken;
      use $crate::InputIter;

      match ($i).iter_elements().next().map(|c| {
        (c, !c.find_token($inp))
      }) {
        None             => $crate::IResult::Incomplete::<_, _>($crate::Needed::Size(1)),
        Some((_, false)) => $crate::IResult::Error(error_position!($crate::ErrorKind::NoneOf, $i)),
        //the unwrap should be safe here
        Some((c, true))  => $crate::IResult::Done($i.slice(c.len()..), $i.iter_elements().next().unwrap().as_char())
      }
    }
  );
);

/// matches one character: `char!(char) => &[u8] -> IResult<&[u8], char>
///
/// # Example
/// ```
/// # #[macro_use] extern crate nom;
/// # use nom::IResult;
/// # fn main() {
/// named!(match_letter_a<char>, char!('a'));
/// assert_eq!(match_letter_a(b"abc"), IResult::Done(&b"bc"[..],'a'));
///
/// assert_eq!(match_letter_a(b"123cdef"), IResult::Error(nom::ErrorKind::Char));
/// # }
/// ```
#[macro_export]
macro_rules! char (
  ($i:expr, $c: expr) => (
    {
      use $crate::Slice;
      use $crate::AsChar;
      use $crate::InputIter;

      match ($i).iter_elements().next().map(|c| {
        (c, c.as_char() == $c)
      }) {
        None             => $crate::IResult::Incomplete::<_, _>($crate::Needed::Size(1)),
        Some((_, false)) => $crate::IResult::Error(error_position!($crate::ErrorKind::Char, $i)),
        //the unwrap should be safe here
        Some((c, true))  => $crate::IResult::Done($i.slice(c.len()..), $i.iter_elements().next().unwrap().as_char())
      }
    }
  );
);

named!(#[doc="Matches a newline character '\\n'"], pub newline<char>, char!('\n'));

named!(#[doc="Matches a tab character '\\t'"], pub tab<char>, char!('\t'));

/// matches one byte as a character. Note that the input type will
/// accept a `str`, but not a `&[u8]`, unlike many other nom parsers.
///
/// # Example
/// ```
/// # #[macro_use] extern crate nom;
/// # use nom::IResult;
/// # use nom::anychar;
/// # fn main() {
/// assert_eq!(anychar("abc"), IResult::Done("bc",'a'));
/// # }
/// ```
pub fn anychar<T>(input: T) -> IResult<T, char> where
  T: InputIter+InputLength+Slice<RangeFrom<usize>>,
  <T as InputIter>::Item: AsChar {
  if input.input_len() == 0 {
    IResult::Incomplete(Needed::Size(1))
  } else {
    IResult::Done(input.slice(1..), input.iter_elements().next().expect("slice should contain at least one element").as_char())
  }
}

#[cfg(test)]
mod tests {
  use internal::IResult::*;
  use util::ErrorKind;

  #[test]
  fn one_of() {
    named!(f<char>, one_of!("ab"));

    let a = &b"abcd"[..];
    assert_eq!(f(a), Done(&b"bcd"[..], 'a'));

    let b = &b"cde"[..];
    assert_eq!(f(b), Error(error_position!(ErrorKind::OneOf, b)));

    named!(utf8(&str) -> char,
      one_of!("+\u{FF0B}"));

    assert!(utf8("+").is_done());
    assert!(utf8("\u{FF0B}").is_done());
  }

  #[test]
  fn none_of() {
    named!(f<char>, none_of!("ab"));

    let a = &b"abcd"[..];
    assert_eq!(f(a), Error(error_position!(ErrorKind::NoneOf, a)));

    let b = &b"cde"[..];
    assert_eq!(f(b), Done(&b"de"[..], 'c'));
  }

  #[test]
  fn char() {
    named!(f<char>, char!('c'));

    let a = &b"abcd"[..];
    assert_eq!(f(a), Error(error_position!(ErrorKind::Char, a)));

    let b = &b"cde"[..];
    assert_eq!(f(b), Done(&b"de"[..], 'c'));
  }

}
<|endoftext|>


<commit_before>use associations::HasTable;
#[cfg(any(feature = "sqlite", feature = "mysql"))]
use associations::Identifiable;
#[cfg(any(feature = "sqlite", feature = "mysql"))]
use dsl::Find;
#[cfg(any(feature = "sqlite", feature = "postgres", feature = "mysql"))]
use dsl::Update;
use query_builder::{AsChangeset, IntoUpdateTarget};
#[cfg(any(feature = "sqlite", feature = "mysql"))]
use query_dsl::methods::{ExecuteDsl, FindDsl};
#[cfg(any(feature = "sqlite", feature = "postgres", feature = "mysql"))]
use query_dsl::{LoadQuery, RunQueryDsl};
use result::QueryResult;

#[doc(hidden)]
pub trait InternalSaveChangesDsl<T, U> {
    fn internal_save_changes(&self, changeset: T) -> QueryResult<U>;
}

#[cfg(feature = "postgres")]
use pg::PgConnection;

#[cfg(feature = "postgres")]
impl<T, U> InternalSaveChangesDsl<T, U> for PgConnection
where
    T: Copy + AsChangeset<Target = <T as HasTable>::Table> + IntoUpdateTarget,
    Update<T, T>: LoadQuery<PgConnection, U>,
{
    fn internal_save_changes(&self, changeset: T) -> QueryResult<U> {
        ::update(changeset).set(changeset).get_result(self)
    }
}

#[cfg(feature = "sqlite")]
use sqlite::SqliteConnection;

#[cfg(feature = "sqlite")]
impl<T, U> InternalSaveChangesDsl<T, U> for SqliteConnection
where
    T: Copy + Identifiable,
    T: AsChangeset<Target = <T as HasTable>::Table> + IntoUpdateTarget,
    T::Table: FindDsl<T::Id>,
    Update<T, T>: ExecuteDsl<SqliteConnection>,
    Find<T::Table, T::Id>: LoadQuery<SqliteConnection, U>,
{
    fn internal_save_changes(&self, changeset: T) -> QueryResult<U> {
        try!(::update(changeset).set(changeset).execute(self));
        T::table().find(changeset.id()).get_result(self)
    }
}

#[cfg(feature = "mysql")]
use mysql::MysqlConnection;

#[cfg(feature = "mysql")]
impl<T, U> InternalSaveChangesDsl<T, U> for MysqlConnection
where
    T: Copy + Identifiable,
    T: AsChangeset<Target = <T as HasTable>::Table> + IntoUpdateTarget,
    T::Table: FindDsl<T::Id>,
    Update<T, T>: ExecuteDsl<MysqlConnection>,
    Find<T::Table, T::Id>: LoadQuery<MysqlConnection, U>,
{
    fn internal_save_changes(&self, changeset: T) -> QueryResult<U> {
        try!(::update(changeset).set(changeset).execute(self));
        T::table().find(changeset.id()).get_result(self)
    }
}

/// Sugar for types which implement both `AsChangeset` and `Identifiable`
///
/// On backends which support the `RETURNING` keyword,
/// `foo.save_changes(&conn)` is equivalent to
/// `update(&foo).set(&foo).get_result(&conn)`.
/// On other backends, two queries will be executed.
///
/// # Example
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// # use schema::animals;
/// #
/// #[derive(Queryable, Debug, PartialEq)]
/// struct Animal {
///    id: i32,
///    species: String,
///    legs: i32,
///    name: Option<String>,
/// }
///
/// #[derive(AsChangeset, Identifiable)]
/// #[table_name = "animals"]
/// struct AnimalForm<'a> {
///     id: i32,
///     name: &'a str,
/// }
///
/// # fn main() {
/// #     run_test();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// #     use animals::dsl::*;
/// #     let connection = establish_connection();
/// let form = AnimalForm { id: 2, name: "Super scary" };
/// let changed_animal = form.save_changes(&connection)?;
/// let expected_animal = Animal {
///     id: 2,
///     species: String::from("spider"),
///     legs: 8,
///     name: Some(String::from("Super scary")),
/// };
/// assert_eq!(expected_animal, changed_animal);
/// #     Ok(())
/// # }
/// ```
pub trait SaveChangesDsl<Conn>: Sized {
    /// See the trait documentation.
    fn save_changes<T>(self, connection: &Conn) -> QueryResult<T>
    where
        Conn: InternalSaveChangesDsl<Self, T>,
    {
        connection.internal_save_changes(self)
    }
}

impl<T, Conn> SaveChangesDsl<Conn> for T
where
    T: Copy + AsChangeset<Target = <T as HasTable>::Table> + IntoUpdateTarget,
{
}
<commit_msg>Move Sized bound to method<commit_after>use associations::HasTable;
#[cfg(any(feature = "sqlite", feature = "mysql"))]
use associations::Identifiable;
#[cfg(any(feature = "sqlite", feature = "mysql"))]
use dsl::Find;
#[cfg(any(feature = "sqlite", feature = "postgres", feature = "mysql"))]
use dsl::Update;
use query_builder::{AsChangeset, IntoUpdateTarget};
#[cfg(any(feature = "sqlite", feature = "mysql"))]
use query_dsl::methods::{ExecuteDsl, FindDsl};
#[cfg(any(feature = "sqlite", feature = "postgres", feature = "mysql"))]
use query_dsl::{LoadQuery, RunQueryDsl};
use result::QueryResult;

#[doc(hidden)]
pub trait InternalSaveChangesDsl<T, U> {
    fn internal_save_changes(&self, changeset: T) -> QueryResult<U>;
}

#[cfg(feature = "postgres")]
use pg::PgConnection;

#[cfg(feature = "postgres")]
impl<T, U> InternalSaveChangesDsl<T, U> for PgConnection
where
    T: Copy + AsChangeset<Target = <T as HasTable>::Table> + IntoUpdateTarget,
    Update<T, T>: LoadQuery<PgConnection, U>,
{
    fn internal_save_changes(&self, changeset: T) -> QueryResult<U> {
        ::update(changeset).set(changeset).get_result(self)
    }
}

#[cfg(feature = "sqlite")]
use sqlite::SqliteConnection;

#[cfg(feature = "sqlite")]
impl<T, U> InternalSaveChangesDsl<T, U> for SqliteConnection
where
    T: Copy + Identifiable,
    T: AsChangeset<Target = <T as HasTable>::Table> + IntoUpdateTarget,
    T::Table: FindDsl<T::Id>,
    Update<T, T>: ExecuteDsl<SqliteConnection>,
    Find<T::Table, T::Id>: LoadQuery<SqliteConnection, U>,
{
    fn internal_save_changes(&self, changeset: T) -> QueryResult<U> {
        try!(::update(changeset).set(changeset).execute(self));
        T::table().find(changeset.id()).get_result(self)
    }
}

#[cfg(feature = "mysql")]
use mysql::MysqlConnection;

#[cfg(feature = "mysql")]
impl<T, U> InternalSaveChangesDsl<T, U> for MysqlConnection
where
    T: Copy + Identifiable,
    T: AsChangeset<Target = <T as HasTable>::Table> + IntoUpdateTarget,
    T::Table: FindDsl<T::Id>,
    Update<T, T>: ExecuteDsl<MysqlConnection>,
    Find<T::Table, T::Id>: LoadQuery<MysqlConnection, U>,
{
    fn internal_save_changes(&self, changeset: T) -> QueryResult<U> {
        try!(::update(changeset).set(changeset).execute(self));
        T::table().find(changeset.id()).get_result(self)
    }
}

/// Sugar for types which implement both `AsChangeset` and `Identifiable`
///
/// On backends which support the `RETURNING` keyword,
/// `foo.save_changes(&conn)` is equivalent to
/// `update(&foo).set(&foo).get_result(&conn)`.
/// On other backends, two queries will be executed.
///
/// # Example
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// # use schema::animals;
/// #
/// #[derive(Queryable, Debug, PartialEq)]
/// struct Animal {
///    id: i32,
///    species: String,
///    legs: i32,
///    name: Option<String>,
/// }
///
/// #[derive(AsChangeset, Identifiable)]
/// #[table_name = "animals"]
/// struct AnimalForm<'a> {
///     id: i32,
///     name: &'a str,
/// }
///
/// # fn main() {
/// #     run_test();
/// # }
/// #
/// # fn run_test() -> QueryResult<()> {
/// #     use animals::dsl::*;
/// #     let connection = establish_connection();
/// let form = AnimalForm { id: 2, name: "Super scary" };
/// let changed_animal = form.save_changes(&connection)?;
/// let expected_animal = Animal {
///     id: 2,
///     species: String::from("spider"),
///     legs: 8,
///     name: Some(String::from("Super scary")),
/// };
/// assert_eq!(expected_animal, changed_animal);
/// #     Ok(())
/// # }
/// ```
pub trait SaveChangesDsl<Conn> {
    /// See the trait documentation.
    fn save_changes<T>(self, connection: &Conn) -> QueryResult<T>
    where
        Self: Sized,
        Conn: InternalSaveChangesDsl<Self, T>,
    {
        connection.internal_save_changes(self)
    }
}

impl<T, Conn> SaveChangesDsl<Conn> for T
where
    T: Copy + AsChangeset<Target = <T as HasTable>::Table> + IntoUpdateTarget,
{
}
<|endoftext|>


<commit_before>iface iterable<A> {
    fn iter(blk: fn(A));
}

impl<A> of iterable<A> for fn@(fn(A)) {
    fn iter(blk: fn(A)) {
        self(blk);
    }
}

impl<A> of iterable<A> for [A] {
    fn iter(blk: fn(A)) {
        vec::iter(self, blk)
    }
}

impl<A> of iterable<A> for option<A> {
    fn iter(blk: fn(A)) {
        option::may(self, blk)
    }
}

fn enumerate<A,IA:iterable<A>>(self: IA, blk: fn(uint, A)) {
    let i = 0u;
    self.iter {|a|
        blk(i, a);
        i += 1u;
    }
}

// Here: we have to use fn@ for predicates and map functions, because
// we will be binding them up into a closure.  Disappointing.  A true
// region type system might be able to do better than this.

fn filter<A,IA:iterable<A>>(self: IA, prd: fn@(A) -> bool, blk: fn(A)) {
    self.iter {|a|
        if prd(a) { blk(a) }
    }
}

fn map<A,B,IA:iterable<A>>(self: IA, cnv: fn@(A) -> B, blk: fn(B)) {
    self.iter {|a|
        let b = cnv(a);
        blk(b);
    }
}

fn flat_map<A,B,IA:iterable<A>,IB:iterable<B>>(
    self: IA, cnv: fn@(A) -> IB, blk: fn(B)) {
    self.iter {|a|
        cnv(a).iter(blk)
    }
}

fn foldl<A,B:copy,IA:iterable<A>>(self: IA, b0: B, blk: fn(B, A) -> B) -> B {
    let b = b0;
    self.iter {|a|
        b = blk(b, a);
    }
    ret b;
}

fn to_list<A:copy,IA:iterable<A>>(self: IA) -> [A] {
    foldl::<A,[A],IA>(self, [], {|r, a| r + [a]})
}

#[test]
fn test_enumerate() {
    enumerate(bind vec::iter([0u, 1u, 2u], _)) {|i,j|
        assert i == j;
    }
}

#[test]
fn test_map_and_to_list() {
    let a = bind vec::iter([0, 1, 2], _);
    let b = bind map(a, {|i| i*2}, _);
    let c = to_list(b);
    assert c == [0, 2, 4];
}

#[test]
fn test_flat_map_with_option() {
    fn if_even(&&i: int) -> option<int> {
        if (i % 2) == 0 { some(i) }
        else { none }
    }

    let a = bind vec::iter([0, 1, 2], _);
    let b = bind flat_map(a, if_even, _);
    let c = to_list(b);
    assert c == [0, 2];
}

#[test]
fn test_flat_map_with_list() {
    fn repeat(&&i: int) -> [int] {
        let r = [];
        int::range(0, i) {|_j| r += [i]; }
        r
    }

    let a = bind vec::iter([0, 1, 2, 3], _);
    let b = bind flat_map(a, repeat, _);
    let c = to_list(b);
    #debug["c = %?", c];
    assert c == [1, 2, 2, 3, 3, 3];
}<commit_msg>Add fn repeat(times: uint, blk: fn(uint))<commit_after>iface iterable<A> {
    fn iter(blk: fn(A));
}

impl<A> of iterable<A> for fn@(fn(A)) {
    fn iter(blk: fn(A)) {
        self(blk);
    }
}

impl<A> of iterable<A> for [A] {
    fn iter(blk: fn(A)) {
        vec::iter(self, blk)
    }
}

impl<A> of iterable<A> for option<A> {
    fn iter(blk: fn(A)) {
        option::may(self, blk)
    }
}

fn enumerate<A,IA:iterable<A>>(self: IA, blk: fn(uint, A)) {
    let i = 0u;
    self.iter {|a|
        blk(i, a);
        i += 1u;
    }
}

// Here: we have to use fn@ for predicates and map functions, because
// we will be binding them up into a closure.  Disappointing.  A true
// region type system might be able to do better than this.

fn filter<A,IA:iterable<A>>(self: IA, prd: fn@(A) -> bool, blk: fn(A)) {
    self.iter {|a|
        if prd(a) { blk(a) }
    }
}

fn map<A,B,IA:iterable<A>>(self: IA, cnv: fn@(A) -> B, blk: fn(B)) {
    self.iter {|a|
        let b = cnv(a);
        blk(b);
    }
}

fn flat_map<A,B,IA:iterable<A>,IB:iterable<B>>(
    self: IA, cnv: fn@(A) -> IB, blk: fn(B)) {
    self.iter {|a|
        cnv(a).iter(blk)
    }
}

fn foldl<A,B:copy,IA:iterable<A>>(self: IA, b0: B, blk: fn(B, A) -> B) -> B {
    let b = b0;
    self.iter {|a|
        b = blk(b, a);
    }
    ret b;
}

fn to_list<A:copy,IA:iterable<A>>(self: IA) -> [A] {
    foldl::<A,[A],IA>(self, [], {|r, a| r + [a]})
}

fn repeat(times: uint, blk: fn(uint)) {
    let i = 0u;
    while i < times {
        blk(i);
        i += 1u;
    }
}

#[test]
fn test_enumerate() {
    enumerate(bind vec::iter([0u, 1u, 2u], _)) {|i,j|
        assert i == j;
    }
}

#[test]
fn test_map_and_to_list() {
    let a = bind vec::iter([0, 1, 2], _);
    let b = bind map(a, {|i| i*2}, _);
    let c = to_list(b);
    assert c == [0, 2, 4];
}

#[test]
fn test_flat_map_with_option() {
    fn if_even(&&i: int) -> option<int> {
        if (i % 2) == 0 { some(i) }
        else { none }
    }

    let a = bind vec::iter([0, 1, 2], _);
    let b = bind flat_map(a, if_even, _);
    let c = to_list(b);
    assert c == [0, 2];
}

#[test]
fn test_flat_map_with_list() {
    fn repeat(&&i: int) -> [int] {
        let r = [];
        int::range(0, i) {|_j| r += [i]; }
        r
    }

    let a = bind vec::iter([0, 1, 2, 3], _);
    let b = bind flat_map(a, repeat, _);
    let c = to_list(b);
    #debug["c = %?", c];
    assert c == [1, 2, 2, 3, 3, 3];
}

#[test]
fn test_repeat() {
    let c = [];
    repeat(5u) {|i|
        c += [(i * 2u)];
    };
    #debug["c = %?", c];
    assert c == [0u, 2u, 4u, 6u, 8u];
}

<|endoftext|>


<commit_before>// vim: tw=80
#![cfg_attr(feature = "nightly-docs", feature(doc_cfg))]

//! Examples of mock objects and their generated methods.
//!
//! This crate only exists to document the autogenerated methods of the
//! [`Mockall`] crate.  You should never use this crate directly.
//!
//! [`Mockall`]: ../mockall/index.html
//

#[cfg(all(feature = "nightly-docs", rustdoc))]
use mockall::*;

#[cfg(all(feature = "nightly-docs", rustdoc))]
#[automock]
pub trait Foo {
    /// A method with a `'static` return type
    fn foo(&self, x: i32, y: i16) -> i32;
}
<commit_msg>More examples<commit_after>// vim: tw=80
#![cfg_attr(feature = "nightly-docs", feature(doc_cfg))]

//! Examples of mock objects and their generated methods.
//!
//! This crate only exists to document the autogenerated methods of the
//! [`Mockall`] crate.  You should never use this crate directly.
//!
//! [`Mockall`]: ../mockall/index.html
//

#[cfg(all(feature = "nightly-docs", rustdoc))]
use mockall::*;

#[cfg(all(feature = "nightly-docs", rustdoc))]
#[automock]
pub trait Foo {
    /// A method with a `'static` return type
    fn foo(&self, x: i32, y: i16) -> i32;

    /// A method returning a reference
    fn bar(&self, x: i32) -> &i32;

    /// A method returning a mutable reference
    fn baz(&mut self, x: i32) -> &mut i32;

    /// A method returning a `'static` reference
    fn bean(&self) -> &'static i32;

    /// A static method
    fn bang(x: i32) -> i32;
}

#[cfg(all(feature = "nightly-docs", rustdoc))]
#[automock(mod mock_ffi;)]
extern "C" {
    /// A foreign "C" function
    pub fn ffi_func();
}
<|endoftext|>


<commit_before>macro_rules! run_find_test {
    ( $db:expr, $coll:expr, $filter:expr, $opt:expr, $outcome:expr ) => {{
        let mut cursor = $coll.find($filter, $opt).unwrap();

        let array = match $outcome.result {
            Bson::Array(ref arr) => arr.clone(),
            _ => panic!("Invalid `result` of find test")
        };

        for bson in array {
            assert!(eq::bson_eq(&bson, &Bson::Document(cursor.next().unwrap())));
        }

        assert!(!cursor.has_next());
        check_coll!($db, $coll, $outcome.collection);
    }};
}

macro_rules! run_insert_many_test {
    ( $db:expr, $coll: expr, $docs:expr, $outcome:expr) => {{
        let inserted = $coll.insert_many($docs, true, None).unwrap().inserted_ids.unwrap();
        let ids_bson = match $outcome.result {
            Bson::Document(ref doc) => doc.get("insertedIds").unwrap(),
            _ => panic!("`insert_one` test result should be a document")
        };

        let ids = match ids_bson {
            &Bson::Array(ref arr) => arr.into_iter(),
            _ => panic!("`insertedIds` test result should be an array")
        };

        let mut actual_ids = inserted.values();

        for expected_id in ids {
            assert!(eq::bson_eq(&expected_id, actual_ids.next().unwrap()));
        }

        check_coll!($db, $coll, $outcome.collection);
    }};
}

macro_rules! run_insert_one_test {
    ( $db:expr, $coll: expr, $doc:expr, $outcome:expr) => {{
        let inserted = $coll.insert_one($doc, None).unwrap().inserted_id.unwrap();
        let id = match $outcome.result {
            Bson::Document(ref doc) => doc.get("insertedId").unwrap(),
            _ => panic!("`insert_one` test result should be a document")
        };

        assert!(eq::bson_eq(&id, &inserted));
        check_coll!($db, $coll, $outcome.collection);
    }};
}

macro_rules! run_delete_test {
    ( $db:expr, $coll: expr, $filter:expr, $outcome:expr, $many:expr) => {{
        let count = if $many {
                        $coll.delete_many($filter, None)
                    } else {
                        $coll.delete_one($filter, None)
                    };

        let expected = count.unwrap().deleted_count;

        let actual = match $outcome.result {
            Bson::Document(ref doc) => doc.get("deletedCount").unwrap(),
            _ => panic!("`insert_one` test result should be a document")
        };

        assert!(actual.int_eq(expected as i64));
        check_coll!($db, $coll, $outcome.collection);
    }};
}

#[macro_export]
macro_rules! run_suite {
    ( $file:expr, $coll:expr ) => {{
        let json = Json::from_file($file).unwrap();
        let suite = json.get_suite().unwrap();
        let client =  MongoClient::new("localhost", 27017).unwrap();
        let db = client.db("test");
        let coll = db.collection($coll);

        for test in suite.tests {
            coll.drop().unwrap();
            coll.insert_many(suite.data.clone(), true, None).unwrap();

            match test.operation {
                Arguments::Delete { filter, many } =>
                    run_delete_test!(db, coll, filter, test.outcome, many),
                Arguments::Find { filter, options } =>
                    run_find_test!(db, coll, filter, Some(options), test.outcome),
                Arguments::InsertMany { documents } =>
                    run_insert_many_test!(db, coll, documents, test.outcome),
                Arguments::InsertOne { document } =>
                    run_insert_one_test!(db, coll, document, test.outcome),
            };
        }
    }};
}

#[macro_export]
macro_rules! check_coll {
    ( $db:expr, $coll:expr, $coll_opt:expr) => {{
        let outcome_coll = match $coll_opt {
            Some(ref coll) => coll.clone(),
            None => return
        };

        let coll = match outcome_coll.name {
            Some(ref str) => $db.collection(&str),
            None => $db.collection(&$coll.name())
        };

        let mut cursor = coll.find(None, None).unwrap();

        for doc in outcome_coll.data.iter() {
            assert!(eq::bson_eq(&Bson::Document(doc.clone()),
                                &Bson::Document(cursor.next().unwrap())));
        }

        assert!(!cursor.has_next());
    }};
}
<commit_msg>fixed improper naming<commit_after>macro_rules! run_find_test {
    ( $db:expr, $coll:expr, $filter:expr, $opt:expr, $outcome:expr ) => {{
        let mut cursor = $coll.find($filter, $opt).unwrap();

        let array = match $outcome.result {
            Bson::Array(ref arr) => arr.clone(),
            _ => panic!("Invalid `result` of find test")
        };

        for bson in array {
            assert!(eq::bson_eq(&bson, &Bson::Document(cursor.next().unwrap())));
        }

        assert!(!cursor.has_next());
        check_coll!($db, $coll, $outcome.collection);
    }};
}

macro_rules! run_insert_many_test {
    ( $db:expr, $coll: expr, $docs:expr, $outcome:expr) => {{
        let inserted = $coll.insert_many($docs, true, None).unwrap().inserted_ids.unwrap();
        let ids_bson = match $outcome.result {
            Bson::Document(ref doc) => doc.get("insertedIds").unwrap(),
            _ => panic!("`insert_one` test result should be a document")
        };

        let ids = match ids_bson {
            &Bson::Array(ref arr) => arr.into_iter(),
            _ => panic!("`insertedIds` test result should be an array")
        };

        let mut actual_ids = inserted.values();

        for expected_id in ids {
            assert!(eq::bson_eq(&expected_id, actual_ids.next().unwrap()));
        }

        check_coll!($db, $coll, $outcome.collection);
    }};
}

macro_rules! run_insert_one_test {
    ( $db:expr, $coll: expr, $doc:expr, $outcome:expr) => {{
        let inserted = $coll.insert_one($doc, None).unwrap().inserted_id.unwrap();
        let id = match $outcome.result {
            Bson::Document(ref doc) => doc.get("insertedId").unwrap(),
            _ => panic!("`insert_one` test result should be a document")
        };

        assert!(eq::bson_eq(&id, &inserted));
        check_coll!($db, $coll, $outcome.collection);
    }};
}

macro_rules! run_delete_test {
    ( $db:expr, $coll: expr, $filter:expr, $outcome:expr, $many:expr) => {{
        let count = if $many {
                        $coll.delete_many($filter, None)
                    } else {
                        $coll.delete_one($filter, None)
                    };

        let expected = count.unwrap().deleted_count;

        let actual = match $outcome.result {
            Bson::Document(ref doc) => doc.get("deletedCount").unwrap(),
            _ => panic!("`delete` test result should be a document")
        };

        assert!(actual.int_eq(expected as i64));
        check_coll!($db, $coll, $outcome.collection);
    }};
}

#[macro_export]
macro_rules! run_suite {
    ( $file:expr, $coll:expr ) => {{
        let json = Json::from_file($file).unwrap();
        let suite = json.get_suite().unwrap();
        let client =  MongoClient::new("localhost", 27017).unwrap();
        let db = client.db("test");
        let coll = db.collection($coll);

        for test in suite.tests {
            coll.drop().unwrap();
            coll.insert_many(suite.data.clone(), true, None).unwrap();

            match test.operation {
                Arguments::Delete { filter, many } =>
                    run_delete_test!(db, coll, filter, test.outcome, many),
                Arguments::Find { filter, options } =>
                    run_find_test!(db, coll, filter, Some(options), test.outcome),
                Arguments::InsertMany { documents } =>
                    run_insert_many_test!(db, coll, documents, test.outcome),
                Arguments::InsertOne { document } =>
                    run_insert_one_test!(db, coll, document, test.outcome),
            };
        }
    }};
}

#[macro_export]
macro_rules! check_coll {
    ( $db:expr, $coll:expr, $coll_opt:expr) => {{
        let outcome_coll = match $coll_opt {
            Some(ref coll) => coll.clone(),
            None => return
        };

        let coll = match outcome_coll.name {
            Some(ref str) => $db.collection(&str),
            None => $db.collection(&$coll.name())
        };

        let mut cursor = coll.find(None, None).unwrap();

        for doc in outcome_coll.data.iter() {
            assert!(eq::bson_eq(&Bson::Document(doc.clone()),
                                &Bson::Document(cursor.next().unwrap())));
        }

        assert!(!cursor.has_next());
    }};
}
<|endoftext|>


<commit_before>use std::str;
use serialize::{Decodable, json};
use request::Request;
use typemap::Key;
use plugin::{Phantom, Plugin, Pluggable};

// Plugin boilerplate
struct JsonBodyParser;
impl Key for JsonBodyParser { type Value = String; }
impl<'a, 'b> Plugin<Request<'a, 'b>> for JsonBodyParser {
    fn eval(req: &mut Request, _: Phantom<JsonBodyParser>) -> Option<String> {
        if !req.origin.body.is_empty() {
            str::from_utf8(&*req.origin.body).ok().map(|s| s.to_string())
        } else {
            None
        }
    }
}

pub trait JsonBody {
    fn json_as<T: Decodable>(&mut self) -> Option<T>;
}

impl<'a, 'b> JsonBody for Request<'a, 'b> {
    fn json_as<T: Decodable>(&mut self) -> Option<T> {
        // FIXME:
        // I think it would be smarter to not return Option<T> but rather
        // DecodeResult<T> to not swallow valuable debugging information.
        // I couldn't figure out how to properly do that
        self.get::<JsonBodyParser>().and_then(|parsed| {
            json::decode::<T>(&parsed[]).ok()
        })
    }
}
<commit_msg>fix(json_body_parser): Update to work with latest rust-plugin.<commit_after>use std::str;
use serialize::{Decodable, json};
use request::Request;
use typemap::Key;
use plugin::{Plugin, Pluggable};

// Plugin boilerplate
struct JsonBodyParser;
impl Key for JsonBodyParser { type Value = String; }
impl<'a, 'b> Plugin<Request<'a, 'b>> for JsonBodyParser {
    type Error = &'static str;

    fn eval(req: &mut Request) -> Result<String, &'static str> {
        if !req.origin.body.is_empty() {
            str::from_utf8(&*req.origin.body)
                .map(|s| s.to_string())
                .map_err(|_| "Request body is not utf-8.")
        }
        else {
            Err("Request body is empty.")
        }
    }
}

pub trait JsonBody {
    fn json_as<T: Decodable>(&mut self) -> Option<T>;
}

impl<'a, 'b> JsonBody for Request<'a, 'b> {
    fn json_as<T: Decodable>(&mut self) -> Option<T> {
        // FIXME:
        // I think it would be smarter to not return Option<T> but rather
        // DecodeResult<T> to not swallow valuable debugging information.
        // I couldn't figure out how to properly do that
        self.get::<JsonBodyParser>().and_then(|parsed| {
            json::decode::<T>(&parsed[]).map_err(|_| "Couldn't parse JSON.")
        }).ok()
    }
}
<|endoftext|>


<commit_before>/*!
Library for reading/writing Labeled Tab-Separated Values

# Example

~~~~~~~~~~~~~~~~~~~~~~
extern mod ltsv;
use ltsv::LTSVWriter;
use ltsv::LTSVReader;

fn main() {
    let infile = io::file_reader(&Path("path/fo/file.tlsv")).get();
    for infile.read_ltsv().each |record| {
        for record.each |&(label, value)| {
            io::println(fmt!("%s: %s", *label, *value));
        }
    }
}
~~~~~~~~~~~~~~~~~~~~~~
*/
#[link(name = "ltsv",
       vers = "0.1",
       uuid = "E0EA0251-E165-4612-919F-38E89ACECBE9",
       url  = "https://github.com/tychosci/rust-ltsv/")];

#[comment = "Library for reading/writing Labeled Tab-Separated Values"];
#[license = "MIT license"];
#[crate_type = "lib"];

use core::container::Map;
use core::hashmap::linear::LinearMap;
use io::WriterUtil;

pub type Record = LinearMap<~str, ~str>;

enum Trailing { EOF, NL, TAB }

enum ParseType {
    Record,
    Field,
    FieldLabel,
    FieldValue(Trailing)
}

enum ParseResult<T> {
    ParseError(~str),
    ParseOk(ParseType, T)
}

pub trait LTSVWriter {
    fn write_ltsv(&self, ltsv: &[Record]);
    fn write_ltsv_record(&self, record: &Record);
}

pub trait LTSVReader {
    fn read_ltsv(&self) -> ~[Record];
}

pub impl<T: io::Writer> LTSVWriter for T {
    fn write_ltsv(&self, ltsv: &[Record]) {
        for ltsv.each |record| {
            self.write_ltsv_record(record);
            self.write_char('\n');
        }
    }
    fn write_ltsv_record(&self, record: &Record) {
        let mut is_first = true;
        for record.each |&(k, v)| {
            if !is_first { self.write_char('\t'); }
            self.write_str(fmt!("%s:%s", *k, *v));
            if is_first { is_first = false; }
        }
    }
}

pub impl<T: io::Reader> LTSVReader for T {
    fn read_ltsv(&self) -> ~[Record] {
        let mut parser = LTSVParser::new(self);
        match parser.parse_records() {
            ParseOk(_, records) => records,
            ParseError(reason) => die!(reason)
        }
    }
}

struct LTSVParser<T> {
    priv rd: &T,
    priv cur: int
}

impl<T: io::Reader> LTSVParser<T> {
    static fn new(rd: &r/T) -> LTSVParser/&r<T> {
        let cur = rd.read_byte();
        LTSVParser { rd: rd, cur: cur }
    }

    fn bump(&mut self) {
        if self.cur != -1 {
            self.cur = self.rd.read_byte();
        }
    }

    fn parse_records(&mut self) -> ParseResult<~[Record]> {
        let mut records = ~[];
        loop {
            match self.parse_fields() {
                ParseOk(_, record) => {
                    records.push(record);
                    if self.cur == -1 { break; }
                }
                ParseError(reason) => {
                    return ParseError(reason);
                }
            }
        }
        ParseOk(Record, records)
    }

    fn parse_fields(&mut self) -> ParseResult<Record> {
        let mut record = LinearMap::new();
        self.skip_whitespaces();
        loop {
            let label = match self.parse_field_label() {
                ParseOk(_, label)  => { self.bump(); label },
                ParseError(reason) => return ParseError(reason)
            };
            match self.parse_field_value() {
                ParseOk(FieldValue(TAB), value) => {
                    self.bump();
                    self.skip_whitespaces();
                    record.insert(label, value);
                }
                ParseOk(_, value) => {
                    self.bump();
                    self.skip_whitespaces();
                    record.insert(label, value);
                    return ParseOk(Field, record);
                }
                ParseError(reason) => {
                    return ParseError(reason);
                }
            }
        }
    }

    fn parse_field_label(&mut self) -> ParseResult<~str> {
        let mut bytes = ~[];
        loop {
            match self.cur {
                0x30..0x39 | 0x41..0x5a | 0x61..0x7a | 0x5f |
                0x2e | 0x2d => bytes.push(self.cur as u8),
                0x3a if bytes.len() == 0 => return ParseError(~"label is empty"),
                0x3a => return ParseOk(FieldLabel, str::from_bytes(bytes)),
                -1   => return ParseError(~"EOF while parsing field label"),
                _    => return ParseError(~"invalid byte detected")
            }
            self.bump();
        }
    }

    fn parse_field_value(&mut self) -> ParseResult<~str> {
        let mut bytes = ~[];
        loop {
            match self.cur {
                0x01..0x08 | 0x0b | 0x0c |
                0x0e..0xff => bytes.push(self.cur as u8),
                0x0d => return self.consume_forward_LF(str::from_bytes(bytes)),
                0x0a => return ParseOk(FieldValue(NL), str::from_bytes(bytes)),
                0x09 => return ParseOk(FieldValue(TAB), str::from_bytes(bytes)),
                -1   => return ParseOk(FieldValue(EOF), str::from_bytes(bytes)),
                _    => return ParseError(~"invalid byte detected")
            }
            self.bump();
        }
    }

    fn consume_forward_LF(&mut self, rv: ~str) -> ParseResult<~str> {
        self.bump();
        if self.cur != 0x0a {
            ParseError(~"CR detected, but not provided with LF")
        } else {
            ParseOk(FieldValue(NL), rv)
        }
    }

    fn skip_whitespaces(&mut self) {
        while char::is_whitespace(self.cur as char) {
            self.bump();
        }
    }
}

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

    #[test]
    fn test_parse_simple() {
        let records = io::with_str_reader(~"a:1\tb:2", |rd| rd.read_ltsv());
        assert records.len() == 1;
    }

    #[test]
    fn test_parse_full() {
        let s = io::with_str_writer(|wr| {
            // genzairyou
            wr.write_str(fmt!("%s:%s\t", "tofu", "豆"));
            wr.write_str(fmt!("%s:%s\t", "kamaboko", "魚"));
            wr.write_str(fmt!("%s:%s\n", "sukonbu", "海藻"));
            // konomi
            wr.write_str(fmt!("%s:%s\t", "tofu", "好き"));
            wr.write_str(fmt!("%s:%s\t", "kamaboko", "普通"));
            wr.write_str(fmt!("%s:%s\n", "sukonbu", "苦手"));
        });
        let records = io::with_str_reader(s, |rd| rd.read_ltsv());
        assert records.len() == 2;
    }

    #[test]
    fn test_parse_ltsv_trailing_nl_and_write() {
        let s = io::with_str_writer(|wr| {
            wr.write_str(fmt!("%s:%s\t", "neko", "yes"));
            wr.write_str(fmt!("%s:%s\t", "inu", "yes"));
            wr.write_str(fmt!("%s:%s\n", "tori", "yes"));
        });
        let records_1 = io::with_str_reader(s, |rd| rd.read_ltsv());
        let s2 = io::with_str_writer(|wr| wr.write_ltsv(records_1));
        let records_2 = io::with_str_reader(s2, |rd| rd.read_ltsv());
        assert records_1 == records_2;
    }
}
<commit_msg>Refactoring, Code cleanup, etc.<commit_after>/*!
Library for reading/writing Labeled Tab-Separated Values

# Example

~~~~~~~~~~~~~~~~~~~~~~
extern mod ltsv;
use ltsv::LTSVWriter;
use ltsv::LTSVReader;

fn main() {
    let infile = io::file_reader(&Path("path/fo/file.tlsv")).get();
    for infile.read_ltsv().each |record| {
        for record.each |&(label, value)| {
            io::println(fmt!("%s: %s", *label, *value));
        }
    }
}
~~~~~~~~~~~~~~~~~~~~~~
*/
#[link(name = "ltsv",
       vers = "0.1",
       uuid = "E0EA0251-E165-4612-919F-38E89ACECBE9",
       url  = "https://github.com/tychosci/rust-ltsv/")];

#[comment = "Library for reading/writing Labeled Tab-Separated Values"];
#[license = "MIT license"];
#[crate_type = "lib"];

use core::container::Map;
use core::hashmap::linear::LinearMap;
use io::WriterUtil;

pub type Record = LinearMap<~str, ~str>;

enum ParseType {
    FieldLabel,
    FieldValue,
    Field,
    Record,
    Ltsv
}

enum ParseResult<T> {
    ParseError(~str),
    ParseOk(ParseType, T)
}

pub trait LTSVWriter {
    fn write_ltsv(&self, ltsv: &[Record]);
    fn write_ltsv_record(&self, record: &Record);
}

pub trait LTSVReader {
    fn read_ltsv(&self) -> ~[Record];
    fn each_ltsv_record(&self, f: &fn(&Record) -> bool);
    fn each_ltsv_field(&self, f: &fn(&(~str, ~str)) -> bool);
}

pub impl<T: io::Writer> LTSVWriter for T {
    fn write_ltsv(&self, ltsv: &[Record]) {
        for ltsv.each |record| {
            self.write_ltsv_record(record);
            self.write_char('\n');
        }
    }
    fn write_ltsv_record(&self, record: &Record) {
        let mut is_first = true;
        for record.each |&(k, v)| {
            if !is_first { self.write_char('\t'); }
            self.write_str(fmt!("%s:%s", *k, *v));
            if is_first { is_first = false; }
        }
    }
}

pub impl<T: io::Reader> LTSVReader for T {
    fn read_ltsv(&self) -> ~[Record] {
        let mut parser = LTSVParser::new(self);
        match parser.parse_ltsv() {
            ParseOk(_, records) => records,
            ParseError(reason) => die!(reason)
        }
    }
    fn each_ltsv_record(&self, f: &fn(&Record) -> bool) {
        let mut parser = LTSVParser::new(self);
        while !parser.eof() {
            match parser.parse_record() {
                ParseOk(_, record) => if !f(&record) { break; },
                ParseError(reason) => die!(reason)
            }
        }
    }
    fn each_ltsv_field(&self, f: &fn(&(~str, ~str)) -> bool) {
        let mut parser = LTSVParser::new(self);
        while !parser.eof() {
            match parser.parse_field() {
                ParseOk(_, field)  => if !f(&field) { break; },
                ParseError(reason) => die!(reason)
            }
        }
    }
}

struct LTSVParser<T> {
    priv rd: &T,
    priv cur: int
}

impl<T: io::Reader> LTSVParser<T> {
    static fn new(rd: &r/T) -> LTSVParser/&r<T> {
        let cur = rd.read_byte();
        LTSVParser { rd: rd, cur: cur }
    }

    fn eof(&self) -> bool { self.cur == -1 }

    fn bump(&mut self) {
        if !self.eof() {
            self.cur = self.rd.read_byte();
        }
    }

    fn parse_ltsv(&mut self) -> ParseResult<~[Record]> {
        let mut records = ~[];
        loop {
            match self.parse_record() {
                ParseOk(_, record) => {
                    records.push(record);
                    if self.eof() { break; }
                }
                ParseError(reason) => {
                    return ParseError(reason);
                }
            }
        }
        ParseOk(Ltsv, records)
    }

    fn parse_record(&mut self) -> ParseResult<Record> {
        let mut record = LinearMap::new();
        self.skip_whitespaces();
        loop {
            match self.parse_field() {
                ParseOk(_, (label, value)) => {
                    let saved_cur = self.cur;
                    self.bump();
                    record.insert(label, value);
                    if saved_cur == 0xa || saved_cur == -1 {
                        self.skip_whitespaces();
                        return ParseOk(Record, record);
                    }
                }
                ParseError(reason) => {
                    return ParseError(reason);
                }
            }
        }
    }

    fn parse_field(&mut self) -> ParseResult<(~str, ~str)> {
        let label = match self.parse_field_label() {
            ParseOk(_, label)  => { self.bump(); label },
            ParseError(reason) => return ParseError(reason)
        };
        match self.parse_field_value() {
            ParseOk(_, value) => {
                ParseOk(Field, (label, value))
            }
            ParseError(reason) => {
                ParseError(reason)
            }
        }
    }

    fn parse_field_label(&mut self) -> ParseResult<~str> {
        let mut bytes = ~[];
        loop {
            match self.cur {
                0x30..0x39 | 0x41..0x5a | 0x61..0x7a | 0x5f |
                0x2e | 0x2d => bytes.push(self.cur as u8),
                0x3a if bytes.len() == 0 => return ParseError(~"label is empty"),
                0x3a => return ParseOk(FieldLabel, str::from_bytes(bytes)),
                -1   => return ParseError(~"EOF while parsing field label"),
                _    => return ParseError(~"invalid byte detected")
            }
            self.bump();
        }
    }

    fn parse_field_value(&mut self) -> ParseResult<~str> {
        let mut bytes = ~[];
        loop {
            match self.cur {
                0x01..0x08 | 0x0b | 0x0c |
                0x0e..0xff => bytes.push(self.cur as u8),
                0x0d => return self.consume_forward_LF(str::from_bytes(bytes)),
                0x0a => return ParseOk(FieldValue, str::from_bytes(bytes)),
                0x09 => return ParseOk(FieldValue, str::from_bytes(bytes)),
                -1   => return ParseOk(FieldValue, str::from_bytes(bytes)),
                _    => return ParseError(~"invalid byte detected")
            }
            self.bump();
        }
    }

    fn consume_forward_LF(&mut self, rv: ~str) -> ParseResult<~str> {
        self.bump();
        if self.cur != 0x0a {
            ParseError(~"CR detected, but not provided with LF")
        } else {
            ParseOk(FieldValue, rv)
        }
    }

    fn skip_whitespaces(&mut self) {
        while char::is_whitespace(self.cur as char) {
            self.bump();
        }
    }
}

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

    #[test]
    fn test_parse_simple() {
        let records = io::with_str_reader(~"a:1\tb:2", |rd| rd.read_ltsv());
        assert records.len() == 1;
    }

    #[test]
    fn test_parse_full() {
        let s = io::with_str_writer(|wr| {
            // genzairyou
            wr.write_str(fmt!("%s:%s\t", "tofu", "豆"));
            wr.write_str(fmt!("%s:%s\t", "kamaboko", "魚"));
            wr.write_str(fmt!("%s:%s\n", "sukonbu", "海藻"));
            // konomi
            wr.write_str(fmt!("%s:%s\t", "tofu", "好き"));
            wr.write_str(fmt!("%s:%s\t", "kamaboko", "普通"));
            wr.write_str(fmt!("%s:%s\n", "sukonbu", "苦手"));
        });
        let records = io::with_str_reader(s, |rd| rd.read_ltsv());
        assert records.len() == 2;
    }

    #[test]
    fn test_parse_ltsv_trailing_nl_and_write() {
        let s = io::with_str_writer(|wr| {
            wr.write_str(fmt!("%s:%s\t", "neko", "yes"));
            wr.write_str(fmt!("%s:%s\t", "inu", "yes"));
            wr.write_str(fmt!("%s:%s\n", "tori", "yes"));
        });
        let records_1 = io::with_str_reader(s, |rd| rd.read_ltsv());
        let s2 = io::with_str_writer(|wr| wr.write_ltsv(records_1));
        let records_2 = io::with_str_reader(s2, |rd| rd.read_ltsv());
        assert records_1 == records_2;
    }
}
<|endoftext|>


<commit_before>use crate::loom::{sync::atomic::AtomicUsize, sync::CausalCell};

use std::fmt;
use std::sync::atomic::Ordering::{AcqRel, Acquire, Release};
use std::task::Waker;

/// A synchronization primitive for task waking.
///
/// `AtomicWaker` will coordinate concurrent wakes with the consumer
/// potentially "waking" the underlying task. This is useful in scenarios
/// where a computation completes in another thread and wants to wake the
/// consumer, but the consumer is in the process of being migrated to a new
/// logical task.
///
/// Consumers should call `register` before checking the result of a computation
/// and producers should call `wake` after producing the computation (this
/// differs from the usual `thread::park` pattern). It is also permitted for
/// `wake` to be called **before** `register`. This results in a no-op.
///
/// A single `AtomicWaker` may be reused for any number of calls to `register` or
/// `wake`.
pub struct AtomicWaker {
    state: AtomicUsize,
    waker: CausalCell<Option<Waker>>,
}

// `AtomicWaker` is a multi-consumer, single-producer transfer cell. The cell
// stores a `Waker` value produced by calls to `register` and many threads can
// race to take the waker by calling `wake.
//
// If a new `Waker` instance is produced by calling `register` before an existing
// one is consumed, then the existing one is overwritten.
//
// While `AtomicWaker` is single-producer, the implementation ensures memory
// safety. In the event of concurrent calls to `register`, there will be a
// single winner whose waker will get stored in the cell. The losers will not
// have their tasks woken. As such, callers should ensure to add synchronization
// to calls to `register`.
//
// The implementation uses a single `AtomicUsize` value to coordinate access to
// the `Waker` cell. There are two bits that are operated on independently. These
// are represented by `REGISTERING` and `WAKING`.
//
// The `REGISTERING` bit is set when a producer enters the critical section. The
// `WAKING` bit is set when a consumer enters the critical section. Neither
// bit being set is represented by `WAITING`.
//
// A thread obtains an exclusive lock on the waker cell by transitioning the
// state from `WAITING` to `REGISTERING` or `WAKING`, depending on the
// operation the thread wishes to perform. When this transition is made, it is
// guaranteed that no other thread will access the waker cell.
//
// # Registering
//
// On a call to `register`, an attempt to transition the state from WAITING to
// REGISTERING is made. On success, the caller obtains a lock on the waker cell.
//
// If the lock is obtained, then the thread sets the waker cell to the waker
// provided as an argument. Then it attempts to transition the state back from
// `REGISTERING` -> `WAITING`.
//
// If this transition is successful, then the registering process is complete
// and the next call to `wake` will observe the waker.
//
// If the transition fails, then there was a concurrent call to `wake` that
// was unable to access the waker cell (due to the registering thread holding the
// lock). To handle this, the registering thread removes the waker it just set
// from the cell and calls `wake` on it. This call to wake represents the
// attempt to wake by the other thread (that set the `WAKING` bit). The
// state is then transitioned from `REGISTERING | WAKING` back to `WAITING`.
// This transition must succeed because, at this point, the state cannot be
// transitioned by another thread.
//
// # Waking
//
// On a call to `wake`, an attempt to transition the state from `WAITING` to
// `WAKING` is made. On success, the caller obtains a lock on the waker cell.
//
// If the lock is obtained, then the thread takes ownership of the current value
// in the waker cell, and calls `wake` on it. The state is then transitioned
// back to `WAITING`. This transition must succeed as, at this point, the state
// cannot be transitioned by another thread.
//
// If the thread is unable to obtain the lock, the `WAKING` bit is still.
// This is because it has either been set by the current thread but the previous
// value included the `REGISTERING` bit **or** a concurrent thread is in the
// `WAKING` critical section. Either way, no action must be taken.
//
// If the current thread is the only concurrent call to `wake` and another
// thread is in the `register` critical section, when the other thread **exits**
// the `register` critical section, it will observe the `WAKING` bit and
// handle the waker itself.
//
// If another thread is in the `waker` critical section, then it will handle
// waking the caller task.
//
// # A potential race (is safely handled).
//
// Imagine the following situation:
//
// * Thread A obtains the `wake` lock and wakes a task.
//
// * Before thread A releases the `wake` lock, the woken task is scheduled.
//
// * Thread B attempts to wake the task. In theory this should result in the
//   task being woken, but it cannot because thread A still holds the wake
//   lock.
//
// This case is handled by requiring users of `AtomicWaker` to call `register`
// **before** attempting to observe the application state change that resulted
// in the task being woken. The wakers also change the application state
// before calling wake.
//
// Because of this, the task will do one of two things.
//
// 1) Observe the application state change that Thread B is waking on. In
//    this case, it is OK for Thread B's wake to be lost.
//
// 2) Call register before attempting to observe the application state. Since
//    Thread A still holds the `wake` lock, the call to `register` will result
//    in the task waking itself and get scheduled again.

/// Idle state
const WAITING: usize = 0;

/// A new waker value is being registered with the `AtomicWaker` cell.
const REGISTERING: usize = 0b01;

/// The task currently registered with the `AtomicWaker` cell is being woken.
const WAKING: usize = 0b10;

impl AtomicWaker {
    /// Create an `AtomicWaker`
    pub fn new() -> AtomicWaker {
        AtomicWaker {
            state: AtomicUsize::new(WAITING),
            waker: CausalCell::new(None),
        }
    }

    /// Registers the current waker to be notified on calls to `wake`.
    ///
    /// This is the same as calling `register_task` with `task::current()`.
    pub fn register(&self, waker: Waker) {
        self.do_register(waker);
    }

    /// Registers the provided waker to be notified on calls to `wake`.
    ///
    /// The new waker will take place of any previous wakers that were registered
    /// by previous calls to `register`. Any calls to `wake` that happen after
    /// a call to `register` (as defined by the memory ordering rules), will
    /// wake the `register` caller's task.
    ///
    /// It is safe to call `register` with multiple other threads concurrently
    /// calling `wake`. This will result in the `register` caller's current
    /// task being woken once.
    ///
    /// This function is safe to call concurrently, but this is generally a bad
    /// idea. Concurrent calls to `register` will attempt to register different
    /// tasks to be woken. One of the callers will win and have its task set,
    /// but there is no guarantee as to which caller will succeed.
    pub fn register_by_ref(&self, waker: &Waker) {
        self.do_register(waker);
    }

    fn do_register<W>(&self, waker: W)
    where
        W: WakerRef,
    {
        debug!(" + register_task");
        match self.state.compare_and_swap(WAITING, REGISTERING, Acquire) {
            WAITING => {
                unsafe {
                    // Locked acquired, update the waker cell
                    self.waker.with_mut(|t| *t = Some(waker.into_waker()));

                    // Release the lock. If the state transitioned to include
                    // the `WAKING` bit, this means that a wake has been
                    // called concurrently, so we have to remove the waker and
                    // wake it.`
                    //
                    // Start by assuming that the state is `REGISTERING` as this
                    // is what we jut set it to.
                    let res = self
                        .state
                        .compare_exchange(REGISTERING, WAITING, AcqRel, Acquire);

                    match res {
                        Ok(_) => {}
                        Err(actual) => {
                            // This branch can only be reached if a
                            // concurrent thread called `wake`. In this
                            // case, `actual` **must** be `REGISTERING |
                            // `WAKING`.
                            debug_assert_eq!(actual, REGISTERING | WAKING);

                            // Take the waker to wake once the atomic operation has
                            // completed.
                            let waker = self.waker.with_mut(|t| (*t).take()).unwrap();

                            // Just swap, because no one could change state
                            // while state == `Registering | `Waking`
                            self.state.swap(WAITING, AcqRel);

                            // The atomic swap was complete, now
                            // wake the waker and return.
                            waker.wake();
                        }
                    }
                }
            }
            WAKING => {
                // Currently in the process of waking the task, i.e.,
                // `wake` is currently being called on the old waker.
                // So, we call wake on the new waker.
                waker.wake();
            }
            state => {
                // In this case, a concurrent thread is holding the
                // "registering" lock. This probably indicates a bug in the
                // caller's code as racing to call `register` doesn't make much
                // sense.
                //
                // We just want to maintain memory safety. It is ok to drop the
                // call to `register`.
                debug_assert!(state == REGISTERING || state == REGISTERING | WAKING);
            }
        }
    }

    /// Wakes the task that last called `register`.
    ///
    /// If `register` has not been called yet, then this does nothing.
    pub fn wake(&self) {
        debug!(" + wake");
        if let Some(waker) = self.take_waker() {
            waker.wake();
        }
    }

    /// Attempts to take the `Waker` value out of the `AtomicWaker` with the
    /// intention that the caller will wake the task later.
    pub fn take_waker(&self) -> Option<Waker> {
        debug!(" + take_waker");
        // AcqRel ordering is used in order to acquire the value of the `waker`
        // cell as well as to establish a `release` ordering with whatever
        // memory the `AtomicWaker` is associated with.
        match self.state.fetch_or(WAKING, AcqRel) {
            WAITING => {
                debug!(" + WAITING");
                // The waking lock has been acquired.
                let waker = unsafe { self.waker.with_mut(|t| (*t).take()) };

                // Release the lock
                self.state.fetch_and(!WAKING, Release);
                debug!(" + Done taking");

                waker
            }
            state => {
                debug!(" + state = {:?}", state);
                // There is a concurrent thread currently updating the
                // associated waker.
                //
                // Nothing more to do as the `WAKING` bit has been set. It
                // doesn't matter if there are concurrent registering threads or
                // not.
                //
                debug_assert!(
                    state == REGISTERING || state == REGISTERING | WAKING || state == WAKING
                );
                None
            }
        }
    }
}

impl Default for AtomicWaker {
    fn default() -> Self {
        AtomicWaker::new()
    }
}

impl fmt::Debug for AtomicWaker {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(fmt, "AtomicWaker")
    }
}

unsafe impl Send for AtomicWaker {}
unsafe impl Sync for AtomicWaker {}

trait WakerRef {
    fn wake(self);
    fn into_waker(self) -> Waker;
}

impl WakerRef for Waker {
    fn wake(self) {
        self.wake()
    }

    fn into_waker(self) -> Waker {
        self
    }
}

impl WakerRef for &Waker {
    fn wake(self) {
        self.wake_by_ref()
    }

    fn into_waker(self) -> Waker {
        self.clone()
    }
}
<commit_msg>sync: add `spin_loop_hint` to atomic waker (#1608)<commit_after>use crate::loom::sync::atomic::{self, AtomicUsize};
use crate::loom::sync::CausalCell;

use std::fmt;
use std::sync::atomic::Ordering::{AcqRel, Acquire, Release};
use std::task::Waker;

/// A synchronization primitive for task waking.
///
/// `AtomicWaker` will coordinate concurrent wakes with the consumer
/// potentially "waking" the underlying task. This is useful in scenarios
/// where a computation completes in another thread and wants to wake the
/// consumer, but the consumer is in the process of being migrated to a new
/// logical task.
///
/// Consumers should call `register` before checking the result of a computation
/// and producers should call `wake` after producing the computation (this
/// differs from the usual `thread::park` pattern). It is also permitted for
/// `wake` to be called **before** `register`. This results in a no-op.
///
/// A single `AtomicWaker` may be reused for any number of calls to `register` or
/// `wake`.
pub struct AtomicWaker {
    state: AtomicUsize,
    waker: CausalCell<Option<Waker>>,
}

// `AtomicWaker` is a multi-consumer, single-producer transfer cell. The cell
// stores a `Waker` value produced by calls to `register` and many threads can
// race to take the waker by calling `wake.
//
// If a new `Waker` instance is produced by calling `register` before an existing
// one is consumed, then the existing one is overwritten.
//
// While `AtomicWaker` is single-producer, the implementation ensures memory
// safety. In the event of concurrent calls to `register`, there will be a
// single winner whose waker will get stored in the cell. The losers will not
// have their tasks woken. As such, callers should ensure to add synchronization
// to calls to `register`.
//
// The implementation uses a single `AtomicUsize` value to coordinate access to
// the `Waker` cell. There are two bits that are operated on independently. These
// are represented by `REGISTERING` and `WAKING`.
//
// The `REGISTERING` bit is set when a producer enters the critical section. The
// `WAKING` bit is set when a consumer enters the critical section. Neither
// bit being set is represented by `WAITING`.
//
// A thread obtains an exclusive lock on the waker cell by transitioning the
// state from `WAITING` to `REGISTERING` or `WAKING`, depending on the
// operation the thread wishes to perform. When this transition is made, it is
// guaranteed that no other thread will access the waker cell.
//
// # Registering
//
// On a call to `register`, an attempt to transition the state from WAITING to
// REGISTERING is made. On success, the caller obtains a lock on the waker cell.
//
// If the lock is obtained, then the thread sets the waker cell to the waker
// provided as an argument. Then it attempts to transition the state back from
// `REGISTERING` -> `WAITING`.
//
// If this transition is successful, then the registering process is complete
// and the next call to `wake` will observe the waker.
//
// If the transition fails, then there was a concurrent call to `wake` that
// was unable to access the waker cell (due to the registering thread holding the
// lock). To handle this, the registering thread removes the waker it just set
// from the cell and calls `wake` on it. This call to wake represents the
// attempt to wake by the other thread (that set the `WAKING` bit). The
// state is then transitioned from `REGISTERING | WAKING` back to `WAITING`.
// This transition must succeed because, at this point, the state cannot be
// transitioned by another thread.
//
// # Waking
//
// On a call to `wake`, an attempt to transition the state from `WAITING` to
// `WAKING` is made. On success, the caller obtains a lock on the waker cell.
//
// If the lock is obtained, then the thread takes ownership of the current value
// in the waker cell, and calls `wake` on it. The state is then transitioned
// back to `WAITING`. This transition must succeed as, at this point, the state
// cannot be transitioned by another thread.
//
// If the thread is unable to obtain the lock, the `WAKING` bit is still.
// This is because it has either been set by the current thread but the previous
// value included the `REGISTERING` bit **or** a concurrent thread is in the
// `WAKING` critical section. Either way, no action must be taken.
//
// If the current thread is the only concurrent call to `wake` and another
// thread is in the `register` critical section, when the other thread **exits**
// the `register` critical section, it will observe the `WAKING` bit and
// handle the waker itself.
//
// If another thread is in the `waker` critical section, then it will handle
// waking the caller task.
//
// # A potential race (is safely handled).
//
// Imagine the following situation:
//
// * Thread A obtains the `wake` lock and wakes a task.
//
// * Before thread A releases the `wake` lock, the woken task is scheduled.
//
// * Thread B attempts to wake the task. In theory this should result in the
//   task being woken, but it cannot because thread A still holds the wake
//   lock.
//
// This case is handled by requiring users of `AtomicWaker` to call `register`
// **before** attempting to observe the application state change that resulted
// in the task being woken. The wakers also change the application state
// before calling wake.
//
// Because of this, the task will do one of two things.
//
// 1) Observe the application state change that Thread B is waking on. In
//    this case, it is OK for Thread B's wake to be lost.
//
// 2) Call register before attempting to observe the application state. Since
//    Thread A still holds the `wake` lock, the call to `register` will result
//    in the task waking itself and get scheduled again.

/// Idle state
const WAITING: usize = 0;

/// A new waker value is being registered with the `AtomicWaker` cell.
const REGISTERING: usize = 0b01;

/// The task currently registered with the `AtomicWaker` cell is being woken.
const WAKING: usize = 0b10;

impl AtomicWaker {
    /// Create an `AtomicWaker`
    pub fn new() -> AtomicWaker {
        AtomicWaker {
            state: AtomicUsize::new(WAITING),
            waker: CausalCell::new(None),
        }
    }

    /// Registers the current waker to be notified on calls to `wake`.
    ///
    /// This is the same as calling `register_task` with `task::current()`.
    pub fn register(&self, waker: Waker) {
        self.do_register(waker);
    }

    /// Registers the provided waker to be notified on calls to `wake`.
    ///
    /// The new waker will take place of any previous wakers that were registered
    /// by previous calls to `register`. Any calls to `wake` that happen after
    /// a call to `register` (as defined by the memory ordering rules), will
    /// wake the `register` caller's task.
    ///
    /// It is safe to call `register` with multiple other threads concurrently
    /// calling `wake`. This will result in the `register` caller's current
    /// task being woken once.
    ///
    /// This function is safe to call concurrently, but this is generally a bad
    /// idea. Concurrent calls to `register` will attempt to register different
    /// tasks to be woken. One of the callers will win and have its task set,
    /// but there is no guarantee as to which caller will succeed.
    pub fn register_by_ref(&self, waker: &Waker) {
        self.do_register(waker);
    }

    fn do_register<W>(&self, waker: W)
    where
        W: WakerRef,
    {
        debug!(" + register_task");
        match self.state.compare_and_swap(WAITING, REGISTERING, Acquire) {
            WAITING => {
                debug!(" + WAITING");
                unsafe {
                    // Locked acquired, update the waker cell
                    self.waker.with_mut(|t| *t = Some(waker.into_waker()));

                    // Release the lock. If the state transitioned to include
                    // the `WAKING` bit, this means that a wake has been
                    // called concurrently, so we have to remove the waker and
                    // wake it.`
                    //
                    // Start by assuming that the state is `REGISTERING` as this
                    // is what we jut set it to.
                    let res = self
                        .state
                        .compare_exchange(REGISTERING, WAITING, AcqRel, Acquire);

                    match res {
                        Ok(_) => {}
                        Err(actual) => {
                            // This branch can only be reached if a
                            // concurrent thread called `wake`. In this
                            // case, `actual` **must** be `REGISTERING |
                            // `WAKING`.
                            debug_assert_eq!(actual, REGISTERING | WAKING);

                            // Take the waker to wake once the atomic operation has
                            // completed.
                            let waker = self.waker.with_mut(|t| (*t).take()).unwrap();

                            // Just swap, because no one could change state
                            // while state == `Registering | `Waking`
                            self.state.swap(WAITING, AcqRel);

                            // The atomic swap was complete, now
                            // wake the waker and return.
                            waker.wake();
                        }
                    }
                }
            }
            WAKING => {
                debug!(" + WAKING");
                // Currently in the process of waking the task, i.e.,
                // `wake` is currently being called on the old waker.
                // So, we call wake on the new waker.
                waker.wake();

                // This is equivalent to a spin lock, so use a spin hint.
                atomic::spin_loop_hint();
            }
            state => {
                // In this case, a concurrent thread is holding the
                // "registering" lock. This probably indicates a bug in the
                // caller's code as racing to call `register` doesn't make much
                // sense.
                //
                // We just want to maintain memory safety. It is ok to drop the
                // call to `register`.
                debug_assert!(state == REGISTERING || state == REGISTERING | WAKING);
            }
        }
    }

    /// Wakes the task that last called `register`.
    ///
    /// If `register` has not been called yet, then this does nothing.
    pub fn wake(&self) {
        debug!(" + wake");
        if let Some(waker) = self.take_waker() {
            waker.wake();
        }
    }

    /// Attempts to take the `Waker` value out of the `AtomicWaker` with the
    /// intention that the caller will wake the task later.
    pub fn take_waker(&self) -> Option<Waker> {
        debug!(" + take_waker");
        // AcqRel ordering is used in order to acquire the value of the `waker`
        // cell as well as to establish a `release` ordering with whatever
        // memory the `AtomicWaker` is associated with.
        match self.state.fetch_or(WAKING, AcqRel) {
            WAITING => {
                debug!(" + WAITING");
                // The waking lock has been acquired.
                let waker = unsafe { self.waker.with_mut(|t| (*t).take()) };

                // Release the lock
                self.state.fetch_and(!WAKING, Release);
                debug!(" + Done taking");

                waker
            }
            state => {
                debug!(" + state = {:?}", state);
                // There is a concurrent thread currently updating the
                // associated waker.
                //
                // Nothing more to do as the `WAKING` bit has been set. It
                // doesn't matter if there are concurrent registering threads or
                // not.
                //
                debug_assert!(
                    state == REGISTERING || state == REGISTERING | WAKING || state == WAKING
                );
                None
            }
        }
    }
}

impl Default for AtomicWaker {
    fn default() -> Self {
        AtomicWaker::new()
    }
}

impl fmt::Debug for AtomicWaker {
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(fmt, "AtomicWaker")
    }
}

unsafe impl Send for AtomicWaker {}
unsafe impl Sync for AtomicWaker {}

trait WakerRef {
    fn wake(self);
    fn into_waker(self) -> Waker;
}

impl WakerRef for Waker {
    fn wake(self) {
        self.wake()
    }

    fn into_waker(self) -> Waker {
        self
    }
}

impl WakerRef for &Waker {
    fn wake(self) {
        self.wake_by_ref()
    }

    fn into_waker(self) -> Waker {
        self.clone()
    }
}
<|endoftext|>


<commit_before>extern crate builtins;

use std::str::Chars;

pub fn read(command_line: &str) {
	match control_machine(&mut command_line.chars()) {
		Ok(mut tree) => tree.execute_command(),
		Err(err) => println!("{}", err),
	}

}

#[derive(PartialEq, Copy, Clone)] // this enum takes 1B therefore copying it is better than having a 4B pointer (on 32bit machines) or a 8B pointer (on 64 bit machines)
pub enum State {
	Start,
	StrArg,
	SubcommandEnd,
}

fn tokenize(char_it: &mut Chars) -> (Result<Command, &'static str>, State) { // uses a recursive automaton
	use self::State::*;
	let mut cmd = Command::new();

	let mut state = State::Start;

	loop {
		if let Some(curr_char) = char_it.next() {
			match (state, curr_char) {
				(Start, ')') => {
					state = SubcommandEnd;
					return (Ok(cmd), state);
				},
				(Start, ' ') | (Start, '\t') => {},
				(Start, '(') => {
					// do recursion
					let (res, recurState) = tokenize(char_it);
					if recurState != SubcommandEnd {
						panic!("ERROR");
					} else if let Err(_) = res {
						return (res, state);
					}
				},
				(Start, _) => {
					state = StrArg
					// create string
					// push character
				},

				(StrArg, ')') => {
					state = SubcommandEnd;
					return (Ok(cmd), state);
				},
				(StrArg, ' ') | (StrArg, '\t') => {
					state = Start;
					// append string to arg vector
				},
				(StrArg, _) => {
					//push character
				},

				(SubcommandEnd, _) => {
					unreachable!();
				},
			}
		} else {
			if state == StrArg {
				// append string to arg array
			}
			break;
		}
	}

	(Ok(cmd), state)
}

fn control_machine(char_it: &mut Chars) -> Result<Command, &'static str> {
	use self::State::*;

	let (res, state) = tokenize(char_it);

	if state != Start && state != StrArg {
		Err("There is an error")
	} else {
		res
	}
}

//TODO:
//struct Command(Vec<Param>);
//https://doc.rust-lang.org/book/structs.html

struct Command {
	cmd: String,
	params: Vec<Param>,
}
impl Command {
	fn new() -> Command {
		Command {
			cmd: String::new(),
			params: Vec::new(),
		}
	}
	fn get_final_arglist(&mut self) -> Vec<&str> {
		let mut final_arglist: Vec<&str> = Vec::with_capacity(self.params.len());

		for arg in self.params.iter_mut() { // substitue subcommands recursively
			let stdout = if let Param::Cmd(ref mut subcommand) = *arg {
				Some(subcommand.execute_subcommand())
			} else {
				None
			};

			if let Some(stdout) = stdout {
				*arg = Param::Arg(stdout); // the datastructure holds the `String`
			}

			if let Param::Arg(ref arg_str) = *arg { // at this point this always happen because `Cmd` became `Arg`s
				final_arglist.push(arg_str);
			}
		}

		final_arglist
	}
	fn execute_command(&mut self) {//returns stdout - possibly return a array of strings?
		match &self.cmd[..] {
			"" => {},
			/*"cd" => builtins::cd(&self.params),
			"exit" => builtins::exit(&self.params),*/
			_ => invoke_command(self),
		};
	}
	fn execute_subcommand(&mut self) -> String {
		match &self.cmd[..] {
			/*"" => {},
			"cd" => builtins::cd(&self.params),
			"exit" => builtins::exit(&self.params),*/
			_ => invoke_subcommand(self),
		}
	}
}
enum Param {
	Arg(String),
	Cmd(Command),

}
fn invoke_command(command: &mut Command) {
	use std::process::Command;
	match Command::new(&command.cmd)
		.args(&command.get_final_arglist())
		.spawn() {
			Ok(mut subproc) => {
				subproc.wait();
			},
			Err(err) => println!("{}", err),
	}
}
fn invoke_subcommand(command: &mut Command) -> String {
	{
		for arg in command.get_final_arglist() {
			println!("shitty debugging: {}", arg);
		}
	}
	use std::process::Command;
	let output = Command::new(&command.cmd)
		.args(&command.get_final_arglist())
		.output()
		.expect("Failed to start command");

	String::from_utf8(output.stdout).unwrap()
}
<commit_msg>Use an actual tokenizer<commit_after>extern crate builtins;

pub fn read(command_line: &str) {
	/*match control_machine(command_line) {
		Ok(mut tree) => tree.execute_command(),
		Err(err) => println!("{}", err),
	}*/
	let token_list = tokenize(command_line);
	let token_iter = token_list.iter();
}

#[derive(PartialEq, Copy, Clone)] // this enum takes 8b therefore copying it is better than having a 32b or 64b pointer
pub enum State {
	Start,
	StrCmd(usize),
	SeparateWs,
	StrArg(usize),
}

pub enum Token<'a, 'b> {
	LeftParen,
	RightParen,
	Cmd(&'a str),
	Arg(&'b str),
}

fn tokenize(command_line: &str) -> Vec<Token> {
	use self::State::*;
	use self::Token::*;

	let mut state = Start;
	let mut token_list = Vec::new();

	let mut char_it = command_line.char_indices();

	loop {
		if let Some((i, curr_char)) = char_it.next() {
			match (state, curr_char) {
				(Start, ' ') | (Start, '\t') => {},
				(Start, '(') => token_list.push(LeftParen),
				(Start, _) => state = StrCmd(i),

				(StrCmd(slice_start), ')') => {
					token_list.push(Cmd(&command_line[slice_start..i]));
					state = Start;
				},
				(StrCmd(slice_start), ' ') | (StrCmd(slice_start), '\t') => {
					token_list.push(Cmd(&command_line[slice_start..i]));
					state = SeparateWs;
				},
				(StrCmd(_), _) => {},

				(SeparateWs, ' ') | (SeparateWs, '\t') => {},
				(SeparateWs, ')') => {
					token_list.push(RightParen);
					state = Start;
				},
				(SeparateWs, '(') => {
					token_list.push(LeftParen);
					state = Start;
				},
				(SeparateWs, _) => state = StrArg(i),

				(StrArg(slice_start), ' ') | (StrArg(slice_start), '\t') => {
					token_list.push(Arg(&command_line[slice_start..i]));
					state = SeparateWs;
				},
				(StrArg(slice_start), ')') => {
					token_list.push(Arg(&command_line[slice_start..i]));
					state = Start;
				}
				(StrArg(_), _) => {},
			}
		}
	}
}

use std::slice::Iter;

fn generate_tree<'a>(token_list: Iter<Vec<Token>>) -> Result<Command<'a>, &'static str> {
	Err("Empy commands are not allowed")
	/*use self::State::*;
	let mut cmd = Command::new();

	let mut state = State::Start;
	let slice_start = 0; // whatever, doesn't matter
	let oldI = 0;

	loop {
		if let Some((i, curr_char)) = char_it.next() {
			match (state, curr_char) {
				(Start, ')') => return (Err("Empty subcommands are not allowed"), state),
				(Start, ' ') | (Start, '\t') => {},
				(Start, '(') => {
					// do recursion
					let (res, recur_state) = tokenize(char_it);
					if recur_state != SubcommandEnd {
						panic!("ERROR");
					} else if let Err(_) = res {
						return (res, state);
					} else {
						cmd.cmd.push(Param::Cmd(res));
					}
				},
				(Start, _) => {
					state = StrCmd;
					slice_start = i;
				},

				(StrCmd, ')') | (SeparateWs, ')') | (StrArg, ')') => {
					state = SubcommandEnd;
					return (Ok(cmd), state);
				},

				(StrCmd, ' ') | (StrCmd, '\t') => {
				//	cmd.cmd = &
				},
				(StrCmd, _) => {},

				(SeparateWs, ' ') | (SeparateWs, '\t') => {},
				(SeparateWs, _) => {
					state = StrArg;
					cmd.params.push(Param::Arg(curr_char.to_string()));
				},

				(StrArg, ' ') | (StrArg, '\t') => {
					state = SeparateWs;
					// append string to arg vector
				},
				(StrArg, _) => {
					let i = cmd.params.len() - 1;
					if let Param::Arg(ref mut str_arg) = cmd.params[i] {
						str_arg.push(curr_char);
					} else {
						unreachable!();
					}
					//push character
				},

				(SubcommandEnd, _) => {
					unreachable!();
				},
			}
			oldI = i;
		} else {
			if state == StrArg {
				// append string to arg array
			}
			break;BNF
		}
	}

	(Ok(cmd), state)*/
}

/*fn control_machine(command_line: &str) -> Result<Command, &'static str> {
	use self::State::*;

	let (res, state) = tokenize(command_line.char_indices(), command_line);

	if state != Start && state != StrArg {
		Err("There is an error")
	} else {
		res
	}
}*/

struct Command<'a> {
	cmd: &'a str,
	params: Vec<Param<'a>>,
}
impl<'a> Command<'a> {
	fn new(cmd: &str) -> Command {
		Command {
			cmd: cmd,
			params: Vec::new(),
		}
	}
	fn get_final_arglist(&mut self) -> Vec<&str> {
		let mut final_arglist: Vec<&str> = Vec::with_capacity(self.params.len());

		for arg in self.params.iter_mut() { // substitue subcommands recursively
			let stdout = if let Param::Cmd(ref mut subcommand) = *arg {
				Some(subcommand.execute_subcommand())
			} else {
				None
			};

			if let Some(stdout) = stdout {
				*arg = Param::Arg(stdout); // the datastructure holds the `String`
			}

			if let Param::Arg(ref arg_str) = *arg { // at this point this always happen because `Cmd` became `Arg`s
				final_arglist.push(arg_str);
			}
		}

		final_arglist
	}
	fn execute_command(&mut self) {//returns stdout - possibly return a array of strings?
		match &self.cmd[..] {
			"" => {},
			/*"cd" => builtins::cd(&self.params),
			"exit" => builtins::exit(&self.params),*/
			_ => invoke_command(self),
		};
	}
	fn execute_subcommand(&mut self) -> String {
		match &self.cmd[..] {
			/*"" => {},
			"cd" => builtins::cd(&self.params),
			"exit" => builtins::exit(&self.params),*/
			_ => invoke_subcommand(self),
		}
	}
}
enum Param<'a> {
	Arg(String),
	Cmd(Command<'a>),

}
fn invoke_command(command: &mut Command) {
	use std::process::Command;
	match Command::new(&command.cmd)
		.args(&command.get_final_arglist())
		.spawn() {
			Ok(mut subproc) => {
				subproc.wait();
			},
			Err(err) => println!("{}", err),
	}
}
fn invoke_subcommand(command: &mut Command) -> String {
	{
		for arg in command.get_final_arglist() {
			println!("shitty debugging: {}", arg);
		}
	}
	use std::process::Command;
	let output = Command::new(&command.cmd)
		.args(&command.get_final_arglist())
		.output()
		.expect("Failed to start command");

	String::from_utf8(output.stdout).unwrap()
}
<|endoftext|>