<commit_before>
#[derive(Debug)]
enum Day {
    Sweetmorn,
    Boomtime,
    Pungenday,
    PricklePrickle,
    SettingOrange,
    StTibsDay,
}

#[derive(Debug)]
enum Season {
    Chaos,
    Discord,
    Confusion,
    Bureaucracy,
    TheAftermath,
    StTibsDay,
}

#[derive(Debug)]
pub struct DiscordianDate {
    season: Season,
    day: u8,
    year_day: u16,
    year: i32,
    week_day: Day,
    week: Option<u8>,
}

pub fn convert(nday: u16, nyear: i32) -> Option<DiscordianDate> {
    let year = nyear + 1166;
    let year_day = nday + 1;  // Switch to one-based

    if !is_leap_year(nyear) {
        let season = match nday {
            0 ... 72 => Season::Chaos,
            73 ... 145 => Season::Discord,
            146 ... 218 => Season::Confusion,
            219 ... 291 => Season::Bureaucracy,
            292 ... 364 => Season::TheAftermath,
            _ => panic!("Day out of range: {}", nday)
        };

        let week_day = week_day(nday);
        let day = ((nday % 73) + 1) as u8;
        let week = Some((nday / 5) as u8);
        return Some(DiscordianDate {season: season, day: day,
                             year_day: year_day, year: year,
                             week: week, week_day: week_day})
    } else {
        let season = match nday {
            59 => Season::StTibsDay,
            0 ... 73 => Season::Chaos,
            74 ... 146 => Season::Discord,
            147 ... 219 => Season::Confusion,
            220 ... 292 => Season::Bureaucracy,
            293 ... 365 => Season::TheAftermath,
            _ => panic!("Day out of range: {}", nday)
        };

        let week_day = match nday {
                0 ... 58 => week_day(nday),
                59 => Day::StTibsDay,
                60 ... 365 => week_day(nday - 1),
                _ => panic!("Day out of range: {}", nday)
        };

        let day = match nday {
                0 ... 58 => nday,
                59 => 1,
                60 ... 365 => (nday - 1) % 73 + 1,
                _ => panic!("Day out of range: {}", nday)
        } as u8;

        let week = match nday {
                0 ... 58 => Some((nday / 5) as u8),
                59 => None,
                60 ... 365 => Some(((nday - 1) / 5) as u8),
                _ => panic!("Day out of range: {}", nday)
        };

        return Some(DiscordianDate {season: season, day: day,
                             year_day: year_day, year: year,
                             week: week, week_day: week_day})

    }

}

fn week_day(nday: u16) -> Day{
    match nday % 5 {
        0 => Day::Sweetmorn,
        1 => Day::Boomtime,
        2 => Day::Pungenday,
        3 => Day::PricklePrickle,
        4 => Day::SettingOrange,
        _ => panic!("Weekday out of range: {}", nday % 5)
    }
}

fn is_leap_year(year_ce: i32) -> bool{
    let has_factor = |n| year_ce % n == 0;
    return has_factor(4) && !has_factor(100) || has_factor(400)
}

mod test {
    #[test]
    fn test_leap_year_positive() {
        assert!(super::is_leap_year(2004));
        assert!(super::is_leap_year(2008));
        assert!(super::is_leap_year(2012));
        assert!(super::is_leap_year(2016));
    }

    #[test]
    fn test_leap_year_century() {
        assert!(super::is_leap_year(2000));
        assert!(!super::is_leap_year(1900));
        assert!(!super::is_leap_year(1800));
        assert!(!super::is_leap_year(2100));
    }

    #[test]
    fn test_leap_year_negative() {
        assert!(!super::is_leap_year(1998));
        assert!(!super::is_leap_year(1999));
        assert!(!super::is_leap_year(2014));
        assert!(!super::is_leap_year(2015));
    }
}
<commit_msg>Add tests for weekdays<commit_after>
#[derive(Debug,PartialEq)]
enum Day {
    Sweetmorn,
    Boomtime,
    Pungenday,
    PricklePrickle,
    SettingOrange,
    StTibsDay,
}

#[derive(Debug)]
enum Season {
    Chaos,
    Discord,
    Confusion,
    Bureaucracy,
    TheAftermath,
    StTibsDay,
}

#[derive(Debug)]
pub struct DiscordianDate {
    season: Season,
    day: u8,
    year_day: u16,
    year: i32,
    week_day: Day,
    week: Option<u8>,
}

pub fn convert(nday: u16, nyear: i32) -> Option<DiscordianDate> {
    let year = nyear + 1166;
    let year_day = nday + 1;  // Switch to one-based

    if !is_leap_year(nyear) {
        let season = match nday {
            0 ... 72 => Season::Chaos,
            73 ... 145 => Season::Discord,
            146 ... 218 => Season::Confusion,
            219 ... 291 => Season::Bureaucracy,
            292 ... 364 => Season::TheAftermath,
            _ => panic!("Day out of range: {}", nday)
        };

        let week_day = week_day(nday);
        let day = ((nday % 73) + 1) as u8;
        let week = Some((nday / 5) as u8);
        return Some(DiscordianDate {season: season, day: day,
                             year_day: year_day, year: year,
                             week: week, week_day: week_day})
    } else {
        let season = match nday {
            59 => Season::StTibsDay,
            0 ... 73 => Season::Chaos,
            74 ... 146 => Season::Discord,
            147 ... 219 => Season::Confusion,
            220 ... 292 => Season::Bureaucracy,
            293 ... 365 => Season::TheAftermath,
            _ => panic!("Day out of range: {}", nday)
        };

        let week_day = match nday {
                0 ... 58 => week_day(nday),
                59 => Day::StTibsDay,
                60 ... 365 => week_day(nday - 1),
                _ => panic!("Day out of range: {}", nday)
        };

        let day = match nday {
                0 ... 58 => nday,
                59 => 1,
                60 ... 365 => (nday - 1) % 73 + 1,
                _ => panic!("Day out of range: {}", nday)
        } as u8;

        let week = match nday {
                0 ... 58 => Some((nday / 5) as u8),
                59 => None,
                60 ... 365 => Some(((nday - 1) / 5) as u8),
                _ => panic!("Day out of range: {}", nday)
        };

        return Some(DiscordianDate {season: season, day: day,
                             year_day: year_day, year: year,
                             week: week, week_day: week_day})

    }

}

fn week_day(nday: u16) -> Day{
    match nday % 5 {
        0 => Day::Sweetmorn,
        1 => Day::Boomtime,
        2 => Day::Pungenday,
        3 => Day::PricklePrickle,
        4 => Day::SettingOrange,
        _ => panic!("Weekday out of range: {}", nday % 5)
    }
}

fn is_leap_year(year_ce: i32) -> bool {
    let has_factor = |n| year_ce % n == 0;
    return has_factor(4) && !has_factor(100) || has_factor(400)
}

#[cfg(test)]
mod test {

    #[test]
    fn test_week_day() {
        assert_eq!(super::week_day(0), super::Day::Sweetmorn);
        assert_eq!(super::week_day(1), super::Day::Boomtime);
        assert_eq!(super::week_day(2), super::Day::Pungenday);
        assert_eq!(super::week_day(3), super::Day::PricklePrickle);
        assert_eq!(super::week_day(4), super::Day::SettingOrange);
        assert_eq!(super::week_day(10), super::Day::Sweetmorn);
        assert_eq!(super::week_day(12), super::Day::Pungenday);
        assert_eq!(super::week_day(21), super::Day::Boomtime);
    }

    #[test]
    fn test_leap_year_positive() {
        assert!(super::is_leap_year(2004));
        assert!(super::is_leap_year(2008));
        assert!(super::is_leap_year(2012));
        assert!(super::is_leap_year(2016));
    }

    #[test]
    fn test_leap_year_century() {
        assert!(super::is_leap_year(2000));
        assert!(!super::is_leap_year(1900));
        assert!(!super::is_leap_year(1800));
        assert!(!super::is_leap_year(2100));
    }

    #[test]
    fn test_leap_year_negative() {
        assert!(!super::is_leap_year(1998));
        assert!(!super::is_leap_year(1999));
        assert!(!super::is_leap_year(2014));
        assert!(!super::is_leap_year(2015));
    }
}
<|endoftext|>


<commit_before>use crate::cmp;
use crate::iter::{adapters::SourceIter, FusedIterator, InPlaceIterable, TrustedLen};
use crate::ops::{ControlFlow, Try};

/// An iterator that only iterates over the first `n` iterations of `iter`.
///
/// This `struct` is created by the [`take`] method on [`Iterator`]. See its
/// documentation for more.
///
/// [`take`]: Iterator::take
/// [`Iterator`]: trait.Iterator.html
#[derive(Clone, Debug)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Take<I> {
    iter: I,
    n: usize,
}

impl<I> Take<I> {
    pub(in crate::iter) fn new(iter: I, n: usize) -> Take<I> {
        Take { iter, n }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I> Iterator for Take<I>
where
    I: Iterator,
{
    type Item = <I as Iterator>::Item;

    #[inline]
    fn next(&mut self) -> Option<<I as Iterator>::Item> {
        if self.n != 0 {
            self.n -= 1;
            self.iter.next()
        } else {
            None
        }
    }

    #[inline]
    fn nth(&mut self, n: usize) -> Option<I::Item> {
        if self.n > n {
            self.n -= n + 1;
            self.iter.nth(n)
        } else {
            if self.n > 0 {
                self.iter.nth(self.n - 1);
                self.n = 0;
            }
            None
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        if self.n == 0 {
            return (0, Some(0));
        }

        let (lower, upper) = self.iter.size_hint();

        let lower = cmp::min(lower, self.n);

        let upper = match upper {
            Some(x) if x < self.n => Some(x),
            _ => Some(self.n),
        };

        (lower, upper)
    }

    #[inline]
    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> R,
        R: Try<Ok = Acc>,
    {
        fn check<'a, T, Acc, R: Try<Ok = Acc>>(
            n: &'a mut usize,
            mut fold: impl FnMut(Acc, T) -> R + 'a,
        ) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> + 'a {
            move |acc, x| {
                *n -= 1;
                let r = fold(acc, x);
                if *n == 0 { ControlFlow::Break(r) } else { ControlFlow::from_try(r) }
            }
        }

        if self.n == 0 {
            try { init }
        } else {
            let n = &mut self.n;
            self.iter.try_fold(init, check(n, fold)).into_try()
        }
    }

    #[inline]
    fn fold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        #[inline]
        fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
            move |acc, x| Ok(f(acc, x))
        }

        self.try_fold(init, ok(fold)).unwrap()
    }
}

#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<S: Iterator, I: Iterator> SourceIter for Take<I>
where
    I: SourceIter<Source = S>,
{
    type Source = S;

    #[inline]
    unsafe fn as_inner(&mut self) -> &mut S {
        // SAFETY: unsafe function forwarding to unsafe function with the same requirements
        unsafe { SourceIter::as_inner(&mut self.iter) }
    }
}

#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<I: InPlaceIterable> InPlaceIterable for Take<I> {}

#[stable(feature = "double_ended_take_iterator", since = "1.38.0")]
impl<I> DoubleEndedIterator for Take<I>
where
    I: DoubleEndedIterator + ExactSizeIterator,
{
    #[inline]
    fn next_back(&mut self) -> Option<Self::Item> {
        if self.n == 0 {
            None
        } else {
            let n = self.n;
            self.n -= 1;
            self.iter.nth_back(self.iter.len().saturating_sub(n))
        }
    }

    #[inline]
    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
        let len = self.iter.len();
        if self.n > n {
            let m = len.saturating_sub(self.n) + n;
            self.n -= n + 1;
            self.iter.nth_back(m)
        } else {
            if len > 0 {
                self.iter.nth_back(len - 1);
            }
            None
        }
    }

    #[inline]
    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> R,
        R: Try<Ok = Acc>,
    {
        if self.n == 0 {
            try { init }
        } else {
            let len = self.iter.len();
            if len > self.n && self.iter.nth_back(len - self.n - 1).is_none() {
                try { init }
            } else {
                self.iter.try_rfold(init, fold)
            }
        }
    }

    #[inline]
    fn rfold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        if self.n == 0 {
            init
        } else {
            let len = self.iter.len();
            if len > self.n && self.iter.nth_back(len - self.n - 1).is_none() {
                init
            } else {
                self.iter.rfold(init, fold)
            }
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I> ExactSizeIterator for Take<I> where I: ExactSizeIterator {}

#[stable(feature = "fused", since = "1.26.0")]
impl<I> FusedIterator for Take<I> where I: FusedIterator {}

#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<I: TrustedLen> TrustedLen for Take<I> {}
<commit_msg>implement TrustedRandomAccess for Take iterator adapter<commit_after>use crate::cmp;
use crate::iter::{
    adapters::zip::try_get_unchecked, adapters::SourceIter, FusedIterator, InPlaceIterable,
    TrustedLen, TrustedRandomAccess,
};
use crate::ops::{ControlFlow, Try};

/// An iterator that only iterates over the first `n` iterations of `iter`.
///
/// This `struct` is created by the [`take`] method on [`Iterator`]. See its
/// documentation for more.
///
/// [`take`]: Iterator::take
/// [`Iterator`]: trait.Iterator.html
#[derive(Clone, Debug)]
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Take<I> {
    iter: I,
    n: usize,
}

impl<I> Take<I> {
    pub(in crate::iter) fn new(iter: I, n: usize) -> Take<I> {
        Take { iter, n }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I> Iterator for Take<I>
where
    I: Iterator,
{
    type Item = <I as Iterator>::Item;

    #[inline]
    fn next(&mut self) -> Option<<I as Iterator>::Item> {
        if self.n != 0 {
            self.n -= 1;
            self.iter.next()
        } else {
            None
        }
    }

    #[inline]
    fn nth(&mut self, n: usize) -> Option<I::Item> {
        if self.n > n {
            self.n -= n + 1;
            self.iter.nth(n)
        } else {
            if self.n > 0 {
                self.iter.nth(self.n - 1);
                self.n = 0;
            }
            None
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        if self.n == 0 {
            return (0, Some(0));
        }

        let (lower, upper) = self.iter.size_hint();

        let lower = cmp::min(lower, self.n);

        let upper = match upper {
            Some(x) if x < self.n => Some(x),
            _ => Some(self.n),
        };

        (lower, upper)
    }

    #[inline]
    fn try_fold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> R,
        R: Try<Ok = Acc>,
    {
        fn check<'a, T, Acc, R: Try<Ok = Acc>>(
            n: &'a mut usize,
            mut fold: impl FnMut(Acc, T) -> R + 'a,
        ) -> impl FnMut(Acc, T) -> ControlFlow<R, Acc> + 'a {
            move |acc, x| {
                *n -= 1;
                let r = fold(acc, x);
                if *n == 0 { ControlFlow::Break(r) } else { ControlFlow::from_try(r) }
            }
        }

        if self.n == 0 {
            try { init }
        } else {
            let n = &mut self.n;
            self.iter.try_fold(init, check(n, fold)).into_try()
        }
    }

    #[inline]
    fn fold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        #[inline]
        fn ok<B, T>(mut f: impl FnMut(B, T) -> B) -> impl FnMut(B, T) -> Result<B, !> {
            move |acc, x| Ok(f(acc, x))
        }

        self.try_fold(init, ok(fold)).unwrap()
    }

    unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> <I as Iterator>::Item
    where
        Self: TrustedRandomAccess,
    {
        // SAFETY: the caller must uphold the contract for
        // `Iterator::__iterator_get_unchecked`.
        unsafe { try_get_unchecked(&mut self.iter, idx) }
    }
}

#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<S: Iterator, I: Iterator> SourceIter for Take<I>
where
    I: SourceIter<Source = S>,
{
    type Source = S;

    #[inline]
    unsafe fn as_inner(&mut self) -> &mut S {
        // SAFETY: unsafe function forwarding to unsafe function with the same requirements
        unsafe { SourceIter::as_inner(&mut self.iter) }
    }
}

#[unstable(issue = "none", feature = "inplace_iteration")]
unsafe impl<I: InPlaceIterable> InPlaceIterable for Take<I> {}

#[stable(feature = "double_ended_take_iterator", since = "1.38.0")]
impl<I> DoubleEndedIterator for Take<I>
where
    I: DoubleEndedIterator + ExactSizeIterator,
{
    #[inline]
    fn next_back(&mut self) -> Option<Self::Item> {
        if self.n == 0 {
            None
        } else {
            let n = self.n;
            self.n -= 1;
            self.iter.nth_back(self.iter.len().saturating_sub(n))
        }
    }

    #[inline]
    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
        let len = self.iter.len();
        if self.n > n {
            let m = len.saturating_sub(self.n) + n;
            self.n -= n + 1;
            self.iter.nth_back(m)
        } else {
            if len > 0 {
                self.iter.nth_back(len - 1);
            }
            None
        }
    }

    #[inline]
    fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> R,
        R: Try<Ok = Acc>,
    {
        if self.n == 0 {
            try { init }
        } else {
            let len = self.iter.len();
            if len > self.n && self.iter.nth_back(len - self.n - 1).is_none() {
                try { init }
            } else {
                self.iter.try_rfold(init, fold)
            }
        }
    }

    #[inline]
    fn rfold<Acc, Fold>(mut self, init: Acc, fold: Fold) -> Acc
    where
        Self: Sized,
        Fold: FnMut(Acc, Self::Item) -> Acc,
    {
        if self.n == 0 {
            init
        } else {
            let len = self.iter.len();
            if len > self.n && self.iter.nth_back(len - self.n - 1).is_none() {
                init
            } else {
                self.iter.rfold(init, fold)
            }
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I> ExactSizeIterator for Take<I> where I: ExactSizeIterator {}

#[stable(feature = "fused", since = "1.26.0")]
impl<I> FusedIterator for Take<I> where I: FusedIterator {}

#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<I: TrustedLen> TrustedLen for Take<I> {}

#[doc(hidden)]
#[unstable(feature = "trusted_random_access", issue = "none")]
unsafe impl<I> TrustedRandomAccess for Take<I>
where
    I: TrustedRandomAccess,
{
    const MAY_HAVE_SIDE_EFFECT: bool = I::MAY_HAVE_SIDE_EFFECT;
}
<|endoftext|>


<commit_before>use extra::sort::merge_sort;
use std::char::{from_u32, MAX};
use error::ParseError::*;

pub mod ParseFlags {
  pub static NoParseFlags:  u8 = 0b00000000;
  pub static NoCapture:     u8 = 0b00000010;
  pub static NonGreedy:     u8 = 0b01000000;
}

pub mod ParseStack {
  use super::{OpCode, Literal, Regexp, CharClass};
  // different representations of expressions on
  // the stack
  pub enum Entry {
    Op(OpCode),
    Literal(Literal),
    Expression(Regexp),
    CharClass(CharClass)
  }
}

// A Regex Operation
pub enum OpCode {
  OpConcatenation,
  OpAlternation,
  OpKleine,
  OpZeroOrOne,
  OpOneOrMore,
  OpLineStart,
  OpLineEnd,
  OpLeftParen,
  OpCapture(uint, Option<~str>),
  OpRepeatOp(uint, Option<uint>),
  OpNoop
}

// Regexp Literal
// a literal character in a regex string (i.e 'abcd')
pub struct Literal {
  value: ~str
}

impl Literal {
  pub fn new(s: &str) -> Literal {
    Literal { value: s.clone().to_owned() }
  }
}

// Regexp
// represents a variable number of states with an
// operator applied to them.
pub struct Regexp {
  op: OpCode,
  state0: Option<~ParseStack::Entry>,
  state1: Option<~ParseStack::Entry>,
  flags: u8
}

impl Regexp {
  pub fn new(op: OpCode, state0: Option<~ParseStack::Entry>,
             state1: Option<~ParseStack::Entry>) -> Regexp {
    Regexp {
      op: op,
      state0: state0,
      state1: state1,
      flags: ParseFlags::NoParseFlags
    }
  }
}

impl Regexp {
  pub fn addFlag(&mut self, flag: u8) {
    self.flags = self.flags | flag;
  }
  pub fn hasFlag(&self, flag: u8) -> bool {
    (self.flags & flag) > 0
  }
}

// RegexpCharClass
// represents a character class (i.e '[a-z123]')
pub struct CharClass {
  ranges: ~[(char, char)]
}

impl CharClass {
  pub fn new() -> CharClass {
    CharClass { ranges: ~[] }
  }
}

impl CharClass {
  pub fn negate(&mut self) -> ParseCode {
    let ordered = do merge_sort(self.ranges) |range1, range2| {
      let &(start1, _) = range1;
      let &(start2, _) = range2;
      start1 <= start2
    };

    let mut min: char = '\U00000000';
    let max: char = MAX;

    self.ranges = ~[];

    for &(start, end) in ordered.iter() {
      match CharClass::prev_char(start) {
        Some(e) => {
          if (min < e) {
            self.addRange(min, e);
          }
        },
        None => { } // continue
      };
      if (min < end) {
        min = match CharClass::next_char(end) {
          Some(c) => c,
          None => end
        };
      }
    }

    // patch the end
    if (min != max) {
      self.addRange(min, max);
    }

    if self.ranges.len() == 0 {
      ParseEmptyCharClassRange
    } else {
      ParseOk
    }
  }
  pub fn containsChar(&mut self, c: char) -> bool {
    let mut covered = false;

    for &(start, end) in self.ranges.iter() {
      if (c >= start && c <= end) {
        covered = true;
        break
      }
    }

    covered
  }
  pub fn addRange(&mut self, s: char, e: char) -> ParseCode {
    if (s <= e) {
      self.ranges.push((s, e));
    } else {
      return ParseEmptyCharClassRange;
    }

    ParseOk
  }
}

impl CharClass {
  fn prev_char(c: char) -> Option<char> {
    match from_u32(c as u32 - 1) {
      None => None,
      r    => r
    }
  }
  fn next_char(c: char) -> Option<char> {
    match from_u32(c as u32 + 1) {
      None => None,
      r    => r
    }
  }
}

// current state of parsing
//
// | - nparen:
// |   number of parenthases not resolved
// | - ncaps:
// |   number of parenthases seen
pub struct ParseState {
  priv stack: ~[ParseStack::Entry],
  priv nparen: uint,
  priv ncaps: uint,
  priv flags: u8
}

impl ParseState {
  pub fn new() -> ParseState {
    ParseState {
      stack: ~[],
      nparen: 0,
      ncaps: 0,
      flags: ParseFlags::NoParseFlags
    }
  }
}

impl ParseState {
  pub fn addFlag(&mut self, flag: u8) {
    self.flags = self.flags | flag;
  }
  pub fn hasFlag(&self, flag: u8) -> bool {
    (self.flags & flag) > 0
  }
}

impl ParseState {
  pub fn pop(&mut self) -> Result<Regexp, ParseCode> {
    match self.stack.pop_opt() {
      Some(ParseStack::Expression(r)) => Ok(r),
      Some(ParseStack::Literal(r)) => {
        Ok(Regexp::new(OpNoop, Some(~ParseStack::Literal(r)), None))
      },
      Some(ParseStack::CharClass(r)) => {
        Ok(Regexp::new(OpNoop, Some(~ParseStack::CharClass(r)), None))
      },
      Some(ParseStack::Op(_)) => Err(ParseInternalError),
      None => Err(ParseEmptyStack)
    }
  }
}

impl ParseState {
  pub fn hasUnmatchedParens(&mut self) -> bool {
    self.nparen > 0
  }
  pub fn hasNoParens(&mut self) -> bool {
    self.nparen == 0
  }
}

impl ParseState {
  pub fn pushLiteral(&mut self, s: &str) -> () {
    self.stack.push(ParseStack::Literal(Literal::new(s)));
  }
  pub fn pushOperation(&mut self, op: OpCode) -> () {
    self.stack.push(ParseStack::Op(op));
  }
  pub fn pushExpression(&mut self, r: Regexp) -> () {
    self.stack.push(ParseStack::Expression(r));
  }
  pub fn pushCharClass(&mut self, cc: CharClass) -> () {
    self.stack.push(ParseStack::CharClass(cc));
  }
}

impl ParseState {
  pub fn pushAlternation(&mut self) -> () {
    self.pushOperation(OpAlternation);
  }
  pub fn pushLeftParen(&mut self) -> () {
    self.nparen += 1;
    self.pushOperation(OpLeftParen);
  }
}

impl ParseState {
  pub fn doAlternation(&mut self) -> ParseCode {
    // try to pop off two items from the stack.
    // these should be branches that you can take.
    //     -> state0
    // s |
    //     -> state1
    //
    // with alternation occuring sequentially, we can
    // make an equivalent model by having state0 or state1
    // also be a regexp with a alternation operand applied to it.
    //     -> state0
    // s |              -> 'state0
    //     -> state1  |
    //                  -> 'state1
    //
    // the operand should be pushed onto the stack before we start parsing
    // the right hand side of the alternation, so the stack should look something
    // like this before doAlternation() is called:
    //
    // state0 (branch2)
    // OpCode(OpAlternation)
    // state1 (branch1)
    let branch1 = match self.stack.pop_opt() {
      Some(s) => s,
      None => return ParseEmptyAlternate
    };
    // make sure there is an alternation operand on the stack,
    // otherwise, might have parsed incorrectly
    match self.stack.pop_opt() {
      Some(ParseStack::Op(OpAlternation)) => { },
      _ => return ParseUnexpectedOperand
    };
    let branch2 = match self.stack.pop_opt() {
      Some(s) => s,
      None => return ParseEmptyAlternate
    };
    let r = Regexp::new(OpAlternation, Some(~branch2), Some(~branch1));

    self.pushExpression(r);

    ParseOk
  }
  pub fn doConcatenation(&mut self) -> ParseCode {
    while (self.stack.len() > 1) {
      // try to take two items off the stack to
      // concatenate.
      // if either of them are opcodes, just
      // push them back no the stack, and return
      // (this means there is a singular item on the stack,
      // and can't be concatenated with anything)
      //
      // state0 -> state1
      let branch1 = match self.stack.pop_opt() {
        Some(ParseStack::Op(op)) => {
          self.pushOperation(op);
          return ParseOk;
        },
        Some(s) => s,
        None => return ParseEmptyConcatenate
      };

      match self.stack.pop_opt() {
        Some(ParseStack::Op(op)) => {
          self.pushOperation(op);
          self.stack.push(branch1);
          return ParseOk;
        },
        Some(ParseStack::Literal(s)) => {
          match branch1 {
            ParseStack::Literal(l) => self.pushLiteral(s.value + l.value),
            _ => {
              let r = Regexp::new(OpConcatenation,
                                  Some(~ParseStack::Literal(s)),
                                  Some(~branch1));
              self.pushExpression(r);
            }
          }
        }
        Some(s) => {
          let r = Regexp::new(OpConcatenation, Some(~s), Some(~branch1));
          self.pushExpression(r);
        },
        None => return ParseEmptyConcatenate
      };
    }

    ParseOk
  }
  pub fn doLeftParen(&mut self, noncapturing: bool) -> ParseCode {
    self.nparen -= 1;
    self.doConcatenation();
    let inner = self.stack.pop();
    // after the left paren operand should be on the top
    // of the stack
    match self.stack.pop_opt() {
      Some(ParseStack::Op(OpLeftParen)) => { },
      _ => return ParseExpectedOperand
    }
    let mut r = Regexp::new(OpCapture(self.ncaps, None),
                            Some(~inner),
                            None);
    if (noncapturing) {
      r.addFlag(ParseFlags::NoCapture);
    } else {
      self.ncaps += 1;
    }

    self.pushExpression(r);

    ParseOk
  }
  pub fn doRepeatOp(&mut self, op: OpCode) -> ParseCode {
    match self.stack.pop_opt() {
      Some(r) => {
        let mut r = r;
        // check if we should have apply a
        // nongreedy flag
        let nongreedy = match op {
          OpZeroOrOne => true,
          _ => false
        };
        // check to see if the expr on the top
        // of the stack has some repition
        // op applied to it.
        let opcode = match &r {
          &ParseStack::Expression(ref e) => {
            match e.op {
              OpKleine => Some(OpKleine),
              OpOneOrMore => Some(OpOneOrMore),
              OpRepeatOp(s, e) => Some(OpRepeatOp(s,e)),
              OpZeroOrOne => Some(OpZeroOrOne),
              _ => None
            }
          },
          _ => {
            None
          }
        };
        // if we found that the expr already had
        // a repeat op, we might need to throw a
        // error
        //
        // otherwise, we can make a new expression.
        match opcode {
          Some(OpOneOrMore) |
          Some(OpKleine) |
          Some(OpRepeatOp(_, _)) |
          Some(OpZeroOrOne) => {
            if (nongreedy) {
              match r {
                ParseStack::Expression(ref mut e) => {
                  e.addFlag(ParseFlags::NonGreedy);
                }
                _ => { } // should never hit this case
              }
              self.stack.push(r)
            } else {
              return ParseRepeatedRepetition;
            }
          },
          None => {
            let expr = Regexp::new(op, Some(~r), None);
            self.pushExpression(expr);
          }
          _ => { } // should never hit this case
        }
      }
      _ => {
        return ParseEmptyRepetition;
      }
    }

    ParseOk
  }
  pub fn doKleine(&mut self) -> ParseCode {
    self.doRepeatOp(OpKleine)
  }
  pub fn doOneOrMore(&mut self) -> ParseCode {
    self.doRepeatOp(OpOneOrMore)
  }
  pub fn doZeroOrOne(&mut self) -> ParseCode {
    self.doRepeatOp(OpZeroOrOne)
  }
  pub fn doBoundedRepetition(&mut self, start: uint, end: uint) -> ParseCode {
    match self.stack.pop_opt() {
      Some(ParseStack::Op(_)) => return ParseUnexpectedOperand,
      Some(s) => {
        if start <= end {
          let expr = Regexp::new(OpRepeatOp(start, Some(end)), Some(~s), None);
          self.pushExpression(expr);
        } else {
          return ParseEmptyRepetitionRange
        }
      }
      None => return ParseEmptyRepetition
    }

    ParseOk
  }
  pub fn doUnboundedRepetition(&mut self, start: uint) -> ParseCode {
    match self.stack.pop_opt() {
      Some(ParseStack::Op(_)) => return ParseUnexpectedOperand,
      Some(s) => {
        let expr = Regexp::new(OpRepeatOp(start, None), Some(~s), None);
        self.pushExpression(expr);
      }
      None => return ParseEmptyRepetition
    }

    ParseOk
  }
}

// debug
impl ParseState {
  pub fn trace(&mut self) {
    println("--STACK--");
    for e in self.stack.iter() {
      println(fmt!("%?", e));
    }
  }
}

// tests

#[cfg(test)]
mod char_class_tests {
  use std::char::MAX;
  use state::*;
  use error::ParseError::*;

  macro_rules! create_cc(
    ([ $(($start: expr, $end: expr)),+ ]) => (
      {
        let mut cc = CharClass::new();
        $(
        cc.addRange($start, $end);
        )+
        cc
      }
    )
  )

  macro_rules! expect_code(
    ($f: expr, $code: pat) => (
      {
        let res = match $f {
          $code => true,
          _ => false
        };
        assert!(res);
      }
    )
  )

  #[test]
  fn char_class_good() {
    let cc = create_cc!([('A', 'Z'), ('F', 'F'), ('A', 'あ')]);
    assert_eq!(cc.ranges, ~[('A', 'Z'), ('F', 'F'), ('A', 'あ')]);
  }

  #[test]
  fn char_class_empty() {
    let mut cc = CharClass::new();
    expect_code!(cc.addRange('Z', 'A'), ParseEmptyCharClassRange);
  }

  #[test]
  fn char_class_negate() {
    let mut cc = create_cc!([('A', '\U0000FA08')]);
    cc.negate();
    assert_eq!(cc.ranges, ~[('\U00000000', '@'), ('\U0000FA09', MAX)]);
  }

  #[test]
  fn char_class_negate_multiple() {
    let mut cc = create_cc!([('們', '我'), ('A', 'Z')]);
    cc.negate();
    assert_eq!(cc.ranges, ~[('\U00000000', '@'), ('[', '\U00005010'),
               ('\U00006212', MAX)])
  }

  #[test]
  fn char_class_negate_overlap() {
    let mut cc = create_cc!([('a', 'c'), ('c', 'c')]);
    cc.negate();
    assert_eq!(cc.ranges, ~[('\U00000000', '`'), ('d', MAX)]);
  }

  #[test]
  fn char_class_negate_bounds() {
    let mut cc = create_cc!([('\U00000000', MAX)]);
    expect_code!(cc.negate(), ParseEmptyCharClassRange);
  }
}
<commit_msg>updated style<commit_after>use extra::sort::merge_sort;
use std::char::{from_u32, MAX};
use error::ParseError::*;

// try to get the previous unicode character
// in sequence
fn prev_char(c: char) -> Option<char> {
  match from_u32(c as u32 - 1) {
    None => None,
    r    => r
  }
}

// try to get the next unicode character
// in sequence
fn next_char(c: char) -> Option<char> {
  match from_u32(c as u32 + 1) {
    None => None,
    r    => r
  }
}

pub mod ParseFlags {
  pub static NoParseFlags:  u8 = 0b00000000;
  pub static NoCapture:     u8 = 0b00000010;
  pub static NonGreedy:     u8 = 0b01000000;
}

pub mod ParseStack {
  use super::{OpCode, Literal, Regexp, CharClass};
  // different representations of expressions on
  // the stack
  pub enum Entry {
    Op(OpCode),
    Literal(Literal),
    Expression(Regexp),
    CharClass(CharClass)
  }
}

// A Regex Operation
pub enum OpCode {
  OpConcatenation,
  OpAlternation,
  OpKleine,
  OpZeroOrOne,
  OpOneOrMore,
  OpLineStart,
  OpLineEnd,
  OpLeftParen,
  OpCapture(uint, Option<~str>),
  OpRepeatOp(uint, Option<uint>),
  OpNoop
}

// Regexp Literal
// a literal character in a regex string (i.e 'abcd')
pub struct Literal {
  value: ~str
}

impl Literal {
  pub fn new(s: &str) -> Literal {
    Literal { value: s.clone().to_owned() }
  }
}

// Regexp
// represents a variable number of states with an
// operator applied to them.
pub struct Regexp {
  op: OpCode,
  state0: Option<~ParseStack::Entry>,
  state1: Option<~ParseStack::Entry>,
  flags: u8
}

impl Regexp {
  pub fn new(op: OpCode, state0: Option<~ParseStack::Entry>,
             state1: Option<~ParseStack::Entry>) -> Regexp {
    Regexp {
      op: op,
      state0: state0,
      state1: state1,
      flags: ParseFlags::NoParseFlags
    }
  }
}

impl Regexp {
  pub fn addFlag(&mut self, flag: u8) {
    self.flags = self.flags | flag;
  }
  pub fn hasFlag(&self, flag: u8) -> bool {
    (self.flags & flag) > 0
  }
}

// RegexpCharClass
// represents a character class (i.e '[a-z123]')
pub struct CharClass {
  ranges: ~[(char, char)]
}

impl CharClass {
  pub fn new() -> CharClass {
    CharClass { ranges: ~[] }
  }
}

impl CharClass {
  pub fn negate(&mut self) -> ParseCode {
    let ordered = do merge_sort(self.ranges) |range1, range2| {
      let &(start1, _) = range1;
      let &(start2, _) = range2;
      start1 <= start2
    };

    let mut min: char = '\U00000000';
    let max: char = MAX;

    self.ranges = ~[];

    for &(start, end) in ordered.iter() {
      match prev_char(start) {
        Some(e) => {
          if (min < e) {
            self.addRange(min, e);
          }
        },
        None => { } // continue
      };
      if (min < end) {
        min = match next_char(end) {
          Some(c) => c,
          None => end
        };
      }
    }

    // patch the end
    if (min != max) {
      self.addRange(min, max);
    }

    if self.ranges.len() == 0 {
      ParseEmptyCharClassRange
    } else {
      ParseOk
    }
  }
  pub fn containsChar(&mut self, c: char) -> bool {
    let mut covered = false;

    for &(start, end) in self.ranges.iter() {
      if (c >= start && c <= end) {
        covered = true;
        break
      }
    }

    covered
  }
  pub fn addRange(&mut self, s: char, e: char) -> ParseCode {
    if (s <= e) {
      self.ranges.push((s, e));
    } else {
      return ParseEmptyCharClassRange;
    }

    ParseOk
  }
}

impl CharClass {
}

// current state of parsing
//
// | - nparen:
// |   number of parenthases not resolved
// | - ncaps:
// |   number of parenthases seen
// | - ptr:
// |   reference to a position in the regexp input str
// | - flags:
// |   global flags
pub struct ParseState {
  priv stack: ~[ParseStack::Entry],
  priv nparen: uint,
  priv ncaps: uint,
  priv ptr: uint,
  priv flags: u8
}

impl ParseState {
  pub fn new() -> ParseState {
    ParseState {
      stack: ~[],
      nparen: 0,
      ncaps: 0,
      ptr: 0,
      flags: ParseFlags::NoParseFlags
    }
  }
}

impl ParseState {
  pub fn addFlag(&mut self, flag: u8) {
    self.flags = self.flags | flag;
  }
  pub fn hasFlag(&self, flag: u8) -> bool {
    (self.flags & flag) > 0
  }
}

impl ParseState {
  pub fn pop(&mut self) -> Result<Regexp, ParseCode> {
    match self.stack.pop_opt() {
      Some(ParseStack::Expression(r)) => Ok(r),
      Some(ParseStack::Literal(r)) => {
        Ok(Regexp::new(OpNoop, Some(~ParseStack::Literal(r)), None))
      },
      Some(ParseStack::CharClass(r)) => {
        Ok(Regexp::new(OpNoop, Some(~ParseStack::CharClass(r)), None))
      },
      Some(ParseStack::Op(_)) => Err(ParseInternalError),
      None => Err(ParseEmptyStack)
    }
  }
}

impl ParseState {
  pub fn hasUnmatchedParens(&mut self) -> bool {
    self.nparen > 0
  }
  pub fn hasNoParens(&mut self) -> bool {
    self.nparen == 0
  }
}

impl ParseState {
  pub fn pushLiteral(&mut self, s: &str) {
    self.stack.push(ParseStack::Literal(Literal::new(s)));
  }
  pub fn pushOperation(&mut self, op: OpCode) {
    self.stack.push(ParseStack::Op(op));
  }
  pub fn pushExpression(&mut self, r: Regexp) {
    self.stack.push(ParseStack::Expression(r));
  }
  pub fn pushCharClass(&mut self, cc: CharClass) {
    self.stack.push(ParseStack::CharClass(cc));
  }
}

impl ParseState {
  pub fn pushAlternation(&mut self) {
    self.pushOperation(OpAlternation);
  }
  pub fn pushLeftParen(&mut self) {
    self.nparen += 1;
    self.pushOperation(OpLeftParen);
  }
}

impl ParseState {
  pub fn doAlternation(&mut self) -> ParseCode {
    // try to pop off two items from the stack.
    // these should be branches that you can take.
    //     -> state0
    // s |
    //     -> state1
    //
    // with alternation occuring sequentially, we can
    // make an equivalent model by having state0 or state1
    // also be a regexp with a alternation operand applied to it.
    //     -> state0
    // s |              -> 'state0
    //     -> state1  |
    //                  -> 'state1
    //
    // the operand should be pushed onto the stack before we start parsing
    // the right hand side of the alternation, so the stack should look something
    // like this before doAlternation() is called:
    //
    // state0 (branch2)
    // OpCode(OpAlternation)
    // state1 (branch1)
    let branch1 = match self.stack.pop_opt() {
      Some(s) => s,
      None => return ParseEmptyAlternate
    };
    // make sure there is an alternation operand on the stack,
    // otherwise, might have parsed incorrectly
    match self.stack.pop_opt() {
      Some(ParseStack::Op(OpAlternation)) => { },
      _ => return ParseUnexpectedOperand
    };
    let branch2 = match self.stack.pop_opt() {
      Some(s) => s,
      None => return ParseEmptyAlternate
    };
    let r = Regexp::new(OpAlternation, Some(~branch2), Some(~branch1));

    self.pushExpression(r);

    ParseOk
  }
  pub fn doConcatenation(&mut self) -> ParseCode {
    while (self.stack.len() > 1) {
      // try to take two items off the stack to
      // concatenate.
      // if either of them are opcodes, just
      // push them back no the stack, and return
      // (this means there is a singular item on the stack,
      // and can't be concatenated with anything)
      //
      // state0 -> state1
      let branch1 = match self.stack.pop_opt() {
        Some(ParseStack::Op(op)) => {
          self.pushOperation(op);
          return ParseOk;
        },
        Some(s) => s,
        None => return ParseEmptyConcatenate
      };

      match self.stack.pop_opt() {
        Some(ParseStack::Op(op)) => {
          self.pushOperation(op);
          self.stack.push(branch1);
          return ParseOk;
        },
        Some(ParseStack::Literal(s)) => {
          match branch1 {
            ParseStack::Literal(l) => self.pushLiteral(s.value + l.value),
            _ => {
              let r = Regexp::new(OpConcatenation,
                                  Some(~ParseStack::Literal(s)),
                                  Some(~branch1));
              self.pushExpression(r);
            }
          }
        }
        Some(s) => {
          let r = Regexp::new(OpConcatenation, Some(~s), Some(~branch1));
          self.pushExpression(r);
        },
        None => return ParseEmptyConcatenate
      };
    }

    ParseOk
  }
  pub fn doLeftParen(&mut self, noncapturing: bool) -> ParseCode {
    self.nparen -= 1;
    self.doConcatenation();
    let inner = self.stack.pop();
    // after the left paren operand should be on the top
    // of the stack
    match self.stack.pop_opt() {
      Some(ParseStack::Op(OpLeftParen)) => { },
      _ => return ParseExpectedOperand
    }
    let mut r = Regexp::new(OpCapture(self.ncaps, None),
                            Some(~inner),
                            None);
    if (noncapturing) {
      r.addFlag(ParseFlags::NoCapture);
    } else {
      self.ncaps += 1;
    }

    self.pushExpression(r);

    ParseOk
  }
  pub fn doRepeatOp(&mut self, op: OpCode) -> ParseCode {
    match self.stack.pop_opt() {
      Some(r) => {
        let mut r = r;
        // check if we should have apply a
        // nongreedy flag
        let nongreedy = match op {
          OpZeroOrOne => true,
          _ => false
        };
        // check to see if the expr on the top
        // of the stack has some repition
        // op applied to it.
        let opcode = match &r {
          &ParseStack::Expression(ref e) => {
            match e.op {
              OpKleine => Some(OpKleine),
              OpOneOrMore => Some(OpOneOrMore),
              OpRepeatOp(s, e) => Some(OpRepeatOp(s,e)),
              OpZeroOrOne => Some(OpZeroOrOne),
              _ => None
            }
          },
          _ => {
            None
          }
        };
        // if we found that the expr already had
        // a repeat op, we might need to throw a
        // error
        //
        // otherwise, we can make a new expression.
        match opcode {
          Some(OpOneOrMore) |
          Some(OpKleine) |
          Some(OpRepeatOp(_, _)) |
          Some(OpZeroOrOne) => {
            if (nongreedy) {
              match r {
                ParseStack::Expression(ref mut e) => {
                  e.addFlag(ParseFlags::NonGreedy);
                }
                _ => { } // should never hit this case
              }
              self.stack.push(r)
            } else {
              return ParseRepeatedRepetition;
            }
          },
          None => {
            let expr = Regexp::new(op, Some(~r), None);
            self.pushExpression(expr);
          }
          _ => unreachable!()
        }
      }
      _ => {
        return ParseEmptyRepetition;
      }
    }

    ParseOk
  }
  pub fn doKleine(&mut self) -> ParseCode {
    self.doRepeatOp(OpKleine)
  }
  pub fn doOneOrMore(&mut self) -> ParseCode {
    self.doRepeatOp(OpOneOrMore)
  }
  pub fn doZeroOrOne(&mut self) -> ParseCode {
    self.doRepeatOp(OpZeroOrOne)
  }
  pub fn doBoundedRepetition(&mut self, start: uint, end: uint) -> ParseCode {
    match self.stack.pop_opt() {
      Some(ParseStack::Op(_)) => return ParseUnexpectedOperand,
      Some(s) => {
        if start <= end {
          let expr = Regexp::new(OpRepeatOp(start, Some(end)), Some(~s), None);
          self.pushExpression(expr);
        } else {
          return ParseEmptyRepetitionRange
        }
      }
      None => return ParseEmptyRepetition
    }

    ParseOk
  }
  pub fn doUnboundedRepetition(&mut self, start: uint) -> ParseCode {
    match self.stack.pop_opt() {
      Some(ParseStack::Op(_)) => return ParseUnexpectedOperand,
      Some(s) => {
        let expr = Regexp::new(OpRepeatOp(start, None), Some(~s), None);
        self.pushExpression(expr);
      }
      None => return ParseEmptyRepetition
    }

    ParseOk
  }
}

// debug
impl ParseState {
  pub fn trace(&mut self) {
    println("--STACK--");
    for e in self.stack.iter() {
      println(fmt!("%?", e));
    }
  }
}

// tests

#[cfg(test)]
mod char_class_tests {
  use std::char::MAX;
  use state::*;
  use error::ParseError::*;

  macro_rules! create_cc(
    ([ $(($start: expr, $end: expr)),+ ]) => (
      {
        let mut cc = CharClass::new();
        $(
        cc.addRange($start, $end);
        )+
        cc
      }
    )
  )

  macro_rules! expect_code(
    ($f: expr, $code: pat) => (
      {
        let res = match $f {
          $code => true,
          _ => false
        };
        assert!(res);
      }
    )
  )

  #[test]
  fn char_class_good() {
    let cc = create_cc!([('A', 'Z'), ('F', 'F'), ('A', 'あ')]);
    assert_eq!(cc.ranges, ~[('A', 'Z'), ('F', 'F'), ('A', 'あ')]);
  }

  #[test]
  fn char_class_empty() {
    let mut cc = CharClass::new();
    expect_code!(cc.addRange('Z', 'A'), ParseEmptyCharClassRange);
  }

  #[test]
  fn char_class_negate() {
    let mut cc = create_cc!([('A', '\U0000FA08')]);
    cc.negate();
    assert_eq!(cc.ranges, ~[('\U00000000', '@'), ('\U0000FA09', MAX)]);
  }

  #[test]
  fn char_class_negate_multiple() {
    let mut cc = create_cc!([('們', '我'), ('A', 'Z')]);
    cc.negate();
    assert_eq!(cc.ranges, ~[('\U00000000', '@'), ('[', '\U00005010'),
               ('\U00006212', MAX)])
  }

  #[test]
  fn char_class_negate_overlap() {
    let mut cc = create_cc!([('a', 'c'), ('c', 'c')]);
    cc.negate();
    assert_eq!(cc.ranges, ~[('\U00000000', '`'), ('d', MAX)]);
  }

  #[test]
  fn char_class_negate_bounds() {
    let mut cc = create_cc!([('\U00000000', MAX)]);
    expect_code!(cc.negate(), ParseEmptyCharClassRange);
  }
}
<|endoftext|>


<commit_before>use std::mem;
use std::fmt;
use std::io::{self, Read};
use std::net::SocketAddr;
use std::time::Duration;
use std::borrow::Cow;

use encoding_rs::{Encoding, UTF_8};
use futures::{Async, Poll, Stream};
use http;
use mime::Mime;
use serde::de::DeserializeOwned;
use serde_json;

use client::KeepCoreThreadAlive;
use hyper::header::HeaderMap;
use {async_impl, StatusCode, Url, Version, wait};

/// A Response to a submitted `Request`.
pub struct Response {
    inner: async_impl::Response,
    body: async_impl::ReadableChunks<WaitBody>,
    content_length: Option<u64>,
    _thread_handle: KeepCoreThreadAlive,
}

impl fmt::Debug for Response {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&self.inner, f)
    }
}

impl Response {
    pub(crate) fn new(mut res: async_impl::Response, timeout: Option<Duration>, thread: KeepCoreThreadAlive) -> Response {
        let body = mem::replace(res.body_mut(), async_impl::Decoder::empty());
        let len = body.content_length();
        let body = async_impl::ReadableChunks::new(WaitBody {
            inner: wait::stream(body, timeout)
        });

        Response {
            inner: res,
            body: body,
            content_length: len,
            _thread_handle: thread,
        }
    }

    /// Get the final `Url` of this `Response`.
    ///
    /// # Example
    ///
    /// ```rust
    /// # fn run() -> Result<(), Box<::std::error::Error>> {
    /// let resp = reqwest::get("http://httpbin.org/redirect/1")?;
    /// assert_eq!(resp.url().as_str(), "http://httpbin.org/get");
    /// # Ok(())
    /// # }
    /// ```
    #[inline]
    pub fn url(&self) -> &Url {
        self.inner.url()
    }

    /// Get the remote address used to get this `Response`.
    ///
    /// # Example
    ///
    /// ```rust
    /// # fn run() -> Result<(), Box<::std::error::Error>> {
    /// let resp = reqwest::get("http://httpbin.org/redirect/1")?;
    /// println!("httpbin.org address: {:?}", resp.remote_addr());
    /// # Ok(())
    /// # }
    /// ```
    pub fn remote_addr(&self) -> Option<SocketAddr> {
        self.inner.remote_addr()

    }

    /// Get the `StatusCode` of this `Response`.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # fn run() -> Result<(), Box<::std::error::Error>> {
    /// let resp = reqwest::get("http://httpbin.org/get")?;
    /// if resp.status().is_success() {
    ///     println!("success!");
    /// } else if resp.status().is_server_error() {
    ///     println!("server error!");
    /// } else {
    ///     println!("Something else happened. Status: {:?}", resp.status());
    /// }
    /// # Ok(())
    /// # }
    /// ```
    ///
    /// ```rust
    /// use reqwest::Client;
    /// use reqwest::StatusCode;
    /// # fn run() -> Result<(), Box<::std::error::Error>> {
    /// let client = Client::new();
    /// let resp = client.post("http://httpbin.org/post")
    ///             .body("possibly too large")
    ///             .send()?;
    /// match resp.status() {
    ///     StatusCode::OK => println!("success!"),
    ///     StatusCode::PAYLOAD_TOO_LARGE => {
    ///         println!("Request payload is too large!");
    ///     }
    ///     s => println!("Received response status: {:?}", s),
    /// };
    /// # Ok(())
    /// # }
    /// ```
    #[inline]
    pub fn status(&self) -> StatusCode {
        self.inner.status()
    }

    /// Get the `Headers` of this `Response`.
    ///
    /// # Example
    ///
    /// Checking the `Content-Length` header before reading the response body.
    ///
    /// ```rust
    /// # use std::io::{Read, Write};
    /// # use reqwest::Client;
    /// # use reqwest::header::CONTENT_LENGTH;
    /// #
    /// # fn run() -> Result<(), Box<::std::error::Error>> {
    /// let client = Client::new();
    /// let mut resp = client.head("http://httpbin.org/bytes/3000").send()?;
    /// if resp.status().is_success() {
    ///     let len = resp.headers().get(CONTENT_LENGTH)
    ///                 .and_then(|ct_len| ct_len.to_str().ok())
    ///                 .and_then(|ct_len| ct_len.parse().ok())
    ///                 .unwrap_or(0);
    ///     // limit 1mb response
    ///     if len <= 1_000_000 {
    ///         let mut buf = Vec::with_capacity(len as usize);
    ///         let mut resp = reqwest::get("http://httpbin.org/bytes/3000")?;
    ///         if resp.status().is_success() {
    ///             ::std::io::copy(&mut resp, &mut buf)?;
    ///         }
    ///     }
    /// }
    /// # Ok(())
    /// # }
    /// ```
    #[inline]
    pub fn headers(&self) -> &HeaderMap {
        self.inner.headers()
    }

    /// Get the HTTP `Version` of this `Response`.
    #[inline]
    pub fn version(&self) -> Version {
        self.inner.version()
    }

    /// Try and deserialize the response body as JSON using `serde`.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate reqwest;
    /// # #[macro_use] extern crate serde_derive;
    /// #
    /// # use reqwest::Error;
    /// #
    /// #[derive(Deserialize)]
    /// struct Ip {
    ///     origin: String,
    /// }
    ///
    /// # fn run() -> Result<(), Error> {
    /// let json: Ip = reqwest::get("http://httpbin.org/ip")?.json()?;
    /// # Ok(())
    /// # }
    /// #
    /// # fn main() { }
    /// ```
    ///
    /// # Errors
    ///
    /// This method fails whenever the response body is not in JSON format
    /// or it cannot be properly deserialized to target type `T`. For more
    /// details please see [`serde_json::from_reader`].
    /// [`serde_json::from_reader`]: https://docs.serde.rs/serde_json/fn.from_reader.html
    #[inline]
    pub fn json<T: DeserializeOwned>(&mut self) -> ::Result<T> {
        // There's 2 ways we could implement this:
        //
        // 1. Just using from_reader(self), making use of our blocking read adapter
        // 2. Just use self.inner.json().wait()
        //
        // Doing 1 is pretty easy, but it means we have the `serde_json` code
        // in more than one place, doing basically the same thing.
        //
        // Doing 2 would mean `serde_json` is only in one place, but we'd
        // need to update the sync Response to lazily make a blocking read
        // adapter, so that our `inner` could possibly still have the original
        // body.
        //
        // Went for easier for now, just to get it working.
        serde_json::from_reader(self).map_err(::error::from)
    }

    /// Get the response text.
    ///
    /// This method decodes the response body with BOM sniffing
    /// and with malformed sequences replaced with the REPLACEMENT CHARACTER.
    /// Encoding is determinated from the `charset` parameter of `Content-Type` header,
    /// and defaults to `utf-8` if not presented.
    ///
    /// # Example
    ///
    /// ```rust
    /// # extern crate reqwest;
    /// # fn run() -> Result<(), Box<::std::error::Error>> {
    /// let content = reqwest::get("http://httpbin.org/range/26")?.text()?;
    /// # Ok(())
    /// # }
    /// ```
    ///
    /// # Note
    ///
    /// This consumes the body. Trying to read more, or use of `response.json()`
    /// will return empty values.
    pub fn text(&mut self) -> ::Result<String> {
        let len = self.content_length.unwrap_or(0);
        let mut content = Vec::with_capacity(len as usize);
        self.read_to_end(&mut content).map_err(::error::from)?;
        let content_type = self.headers().get(::header::CONTENT_TYPE)
            .and_then(|value| {
                value.to_str().ok()
            })
            .and_then(|value| {
                value.parse::<Mime>().ok()
            });
        let encoding_name = content_type
            .as_ref()
            .and_then(|mime| {
                mime
                    .get_param("charset")
                    .map(|charset| charset.as_str())
            })
            .unwrap_or("utf-8");
        let encoding = Encoding::for_label(encoding_name.as_bytes()).unwrap_or(UTF_8);
        // a block because of borrow checker
        {
            let (text, _, _) = encoding.decode(&content);
            match text {
                Cow::Owned(s) => return Ok(s),
                _ => (),
            }
        }
        unsafe {
            // decoding returned Cow::Borrowed, meaning these bytes
            // are already valid utf8
            Ok(String::from_utf8_unchecked(content))
        }
    }

    /// Copy the response body into a writer.
    ///
    /// This function internally uses [`std::io::copy`] and hence will continuously read data from
    /// the body and then write it into writer in a streaming fashion until EOF is met.
    ///
    /// On success, the total number of bytes that were copied to `writer` is returned.
    /// [`std::io::copy`]: https://doc.rust-lang.org/std/io/fn.copy.html
    ///
    /// # Example
    ///
    /// ```rust
    /// # fn run() -> Result<(), Box<::std::error::Error>> {
    /// let mut resp = reqwest::get("http://httpbin.org/range/5")?;
    /// let mut buf: Vec<u8> = vec![];
    /// resp.copy_to(&mut buf)?;
    /// assert_eq!(b"abcde", buf.as_slice());
    /// # Ok(())
    /// # }
    /// ```
    #[inline]
    pub fn copy_to<W: ?Sized>(&mut self, w: &mut W) -> ::Result<u64>
        where W: io::Write
    {
        io::copy(self, w).map_err(::error::from)
    }

    /// Turn a response into an error if the server returned an error.
    ///
    /// # Example
    ///
    /// ```rust,no_run
    /// # extern crate reqwest;
    /// # fn run() -> Result<(), Box<::std::error::Error>> {
    /// let res = reqwest::get("http://httpbin.org/status/400")?
    ///     .error_for_status();
    /// if let Err(err) = res {
    ///     assert_eq!(err.status(), Some(reqwest::StatusCode::BAD_REQUEST));
    /// }
    /// # Ok(())
    /// # }
    /// # fn main() {}
    /// ```
    #[inline]
    pub fn error_for_status(self) -> ::Result<Self> {
        let Response { body, content_length, inner, _thread_handle } = self;
        inner.error_for_status().map(move |inner| {
            Response {
                inner,
                body,
                content_length,
                _thread_handle,
            }
        })
    }
}

impl Read for Response {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.body.read(buf)
    }
}

struct WaitBody {
    inner: wait::WaitStream<async_impl::Decoder>
}

impl Stream for WaitBody {
    type Item = <async_impl::Decoder as Stream>::Item;
    type Error = <async_impl::Decoder as Stream>::Error;

    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        match self.inner.next() {
            Some(Ok(chunk)) => Ok(Async::Ready(Some(chunk))),
            Some(Err(e)) => {
                let req_err = match e {
                    wait::Waited::TimedOut => ::error::timedout(None),
                    wait::Waited::Err(e) => e,
                };

                Err(req_err)
            },
            None => Ok(Async::Ready(None)),
        }
    }
}

impl<T: Into<async_impl::body::Body>> From<http::Response<T>> for Response {
    fn from(r: http::Response<T>) -> Response {
        let response = async_impl::Response::from(r);
        Response::new(response, None, KeepCoreThreadAlive::empty())
    }
}
<commit_msg>Response.copy_to: Fix docs markup<commit_after>use std::mem;
use std::fmt;
use std::io::{self, Read};
use std::net::SocketAddr;
use std::time::Duration;
use std::borrow::Cow;

use encoding_rs::{Encoding, UTF_8};
use futures::{Async, Poll, Stream};
use http;
use mime::Mime;
use serde::de::DeserializeOwned;
use serde_json;

use client::KeepCoreThreadAlive;
use hyper::header::HeaderMap;
use {async_impl, StatusCode, Url, Version, wait};

/// A Response to a submitted `Request`.
pub struct Response {
    inner: async_impl::Response,
    body: async_impl::ReadableChunks<WaitBody>,
    content_length: Option<u64>,
    _thread_handle: KeepCoreThreadAlive,
}

impl fmt::Debug for Response {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&self.inner, f)
    }
}

impl Response {
    pub(crate) fn new(mut res: async_impl::Response, timeout: Option<Duration>, thread: KeepCoreThreadAlive) -> Response {
        let body = mem::replace(res.body_mut(), async_impl::Decoder::empty());
        let len = body.content_length();
        let body = async_impl::ReadableChunks::new(WaitBody {
            inner: wait::stream(body, timeout)
        });

        Response {
            inner: res,
            body: body,
            content_length: len,
            _thread_handle: thread,
        }
    }

    /// Get the final `Url` of this `Response`.
    ///
    /// # Example
    ///
    /// ```rust
    /// # fn run() -> Result<(), Box<::std::error::Error>> {
    /// let resp = reqwest::get("http://httpbin.org/redirect/1")?;
    /// assert_eq!(resp.url().as_str(), "http://httpbin.org/get");
    /// # Ok(())
    /// # }
    /// ```
    #[inline]
    pub fn url(&self) -> &Url {
        self.inner.url()
    }

    /// Get the remote address used to get this `Response`.
    ///
    /// # Example
    ///
    /// ```rust
    /// # fn run() -> Result<(), Box<::std::error::Error>> {
    /// let resp = reqwest::get("http://httpbin.org/redirect/1")?;
    /// println!("httpbin.org address: {:?}", resp.remote_addr());
    /// # Ok(())
    /// # }
    /// ```
    pub fn remote_addr(&self) -> Option<SocketAddr> {
        self.inner.remote_addr()

    }

    /// Get the `StatusCode` of this `Response`.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # fn run() -> Result<(), Box<::std::error::Error>> {
    /// let resp = reqwest::get("http://httpbin.org/get")?;
    /// if resp.status().is_success() {
    ///     println!("success!");
    /// } else if resp.status().is_server_error() {
    ///     println!("server error!");
    /// } else {
    ///     println!("Something else happened. Status: {:?}", resp.status());
    /// }
    /// # Ok(())
    /// # }
    /// ```
    ///
    /// ```rust
    /// use reqwest::Client;
    /// use reqwest::StatusCode;
    /// # fn run() -> Result<(), Box<::std::error::Error>> {
    /// let client = Client::new();
    /// let resp = client.post("http://httpbin.org/post")
    ///             .body("possibly too large")
    ///             .send()?;
    /// match resp.status() {
    ///     StatusCode::OK => println!("success!"),
    ///     StatusCode::PAYLOAD_TOO_LARGE => {
    ///         println!("Request payload is too large!");
    ///     }
    ///     s => println!("Received response status: {:?}", s),
    /// };
    /// # Ok(())
    /// # }
    /// ```
    #[inline]
    pub fn status(&self) -> StatusCode {
        self.inner.status()
    }

    /// Get the `Headers` of this `Response`.
    ///
    /// # Example
    ///
    /// Checking the `Content-Length` header before reading the response body.
    ///
    /// ```rust
    /// # use std::io::{Read, Write};
    /// # use reqwest::Client;
    /// # use reqwest::header::CONTENT_LENGTH;
    /// #
    /// # fn run() -> Result<(), Box<::std::error::Error>> {
    /// let client = Client::new();
    /// let mut resp = client.head("http://httpbin.org/bytes/3000").send()?;
    /// if resp.status().is_success() {
    ///     let len = resp.headers().get(CONTENT_LENGTH)
    ///                 .and_then(|ct_len| ct_len.to_str().ok())
    ///                 .and_then(|ct_len| ct_len.parse().ok())
    ///                 .unwrap_or(0);
    ///     // limit 1mb response
    ///     if len <= 1_000_000 {
    ///         let mut buf = Vec::with_capacity(len as usize);
    ///         let mut resp = reqwest::get("http://httpbin.org/bytes/3000")?;
    ///         if resp.status().is_success() {
    ///             ::std::io::copy(&mut resp, &mut buf)?;
    ///         }
    ///     }
    /// }
    /// # Ok(())
    /// # }
    /// ```
    #[inline]
    pub fn headers(&self) -> &HeaderMap {
        self.inner.headers()
    }

    /// Get the HTTP `Version` of this `Response`.
    #[inline]
    pub fn version(&self) -> Version {
        self.inner.version()
    }

    /// Try and deserialize the response body as JSON using `serde`.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # extern crate reqwest;
    /// # #[macro_use] extern crate serde_derive;
    /// #
    /// # use reqwest::Error;
    /// #
    /// #[derive(Deserialize)]
    /// struct Ip {
    ///     origin: String,
    /// }
    ///
    /// # fn run() -> Result<(), Error> {
    /// let json: Ip = reqwest::get("http://httpbin.org/ip")?.json()?;
    /// # Ok(())
    /// # }
    /// #
    /// # fn main() { }
    /// ```
    ///
    /// # Errors
    ///
    /// This method fails whenever the response body is not in JSON format
    /// or it cannot be properly deserialized to target type `T`. For more
    /// details please see [`serde_json::from_reader`].
    /// [`serde_json::from_reader`]: https://docs.serde.rs/serde_json/fn.from_reader.html
    #[inline]
    pub fn json<T: DeserializeOwned>(&mut self) -> ::Result<T> {
        // There's 2 ways we could implement this:
        //
        // 1. Just using from_reader(self), making use of our blocking read adapter
        // 2. Just use self.inner.json().wait()
        //
        // Doing 1 is pretty easy, but it means we have the `serde_json` code
        // in more than one place, doing basically the same thing.
        //
        // Doing 2 would mean `serde_json` is only in one place, but we'd
        // need to update the sync Response to lazily make a blocking read
        // adapter, so that our `inner` could possibly still have the original
        // body.
        //
        // Went for easier for now, just to get it working.
        serde_json::from_reader(self).map_err(::error::from)
    }

    /// Get the response text.
    ///
    /// This method decodes the response body with BOM sniffing
    /// and with malformed sequences replaced with the REPLACEMENT CHARACTER.
    /// Encoding is determinated from the `charset` parameter of `Content-Type` header,
    /// and defaults to `utf-8` if not presented.
    ///
    /// # Example
    ///
    /// ```rust
    /// # extern crate reqwest;
    /// # fn run() -> Result<(), Box<::std::error::Error>> {
    /// let content = reqwest::get("http://httpbin.org/range/26")?.text()?;
    /// # Ok(())
    /// # }
    /// ```
    ///
    /// # Note
    ///
    /// This consumes the body. Trying to read more, or use of `response.json()`
    /// will return empty values.
    pub fn text(&mut self) -> ::Result<String> {
        let len = self.content_length.unwrap_or(0);
        let mut content = Vec::with_capacity(len as usize);
        self.read_to_end(&mut content).map_err(::error::from)?;
        let content_type = self.headers().get(::header::CONTENT_TYPE)
            .and_then(|value| {
                value.to_str().ok()
            })
            .and_then(|value| {
                value.parse::<Mime>().ok()
            });
        let encoding_name = content_type
            .as_ref()
            .and_then(|mime| {
                mime
                    .get_param("charset")
                    .map(|charset| charset.as_str())
            })
            .unwrap_or("utf-8");
        let encoding = Encoding::for_label(encoding_name.as_bytes()).unwrap_or(UTF_8);
        // a block because of borrow checker
        {
            let (text, _, _) = encoding.decode(&content);
            match text {
                Cow::Owned(s) => return Ok(s),
                _ => (),
            }
        }
        unsafe {
            // decoding returned Cow::Borrowed, meaning these bytes
            // are already valid utf8
            Ok(String::from_utf8_unchecked(content))
        }
    }

    /// Copy the response body into a writer.
    ///
    /// This function internally uses [`std::io::copy`] and hence will continuously read data from
    /// the body and then write it into writer in a streaming fashion until EOF is met.
    ///
    /// On success, the total number of bytes that were copied to `writer` is returned.
    ///
    /// [`std::io::copy`]: https://doc.rust-lang.org/std/io/fn.copy.html
    ///
    /// # Example
    ///
    /// ```rust
    /// # fn run() -> Result<(), Box<::std::error::Error>> {
    /// let mut resp = reqwest::get("http://httpbin.org/range/5")?;
    /// let mut buf: Vec<u8> = vec![];
    /// resp.copy_to(&mut buf)?;
    /// assert_eq!(b"abcde", buf.as_slice());
    /// # Ok(())
    /// # }
    /// ```
    #[inline]
    pub fn copy_to<W: ?Sized>(&mut self, w: &mut W) -> ::Result<u64>
        where W: io::Write
    {
        io::copy(self, w).map_err(::error::from)
    }

    /// Turn a response into an error if the server returned an error.
    ///
    /// # Example
    ///
    /// ```rust,no_run
    /// # extern crate reqwest;
    /// # fn run() -> Result<(), Box<::std::error::Error>> {
    /// let res = reqwest::get("http://httpbin.org/status/400")?
    ///     .error_for_status();
    /// if let Err(err) = res {
    ///     assert_eq!(err.status(), Some(reqwest::StatusCode::BAD_REQUEST));
    /// }
    /// # Ok(())
    /// # }
    /// # fn main() {}
    /// ```
    #[inline]
    pub fn error_for_status(self) -> ::Result<Self> {
        let Response { body, content_length, inner, _thread_handle } = self;
        inner.error_for_status().map(move |inner| {
            Response {
                inner,
                body,
                content_length,
                _thread_handle,
            }
        })
    }
}

impl Read for Response {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        self.body.read(buf)
    }
}

struct WaitBody {
    inner: wait::WaitStream<async_impl::Decoder>
}

impl Stream for WaitBody {
    type Item = <async_impl::Decoder as Stream>::Item;
    type Error = <async_impl::Decoder as Stream>::Error;

    fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
        match self.inner.next() {
            Some(Ok(chunk)) => Ok(Async::Ready(Some(chunk))),
            Some(Err(e)) => {
                let req_err = match e {
                    wait::Waited::TimedOut => ::error::timedout(None),
                    wait::Waited::Err(e) => e,
                };

                Err(req_err)
            },
            None => Ok(Async::Ready(None)),
        }
    }
}

impl<T: Into<async_impl::body::Body>> From<http::Response<T>> for Response {
    fn from(r: http::Response<T>) -> Response {
        let response = async_impl::Response::from(r);
        Response::new(response, None, KeepCoreThreadAlive::empty())
    }
}
<|endoftext|>


<commit_before>use action;
use settings;
use glfw;
use Settings = piston::game::Settings;
use Game = piston::game::Game;
use piston::gl::Gl;
use graphics;
use graphics::*;
use object;
use Object = object::Object;
use text;
use game_state;

pub struct SnakeApp {
    settings: Settings,
    // Tells where the surface is.
    surface_y: Option<f64>,
    game_state: Option<game_state::GameState>,
    camera_pos: Option<[f64, ..2]>,
    camera_follow_percentage: Option<f64>,
    player_index: Option<uint>,
    blood_bar_index: Option<uint>,
    // Contains the game objects.
    objects: Vec<Object>,
}

impl Game for SnakeApp {
    fn get_settings<'a>(&'a self) -> &'a Settings { &self.settings }

    fn render(&self, c: &graphics::Context, gl: &mut Gl) {
        // Get camera coordinates.
        let (cam_x, cam_y) = if self.camera_pos.is_some() {
                let camera_pos = self.camera_pos.unwrap();
                (camera_pos[0], camera_pos[1])
            } else { (0.0, 0.0) };

        // Render surface.
        let surface_y = self.surface_y.unwrap();
        c.rect(-1.0, surface_y - cam_y, 2.0, 0.05).color(settings::BLUE).fill(gl);

        // Render round rectangle around bars.
        let bar_bgh = settings::BAR_BACKGROUND_HEIGHT;
        let bar_color = settings::BAR_BACKGROUND_COLOR;
        c.rect(-1.0, 1.0 - bar_bgh, 2.0, bar_bgh).round(0.1).color(bar_color).fill(gl);

        // Render objects.
        let cam = &c.trans(-cam_x, -cam_y);
        for obj in self.objects.iter() {
            obj.render(cam, c, gl);
        }

        match self.game_state.unwrap() {
            game_state::Win => {
                let pos = settings::YOU_WIN_POS;
                text::text("you win", &c.flip_v_local().zoom(0.0025).trans(pos[0], pos[1]).color(settings::YOU_WIN_TEXT_COLOR), gl);
            },
            game_state::Loose => {

            },
            game_state::Play => {

            },
        }

        // TEST
        // text::text("restart", &c.flip_v_local().zoom(0.001).color(settings::BLACK), gl);
    }

    fn update(&mut self, dt: f64) {
        if self.player_index == None { return; }

        // Update states of objects.
        let player_index = self.player_index.unwrap();
        let player_pos = self.objects.get(player_index).pos;
        let mut attack_damage: f64 = 0.0;
        for obj in self.objects.mut_iter() {
            match obj.update(dt, player_pos) {
                action::Passive => {},
                action::Attack(attack) => { attack_damage += attack; },
            }
        }

        // When player reaches surface, win.
        if player_pos[1] >= self.surface_y.unwrap() {
            self.game_state = Some(game_state::Win);
            return;
        }

        // Decrease the players life with attacks.
        *self.objects.get_mut(player_index).blood_mut().unwrap() -= attack_damage;

        if self.blood_bar_index == None { return; }

        // Show blood.
        let player_blood = self.objects.get(player_index).blood().unwrap();
        let blood_bar_index = self.blood_bar_index.unwrap();
        let blood_bar = self.objects.get_mut(blood_bar_index);
        match blood_bar.data {
            object::BarData(ref mut bar) => {
                bar.value = player_blood;
            },
            _ => {},
        }

        if self.camera_pos.is_none() { return; }

        // Make camera follow player.
        let camera_pos = self.camera_pos.unwrap();
        let camera_follow_percentage = self.camera_follow_percentage.unwrap();
        let (dx, dy) = (player_pos[0] - camera_pos[0], player_pos[1] - camera_pos[1]);
        let dx = camera_follow_percentage * dt * dx;
        let dy = camera_follow_percentage * dt * dy;
        self.camera_pos = Some([camera_pos[0] + dx, camera_pos[1] + dy]);
    }

    fn load(&mut self) {
        self.camera_follow_percentage = Some(settings::CAMERA_FOLLOW_PERCENTAGE);
        self.camera_pos = Some(settings::INITIAL_CAMERA_POS);
        self.surface_y = Some(settings::SURFACE_Y);
        self.game_state = Some(settings::INITIAL_GAME_STATE);

        // Add player.
        self.objects.push(Object::player(
            settings::ORIGIN,
            settings::BLUE,
            settings::PLAYER_INITIAL_BLOOD,
            [settings::PLAYER_SPEED_LEFT, settings::PLAYER_SPEED_RIGHT],
            [settings::PLAYER_SPEED_UP, settings::PLAYER_SPEED_DOWN]
        ));
        self.player_index = Some(0);

        // Add blood and air bar.
        self.add_bars();

        // Add sharks.
        self.add_sharks();
    }

    fn key_press(&mut self, key: glfw::Key) {
        // TEST
        // println!("Key pressed {}", key);

        if self.game_state.unwrap() != game_state::Play { return; }

        match (key, self.player_index) {
            (glfw::KeyRight, Some(player_index)) => {
                self.objects.get_mut(player_index).move_right();
            },
            (glfw::KeyUp, Some(player_index)) => {
                self.objects.get_mut(player_index).move_up();
            },
            (glfw::KeyLeft, Some(player_index)) => {
                self.objects.get_mut(player_index).move_left();
            },
            (glfw::KeyDown, Some(player_index)) => {
                self.objects.get_mut(player_index).move_down();
            },
            _ => {},
        }
    }

    fn key_release(&mut self, key: glfw::Key) {
        // TEST
        // println!("Key released {}", key);
    }
}

impl SnakeApp {
    pub fn new() -> SnakeApp {
        let exit_on_esc = true;
        let background_color = [1.0, 1.0, 1.0, 1.0];
        SnakeApp {
            camera_pos: None,
            camera_follow_percentage: None,
            settings: Settings::new(exit_on_esc, background_color),
            game_state: None,
            surface_y: None,
            objects: Vec::new(),
            player_index: None,
            blood_bar_index: None,
        }
    }

    pub fn add_bars(&mut self) {
        self.objects.push(Object::bar(
            settings::AIR_BAR_POS,
            "air",
            settings::AIR_BAR_TEXT_COLOR,
            settings::AIR_BAR_BACKGROUND_COLOR,
            settings::AIR_BAR_BAR_COLOR,
            settings::AIR_BAR_INITIAL_VALUE
        ));
        self.objects.push(Object::bar(
            settings::BLOOD_BAR_POS,
            "blood",
            settings::BLOOD_BAR_TEXT_COLOR,
            settings::BLOOD_BAR_BACKGROUND_COLOR,
            settings::BLOOD_BAR_BAR_COLOR,
            settings::BLOOD_BAR_INITIAL_VALUE
        ));
        self.blood_bar_index = Some(self.objects.len() - 1);
    }

    pub fn add_sharks(&mut self) {
        self.objects.push(Object::shark(settings::SHARK_1_POS, settings::SHARK_1_SETTINGS));
    }
}

<commit_msg>Refactored<commit_after>use action;
use settings;
use glfw;
use Settings = piston::game::Settings;
use Game = piston::game::Game;
use piston::gl::Gl;
use graphics;
use graphics::*;
use object;
use Object = object::Object;
use text;
use game_state;

pub struct SnakeApp {
    settings: Settings,
    // Tells where the surface is.
    surface_y: Option<f64>,
    game_state: Option<game_state::GameState>,
    camera_pos: Option<[f64, ..2]>,
    camera_follow_percentage: Option<f64>,
    player_index: Option<uint>,
    blood_bar_index: Option<uint>,
    // Contains the game objects.
    objects: Vec<Object>,
}

impl Game for SnakeApp {
    fn get_settings<'a>(&'a self) -> &'a Settings { &self.settings }

    fn render(&self, c: &graphics::Context, gl: &mut Gl) {
        // Get camera coordinates.
        let (cam_x, cam_y) = if self.camera_pos.is_some() {
                let camera_pos = self.camera_pos.unwrap();
                (camera_pos[0], camera_pos[1])
            } else { (0.0, 0.0) };

        // Render surface.
        let surface_y = self.surface_y.unwrap();
        c.rect(-1.0, surface_y - cam_y, 2.0, 0.05).color(settings::BLUE).fill(gl);

        // Render round rectangle around bars.
        let bar_bgh = settings::BAR_BACKGROUND_HEIGHT;
        let bar_color = settings::BAR_BACKGROUND_COLOR;
        c.rect(-1.0, 1.0 - bar_bgh, 2.0, bar_bgh).round(0.1).color(bar_color).fill(gl);

        // Render objects.
        let cam = &c.trans(-cam_x, -cam_y);
        for obj in self.objects.iter() {
            obj.render(cam, c, gl);
        }

        match self.game_state.unwrap() {
            game_state::Win => {
                let pos = settings::YOU_WIN_POS;
                text::text("you win", &c.flip_v_local().zoom(0.0025).trans(pos[0], pos[1]).color(settings::YOU_WIN_TEXT_COLOR), gl);
            },
            game_state::Loose => {

            },
            game_state::Play => {

            },
        }

        // TEST
        // text::text("restart", &c.flip_v_local().zoom(0.001).color(settings::BLACK), gl);
    }

    fn update(&mut self, dt: f64) {
        self.update_objects(dt);
        self.win();
        self.show_blood();
        self.follow_player(dt);
    }

    fn load(&mut self) {
        self.camera_follow_percentage = Some(settings::CAMERA_FOLLOW_PERCENTAGE);
        self.camera_pos = Some(settings::INITIAL_CAMERA_POS);
        self.surface_y = Some(settings::SURFACE_Y);
        self.game_state = Some(settings::INITIAL_GAME_STATE);

        // Add player.
        self.objects.push(Object::player(
            settings::ORIGIN,
            settings::BLUE,
            settings::PLAYER_INITIAL_BLOOD,
            [settings::PLAYER_SPEED_LEFT, settings::PLAYER_SPEED_RIGHT],
            [settings::PLAYER_SPEED_UP, settings::PLAYER_SPEED_DOWN]
        ));
        self.player_index = Some(0);

        // Add blood and air bar.
        self.add_bars();

        // Add sharks.
        self.add_sharks();
    }

    fn key_press(&mut self, key: glfw::Key) {
        // TEST
        // println!("Key pressed {}", key);

        if self.game_state.unwrap() != game_state::Play { return; }

        match (key, self.player_index) {
            (glfw::KeyRight, Some(player_index)) => {
                self.objects.get_mut(player_index).move_right();
            },
            (glfw::KeyUp, Some(player_index)) => {
                self.objects.get_mut(player_index).move_up();
            },
            (glfw::KeyLeft, Some(player_index)) => {
                self.objects.get_mut(player_index).move_left();
            },
            (glfw::KeyDown, Some(player_index)) => {
                self.objects.get_mut(player_index).move_down();
            },
            _ => {},
        }
    }

    fn key_release(&mut self, key: glfw::Key) {
        // TEST
        // println!("Key released {}", key);
    }
}

impl SnakeApp {
    pub fn new() -> SnakeApp {
        let exit_on_esc = true;
        let background_color = [1.0, 1.0, 1.0, 1.0];
        SnakeApp {
            camera_pos: None,
            camera_follow_percentage: None,
            settings: Settings::new(exit_on_esc, background_color),
            game_state: None,
            surface_y: None,
            objects: Vec::new(),
            player_index: None,
            blood_bar_index: None,
        }
    }

    pub fn add_bars(&mut self) {
        self.objects.push(Object::bar(
            settings::AIR_BAR_POS,
            "air",
            settings::AIR_BAR_TEXT_COLOR,
            settings::AIR_BAR_BACKGROUND_COLOR,
            settings::AIR_BAR_BAR_COLOR,
            settings::AIR_BAR_INITIAL_VALUE
        ));
        self.objects.push(Object::bar(
            settings::BLOOD_BAR_POS,
            "blood",
            settings::BLOOD_BAR_TEXT_COLOR,
            settings::BLOOD_BAR_BACKGROUND_COLOR,
            settings::BLOOD_BAR_BAR_COLOR,
            settings::BLOOD_BAR_INITIAL_VALUE
        ));
        self.blood_bar_index = Some(self.objects.len() - 1);
    }

    pub fn add_sharks(&mut self) {
        self.objects.push(Object::shark(settings::SHARK_1_POS, settings::SHARK_1_SETTINGS));
    }

    fn follow_player(&mut self, dt: f64) {
        if self.camera_pos.is_none() { return; }
        // Make camera follow player.
        let camera_pos = self.camera_pos.unwrap();
        let camera_follow_percentage = self.camera_follow_percentage.unwrap();
        let player_pos = self.player_pos();
        let (dx, dy) = (player_pos[0] - camera_pos[0], player_pos[1] - camera_pos[1]);
        let dx = camera_follow_percentage * dt * dx;
        let dy = camera_follow_percentage * dt * dy;
        self.camera_pos = Some([camera_pos[0] + dx, camera_pos[1] + dy]);
    }

    fn show_blood(&mut self) {
        if self.blood_bar_index == None { return; }
        // Show blood.
        let player_blood = self.player_blood();
        let blood_bar_index = self.blood_bar_index.unwrap();
        let blood_bar = self.objects.get_mut(blood_bar_index);
        match blood_bar.data {
            object::BarData(ref mut bar) => {
                bar.value = player_blood;
            },
            _ => {},
        }
    }

    fn win(&mut self) {
        let player_pos = self.player_pos();
        // When player reaches surface, win.
        if player_pos[1] >= self.surface_y.unwrap() {
            self.game_state = Some(game_state::Win);
            return;
        }
    }

    fn update_objects(&mut self, dt: f64) {
        // Update states of objects.
        let player_pos = self.player_pos();
        let mut attack_damage: f64 = 0.0;
        for obj in self.objects.mut_iter() {
            match obj.update(dt, player_pos) {
                action::Passive => {},
                action::Attack(attack) => { attack_damage += attack; },
            }
        }
        // Decrease the players life with attacks.
        let blood = self.player_blood();
        self.set_player_blood(blood - attack_damage);
    }

    fn player_pos(&self) -> [f64, ..2] {
        let player_index = self.player_index.unwrap();
        self.objects.get(player_index).pos
    }

    fn player_blood(&self) -> f64 {
        let player_index = self.player_index.unwrap();
        self.objects.get(player_index).blood().unwrap()
    }

    fn set_player_blood(&mut self, val: f64) {
        let player_index = self.player_index.unwrap();
        *self.objects.get_mut(player_index).blood_mut().unwrap() = val;
    }
}

<|endoftext|>


<commit_before>use serde_json::value::Value;
use easter::expr::Expr;
use easter::obj::DotKey;
use easter::id::IdExt;
use easter::punc::{Unop, Binop, Assop, Logop};
use unjson::ty::{Object, TyOf};
use unjson::ExtractField;
use joker::token::RegExpLiteral;

use tag::{Tag, TagOf};
use id::IntoId;
use result::Result;
use error::{Error, string_error, node_type_error, type_error};
use node::ExtractNode;
use fun::IntoFun;
use lit::{IntoStringLiteral, IntoNumberLiteral};

pub trait IntoExpr {
    fn into_expr(self) -> Result<Expr>;
    fn into_lit(self) -> Result<Expr>;
}

impl IntoExpr for Object {
    fn into_expr(mut self) -> Result<Expr> {
        let tag = try!(self.tag());
        Ok(match tag {
            Tag::Identifier => { return Ok(try!(self.into_id()).into_expr()); }
            Tag::Literal => try!(IntoExpr::into_lit(self)),
            Tag::BinaryExpression => {
                let str = try!(self.extract_string("operator").map_err(Error::Json));
                let op: Binop = match str.parse() {
                    Ok(op) => op,
                    Err(_) => { return string_error("binary operator", str); }
                };
                let left = try!(self.extract_expr("left"));
                let right = try!(self.extract_expr("right"));
                Expr::Binop(None, op, Box::new(left), Box::new(right))
            }
            Tag::AssignmentExpression => {
                let str = try!(self.extract_string("operator").map_err(Error::Json));
                let right = Box::new(try!(self.extract_expr("right")));
                match &str[..] {
                    "=" => Expr::Assign(None, try!(self.extract_assign_patt("left")), right),
                    _ => {
                        let op: Assop = match str.parse() {
                            Ok(op) => op,
                            Err(_) => { return string_error("assignment operator", str); }
                        };
                        Expr::BinAssign(None, op, try!(self.extract_assign_target("left")), right)
                    }
                }
            }
            Tag::LogicalExpression => {
                let str = try!(self.extract_string("operator").map_err(Error::Json));
                let op: Logop = match str.parse() {
                    Ok(op) => op,
                    Err(_) => { return string_error("logical operator", str); }
                };
                let left = try!(self.extract_expr("left"));
                let right = try!(self.extract_expr("right"));
                Expr::Logop(None, op, Box::new(left), Box::new(right))
            }
            Tag::UnaryExpression => {
                let str = try!(self.extract_string("operator").map_err(Error::Json));
                let op: Unop = match str.parse() {
                    Ok(op) => op,
                    Err(_) => { return string_error("unary operator", str); }
                };
                let arg = try!(self.extract_expr("argument"));
                Expr::Unop(None, op, Box::new(arg))
            }
            Tag::UpdateExpression => {
                let op = try!(self.extract_string("operator").map_err(Error::Json));
                let arg = Box::new(try!(self.extract_assign_target("argument")));
                let prefix = try!(self.extract_bool("prefix").map_err(Error::Json));
                match (&op[..], prefix) {
                    ("++", true)  => Expr::PreInc(None, arg),
                    ("++", false) => Expr::PostInc(None, arg),
                    ("--", true)  => Expr::PreDec(None, arg),
                    ("--", false) => Expr::PostDec(None, arg),
                    _ => { return string_error("'++' or '--'", op); }
                }
            }
            Tag::MemberExpression => {
                let obj = Box::new(try!(self.extract_expr("object")));
                if try!(self.extract_bool("computed").map_err(Error::Json)) {
                    let prop = Box::new(try!(self.extract_expr("property")));
                    Expr::Brack(None, obj, prop)
                } else {
                    let id = try!(try!(self.extract_object("property").map_err(Error::Json)).into_id());
                    let key = DotKey { location: None, value: id.name.into_string() };
                    Expr::Dot(None, obj, key)
                }
            }
            Tag::CallExpression => {
                let callee = Box::new(try!(self.extract_expr("callee")));
                let args = try!(self.extract_expr_list("arguments"));
                Expr::Call(None, callee, args)
            }
            Tag::NewExpression => {
                let callee = Box::new(try!(self.extract_expr("callee")));
                let args = try!(self.extract_expr_list("arguments"));
                Expr::New(None, callee, Some(args))
            }
            Tag::ArrayExpression => {
                let elts = try!(self.extract_expr_opt_list("elements"));
                Expr::Arr(None, elts)
            }
            Tag::FunctionExpression => {
                let fun = try!(self.into_fun());
                Expr::Fun(fun)
            }
            Tag::SequenceExpression => {
                let exprs = try!(self.extract_expr_list("expressions"));
                Expr::Seq(None, exprs)
            }
            Tag::ObjectExpression => {
                let props = try!(self.extract_prop_list("properties"));
                Expr::Obj(None, props)
            }
            Tag::ConditionalExpression => {
                let test = Box::new(try!(self.extract_expr("test")));
                let cons = Box::new(try!(self.extract_expr("consequent")));
                let alt = Box::new(try!(self.extract_expr("alternate")));
                Expr::Cond(None, test, cons, alt)
            }
            Tag::ThisExpression => Expr::This(None),
            _ => { return node_type_error("expression", tag); }
        })
    }

    fn into_lit(mut self) -> Result<Expr> {
        let json = try!(self.extract_field("value").map_err(Error::Json));
        Ok(match json {
            Value::Bool(val) => if val { Expr::True(None) } else { Expr::False(None) },
            Value::String(value) => Expr::String(None, value.into_string_literal()),
            Value::I64(val) => Expr::Number(None, val.into_number_literal()),
            Value::U64(val) => Expr::Number(None, val.into_number_literal()),
            Value::F64(val) => Expr::Number(None, val.into_number_literal()),
            Value::Null | Value::Object(_) => {
                if json == Value::Null && !self.contains_key("regex") {
                    Expr::Null(None)
                } else {
                    let mut regex = try!(self.extract_object("regex").map_err(Error::Json));
                    let pattern = try!(regex.extract_string("pattern").map_err(Error::Json));
                    let flags = try!(regex.extract_string("flags").map_err(Error::Json));
                    Expr::RegExp(None, RegExpLiteral {
                        pattern: pattern,
                        flags: flags.chars().collect()
                    })
                }
            }
            _ => { return type_error("null, number, boolean, string, or object", json.ty()); }
        })
    }
}
<commit_msg>Use better pattern matching in into_lit.<commit_after>use serde_json::value::Value;
use easter::expr::Expr;
use easter::obj::DotKey;
use easter::id::IdExt;
use easter::punc::{Unop, Binop, Assop, Logop};
use unjson::ty::{Object, TyOf};
use unjson::ExtractField;
use joker::token::RegExpLiteral;

use tag::{Tag, TagOf};
use id::IntoId;
use result::Result;
use error::{Error, string_error, node_type_error, type_error};
use node::ExtractNode;
use fun::IntoFun;
use lit::{IntoStringLiteral, IntoNumberLiteral};

pub trait IntoExpr {
    fn into_expr(self) -> Result<Expr>;
    fn into_lit(self) -> Result<Expr>;
}

impl IntoExpr for Object {
    fn into_expr(mut self) -> Result<Expr> {
        let tag = try!(self.tag());
        Ok(match tag {
            Tag::Identifier => { return Ok(try!(self.into_id()).into_expr()); }
            Tag::Literal => try!(IntoExpr::into_lit(self)),
            Tag::BinaryExpression => {
                let str = try!(self.extract_string("operator").map_err(Error::Json));
                let op: Binop = match str.parse() {
                    Ok(op) => op,
                    Err(_) => { return string_error("binary operator", str); }
                };
                let left = try!(self.extract_expr("left"));
                let right = try!(self.extract_expr("right"));
                Expr::Binop(None, op, Box::new(left), Box::new(right))
            }
            Tag::AssignmentExpression => {
                let str = try!(self.extract_string("operator").map_err(Error::Json));
                let right = Box::new(try!(self.extract_expr("right")));
                match &str[..] {
                    "=" => Expr::Assign(None, try!(self.extract_assign_patt("left")), right),
                    _ => {
                        let op: Assop = match str.parse() {
                            Ok(op) => op,
                            Err(_) => { return string_error("assignment operator", str); }
                        };
                        Expr::BinAssign(None, op, try!(self.extract_assign_target("left")), right)
                    }
                }
            }
            Tag::LogicalExpression => {
                let str = try!(self.extract_string("operator").map_err(Error::Json));
                let op: Logop = match str.parse() {
                    Ok(op) => op,
                    Err(_) => { return string_error("logical operator", str); }
                };
                let left = try!(self.extract_expr("left"));
                let right = try!(self.extract_expr("right"));
                Expr::Logop(None, op, Box::new(left), Box::new(right))
            }
            Tag::UnaryExpression => {
                let str = try!(self.extract_string("operator").map_err(Error::Json));
                let op: Unop = match str.parse() {
                    Ok(op) => op,
                    Err(_) => { return string_error("unary operator", str); }
                };
                let arg = try!(self.extract_expr("argument"));
                Expr::Unop(None, op, Box::new(arg))
            }
            Tag::UpdateExpression => {
                let op = try!(self.extract_string("operator").map_err(Error::Json));
                let arg = Box::new(try!(self.extract_assign_target("argument")));
                let prefix = try!(self.extract_bool("prefix").map_err(Error::Json));
                match (&op[..], prefix) {
                    ("++", true)  => Expr::PreInc(None, arg),
                    ("++", false) => Expr::PostInc(None, arg),
                    ("--", true)  => Expr::PreDec(None, arg),
                    ("--", false) => Expr::PostDec(None, arg),
                    _ => { return string_error("'++' or '--'", op); }
                }
            }
            Tag::MemberExpression => {
                let obj = Box::new(try!(self.extract_expr("object")));
                if try!(self.extract_bool("computed").map_err(Error::Json)) {
                    let prop = Box::new(try!(self.extract_expr("property")));
                    Expr::Brack(None, obj, prop)
                } else {
                    let id = try!(try!(self.extract_object("property").map_err(Error::Json)).into_id());
                    let key = DotKey { location: None, value: id.name.into_string() };
                    Expr::Dot(None, obj, key)
                }
            }
            Tag::CallExpression => {
                let callee = Box::new(try!(self.extract_expr("callee")));
                let args = try!(self.extract_expr_list("arguments"));
                Expr::Call(None, callee, args)
            }
            Tag::NewExpression => {
                let callee = Box::new(try!(self.extract_expr("callee")));
                let args = try!(self.extract_expr_list("arguments"));
                Expr::New(None, callee, Some(args))
            }
            Tag::ArrayExpression => {
                let elts = try!(self.extract_expr_opt_list("elements"));
                Expr::Arr(None, elts)
            }
            Tag::FunctionExpression => {
                let fun = try!(self.into_fun());
                Expr::Fun(fun)
            }
            Tag::SequenceExpression => {
                let exprs = try!(self.extract_expr_list("expressions"));
                Expr::Seq(None, exprs)
            }
            Tag::ObjectExpression => {
                let props = try!(self.extract_prop_list("properties"));
                Expr::Obj(None, props)
            }
            Tag::ConditionalExpression => {
                let test = Box::new(try!(self.extract_expr("test")));
                let cons = Box::new(try!(self.extract_expr("consequent")));
                let alt = Box::new(try!(self.extract_expr("alternate")));
                Expr::Cond(None, test, cons, alt)
            }
            Tag::ThisExpression => Expr::This(None),
            _ => { return node_type_error("expression", tag); }
        })
    }

    fn into_lit(mut self) -> Result<Expr> {
        let json = try!(self.extract_field("value").map_err(Error::Json));
        Ok(match json {
            Value::Null if !self.contains_key("regex") => Expr::Null(None),
            Value::Bool(true) => Expr::True(None),
            Value::Bool(false) => Expr::False(None),
            Value::String(value) => Expr::String(None, value.into_string_literal()),
            Value::I64(val) => Expr::Number(None, val.into_number_literal()),
            Value::U64(val) => Expr::Number(None, val.into_number_literal()),
            Value::F64(val) => Expr::Number(None, val.into_number_literal()),
            Value::Null | Value::Object(_) => {
                let mut regex = try!(self.extract_object("regex").map_err(Error::Json));
                let pattern = try!(regex.extract_string("pattern").map_err(Error::Json));
                let flags = try!(regex.extract_string("flags").map_err(Error::Json));
                Expr::RegExp(None, RegExpLiteral {
                    pattern: pattern,
                    flags: flags.chars().collect()
                })
            }
            _ => { return type_error("null, number, boolean, string, or object", json.ty()); }
        })
    }
}
<|endoftext|>