<commit_before>use gen::GenError;

pub trait SerializeFn<I>: Fn(I) -> Result<I, GenError> {}

impl<I, F:  Fn(I) ->Result<I, GenError>> SerializeFn<I> for F {}

pub fn slice<'a, S: 'a + AsRef<[u8]>>(data: S) -> impl SerializeFn<&'a mut [u8]> {
    let len = data.as_ref().len();

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            (&mut out[..len]).copy_from_slice(data.as_ref());
            Ok(&mut out[len..])
        }
    }
}

pub fn string<'a, S: 'a+AsRef<str>>(data: S) -> impl SerializeFn<&'a mut [u8]> {

    let len = data.as_ref().len();
    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            (&mut out[..len]).copy_from_slice(data.as_ref().as_bytes());
            Ok(&mut out[len..])
        }
    }
}

use std::io::{Cursor, Write};
use std::fmt;
pub fn hex<'a, S: 'a + fmt::UpperHex>(data: S) -> impl SerializeFn<&'a mut [u8]> {

  move |out: &'a mut [u8]| {
    let mut c = Cursor::new(out);
    match write!(&mut c, "{:X}", data) {
      Err(_) => Err(GenError::CustomError(42)),
      Ok(_) => {
        let pos = c.position() as usize;
        let out = c.into_inner();
        Ok(&mut out[pos..])
      }
    }
  }
}

pub fn skip<'a>(len: usize) -> impl SerializeFn<&'a mut [u8]> {

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            Ok(&mut out[len..])
        }
    }
}

pub fn position<'a, F>(f: F) -> impl Fn(&'a mut [u8]) -> Result<(&'a mut [u8], &'a mut [u8]), GenError>
  where F: SerializeFn<&'a mut [u8]> {

    move |out: &'a mut [u8]| {
        unsafe {
            let ptr = out.as_mut_ptr();
            let out = f(out)?;
            let len = out.as_ptr() as usize - ptr as usize;

            Ok((std::slice::from_raw_parts_mut(ptr, len), out))
        }
    }
}

fn pair<F, G, I>(first: F, second: G) -> impl SerializeFn<I>
where F: SerializeFn<I>,
      G: SerializeFn<I> {

  move |out: I| {
    let out = first(out)?;
    second(out)
  }
}

fn cond<F, G, I>(condition: bool, f: F) -> impl SerializeFn<I>
where F: SerializeFn<I>, {

  move |out: I| {
    if condition {
      f(out)
    } else {
      Ok(out)
    }
  }
}

pub fn all<'a, 'b, G, I, It>(values: It) -> impl SerializeFn<I> + 'a
  where G: SerializeFn<I> + 'b,
        It: 'a + Clone + Iterator<Item=G> {

  move |mut out: I| {
    let it = values.clone();

    for v in it {
      out = v(out)?;
    }

    Ok(out)
  }
}

pub fn separated_list<'a, 'b, 'c, F, G, I, It: Iterator<Item=G>, Arg: 'a+Clone+IntoIterator<Item=G, IntoIter=It>>(sep: F, values: Arg) -> impl SerializeFn<I> + 'a
  where F: SerializeFn<I> + 'b + 'a,
        G: SerializeFn<I> + 'c {

  move |mut out: I| {
    let mut it = values.clone().into_iter();
    match it.next() {
      None => return Ok(out),
      Some(first) => {
        out = first(out)?;
      }
    }

    for v in it {
      out = sep(out)?;
      out = v(out)?;
    }

    Ok(out)
  }
}

pub fn be_u8<'a>(i: u8) -> impl SerializeFn<&'a mut [u8]> {
   let len = 1;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = i;
            Ok(&mut out[len..])
        }
    }
}

pub fn be_u16<'a>(i: u16) -> impl SerializeFn<&'a mut [u8]> {
   let len = 2;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = ((i >> 8) & 0xff) as u8;
            out[1] = (i        & 0xff) as u8;
            Ok(&mut out[len..])
        }
    }
}

pub fn be_u32<'a>(i: u32) -> impl SerializeFn<&'a mut [u8]> {
   let len = 4;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = ((i >> 24) & 0xff) as u8;
            out[1] = ((i >> 16) & 0xff) as u8;
            out[2] = ((i >> 8)  & 0xff) as u8;
            out[3] = (i         & 0xff) as u8;
            Ok(&mut out[len..])
        }
    }
}

pub fn be_u64<'a>(i: u64) -> impl SerializeFn<&'a mut [u8]> {
   let len = 8;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = ((i >> 56) & 0xff) as u8;
            out[1] = ((i >> 48) & 0xff) as u8;
            out[2] = ((i >> 40) & 0xff) as u8;
            out[3] = ((i >> 32) & 0xff) as u8;
            out[4] = ((i >> 24) & 0xff) as u8;
            out[5] = ((i >> 16) & 0xff) as u8;
            out[6] = ((i >> 8)  & 0xff) as u8;
            out[7] = (i         & 0xff) as u8;
            Ok(&mut out[len..])
        }
    }
}

pub fn be_i8<'a>(i: i8) -> impl SerializeFn<&'a mut [u8]> {
    be_u8(i as u8)
}

pub fn be_i16<'a>(i: i16) -> impl SerializeFn<&'a mut [u8]> {
    be_u16(i as u16)
}

pub fn be_i32<'a>(i: i32) -> impl SerializeFn<&'a mut [u8]> {
    be_u32(i as u32)
}

pub fn be_i64<'a>(i: i64) -> impl SerializeFn<&'a mut [u8]> {
    be_u64(i as u64)
}

pub fn be_f32<'a>(i: f32) -> impl SerializeFn<&'a mut [u8]> {
    be_u32(unsafe { std::mem::transmute::<f32, u32>(i) })
}

pub fn be_f64<'a>(i: f64) -> impl SerializeFn<&'a mut [u8]> {
    be_u64(unsafe { std::mem::transmute::<f64, u64>(i) })
}

pub fn le_u8<'a>(i: u8) -> impl SerializeFn<&'a mut [u8]> {
   let len = 1;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = i;
            Ok(&mut out[len..])
        }
    }
}

pub fn le_u16<'a>(i: u16) -> impl SerializeFn<&'a mut [u8]> {
   let len = 2;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = (i        & 0xff) as u8;
            out[1] = ((i >> 8) & 0xff) as u8;
            Ok(&mut out[len..])
        }
    }
}

pub fn le_u32<'a>(i: u32) -> impl SerializeFn<&'a mut [u8]> {
   let len = 4;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = (i         & 0xff) as u8;
            out[1] = ((i >> 8)  & 0xff) as u8;
            out[2] = ((i >> 16) & 0xff) as u8;
            out[3] = ((i >> 24) & 0xff) as u8;
            Ok(&mut out[len..])
        }
    }
}

pub fn le_u64<'a>(i: u64) -> impl SerializeFn<&'a mut [u8]> {
   let len = 8;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = (i         & 0xff) as u8;
            out[1] = ((i >> 8)  & 0xff) as u8;
            out[2] = ((i >> 16) & 0xff) as u8;
            out[3] = ((i >> 24) & 0xff) as u8;
            out[4] = ((i >> 32) & 0xff) as u8;
            out[5] = ((i >> 40) & 0xff) as u8;
            out[6] = ((i >> 48) & 0xff) as u8;
            out[7] = ((i >> 56) & 0xff) as u8;
            Ok(&mut out[len..])
        }
    }
}

pub fn le_i8<'a>(i: i8) -> impl SerializeFn<&'a mut [u8]> {
    le_u8(i as u8)
}

pub fn le_i16<'a>(i: i16) -> impl SerializeFn<&'a mut [u8]> {
    le_u16(i as u16)
}

pub fn le_i32<'a>(i: i32) -> impl SerializeFn<&'a mut [u8]> {
    le_u32(i as u32)
}

pub fn le_i64<'a>(i: i64) -> impl SerializeFn<&'a mut [u8]> {
    le_u64(i as u64)
}

pub fn le_f32<'a>(i: f32) -> impl SerializeFn<&'a mut [u8]> {
    le_u32(unsafe { std::mem::transmute::<f32, u32>(i) })
}

pub fn le_f64<'a>(i: f64) -> impl SerializeFn<&'a mut [u8]> {
    le_u64(unsafe { std::mem::transmute::<f64, u64>(i) })
}

pub fn many_ref<'a, E, It, I, F, G, O>(items: I, generator: F) -> impl SerializeFn<O> + 'a
where
    It: Iterator<Item = E> + Clone + 'a,
    I: IntoIterator<Item = E, IntoIter = It>,
    F: Fn(E) -> G + 'a,
    G: SerializeFn<O> + 'a,
    O: 'a
{
    let items = items.into_iter();
    move |mut out: O| {
        for item in items.clone() {
            out = generator(item)(out)?;
        }
        Ok(out)
    }
}

pub fn length<'a, F>(f: F) -> impl Fn(&'a mut [u8]) -> Result<(usize, &'a mut [u8]), GenError>
  where F: SerializeFn<&'a mut [u8]> {
  move |out: &'a mut [u8]| {
    let start = out.as_ptr() as usize;

    let out = f(out)?;

    let end = out.as_ptr() as usize;
    Ok((end - start, out))
  }
}
//missing combinators:
//or
//empty
//then
//stream
//length_value
//text print
//text upperhex
//text lowerhex
<commit_msg>separated_list should take an iterator as argument<commit_after>use gen::GenError;

pub trait SerializeFn<I>: Fn(I) -> Result<I, GenError> {}

impl<I, F:  Fn(I) ->Result<I, GenError>> SerializeFn<I> for F {}

pub fn slice<'a, S: 'a + AsRef<[u8]>>(data: S) -> impl SerializeFn<&'a mut [u8]> {
    let len = data.as_ref().len();

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            (&mut out[..len]).copy_from_slice(data.as_ref());
            Ok(&mut out[len..])
        }
    }
}

pub fn string<'a, S: 'a+AsRef<str>>(data: S) -> impl SerializeFn<&'a mut [u8]> {

    let len = data.as_ref().len();
    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            (&mut out[..len]).copy_from_slice(data.as_ref().as_bytes());
            Ok(&mut out[len..])
        }
    }
}

use std::io::{Cursor, Write};
use std::fmt;
pub fn hex<'a, S: 'a + fmt::UpperHex>(data: S) -> impl SerializeFn<&'a mut [u8]> {

  move |out: &'a mut [u8]| {
    let mut c = Cursor::new(out);
    match write!(&mut c, "{:X}", data) {
      Err(_) => Err(GenError::CustomError(42)),
      Ok(_) => {
        let pos = c.position() as usize;
        let out = c.into_inner();
        Ok(&mut out[pos..])
      }
    }
  }
}

pub fn skip<'a>(len: usize) -> impl SerializeFn<&'a mut [u8]> {

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            Ok(&mut out[len..])
        }
    }
}

pub fn position<'a, F>(f: F) -> impl Fn(&'a mut [u8]) -> Result<(&'a mut [u8], &'a mut [u8]), GenError>
  where F: SerializeFn<&'a mut [u8]> {

    move |out: &'a mut [u8]| {
        unsafe {
            let ptr = out.as_mut_ptr();
            let out = f(out)?;
            let len = out.as_ptr() as usize - ptr as usize;

            Ok((std::slice::from_raw_parts_mut(ptr, len), out))
        }
    }
}

fn pair<F, G, I>(first: F, second: G) -> impl SerializeFn<I>
where F: SerializeFn<I>,
      G: SerializeFn<I> {

  move |out: I| {
    let out = first(out)?;
    second(out)
  }
}

fn cond<F, G, I>(condition: bool, f: F) -> impl SerializeFn<I>
where F: SerializeFn<I>, {

  move |out: I| {
    if condition {
      f(out)
    } else {
      Ok(out)
    }
  }
}

pub fn all<'a, 'b, G, I, It>(values: It) -> impl SerializeFn<I> + 'a
  where G: SerializeFn<I> + 'b,
        It: 'a + Clone + Iterator<Item=G> {

  move |mut out: I| {
    let it = values.clone();

    for v in it {
      out = v(out)?;
    }

    Ok(out)
  }
}

/// applies an iterator of serializers
///
/// ```rust
/// use cookie_factory::{length, separated_list, string};
///
/// let mut buf = [0u8; 100];
///
/// let data = vec!["abcd", "efgh", "ijkl"];
/// let len = {
///   let (len, _) = length(separated_list(string(","), data.iter().map(string)))(&mut buf[..]).unwrap();
///   len
/// };
///
/// assert_eq!(len, 14usize);
/// assert_eq!(&buf[..14], &b"abcd,efgh,ijkl"[..]);
/// ```
pub fn separated_list<'a, 'b, 'c, F, G, I, It>(sep: F, values: It) -> impl SerializeFn<I> + 'a
  where F: SerializeFn<I> + 'b + 'a,
        G: SerializeFn<I> + 'c,
        It: 'a + Clone + Iterator<Item=G> {

  move |mut out: I| {
    let mut it = values.clone();

    match it.next() {
      None => return Ok(out),
      Some(first) => {
        out = first(out)?;
      }
    }

    for v in it {
      out = sep(out)?;
      out = v(out)?;
    }

    Ok(out)
  }
}

pub fn be_u8<'a>(i: u8) -> impl SerializeFn<&'a mut [u8]> {
   let len = 1;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = i;
            Ok(&mut out[len..])
        }
    }
}

pub fn be_u16<'a>(i: u16) -> impl SerializeFn<&'a mut [u8]> {
   let len = 2;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = ((i >> 8) & 0xff) as u8;
            out[1] = (i        & 0xff) as u8;
            Ok(&mut out[len..])
        }
    }
}

pub fn be_u32<'a>(i: u32) -> impl SerializeFn<&'a mut [u8]> {
   let len = 4;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = ((i >> 24) & 0xff) as u8;
            out[1] = ((i >> 16) & 0xff) as u8;
            out[2] = ((i >> 8)  & 0xff) as u8;
            out[3] = (i         & 0xff) as u8;
            Ok(&mut out[len..])
        }
    }
}

pub fn be_u64<'a>(i: u64) -> impl SerializeFn<&'a mut [u8]> {
   let len = 8;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = ((i >> 56) & 0xff) as u8;
            out[1] = ((i >> 48) & 0xff) as u8;
            out[2] = ((i >> 40) & 0xff) as u8;
            out[3] = ((i >> 32) & 0xff) as u8;
            out[4] = ((i >> 24) & 0xff) as u8;
            out[5] = ((i >> 16) & 0xff) as u8;
            out[6] = ((i >> 8)  & 0xff) as u8;
            out[7] = (i         & 0xff) as u8;
            Ok(&mut out[len..])
        }
    }
}

pub fn be_i8<'a>(i: i8) -> impl SerializeFn<&'a mut [u8]> {
    be_u8(i as u8)
}

pub fn be_i16<'a>(i: i16) -> impl SerializeFn<&'a mut [u8]> {
    be_u16(i as u16)
}

pub fn be_i32<'a>(i: i32) -> impl SerializeFn<&'a mut [u8]> {
    be_u32(i as u32)
}

pub fn be_i64<'a>(i: i64) -> impl SerializeFn<&'a mut [u8]> {
    be_u64(i as u64)
}

pub fn be_f32<'a>(i: f32) -> impl SerializeFn<&'a mut [u8]> {
    be_u32(unsafe { std::mem::transmute::<f32, u32>(i) })
}

pub fn be_f64<'a>(i: f64) -> impl SerializeFn<&'a mut [u8]> {
    be_u64(unsafe { std::mem::transmute::<f64, u64>(i) })
}

pub fn le_u8<'a>(i: u8) -> impl SerializeFn<&'a mut [u8]> {
   let len = 1;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = i;
            Ok(&mut out[len..])
        }
    }
}

pub fn le_u16<'a>(i: u16) -> impl SerializeFn<&'a mut [u8]> {
   let len = 2;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = (i        & 0xff) as u8;
            out[1] = ((i >> 8) & 0xff) as u8;
            Ok(&mut out[len..])
        }
    }
}

pub fn le_u32<'a>(i: u32) -> impl SerializeFn<&'a mut [u8]> {
   let len = 4;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = (i         & 0xff) as u8;
            out[1] = ((i >> 8)  & 0xff) as u8;
            out[2] = ((i >> 16) & 0xff) as u8;
            out[3] = ((i >> 24) & 0xff) as u8;
            Ok(&mut out[len..])
        }
    }
}

pub fn le_u64<'a>(i: u64) -> impl SerializeFn<&'a mut [u8]> {
   let len = 8;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = (i         & 0xff) as u8;
            out[1] = ((i >> 8)  & 0xff) as u8;
            out[2] = ((i >> 16) & 0xff) as u8;
            out[3] = ((i >> 24) & 0xff) as u8;
            out[4] = ((i >> 32) & 0xff) as u8;
            out[5] = ((i >> 40) & 0xff) as u8;
            out[6] = ((i >> 48) & 0xff) as u8;
            out[7] = ((i >> 56) & 0xff) as u8;
            Ok(&mut out[len..])
        }
    }
}

pub fn le_i8<'a>(i: i8) -> impl SerializeFn<&'a mut [u8]> {
    le_u8(i as u8)
}

pub fn le_i16<'a>(i: i16) -> impl SerializeFn<&'a mut [u8]> {
    le_u16(i as u16)
}

pub fn le_i32<'a>(i: i32) -> impl SerializeFn<&'a mut [u8]> {
    le_u32(i as u32)
}

pub fn le_i64<'a>(i: i64) -> impl SerializeFn<&'a mut [u8]> {
    le_u64(i as u64)
}

pub fn le_f32<'a>(i: f32) -> impl SerializeFn<&'a mut [u8]> {
    le_u32(unsafe { std::mem::transmute::<f32, u32>(i) })
}

pub fn le_f64<'a>(i: f64) -> impl SerializeFn<&'a mut [u8]> {
    le_u64(unsafe { std::mem::transmute::<f64, u64>(i) })
}

pub fn many_ref<'a, E, It, I, F, G, O>(items: I, generator: F) -> impl SerializeFn<O> + 'a
where
    It: Iterator<Item = E> + Clone + 'a,
    I: IntoIterator<Item = E, IntoIter = It>,
    F: Fn(E) -> G + 'a,
    G: SerializeFn<O> + 'a,
    O: 'a
{
    let items = items.into_iter();
    move |mut out: O| {
        for item in items.clone() {
            out = generator(item)(out)?;
        }
        Ok(out)
    }
}

pub fn length<'a, F>(f: F) -> impl Fn(&'a mut [u8]) -> Result<(usize, &'a mut [u8]), GenError>
  where F: SerializeFn<&'a mut [u8]> {
  move |out: &'a mut [u8]| {
    let start = out.as_ptr() as usize;

    let out = f(out)?;

    let end = out.as_ptr() as usize;
    Ok((end - start, out))
  }
}
//missing combinators:
//or
//empty
//then
//stream
//length_value
//text print
//text upperhex
//text lowerhex
<|endoftext|>


<commit_before>use gen::GenError;

pub trait SerializeFn<I>: Fn(I) -> Result<I, GenError> {}

impl<I, F:  Fn(I) ->Result<I, GenError>> SerializeFn<I> for F {}

pub fn slice<'a, S: 'a + AsRef<[u8]>>(data: S) -> impl SerializeFn<&'a mut [u8]> {
    let len = data.as_ref().len();

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            (&mut out[..len]).copy_from_slice(data.as_ref());
            Ok(&mut out[len..])
        }
    }
}

pub fn string<'a, S: 'a+AsRef<str>>(data: S) -> impl SerializeFn<&'a mut [u8]> {

    let len = data.as_ref().len();
    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            (&mut out[..len]).copy_from_slice(data.as_ref().as_bytes());
            Ok(&mut out[len..])
        }
    }
}

use std::io::{Cursor, Write};
use std::fmt;
pub fn hex<'a, S: 'a + fmt::UpperHex>(data: S) -> impl SerializeFn<&'a mut [u8]> {

  move |out: &'a mut [u8]| {
    let mut c = Cursor::new(out);
    match write!(&mut c, "{:X}", data) {
      Err(_) => Err(GenError::CustomError(42)),
      Ok(_) => {
        let pos = c.position() as usize;
        let out = c.into_inner();
        Ok(&mut out[pos..])
      }
    }
  }
}

pub fn skip<'a>(len: usize) -> impl SerializeFn<&'a mut [u8]> {

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            Ok(&mut out[len..])
        }
    }
}

pub fn position<'a, F>(f: F) -> impl Fn(&'a mut [u8]) -> Result<(&'a mut [u8], &'a mut [u8]), GenError>
  where F: SerializeFn<&'a mut [u8]> {

    move |out: &'a mut [u8]| {
        unsafe {
            let ptr = out.as_mut_ptr();
            let out = f(out)?;
            let len = out.as_ptr() as usize - ptr as usize;

            Ok((std::slice::from_raw_parts_mut(ptr, len), out))
        }
    }
}

fn pair<F, G, I>(first: F, second: G) -> impl SerializeFn<I>
where F: SerializeFn<I>,
      G: SerializeFn<I> {

  move |out: I| {
    let out = first(out)?;
    second(out)
  }
}

fn cond<F, G, I>(condition: bool, f: F) -> impl SerializeFn<I>
where F: SerializeFn<I>, {

  move |out: I| {
    if condition {
      f(out)
    } else {
      Ok(out)
    }
  }
}

pub fn _all<'a, 'b, G, I, It: Iterator<Item=G>, Arg: 'a+Clone+IntoIterator<Item=G, IntoIter=It>>(values: Arg) -> impl SerializeFn<I> + 'a
  where G: SerializeFn<I> + 'b {

  move |mut out: I| {
    let it = values.clone().into_iter();

    for v in it {
      out = v(out)?;
    }

    Ok(out)
  }
}

pub fn separated_list<'a, 'b, 'c, F, G, I, It: Iterator<Item=G>, Arg: 'a+Clone+IntoIterator<Item=G, IntoIter=It>>(sep: F, values: Arg) -> impl SerializeFn<I> + 'a
  where F: SerializeFn<I> + 'b + 'a,
        G: SerializeFn<I> + 'c {

  move |mut out: I| {
    let mut it = values.clone().into_iter();
    match it.next() {
      None => return Ok(out),
      Some(first) => {
        out = first(out)?;
      }
    }

    for v in it {
      out = sep(out)?;
      out = v(out)?;
    }

    Ok(out)
  }
}

pub fn be_u8<'a>(i: u8) -> impl SerializeFn<&'a mut [u8]> {
   let len = 1;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = i;
            Ok(&mut out[len..])
        }
    }
}

pub fn be_u16<'a>(i: u16) -> impl SerializeFn<&'a mut [u8]> {
   let len = 2;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = ((i >> 8) & 0xff) as u8;
            out[1] = (i        & 0xff) as u8;
            Ok(&mut out[len..])
        }
    }
}

pub fn be_u32<'a>(i: u32) -> impl SerializeFn<&'a mut [u8]> {
   let len = 4;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = ((i >> 24) & 0xff) as u8;
            out[1] = ((i >> 16) & 0xff) as u8;
            out[2] = ((i >> 8)  & 0xff) as u8;
            out[3] = (i         & 0xff) as u8;
            Ok(&mut out[len..])
        }
    }
}

pub fn be_u64<'a>(i: u64) -> impl SerializeFn<&'a mut [u8]> {
   let len = 8;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = ((i >> 56) & 0xff) as u8;
            out[1] = ((i >> 48) & 0xff) as u8;
            out[2] = ((i >> 40) & 0xff) as u8;
            out[3] = ((i >> 32) & 0xff) as u8;
            out[4] = ((i >> 24) & 0xff) as u8;
            out[5] = ((i >> 16) & 0xff) as u8;
            out[6] = ((i >> 8)  & 0xff) as u8;
            out[7] = (i         & 0xff) as u8;
            Ok(&mut out[len..])
        }
    }
}

pub fn be_i8<'a>(i: i8) -> impl SerializeFn<&'a mut [u8]> {
    be_u8(i as u8)
}

pub fn be_i16<'a>(i: i16) -> impl SerializeFn<&'a mut [u8]> {
    be_u16(i as u16)
}

pub fn be_i32<'a>(i: i32) -> impl SerializeFn<&'a mut [u8]> {
    be_u32(i as u32)
}

pub fn be_i64<'a>(i: i64) -> impl SerializeFn<&'a mut [u8]> {
    be_u64(i as u64)
}

pub fn be_f32<'a>(i: f32) -> impl SerializeFn<&'a mut [u8]> {
    be_u32(unsafe { std::mem::transmute::<f32, u32>(i) })
}

pub fn be_f64<'a>(i: f64) -> impl SerializeFn<&'a mut [u8]> {
    be_u64(unsafe { std::mem::transmute::<f64, u64>(i) })
}

pub fn le_u8<'a>(i: u8) -> impl SerializeFn<&'a mut [u8]> {
   let len = 1;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = i;
            Ok(&mut out[len..])
        }
    }
}

pub fn le_u16<'a>(i: u16) -> impl SerializeFn<&'a mut [u8]> {
   let len = 2;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = (i        & 0xff) as u8;
            out[1] = ((i >> 8) & 0xff) as u8;
            Ok(&mut out[len..])
        }
    }
}

pub fn le_u32<'a>(i: u32) -> impl SerializeFn<&'a mut [u8]> {
   let len = 4;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = (i         & 0xff) as u8;
            out[1] = ((i >> 8)  & 0xff) as u8;
            out[2] = ((i >> 16) & 0xff) as u8;
            out[3] = ((i >> 24) & 0xff) as u8;
            Ok(&mut out[len..])
        }
    }
}

pub fn le_u64<'a>(i: u64) -> impl SerializeFn<&'a mut [u8]> {
   let len = 8;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = (i         & 0xff) as u8;
            out[1] = ((i >> 8)  & 0xff) as u8;
            out[2] = ((i >> 16) & 0xff) as u8;
            out[3] = ((i >> 24) & 0xff) as u8;
            out[4] = ((i >> 32) & 0xff) as u8;
            out[5] = ((i >> 40) & 0xff) as u8;
            out[6] = ((i >> 48) & 0xff) as u8;
            out[7] = ((i >> 56) & 0xff) as u8;
            Ok(&mut out[len..])
        }
    }
}

pub fn le_i8<'a>(i: i8) -> impl SerializeFn<&'a mut [u8]> {
    le_u8(i as u8)
}

pub fn le_i16<'a>(i: i16) -> impl SerializeFn<&'a mut [u8]> {
    le_u16(i as u16)
}

pub fn le_i32<'a>(i: i32) -> impl SerializeFn<&'a mut [u8]> {
    le_u32(i as u32)
}

pub fn le_i64<'a>(i: i64) -> impl SerializeFn<&'a mut [u8]> {
    le_u64(i as u64)
}

pub fn le_f32<'a>(i: f32) -> impl SerializeFn<&'a mut [u8]> {
    le_u32(unsafe { std::mem::transmute::<f32, u32>(i) })
}

pub fn le_f64<'a>(i: f64) -> impl SerializeFn<&'a mut [u8]> {
    le_u64(unsafe { std::mem::transmute::<f64, u64>(i) })
}

//missing combinators:
//or
//empty
//then
//stream
//length_value
//text print
//text upperhex
//text lowerhex
<commit_msg>add many_ref<commit_after>use gen::GenError;

pub trait SerializeFn<I>: Fn(I) -> Result<I, GenError> {}

impl<I, F:  Fn(I) ->Result<I, GenError>> SerializeFn<I> for F {}

pub fn slice<'a, S: 'a + AsRef<[u8]>>(data: S) -> impl SerializeFn<&'a mut [u8]> {
    let len = data.as_ref().len();

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            (&mut out[..len]).copy_from_slice(data.as_ref());
            Ok(&mut out[len..])
        }
    }
}

pub fn string<'a, S: 'a+AsRef<str>>(data: S) -> impl SerializeFn<&'a mut [u8]> {

    let len = data.as_ref().len();
    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            (&mut out[..len]).copy_from_slice(data.as_ref().as_bytes());
            Ok(&mut out[len..])
        }
    }
}

use std::io::{Cursor, Write};
use std::fmt;
pub fn hex<'a, S: 'a + fmt::UpperHex>(data: S) -> impl SerializeFn<&'a mut [u8]> {

  move |out: &'a mut [u8]| {
    let mut c = Cursor::new(out);
    match write!(&mut c, "{:X}", data) {
      Err(_) => Err(GenError::CustomError(42)),
      Ok(_) => {
        let pos = c.position() as usize;
        let out = c.into_inner();
        Ok(&mut out[pos..])
      }
    }
  }
}

pub fn skip<'a>(len: usize) -> impl SerializeFn<&'a mut [u8]> {

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            Ok(&mut out[len..])
        }
    }
}

pub fn position<'a, F>(f: F) -> impl Fn(&'a mut [u8]) -> Result<(&'a mut [u8], &'a mut [u8]), GenError>
  where F: SerializeFn<&'a mut [u8]> {

    move |out: &'a mut [u8]| {
        unsafe {
            let ptr = out.as_mut_ptr();
            let out = f(out)?;
            let len = out.as_ptr() as usize - ptr as usize;

            Ok((std::slice::from_raw_parts_mut(ptr, len), out))
        }
    }
}

fn pair<F, G, I>(first: F, second: G) -> impl SerializeFn<I>
where F: SerializeFn<I>,
      G: SerializeFn<I> {

  move |out: I| {
    let out = first(out)?;
    second(out)
  }
}

fn cond<F, G, I>(condition: bool, f: F) -> impl SerializeFn<I>
where F: SerializeFn<I>, {

  move |out: I| {
    if condition {
      f(out)
    } else {
      Ok(out)
    }
  }
}

pub fn _all<'a, 'b, G, I, It: Iterator<Item=G>, Arg: 'a+Clone+IntoIterator<Item=G, IntoIter=It>>(values: Arg) -> impl SerializeFn<I> + 'a
  where G: SerializeFn<I> + 'b {

  move |mut out: I| {
    let it = values.clone().into_iter();

    for v in it {
      out = v(out)?;
    }

    Ok(out)
  }
}

pub fn separated_list<'a, 'b, 'c, F, G, I, It: Iterator<Item=G>, Arg: 'a+Clone+IntoIterator<Item=G, IntoIter=It>>(sep: F, values: Arg) -> impl SerializeFn<I> + 'a
  where F: SerializeFn<I> + 'b + 'a,
        G: SerializeFn<I> + 'c {

  move |mut out: I| {
    let mut it = values.clone().into_iter();
    match it.next() {
      None => return Ok(out),
      Some(first) => {
        out = first(out)?;
      }
    }

    for v in it {
      out = sep(out)?;
      out = v(out)?;
    }

    Ok(out)
  }
}

pub fn be_u8<'a>(i: u8) -> impl SerializeFn<&'a mut [u8]> {
   let len = 1;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = i;
            Ok(&mut out[len..])
        }
    }
}

pub fn be_u16<'a>(i: u16) -> impl SerializeFn<&'a mut [u8]> {
   let len = 2;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = ((i >> 8) & 0xff) as u8;
            out[1] = (i        & 0xff) as u8;
            Ok(&mut out[len..])
        }
    }
}

pub fn be_u32<'a>(i: u32) -> impl SerializeFn<&'a mut [u8]> {
   let len = 4;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = ((i >> 24) & 0xff) as u8;
            out[1] = ((i >> 16) & 0xff) as u8;
            out[2] = ((i >> 8)  & 0xff) as u8;
            out[3] = (i         & 0xff) as u8;
            Ok(&mut out[len..])
        }
    }
}

pub fn be_u64<'a>(i: u64) -> impl SerializeFn<&'a mut [u8]> {
   let len = 8;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = ((i >> 56) & 0xff) as u8;
            out[1] = ((i >> 48) & 0xff) as u8;
            out[2] = ((i >> 40) & 0xff) as u8;
            out[3] = ((i >> 32) & 0xff) as u8;
            out[4] = ((i >> 24) & 0xff) as u8;
            out[5] = ((i >> 16) & 0xff) as u8;
            out[6] = ((i >> 8)  & 0xff) as u8;
            out[7] = (i         & 0xff) as u8;
            Ok(&mut out[len..])
        }
    }
}

pub fn be_i8<'a>(i: i8) -> impl SerializeFn<&'a mut [u8]> {
    be_u8(i as u8)
}

pub fn be_i16<'a>(i: i16) -> impl SerializeFn<&'a mut [u8]> {
    be_u16(i as u16)
}

pub fn be_i32<'a>(i: i32) -> impl SerializeFn<&'a mut [u8]> {
    be_u32(i as u32)
}

pub fn be_i64<'a>(i: i64) -> impl SerializeFn<&'a mut [u8]> {
    be_u64(i as u64)
}

pub fn be_f32<'a>(i: f32) -> impl SerializeFn<&'a mut [u8]> {
    be_u32(unsafe { std::mem::transmute::<f32, u32>(i) })
}

pub fn be_f64<'a>(i: f64) -> impl SerializeFn<&'a mut [u8]> {
    be_u64(unsafe { std::mem::transmute::<f64, u64>(i) })
}

pub fn le_u8<'a>(i: u8) -> impl SerializeFn<&'a mut [u8]> {
   let len = 1;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = i;
            Ok(&mut out[len..])
        }
    }
}

pub fn le_u16<'a>(i: u16) -> impl SerializeFn<&'a mut [u8]> {
   let len = 2;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = (i        & 0xff) as u8;
            out[1] = ((i >> 8) & 0xff) as u8;
            Ok(&mut out[len..])
        }
    }
}

pub fn le_u32<'a>(i: u32) -> impl SerializeFn<&'a mut [u8]> {
   let len = 4;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = (i         & 0xff) as u8;
            out[1] = ((i >> 8)  & 0xff) as u8;
            out[2] = ((i >> 16) & 0xff) as u8;
            out[3] = ((i >> 24) & 0xff) as u8;
            Ok(&mut out[len..])
        }
    }
}

pub fn le_u64<'a>(i: u64) -> impl SerializeFn<&'a mut [u8]> {
   let len = 8;

    move |out: &'a mut [u8]| {
        if out.len() < len {
            Err(GenError::BufferTooSmall(len))
        } else {
            out[0] = (i         & 0xff) as u8;
            out[1] = ((i >> 8)  & 0xff) as u8;
            out[2] = ((i >> 16) & 0xff) as u8;
            out[3] = ((i >> 24) & 0xff) as u8;
            out[4] = ((i >> 32) & 0xff) as u8;
            out[5] = ((i >> 40) & 0xff) as u8;
            out[6] = ((i >> 48) & 0xff) as u8;
            out[7] = ((i >> 56) & 0xff) as u8;
            Ok(&mut out[len..])
        }
    }
}

pub fn le_i8<'a>(i: i8) -> impl SerializeFn<&'a mut [u8]> {
    le_u8(i as u8)
}

pub fn le_i16<'a>(i: i16) -> impl SerializeFn<&'a mut [u8]> {
    le_u16(i as u16)
}

pub fn le_i32<'a>(i: i32) -> impl SerializeFn<&'a mut [u8]> {
    le_u32(i as u32)
}

pub fn le_i64<'a>(i: i64) -> impl SerializeFn<&'a mut [u8]> {
    le_u64(i as u64)
}

pub fn le_f32<'a>(i: f32) -> impl SerializeFn<&'a mut [u8]> {
    le_u32(unsafe { std::mem::transmute::<f32, u32>(i) })
}

pub fn le_f64<'a>(i: f64) -> impl SerializeFn<&'a mut [u8]> {
    le_u64(unsafe { std::mem::transmute::<f64, u64>(i) })
}

pub fn many_ref<'a, E, It, I, F, G, O>(items: I, generator: F) -> impl SerializeFn<O> + 'a
where
    It: Iterator<Item = E> + Clone + 'a,
    I: IntoIterator<Item = E, IntoIter = It>,
    F: Fn(E) -> G + 'a,
    G: SerializeFn<O> + 'a,
    O: 'a
{
    let items = items.into_iter();
    move |mut out: O| {
        for item in items.clone() {
            out = generator(item)(out)?;
        }
        Ok(out)
    }
}

//missing combinators:
//or
//empty
//then
//stream
//length_value
//text print
//text upperhex
//text lowerhex
<|endoftext|>


<commit_before>use cocoa::base::{id, nil};
use objc::runtime::BOOL;
use std::collections::HashMap;
use std::convert::{From, Into};
use std::default::Default;
use sys::{MTLCompileOptions, MTLLanguageVersion};

#[derive(Clone, Debug, PartialEq)]
pub struct CompileOptions {
    pub fast_math_enabled: bool,
    pub language_version: LanguageVersion,
    pub preprocessor_macros: HashMap<String, PreprocessorMacroValue>
}

impl CompileOptions {
    #[allow(unreachable_code)]
    pub fn mtl_compile_options(&self) -> id {
        unsafe {
            let ll_compile_opts = MTLCompileOptions::new(nil);

            ll_compile_opts.setFastMathEnabled(self.fast_math_enabled as BOOL);

            if let LanguageVersion::Specific(version) = self.language_version {
                ll_compile_opts.setLanguageVersion(version.into());
            }

            // TODO(George): Set the rest of the compile options correctly
            if !self.preprocessor_macros.is_empty() {
                unimplemented!();
            }

            ll_compile_opts
        }
    }
}

impl Default for CompileOptions {
    fn default() -> Self {
        CompileOptions {
            fast_math_enabled: true,
            language_version: Default::default(),
            preprocessor_macros: Default::default()
        }
    }
}

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum LanguageVersion {
    Latest,
    Specific(SpecificLanguageVersion)
}

impl Default for LanguageVersion {
    fn default() -> Self {
        LanguageVersion::Latest
    }
}

/// Used to choose a specific version of the Metal shader language to use
// An underscore is a good separator for numbers
#[allow(non_camel_case_types)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum SpecificLanguageVersion {
    /// Version 1.0
    Version_1_0,

    /// Version 1.1
    Version_1_1
}

impl From<MTLLanguageVersion> for SpecificLanguageVersion {
    fn from(language_version: MTLLanguageVersion) -> Self {
        match language_version {
            MTLLanguageVersion::MTLLanguageVersion1_0 => SpecificLanguageVersion::Version_1_0,
            MTLLanguageVersion::MTLLanguageVersion1_1 => SpecificLanguageVersion::Version_1_1,
        }
    }
}

impl Into<MTLLanguageVersion> for SpecificLanguageVersion {
    fn into(self) -> MTLLanguageVersion {
        match self {
            SpecificLanguageVersion::Version_1_0 => MTLLanguageVersion::MTLLanguageVersion1_0,
            SpecificLanguageVersion::Version_1_1 => MTLLanguageVersion::MTLLanguageVersion1_1,
        }
    }
}

#[derive(Clone, Debug, PartialEq)]
pub enum PreprocessorMacroValue {
    Floating(f64),
    Integral(i64),
    String(String)
}
<commit_msg>Implement setting preprocessor values in compile_options.rs<commit_after>use cocoa::base::{id, nil};
use cocoa::foundation::{NSString, NSUInteger};
use core_foundation::base::TCFType;
use core_foundation::number::CFNumber;
use core_foundation::string::CFString;
use objc::runtime::BOOL;
use objc_bringup::NSDictionary;
use std::collections::HashMap;
use std::convert::{From, Into};
use std::default::Default;
use sys::{MTLCompileOptions, MTLLanguageVersion};

#[derive(Clone, Debug, PartialEq)]
pub struct CompileOptions {
    pub fast_math_enabled: bool,
    pub language_version: LanguageVersion,
    pub preprocessor_macros: HashMap<String, PreprocessorMacroValue>
}

impl CompileOptions {
    pub fn mtl_compile_options(&self) -> id {
        unsafe {
            let ll_compile_opts = MTLCompileOptions::new(nil);

            ll_compile_opts.setFastMathEnabled(self.fast_math_enabled as BOOL);

            if let LanguageVersion::Specific(version) = self.language_version {
                ll_compile_opts.setLanguageVersion(version.into());
            }

            if !self.preprocessor_macros.is_empty() {
                let mut keys = self.preprocessor_macros
                                   .keys()
                                   .map(|k| NSString::alloc(nil).init_str(k.as_ref()))
                                   .collect::<Vec<_>>();

                let mut objs =
                    self.preprocessor_macros
                        .values()
                        .map(|v| {
                            match v {
                                &PreprocessorMacroValue::Floating(f) => {
                                    CFNumber::from_f64(f).as_CFTypeRef() as id
                                }
                                &PreprocessorMacroValue::Integral(i) => {
                                    CFNumber::from_i64(i).as_CFTypeRef() as id
                                }
                                &PreprocessorMacroValue::String(ref s) => {
                                    CFString::new(s.as_ref()).as_CFTypeRef() as id
                                }
                            }
                        })
                        .collect::<Vec<_>>();

                let num_macros = self.preprocessor_macros.len() as NSUInteger;

                let macros = NSDictionary::dictionaryWithObjects_forKeys_count(objs.as_mut_ptr(),
                                                                               keys.as_mut_ptr(),
                                                                               num_macros);
                ll_compile_opts.setPreprocessorMacros(macros);
            }

            ll_compile_opts
        }
    }
}

impl Default for CompileOptions {
    fn default() -> Self {
        CompileOptions {
            fast_math_enabled: true,
            language_version: Default::default(),
            preprocessor_macros: Default::default()
        }
    }
}

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum LanguageVersion {
    Latest,
    Specific(SpecificLanguageVersion)
}

impl Default for LanguageVersion {
    fn default() -> Self {
        LanguageVersion::Latest
    }
}

/// Used to choose a specific version of the Metal shader language to use
// An underscore is a good separator for numbers
#[allow(non_camel_case_types)]
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum SpecificLanguageVersion {
    /// Version 1.0
    Version_1_0,

    /// Version 1.1
    Version_1_1
}

impl From<MTLLanguageVersion> for SpecificLanguageVersion {
    fn from(language_version: MTLLanguageVersion) -> Self {
        match language_version {
            MTLLanguageVersion::MTLLanguageVersion1_0 => SpecificLanguageVersion::Version_1_0,
            MTLLanguageVersion::MTLLanguageVersion1_1 => SpecificLanguageVersion::Version_1_1,
        }
    }
}

impl Into<MTLLanguageVersion> for SpecificLanguageVersion {
    fn into(self) -> MTLLanguageVersion {
        match self {
            SpecificLanguageVersion::Version_1_0 => MTLLanguageVersion::MTLLanguageVersion1_0,
            SpecificLanguageVersion::Version_1_1 => MTLLanguageVersion::MTLLanguageVersion1_1,
        }
    }
}

#[derive(Clone, Debug, PartialEq)]
pub enum PreprocessorMacroValue {
    Floating(f64),
    Integral(i64),
    String(String)
}
<|endoftext|>


<commit_before>//! Types and traits for arranging collections.
//!
//! Differential dataflow collections can be "arranged" into maintained, worker-local
//! indices that can be re-used by other dataflows at relatively low cost.
//!
//! The `arrange` operator, and its variants, takes a `Collection` and produces as an
//! output an instance of the `Arrangement` type. An arrangement is logically equivalent
//! to its input collection, but it is distributed across workers and maintained in a
//! way that makes it easy to re-use.
//!
//! The `arrange` operator receives update triples `(data, time, diff)` from its input,
//! and responds to changes in its input frontier, which as it advances signals further
//! times that will no longer be observed in input updates. For each frontier advance,
//! the operator creates a new "batch", containing exactly those updates whose times are
//! in advance of the previous frontier but not in advance of the new frontier. Updates
//! are partitioned among workers by a key, and each batch is indexed by this key.
//!
//! This sequence of batches defines a continually expanding view of committed updates
//! in the collection.
//! The sequence is presented by the `Arrangement` in two forms (its fields):
//!
//! 1.  A timely dataflow `Stream` of batch elements.
//!
//!     The stream is used by operators that want to exploit the arranged structure of
//!     batches, but want the push-based computational model of timely dataflow.
//!     Many differential dataflow operators can consume streams of batches, although
//!     they may also rely on access to the second representation of the sequence.
//!
//! 2.  A `Trace` type that provides a compact representation of the accumulated batches.
//!
//!     A trace is logically equivalent to a sequence of batches, but it is able to alter
//!     the representation for efficiency. In particular, the trace may merge batches so
//!     that the total number is kept small, and it may merge logical times if it able to
//!     determine that no trace users can distinguish between them.
//!
//! Importantly, the `Trace` type has no connection to the timely dataflow runtime.
//! This means a trace can be used in a variety of contexts where a `Stream` would not be
//! appropriate, for example outside of the dataflow in which the arragement is performed.
//! Traces may be directly inspected by any code with access to them, and they can even be
//! used to introduce the batches to other dataflows with the `import` method.

use std::rc::{Rc, Weak};
use std::cell::RefCell;
use std::collections::VecDeque;

use timely::scheduling::Activator;
use trace::TraceReader;

/// Operating instructions on how to replay a trace.
pub enum TraceReplayInstruction

where
    Tr: TraceReader,
{
    /// Describes a frontier advance.
    Frontier(Vec
),
    /// Describes a batch of data and a capability hint.
    Batch(Tr::Batch, Option
),
}

// Short names for strongly and weakly owned activators and shared queues.
type BatchQueue
 = VecDeque<TraceReplayInstruction
>;
type TraceAgentQueueReader
 = Rc<(Activator, RefCell<BatchQueue
>)>;
type TraceAgentQueueWriter
 = Weak<(Activator, RefCell<BatchQueue
>)>;

pub mod writer;
pub mod agent;
pub mod arrangement;

pub use self::writer::TraceWriter;
pub use self::agent::TraceAgent;

pub use self::arrangement::{Arranged, ArrangeByKey, ArrangeBySelf};<commit_msg>export better<commit_after>//! Types and traits for arranging collections.
//!
//! Differential dataflow collections can be "arranged" into maintained, worker-local
//! indices that can be re-used by other dataflows at relatively low cost.
//!
//! The `arrange` operator, and its variants, takes a `Collection` and produces as an
//! output an instance of the `Arrangement` type. An arrangement is logically equivalent
//! to its input collection, but it is distributed across workers and maintained in a
//! way that makes it easy to re-use.
//!
//! The `arrange` operator receives update triples `(data, time, diff)` from its input,
//! and responds to changes in its input frontier, which as it advances signals further
//! times that will no longer be observed in input updates. For each frontier advance,
//! the operator creates a new "batch", containing exactly those updates whose times are
//! in advance of the previous frontier but not in advance of the new frontier. Updates
//! are partitioned among workers by a key, and each batch is indexed by this key.
//!
//! This sequence of batches defines a continually expanding view of committed updates
//! in the collection.
//! The sequence is presented by the `Arrangement` in two forms (its fields):
//!
//! 1.  A timely dataflow `Stream` of batch elements.
//!
//!     The stream is used by operators that want to exploit the arranged structure of
//!     batches, but want the push-based computational model of timely dataflow.
//!     Many differential dataflow operators can consume streams of batches, although
//!     they may also rely on access to the second representation of the sequence.
//!
//! 2.  A `Trace` type that provides a compact representation of the accumulated batches.
//!
//!     A trace is logically equivalent to a sequence of batches, but it is able to alter
//!     the representation for efficiency. In particular, the trace may merge batches so
//!     that the total number is kept small, and it may merge logical times if it able to
//!     determine that no trace users can distinguish between them.
//!
//! Importantly, the `Trace` type has no connection to the timely dataflow runtime.
//! This means a trace can be used in a variety of contexts where a `Stream` would not be
//! appropriate, for example outside of the dataflow in which the arragement is performed.
//! Traces may be directly inspected by any code with access to them, and they can even be
//! used to introduce the batches to other dataflows with the `import` method.

use std::rc::{Rc, Weak};
use std::cell::RefCell;
use std::collections::VecDeque;

use timely::scheduling::Activator;
use trace::TraceReader;

/// Operating instructions on how to replay a trace.
pub enum TraceReplayInstruction

where
    Tr: TraceReader,
{
    /// Describes a frontier advance.
    Frontier(Vec
),
    /// Describes a batch of data and a capability hint.
    Batch(Tr::Batch, Option
),
}

// Short names for strongly and weakly owned activators and shared queues.
type BatchQueue
 = VecDeque<TraceReplayInstruction
>;
type TraceAgentQueueReader
 = Rc<(Activator, RefCell<BatchQueue
>)>;
type TraceAgentQueueWriter
 = Weak<(Activator, RefCell<BatchQueue
>)>;

pub mod writer;
pub mod agent;
pub mod arrangement;

pub use self::writer::TraceWriter;
pub use self::agent::{TraceAgent, ShutdownButton};

pub use self::arrangement::{Arranged, Arrange, ArrangeByKey, ArrangeBySelf};<|endoftext|>


<commit_before>extern crate rulinalg;

use self::rulinalg::vector::Vector;
use self::rulinalg::matrix::Matrix;
use self::rulinalg::matrix::BaseMatrix;
use self::rulinalg::matrix::BaseMatrixMut;

pub struct Ctrnn {
}

impl Ctrnn {
    pub fn new() -> Ctrnn{
        Ctrnn {}
    }

    pub fn activate(&self, steps: usize, gamma_v: &Vec<f64>, delta_t: f64, tau_v: &Vec<f64>, wij_v: &Vec<Vec<f64>>, theta_v: &Vec<f64>, wik_v: &Vec<Vec<f64>>, i_v: &Vec<f64>) -> Vec<f64> {
        let mut gamma = Ctrnn::matrix_from_vector(gamma_v);
        let mut theta = Ctrnn::matrix_from_vector(theta_v);
        let mut wij = Ctrnn::matrix_from_vectors(wij_v);
        let mut wik = Ctrnn::matrix_from_vectors(wik_v);
        let mut i = Ctrnn::matrix_from_vector(i_v);
        let mut tau = Ctrnn::matrix_from_vector(tau_v);
        let mut result = &gamma + (tau.apply( &(|x| 1.0/x) ) * delta_t).elemul(&( (&wij * ( &gamma - &theta ).apply(&Ctrnn::sigmoid)) - &gamma + (&wik * &i)));
        println!("{:?}", result);
        return vec![0.0, 0.0];
    }

    fn sigmoid(y: f64) -> f64 {
        1f64 / (1f64 + (-y).exp())
    }

    fn matrix_from_vector(vector: &Vec<f64>) -> Matrix<f64> {
        Matrix::new(vector.len(), 1, vector.as_slice())
    }

    fn matrix_from_vectors(vectors: &Vec<Vec<f64>>) -> Matrix<f64> {
        Matrix::new(vectors.len(), vectors[1].len(), vectors.iter().flat_map(|s| s.iter().cloned()).collect::<Vec<f64>>())
    }
}

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

    #[test]
    fn neural_network_activation_should_return_correct_values(){
        let gamma =         vec![0.0, 0.0, 0.0];
        let delta_t =       13.436;
        let tau =           vec![61.694, 10.149, 16.851];
        let wij =           vec![vec![-2.94737, 2.70665, -0.57046],
                            vec![-3.27553,   3.67193, 1.83218],
                            vec![2.32476,   0.24739, 0.58587]];
        let theta =         vec![-0.695126, -0.677891, -0.072129];
        let wik =           vec![vec![-0.10097, -3.04457],
                            vec![-4.86594, 1.79273],
                            vec![-3.45899, -1.27388]];
        let i =             vec![0.98856, 0.31540];

        let ctrnn = Ctrnn::new();

        assert_eq!( ctrnn.activate(1, &gamma, delta_t, &tau, &wij, &theta, &wik, &i),
            vec![-0.33246, -4.03171, -1.43741]);

        assert_eq!( ctrnn.activate(2, &gamma, delta_t, &tau, &wij, &theta, &wik, &i),
            vec![-0.86998, -6.11057, -2.14179]);
        assert_eq!( ctrnn.activate(10, &gamma, delta_t, &tau, &wij, &theta, &wik, &i),
            vec![-1.7698, -4.9550, -3.1953]);
        assert_eq!( ctrnn.activate(30, &gamma, delta_t, &tau, &wij, &theta, &wik, &i),
            vec![-1.7869, -4.9408, -3.2092]);

        //converges
        assert_eq!( ctrnn.activate(30, &gamma, delta_t, &tau, &wij, &theta, &wik, &i),
            ctrnn.activate(100, &gamma, delta_t, &tau, &wij, &theta, &wik, &i));
    }
}
<commit_msg>Ctrnn passes tests<commit_after>extern crate rulinalg;

use self::rulinalg::matrix::Matrix;
use self::rulinalg::matrix::BaseMatrix;
use self::rulinalg::matrix::BaseMatrixMut;

pub struct Ctrnn {
}

impl Ctrnn {
    pub fn new() -> Ctrnn{
        Ctrnn {}
    }

    pub fn activate(&self, steps: usize, gamma_v: &Vec<f64>, delta_t: f64, tau_v: &Vec<f64>, wij_v: &Vec<Vec<f64>>, theta_v: &Vec<f64>, wik_v: &Vec<Vec<f64>>, i_v: &Vec<f64>) -> Vec<f64> {
        let mut gamma = Ctrnn::matrix_from_vector(gamma_v);
        let theta = Ctrnn::matrix_from_vector(theta_v);
        let wij = Ctrnn::matrix_from_vectors(wij_v);
        let wik = Ctrnn::matrix_from_vectors(wik_v);
        let i = Ctrnn::matrix_from_vector(i_v);
        let tau = Ctrnn::matrix_from_vector(tau_v);
        let delta_t_tau = tau.apply( &(|x| 1.0/x) ) * delta_t;
        for _ in 0..steps {
            gamma = &gamma + delta_t_tau.elemul(&( (&wij * ( &gamma - &theta ).apply(&Ctrnn::sigmoid)) - &gamma + (&wik * &i)));
        }
        return gamma.into_vec();
    }

    fn sigmoid(y: f64) -> f64 {
        1f64 / (1f64 + (-y).exp())
    }

    fn matrix_from_vector(vector: &Vec<f64>) -> Matrix<f64> {
        Matrix::new(vector.len(), 1, vector.as_slice())
    }

    fn matrix_from_vectors(vectors: &Vec<Vec<f64>>) -> Matrix<f64> {
        Matrix::new(vectors.len(), vectors[1].len(), vectors.iter().flat_map(|s| s.iter().cloned()).collect::<Vec<f64>>())
    }
}

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

    #[test]
    fn neural_network_activation_should_return_correct_values(){
        let gamma =         vec![0.0, 0.0, 0.0];
        let delta_t =       13.436;
        let tau =           vec![61.694, 10.149, 16.851];
        let wij =           vec![vec![-2.94737, 2.70665, -0.57046],
                            vec![-3.27553,   3.67193, 1.83218],
                            vec![2.32476,   0.24739, 0.58587]];
        let theta =         vec![-0.695126, -0.677891, -0.072129];
        let wik =           vec![vec![-0.10097, -3.04457],
                            vec![-4.86594, 1.79273],
                            vec![-3.45899, -1.27388]];
        let i =             vec![0.98856, 0.31540];

        let ctrnn = Ctrnn::new();

        assert_eq!( ctrnn.activate(1, &gamma, delta_t, &tau, &wij, &theta, &wik, &i),
            vec![-0.3324610969203632, -4.031708339680356, -1.4374137183957871]);

        assert_eq!( ctrnn.activate(2, &gamma, delta_t, &tau, &wij, &theta, &wik, &i),
            vec![-0.8747989167571583, -6.213498344386237, -2.143379723316894]);
        assert_eq!( ctrnn.activate(10, &gamma, delta_t, &tau, &wij, &theta, &wik, &i),
            vec![-1.7607615233242453, -4.96208021858224, -3.1877336197565627]);
        assert_eq!( ctrnn.activate(30, &gamma, delta_t, &tau, &wij, &theta, &wik, &i),
            vec![-1.7868613827907782, -4.940744845752775, -3.2091966016693183]);

        //converges
        assert_eq!( ctrnn.activate(100, &gamma, delta_t, &tau, &wij, &theta, &wik, &i),
            vec![-1.7868662273977671, -4.940740909854486, -3.2092005096958243]);
    }
}
<|endoftext|>


<commit_before>//! Traits for working with JavaScript objects.
//!
//! This module defines the [`Object`](Object) trait, which is implemented
//! by all object types in the [JavaScript type hierarchy][hierarchy]. This
//! trait provides key operations in the semantics of JavaScript objects,
//! such as getting and setting an object's properties.
//!
//! ## Property Keys
//!
//! Object properties are accessed by a _property key_, which in JavaScript
//! can be a string or [symbol][symbol]. (Neon does not yet have support for
//! symbols.) For convenience, the [`PropertyKey`](PropertyKey) trait allows
//! Neon programs to use various Rust string types, as well as numeric types,
//! as keys when accessing object properties, converting the keys to strings
//! as necessary:
//!
//! ```
//! # use neon::prelude::*;
//! fn set_and_check<'a>(
//!     cx: &mut impl Context<'a>,
//!     obj: Handle<'a, JsObject>
//! ) -> JsResult<'a, JsValue> {
//!     let value = cx.string("hello!");
//!     // set property "17" with integer shorthand
//!     obj.set(17, value)?;
//!     // get property "17" with string shorthand
//!     // returns the same value ("hello!")
//!     obj.get("17")
//! }
//! ```
//!
//! [hierarchy]: crate::types#the-javascript-type-hierarchy
//! [symbol]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol

#[cfg(feature = "legacy-runtime")]
pub(crate) mod class;

#[cfg(feature = "legacy-runtime")]
pub use self::class::{Class, ClassDescriptor};
pub use self::traits::*;

#[cfg(feature = "legacy-runtime")]
mod traits {
    use crate::context::Context;
    use crate::handle::{Handle, Managed};
    use crate::result::{JsResult, NeonResult, Throw};
    use crate::types::utf8::Utf8;
    use crate::types::{build, JsArray, JsValue, Value};
    use neon_runtime::raw;

    /// A property key in a JavaScript object.
    pub trait PropertyKey {
        unsafe fn get_from(self, out: &mut raw::Local, obj: raw::Local) -> bool;
        unsafe fn set_from(self, out: &mut bool, obj: raw::Local, val: raw::Local) -> bool;
    }

    impl PropertyKey for u32 {
        unsafe fn get_from(self, out: &mut raw::Local, obj: raw::Local) -> bool {
            neon_runtime::object::get_index(out, obj, self)
        }

        unsafe fn set_from(self, out: &mut bool, obj: raw::Local, val: raw::Local) -> bool {
            neon_runtime::object::set_index(out, obj, self, val)
        }
    }

    impl<'a, K: Value> PropertyKey for Handle<'a, K> {
        unsafe fn get_from(self, out: &mut raw::Local, obj: raw::Local) -> bool {
            neon_runtime::object::get(out, obj, self.to_raw())
        }

        unsafe fn set_from(self, out: &mut bool, obj: raw::Local, val: raw::Local) -> bool {
            neon_runtime::object::set(out, obj, self.to_raw(), val)
        }
    }

    impl<'a> PropertyKey for &'a str {
        unsafe fn get_from(self, out: &mut raw::Local, obj: raw::Local) -> bool {
            let (ptr, len) = Utf8::from(self).into_small_unwrap().lower();
            neon_runtime::object::get_string(out, obj, ptr, len)
        }

        unsafe fn set_from(self, out: &mut bool, obj: raw::Local, val: raw::Local) -> bool {
            let (ptr, len) = Utf8::from(self).into_small_unwrap().lower();
            neon_runtime::object::set_string(out, obj, ptr, len, val)
        }
    }

    /// The trait of all object types.
    pub trait Object: Value {
        fn get<'a, C: Context<'a>, K: PropertyKey>(
            self,
            cx: &mut C,
            key: K,
        ) -> NeonResult<Handle<'a, JsValue>> {
            build(cx.env(), |out| unsafe { key.get_from(out, self.to_raw()) })
        }

        fn get_own_property_names<'a, C: Context<'a>>(self, cx: &mut C) -> JsResult<'a, JsArray> {
            let env = cx.env();
            build(env, |out| unsafe {
                neon_runtime::object::get_own_property_names(out, env.to_raw(), self.to_raw())
            })
        }

        fn set<'a, C: Context<'a>, K: PropertyKey, W: Value>(
            self,
            _: &mut C,
            key: K,
            val: Handle<W>,
        ) -> NeonResult<bool> {
            let mut result = false;
            if unsafe { key.set_from(&mut result, self.to_raw(), val.to_raw()) } {
                Ok(result)
            } else {
                Err(Throw)
            }
        }
    }

    /// The trait of types that can be a function's `this` binding.
    pub unsafe trait This: Managed {
        #[allow(clippy::wrong_self_convention)]
        fn as_this(h: raw::Local) -> Self;
    }
}

#[cfg(feature = "napi-1")]
mod traits {
    use crate::context::internal::Env;
    use crate::context::Context;
    use crate::handle::{Handle, Managed, Root};
    use crate::result::{NeonResult, Throw};
    use crate::types::utf8::Utf8;
    use crate::types::{build, JsValue, Value};
    use neon_runtime::raw;

    #[cfg(feature = "napi-6")]
    use crate::result::JsResult;
    #[cfg(feature = "napi-6")]
    use crate::types::JsArray;

    /// A property key in a JavaScript object.
    pub trait PropertyKey {
        unsafe fn get_from<'c, C: Context<'c>>(
            self,
            cx: &mut C,
            out: &mut raw::Local,
            obj: raw::Local,
        ) -> bool;

        unsafe fn set_from<'c, C: Context<'c>>(
            self,
            cx: &mut C,
            out: &mut bool,
            obj: raw::Local,
            val: raw::Local,
        ) -> bool;
    }

    impl PropertyKey for u32 {
        unsafe fn get_from<'c, C: Context<'c>>(
            self,
            cx: &mut C,
            out: &mut raw::Local,
            obj: raw::Local,
        ) -> bool {
            neon_runtime::object::get_index(out, cx.env().to_raw(), obj, self)
        }

        unsafe fn set_from<'c, C: Context<'c>>(
            self,
            cx: &mut C,
            out: &mut bool,
            obj: raw::Local,
            val: raw::Local,
        ) -> bool {
            neon_runtime::object::set_index(out, cx.env().to_raw(), obj, self, val)
        }
    }

    impl<'a, K: Value> PropertyKey for Handle<'a, K> {
        unsafe fn get_from<'c, C: Context<'c>>(
            self,
            cx: &mut C,
            out: &mut raw::Local,
            obj: raw::Local,
        ) -> bool {
            let env = cx.env().to_raw();

            neon_runtime::object::get(out, env, obj, self.to_raw())
        }

        unsafe fn set_from<'c, C: Context<'c>>(
            self,
            cx: &mut C,
            out: &mut bool,
            obj: raw::Local,
            val: raw::Local,
        ) -> bool {
            let env = cx.env().to_raw();

            neon_runtime::object::set(out, env, obj, self.to_raw(), val)
        }
    }

    impl<'a> PropertyKey for &'a str {
        unsafe fn get_from<'c, C: Context<'c>>(
            self,
            cx: &mut C,
            out: &mut raw::Local,
            obj: raw::Local,
        ) -> bool {
            let (ptr, len) = Utf8::from(self).into_small_unwrap().lower();
            let env = cx.env().to_raw();

            neon_runtime::object::get_string(env, out, obj, ptr, len)
        }

        unsafe fn set_from<'c, C: Context<'c>>(
            self,
            cx: &mut C,
            out: &mut bool,
            obj: raw::Local,
            val: raw::Local,
        ) -> bool {
            let (ptr, len) = Utf8::from(self).into_small_unwrap().lower();
            let env = cx.env().to_raw();

            neon_runtime::object::set_string(env, out, obj, ptr, len, val)
        }
    }

    /// The trait of all object types.
    pub trait Object: Value {
        fn get<'a, C: Context<'a>, K: PropertyKey>(
            self,
            cx: &mut C,
            key: K,
        ) -> NeonResult<Handle<'a, JsValue>> {
            build(cx.env(), |out| unsafe {
                key.get_from(cx, out, self.to_raw())
            })
        }

        #[cfg(feature = "napi-6")]
        fn get_own_property_names<'a, C: Context<'a>>(self, cx: &mut C) -> JsResult<'a, JsArray> {
            let env = cx.env();

            build(cx.env(), |out| unsafe {
                neon_runtime::object::get_own_property_names(out, env.to_raw(), self.to_raw())
            })
        }

        fn set<'a, C: Context<'a>, K: PropertyKey, W: Value>(
            self,
            cx: &mut C,
            key: K,
            val: Handle<W>,
        ) -> NeonResult<bool> {
            let mut result = false;
            if unsafe { key.set_from(cx, &mut result, self.to_raw(), val.to_raw()) } {
                Ok(result)
            } else {
                Err(Throw)
            }
        }

        fn root<'a, C: Context<'a>>(&self, cx: &mut C) -> Root<Self> {
            Root::new(cx, self)
        }
    }

    /// The trait of types that can be a function's `this` binding.
    pub unsafe trait This: Managed {
        #[allow(clippy::wrong_self_convention)]
        fn as_this(env: Env, h: raw::Local) -> Self;
    }
}
<commit_msg>Fix API docs example code to pass CI.<commit_after>//! Traits for working with JavaScript objects.
//!
//! This module defines the [`Object`](Object) trait, which is implemented
//! by all object types in the [JavaScript type hierarchy][hierarchy]. This
//! trait provides key operations in the semantics of JavaScript objects,
//! such as getting and setting an object's properties.
//!
//! ## Property Keys
//!
//! Object properties are accessed by a _property key_, which in JavaScript
//! can be a string or [symbol][symbol]. (Neon does not yet have support for
//! symbols.) For convenience, the [`PropertyKey`](PropertyKey) trait allows
//! Neon programs to use various Rust string types, as well as numeric types,
//! as keys when accessing object properties, converting the keys to strings
//! as necessary:
//!
//! ```
//! # #[cfg(feature = "napi-1")] {
//! # use neon::prelude::*;
//! fn set_and_check<'a>(
//!     cx: &mut impl Context<'a>,
//!     obj: Handle<'a, JsObject>
//! ) -> JsResult<'a, JsValue> {
//!     let value = cx.string("hello!");
//!     // set property "17" with integer shorthand
//!     obj.set(cx, 17, value)?;
//!     // get property "17" with string shorthand
//!     // returns the same value ("hello!")
//!     obj.get(cx, "17")
//! }
//! # }
//! ```
//!
//! [hierarchy]: crate::types#the-javascript-type-hierarchy
//! [symbol]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol

#[cfg(feature = "legacy-runtime")]
pub(crate) mod class;

#[cfg(feature = "legacy-runtime")]
pub use self::class::{Class, ClassDescriptor};
pub use self::traits::*;

#[cfg(feature = "legacy-runtime")]
mod traits {
    use crate::context::Context;
    use crate::handle::{Handle, Managed};
    use crate::result::{JsResult, NeonResult, Throw};
    use crate::types::utf8::Utf8;
    use crate::types::{build, JsArray, JsValue, Value};
    use neon_runtime::raw;

    /// A property key in a JavaScript object.
    pub trait PropertyKey {
        unsafe fn get_from(self, out: &mut raw::Local, obj: raw::Local) -> bool;
        unsafe fn set_from(self, out: &mut bool, obj: raw::Local, val: raw::Local) -> bool;
    }

    impl PropertyKey for u32 {
        unsafe fn get_from(self, out: &mut raw::Local, obj: raw::Local) -> bool {
            neon_runtime::object::get_index(out, obj, self)
        }

        unsafe fn set_from(self, out: &mut bool, obj: raw::Local, val: raw::Local) -> bool {
            neon_runtime::object::set_index(out, obj, self, val)
        }
    }

    impl<'a, K: Value> PropertyKey for Handle<'a, K> {
        unsafe fn get_from(self, out: &mut raw::Local, obj: raw::Local) -> bool {
            neon_runtime::object::get(out, obj, self.to_raw())
        }

        unsafe fn set_from(self, out: &mut bool, obj: raw::Local, val: raw::Local) -> bool {
            neon_runtime::object::set(out, obj, self.to_raw(), val)
        }
    }

    impl<'a> PropertyKey for &'a str {
        unsafe fn get_from(self, out: &mut raw::Local, obj: raw::Local) -> bool {
            let (ptr, len) = Utf8::from(self).into_small_unwrap().lower();
            neon_runtime::object::get_string(out, obj, ptr, len)
        }

        unsafe fn set_from(self, out: &mut bool, obj: raw::Local, val: raw::Local) -> bool {
            let (ptr, len) = Utf8::from(self).into_small_unwrap().lower();
            neon_runtime::object::set_string(out, obj, ptr, len, val)
        }
    }

    /// The trait of all object types.
    pub trait Object: Value {
        fn get<'a, C: Context<'a>, K: PropertyKey>(
            self,
            cx: &mut C,
            key: K,
        ) -> NeonResult<Handle<'a, JsValue>> {
            build(cx.env(), |out| unsafe { key.get_from(out, self.to_raw()) })
        }

        fn get_own_property_names<'a, C: Context<'a>>(self, cx: &mut C) -> JsResult<'a, JsArray> {
            let env = cx.env();
            build(env, |out| unsafe {
                neon_runtime::object::get_own_property_names(out, env.to_raw(), self.to_raw())
            })
        }

        fn set<'a, C: Context<'a>, K: PropertyKey, W: Value>(
            self,
            _: &mut C,
            key: K,
            val: Handle<W>,
        ) -> NeonResult<bool> {
            let mut result = false;
            if unsafe { key.set_from(&mut result, self.to_raw(), val.to_raw()) } {
                Ok(result)
            } else {
                Err(Throw)
            }
        }
    }

    /// The trait of types that can be a function's `this` binding.
    pub unsafe trait This: Managed {
        #[allow(clippy::wrong_self_convention)]
        fn as_this(h: raw::Local) -> Self;
    }
}

#[cfg(feature = "napi-1")]
mod traits {
    use crate::context::internal::Env;
    use crate::context::Context;
    use crate::handle::{Handle, Managed, Root};
    use crate::result::{NeonResult, Throw};
    use crate::types::utf8::Utf8;
    use crate::types::{build, JsValue, Value};
    use neon_runtime::raw;

    #[cfg(feature = "napi-6")]
    use crate::result::JsResult;
    #[cfg(feature = "napi-6")]
    use crate::types::JsArray;

    /// A property key in a JavaScript object.
    pub trait PropertyKey {
        unsafe fn get_from<'c, C: Context<'c>>(
            self,
            cx: &mut C,
            out: &mut raw::Local,
            obj: raw::Local,
        ) -> bool;

        unsafe fn set_from<'c, C: Context<'c>>(
            self,
            cx: &mut C,
            out: &mut bool,
            obj: raw::Local,
            val: raw::Local,
        ) -> bool;
    }

    impl PropertyKey for u32 {
        unsafe fn get_from<'c, C: Context<'c>>(
            self,
            cx: &mut C,
            out: &mut raw::Local,
            obj: raw::Local,
        ) -> bool {
            neon_runtime::object::get_index(out, cx.env().to_raw(), obj, self)
        }

        unsafe fn set_from<'c, C: Context<'c>>(
            self,
            cx: &mut C,
            out: &mut bool,
            obj: raw::Local,
            val: raw::Local,
        ) -> bool {
            neon_runtime::object::set_index(out, cx.env().to_raw(), obj, self, val)
        }
    }

    impl<'a, K: Value> PropertyKey for Handle<'a, K> {
        unsafe fn get_from<'c, C: Context<'c>>(
            self,
            cx: &mut C,
            out: &mut raw::Local,
            obj: raw::Local,
        ) -> bool {
            let env = cx.env().to_raw();

            neon_runtime::object::get(out, env, obj, self.to_raw())
        }

        unsafe fn set_from<'c, C: Context<'c>>(
            self,
            cx: &mut C,
            out: &mut bool,
            obj: raw::Local,
            val: raw::Local,
        ) -> bool {
            let env = cx.env().to_raw();

            neon_runtime::object::set(out, env, obj, self.to_raw(), val)
        }
    }

    impl<'a> PropertyKey for &'a str {
        unsafe fn get_from<'c, C: Context<'c>>(
            self,
            cx: &mut C,
            out: &mut raw::Local,
            obj: raw::Local,
        ) -> bool {
            let (ptr, len) = Utf8::from(self).into_small_unwrap().lower();
            let env = cx.env().to_raw();

            neon_runtime::object::get_string(env, out, obj, ptr, len)
        }

        unsafe fn set_from<'c, C: Context<'c>>(
            self,
            cx: &mut C,
            out: &mut bool,
            obj: raw::Local,
            val: raw::Local,
        ) -> bool {
            let (ptr, len) = Utf8::from(self).into_small_unwrap().lower();
            let env = cx.env().to_raw();

            neon_runtime::object::set_string(env, out, obj, ptr, len, val)
        }
    }

    /// The trait of all object types.
    pub trait Object: Value {
        fn get<'a, C: Context<'a>, K: PropertyKey>(
            self,
            cx: &mut C,
            key: K,
        ) -> NeonResult<Handle<'a, JsValue>> {
            build(cx.env(), |out| unsafe {
                key.get_from(cx, out, self.to_raw())
            })
        }

        #[cfg(feature = "napi-6")]
        fn get_own_property_names<'a, C: Context<'a>>(self, cx: &mut C) -> JsResult<'a, JsArray> {
            let env = cx.env();

            build(cx.env(), |out| unsafe {
                neon_runtime::object::get_own_property_names(out, env.to_raw(), self.to_raw())
            })
        }

        fn set<'a, C: Context<'a>, K: PropertyKey, W: Value>(
            self,
            cx: &mut C,
            key: K,
            val: Handle<W>,
        ) -> NeonResult<bool> {
            let mut result = false;
            if unsafe { key.set_from(cx, &mut result, self.to_raw(), val.to_raw()) } {
                Ok(result)
            } else {
                Err(Throw)
            }
        }

        fn root<'a, C: Context<'a>>(&self, cx: &mut C) -> Root<Self> {
            Root::new(cx, self)
        }
    }

    /// The trait of types that can be a function's `this` binding.
    pub unsafe trait This: Managed {
        #[allow(clippy::wrong_self_convention)]
        fn as_this(env: Env, h: raw::Local) -> Self;
    }
}
<|endoftext|>


<commit_before>// From WinNT.h

pub type CHAR = super::__gl_imports::raw::c_char;
pub type HANDLE = PVOID;
pub type LONG = super::__gl_imports::raw::c_long;
pub type LPCSTR = *const super::__gl_imports::raw::c_char;
pub type VOID = ();
// #define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name
pub type HPBUFFERARB = *const super::__gl_imports::raw::c_void;
pub type HPBUFFEREXT = *const super::__gl_imports::raw::c_void;
pub type HVIDEOOUTPUTDEVICENV = *const super::__gl_imports::raw::c_void;
pub type HPVIDEODEV = *const super::__gl_imports::raw::c_void;
pub type HPGPUNV = *const super::__gl_imports::raw::c_void;
pub type HGPUNV = *const super::__gl_imports::raw::c_void;
pub type HVIDEOINPUTDEVICENV = *const super::__gl_imports::raw::c_void;

// From Windef.h

pub type BOOL = super::__gl_imports::raw::c_int;
pub type BYTE = super::__gl_imports::raw::c_uchar;
pub type COLORREF = DWORD;
pub type FLOAT = super::__gl_imports::raw::c_float;
pub type HDC = HANDLE;
pub type HENHMETAFILE = HANDLE;
pub type HGLRC = *const super::__gl_imports::raw::c_void;
pub type INT = super::__gl_imports::raw::c_int;
pub type PVOID = *const super::__gl_imports::raw::c_void;
pub type LPVOID = *const super::__gl_imports::raw::c_void;
pub type PROC = extern "system" fn(); // Not sure about this one :/

#[repr(C)]
pub struct RECT {
    left: LONG,
    top: LONG,
    right: LONG,
    bottom: LONG,
}

pub type UINT = super::__gl_imports::raw::c_uint;
pub type USHORT = super::__gl_imports::raw::c_ushort;
pub type WORD = super::__gl_imports::raw::c_ushort;

// From BaseTsd.h

pub type INT32 = i32;
pub type INT64 = i64;

// From IntSafe.h

pub type DWORD = super::__gl_imports::raw::c_ulong;

// From Wingdi.h

#[repr(C)]
pub struct POINTFLOAT {
    pub x: FLOAT,
    pub y: FLOAT,
}

#[repr(C)]
pub struct GLYPHMETRICSFLOAT {
    pub gmfBlackBoxX: FLOAT,
    pub gmfBlackBoxY: FLOAT,
    pub gmfptGlyphOrigin: POINTFLOAT,
    pub gmfCellIncX: FLOAT,
    pub gmfCellIncY: FLOAT,
}
pub type LPGLYPHMETRICSFLOAT = *const GLYPHMETRICSFLOAT;

#[repr(C)]
pub struct LAYERPLANEDESCRIPTOR {
    pub nSize: WORD,
    pub nVersion: WORD,
    pub dwFlags: DWORD,
    pub iPixelType: BYTE,
    pub cColorBits: BYTE,
    pub cRedBits: BYTE,
    pub cRedShift: BYTE,
    pub cGreenBits: BYTE,
    pub cGreenShift: BYTE,
    pub cBlueBits: BYTE,
    pub cBlueShift: BYTE,
    pub cAlphaBits: BYTE,
    pub cAlphaShift: BYTE,
    pub cAccumBits: BYTE,
    pub cAccumRedBits: BYTE,
    pub cAccumGreenBits: BYTE,
    pub cAccumBlueBits: BYTE,
    pub cAccumAlphaBits: BYTE,
    pub cDepthBits: BYTE,
    pub cStencilBits: BYTE,
    pub cAuxBuffers: BYTE,
    pub iLayerType: BYTE,
    pub bReserved: BYTE,
    pub crTransparent: COLORREF,
}

#[repr(C)]
pub struct PIXELFORMATDESCRIPTOR {
    pub nSize: WORD,
    pub nVersion: WORD,
    pub dwFlags: DWORD,
    pub iPixelType: BYTE,
    pub cColorBits: BYTE,
    pub cRedBits: BYTE,
    pub cRedShift: BYTE,
    pub cGreenBits: BYTE,
    pub cGreenShift: BYTE,
    pub cBlueBits: BYTE,
    pub cBlueShift: BYTE,
    pub cAlphaBits: BYTE,
    pub cAlphaShift: BYTE,
    pub cAccumBits: BYTE,
    pub cAccumRedBits: BYTE,
    pub cAccumGreenBits: BYTE,
    pub cAccumBlueBits: BYTE,
    pub cAccumAlphaBits: BYTE,
    pub cDepthBits: BYTE,
    pub cStencilBits: BYTE,
    pub cAuxBuffers: BYTE,
    pub iLayerType: BYTE,
    pub bReserved: BYTE,
    pub dwLayerMask: DWORD,
    pub dwVisibleMask: DWORD,
    pub dwDamageMask: DWORD,
}

#[repr(C)]
pub struct _GPU_DEVICE {
    cb: DWORD,
    DeviceName: [CHAR; 32],
    DeviceString: [CHAR; 128],
    Flags: DWORD,
    rcVirtualScreen: RECT,
}

pub struct GPU_DEVICE(_GPU_DEVICE);
pub struct PGPU_DEVICE(*const _GPU_DEVICE);
<commit_msg>wgl: Fix PROC definition<commit_after>// From WinNT.h

pub type CHAR = super::__gl_imports::raw::c_char;
pub type HANDLE = PVOID;
pub type LONG = super::__gl_imports::raw::c_long;
pub type LPCSTR = *const super::__gl_imports::raw::c_char;
pub type VOID = ();
// #define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name
pub type HPBUFFERARB = *const super::__gl_imports::raw::c_void;
pub type HPBUFFEREXT = *const super::__gl_imports::raw::c_void;
pub type HVIDEOOUTPUTDEVICENV = *const super::__gl_imports::raw::c_void;
pub type HPVIDEODEV = *const super::__gl_imports::raw::c_void;
pub type HPGPUNV = *const super::__gl_imports::raw::c_void;
pub type HGPUNV = *const super::__gl_imports::raw::c_void;
pub type HVIDEOINPUTDEVICENV = *const super::__gl_imports::raw::c_void;

// From Windef.h

pub type BOOL = super::__gl_imports::raw::c_int;
pub type BYTE = super::__gl_imports::raw::c_uchar;
pub type COLORREF = DWORD;
pub type FLOAT = super::__gl_imports::raw::c_float;
pub type HDC = HANDLE;
pub type HENHMETAFILE = HANDLE;
pub type HGLRC = *const super::__gl_imports::raw::c_void;
pub type INT = super::__gl_imports::raw::c_int;
pub type PVOID = *const super::__gl_imports::raw::c_void;
pub type LPVOID = *const super::__gl_imports::raw::c_void;
pub enum __proc_fn {}
pub type PROC = *mut __proc_fn;

#[repr(C)]
pub struct RECT {
    left: LONG,
    top: LONG,
    right: LONG,
    bottom: LONG,
}

pub type UINT = super::__gl_imports::raw::c_uint;
pub type USHORT = super::__gl_imports::raw::c_ushort;
pub type WORD = super::__gl_imports::raw::c_ushort;

// From BaseTsd.h

pub type INT32 = i32;
pub type INT64 = i64;

// From IntSafe.h

pub type DWORD = super::__gl_imports::raw::c_ulong;

// From Wingdi.h

#[repr(C)]
pub struct POINTFLOAT {
    pub x: FLOAT,
    pub y: FLOAT,
}

#[repr(C)]
pub struct GLYPHMETRICSFLOAT {
    pub gmfBlackBoxX: FLOAT,
    pub gmfBlackBoxY: FLOAT,
    pub gmfptGlyphOrigin: POINTFLOAT,
    pub gmfCellIncX: FLOAT,
    pub gmfCellIncY: FLOAT,
}
pub type LPGLYPHMETRICSFLOAT = *const GLYPHMETRICSFLOAT;

#[repr(C)]
pub struct LAYERPLANEDESCRIPTOR {
    pub nSize: WORD,
    pub nVersion: WORD,
    pub dwFlags: DWORD,
    pub iPixelType: BYTE,
    pub cColorBits: BYTE,
    pub cRedBits: BYTE,
    pub cRedShift: BYTE,
    pub cGreenBits: BYTE,
    pub cGreenShift: BYTE,
    pub cBlueBits: BYTE,
    pub cBlueShift: BYTE,
    pub cAlphaBits: BYTE,
    pub cAlphaShift: BYTE,
    pub cAccumBits: BYTE,
    pub cAccumRedBits: BYTE,
    pub cAccumGreenBits: BYTE,
    pub cAccumBlueBits: BYTE,
    pub cAccumAlphaBits: BYTE,
    pub cDepthBits: BYTE,
    pub cStencilBits: BYTE,
    pub cAuxBuffers: BYTE,
    pub iLayerType: BYTE,
    pub bReserved: BYTE,
    pub crTransparent: COLORREF,
}

#[repr(C)]
pub struct PIXELFORMATDESCRIPTOR {
    pub nSize: WORD,
    pub nVersion: WORD,
    pub dwFlags: DWORD,
    pub iPixelType: BYTE,
    pub cColorBits: BYTE,
    pub cRedBits: BYTE,
    pub cRedShift: BYTE,
    pub cGreenBits: BYTE,
    pub cGreenShift: BYTE,
    pub cBlueBits: BYTE,
    pub cBlueShift: BYTE,
    pub cAlphaBits: BYTE,
    pub cAlphaShift: BYTE,
    pub cAccumBits: BYTE,
    pub cAccumRedBits: BYTE,
    pub cAccumGreenBits: BYTE,
    pub cAccumBlueBits: BYTE,
    pub cAccumAlphaBits: BYTE,
    pub cDepthBits: BYTE,
    pub cStencilBits: BYTE,
    pub cAuxBuffers: BYTE,
    pub iLayerType: BYTE,
    pub bReserved: BYTE,
    pub dwLayerMask: DWORD,
    pub dwVisibleMask: DWORD,
    pub dwDamageMask: DWORD,
}

#[repr(C)]
pub struct _GPU_DEVICE {
    cb: DWORD,
    DeviceName: [CHAR; 32],
    DeviceString: [CHAR; 128],
    Flags: DWORD,
    rcVirtualScreen: RECT,
}

pub struct GPU_DEVICE(_GPU_DEVICE);
pub struct PGPU_DEVICE(*const _GPU_DEVICE);
<|endoftext|>


<commit_before>// C preprocessor

use crate::token::*;
use std::cell::RefCell;
use std::collections::HashMap;

thread_local! {
    static DEFINED: RefCell<HashMap<String, Vec<Token>>> = RefCell::new(HashMap::new());
}

fn defined_get(key: &String) -> Option<Vec<Token>> {
    DEFINED.with(|defined| {
        match defined.borrow().get(key) {
            Some(v) => Some(v.clone()),
            None => None,
        }
    })
}

fn defined_put(key: String, value: Vec<Token>) {
    DEFINED.with(|defined| {
        defined.borrow_mut().insert(key, value);
    })
}

pub fn preprocess(tokens: Vec<Token>) -> Vec<Token> {
    // if(!defined) ...

    let mut v: Vec<Token> = Vec::new();

    let mut i = 0;
    while i < tokens.len() {
        let mut t = &tokens[i];
        i += 1;

        if t.ty == TokenType::IDENT {
            match defined_get(&t.name) {
                Some(macro_token) => {
                    v.append(&mut macro_token.clone());
                }
                None => {
                    v.push(t.clone());
                }
            }
            continue;
        }

        if t.ty != TokenType::SHARP {
            v.push(t.clone());
            continue;
        }

        t = &tokens[i];
        i += 1;
        if t.ty != TokenType::IDENT {
            bad_token(&t, "identifier expected".to_string());
        }

        if t.name == "define" {
            t = &tokens[i];
            i += 1;
            if t.ty != TokenType::IDENT {
                bad_token(&t, "macro name expected".to_string());
            }
            let name = t.name.clone();

            let mut v2 = Vec::new();
            while i < tokens.len() {
                t = &tokens[i];
                i += 1;
                if t.ty == TokenType::NEW_LINE {
                    break;
                }
                v2.push(t.clone());
            }
            defined_put(name, v2);
            continue;
        }

        if t.name == "include" {
            t = &tokens[i];
            i += 1;
            if t.ty != TokenType::STR {
                bad_token(&t, "string expected".to_string());
            }

            let path = t.str_cnt.clone();

            t = &tokens[i];
            i += 1;
            if t.ty != TokenType::NEW_LINE {
                bad_token(&t, "newline expected".to_string());
            }

            v.append(&mut tokenize(path, false));
            continue;
        }
    }

    return v;
}
<commit_msg>Split preprocess() into smaller functions.<commit_after>// C preprocessor

use crate::token::*;
use std::cell::RefCell;
use std::collections::HashMap;

thread_local! {
    static MACROS: RefCell<HashMap<String, Vec<Token>>> = RefCell::new(HashMap::new());

    static CTX: RefCell<Context> = RefCell::new(Context::new());
}

fn set_ctx(ctx: Context) {
    CTX.with(|c| {
        *c.borrow_mut() = ctx;
    })
}

fn get_ctx() -> Option<Context> {
    CTX.with(|c| {
        Some(c.borrow().clone())
    })
}

fn ctx_pop() {
    CTX.with(|c| {
        let next = c.borrow().next.clone();
        if next.is_some() {
            *c.borrow_mut() = *next.unwrap();
        }
    })
}

fn ctx_output() -> Vec<Token> {
    CTX.with(|c| {
        return c.borrow().output.clone();
    })
}

fn macros_get(key: &String) -> Option<Vec<Token>> {
    MACROS.with(|m| {
        match m.borrow().get(key) {
            Some(v) => Some(v.clone()),
            None => None,
        }
    })
}

fn macros_put(key: String, value: Vec<Token>) {
    MACROS.with(|m| {
        m.borrow_mut().insert(key, value);
    })
}

#[derive(Clone, Debug)]
struct Context {
    input: Vec<Token>,
    output: Vec<Token>,
    pos: usize,
    next: Option<Box<Context>>,
}

impl Context {
    fn new() -> Context {
        Context {
            input: Vec::new(),
            output: Vec::new(),
            pos: 0,
            next: None,
        }
    }
}

fn new_ctx(next: Option<Context>, input: Vec<Token>) -> Context {
    let mut ctx = Context::new();
    ctx.input = input;
    if next.is_none() {
        ctx.next = None;
    } else {
        ctx.next = Some(Box::new(next.unwrap()));
    }
    return ctx;
}

fn append(v: &mut Vec<Token>) {
    CTX.with(|ctx| {
        ctx.borrow_mut().output.append(v);
    })
}

fn add(t: Token) {
    CTX.with(|ctx| {
        ctx.borrow_mut().output.push(t);
    })
}

fn next() -> Token {
    CTX.with(|ctx| {
        let pos = ctx.borrow().pos;
        assert!(pos < ctx.borrow().input.len());
        ctx.borrow_mut().pos += 1;
        return ctx.borrow().input[pos].clone();
    })
}

fn eof() -> bool {
    CTX.with(|c| {
        let ctx = c.borrow();
        return ctx.pos == ctx.input.len();
    })
}

fn get(ty: TokenType, msg: String) -> Token {
    let t = next();
    if t.ty != ty {
        bad_token(&t, msg);
    }
    return t;
}

fn define() {
    let mut t = get(TokenType::IDENT, "macro name expected".to_string());
    let name = t.name;

    let mut v = Vec::new();
    while !eof() {
        t = next();
        if t.ty == TokenType::NEW_LINE {
            break;
        }
        v.push(t.clone());
    }
    macros_put(name, v);
}

fn include() {
    let t = get(TokenType::STR, "string expected".to_string());
    let path = t.str_cnt;
    get(TokenType::NEW_LINE, "newline expected".to_string());
    return append(&mut tokenize(path, false));
}

pub fn preprocess(tokens: Vec<Token>) -> Vec<Token> {
    set_ctx(new_ctx(get_ctx(), tokens.clone()));

    while !eof() {
        let mut t = next();

        if t.ty == TokenType::IDENT {
            match macros_get(&t.name) {
                Some(macro_token) => {
                    append(&mut macro_token.clone());
                }
                None => {
                    add(t.clone());
                }
            }
            continue;
        }

        if t.ty != TokenType::SHARP {
            add(t.clone());
            continue;
        }

        t = get(TokenType::IDENT, "identifier expected".to_string());

        if t.name == "define" {
            define();
        } else if t.name == "include" {
            include();
        } else {
            bad_token(&t, "unknown directive".to_string());
        }
    }

    let v = ctx_output();
    ctx_pop();
    return v;
}
<|endoftext|>


<commit_before>extern crate time;

use std::fs::{File, read_dir};
use std::io::{BufReader, BufRead, Read, Write};
use std::io;
use std::path::Path;
use std::collections::HashMap;
use std::error::Error;
use std::fmt;
use models::LanguageModelBuilder;

#[derive(Debug)]
pub struct FormatError;
impl fmt::Display for FormatError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Invalid format for vocabulary file")
    }
}

impl Error for FormatError {
    fn description(&self) -> &str {
        "The format of the vocabulary file was Invalid"
    }
    fn cause(&self) -> Option<&Error> {
        None
    }
}

pub fn find_most_common_words(corpus: &Path, num: usize) -> Vec<(String, u32)> {
    let words = files(corpus).flat_map(|file| read_words(file));

    let mut word_counts = HashMap::new();
    for word in words {
        *word_counts.entry(word).or_insert(0) += 1;
    }

    let mut counts: Vec<_> = word_counts.into_iter().collect();
    counts.sort_by(|a, b| b.1.cmp(&a.1));
    counts.truncate(num);

    counts
}

pub fn save_words(path: &Path, words: &Vec<(String, u32)>) -> io::Result<()> {
    let mut out = try!(File::create(path));
    for &(ref word, count) in words {
        try!(out.write_all(format!("{}, {}\n", &word, count).as_bytes()));
    }

    Ok(())
}

pub fn load_most_common_words(filename: &str,
                              num: usize)
                              -> Result<Vec<(String, u32)>, Box<Error>> {
    let file = try!(File::open(&Path::new(filename)));
    let reader = BufReader::new(file);
    let mut words = vec![];
    for line in reader.lines().take(num) {
        if let Ok(line) = line {
            let mut columns = line.split(',');
            let word = columns.next().map(|w| w.trim().to_string());
            let num = columns.next().map(|n| n.trim().parse());

            match (word, num) {
                (Some(word), Some(num)) => words.push((word, try!(num))),
                _ => return Err(Box::new(FormatError)),
            }
        } else {
            return Err(Box::new(FormatError));
        }
    }

    Ok(words)
}

fn sentences<T: Read + 'static>(reader: BufReader<T>) -> Box<Iterator<Item = String>> {
    Box::new(reader.split('.' as u8)
                   .filter_map(|v| {
                       let lowercase = v.unwrap();
                       String::from_utf8(lowercase).ok().map(|s| s.to_lowercase())
                   }))
}

fn read_words<R: BufRead + 'static>(reader: R) -> Box<Iterator<Item = String>> {
    Box::new(reader.lines()
                   .filter_map(|line| line.ok())
                   .flat_map(|line| {
                       line.split(|c| {
                               match c {
                                   'a'...'z' | 'A'...'Z' => false,
                                   _ => true,
                               }
                           })
                           .filter(|word| !word.is_empty())
                           .map(|word| word.to_lowercase())
                           .collect::<Vec<_>>()
                           .into_iter()
                   }))
}

fn files(path: &Path) -> Box<Iterator<Item = BufReader<File>>> {
    Box::new(read_dir(path)
                 .unwrap()
                 .map(|path| path.unwrap().path())
                 .filter(|path| path.to_str().unwrap().ends_with(".txt"))
                 .map(|path| {
                     let file = File::open(&path).unwrap();
                     BufReader::new(file)
                 }))
}

pub fn create_model(corpus: &Path, words: Vec<String>) -> LanguageModelBuilder {
    let mut builder = LanguageModelBuilder::new(10, words);

    for sentence in files(corpus).take(10).flat_map(sentences) {
        let mut acc = builder.new_sentence();
        for word in sentence.split(|c| {
                                match c {
                                    'a'...'z' => false,
                                    _ => true,
                                }
                            })
                            .filter(|w| !w.is_empty()) {
            acc.add_word(word);
        }
    }

    builder
}
<commit_msg>Tiny refactor<commit_after>extern crate time;

use std::fs::{File, read_dir};
use std::io::{BufReader, BufRead, Read, Write};
use std::io;
use std::path::Path;
use std::collections::HashMap;
use std::error::Error;
use std::fmt;
use models::LanguageModelBuilder;

#[derive(Debug)]
pub struct FormatError;
impl fmt::Display for FormatError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Invalid format for vocabulary file")
    }
}

impl Error for FormatError {
    fn description(&self) -> &str {
        "The format of the vocabulary file was Invalid"
    }
    fn cause(&self) -> Option<&Error> {
        None
    }
}

pub fn find_most_common_words(corpus: &Path, num: usize) -> Vec<(String, u32)> {
    let words = files(corpus).flat_map(|file| read_words(file));

    let mut word_counts = HashMap::new();
    for word in words {
        *word_counts.entry(word).or_insert(0) += 1;
    }

    let mut counts: Vec<_> = word_counts.into_iter().collect();
    counts.sort_by(|a, b| b.1.cmp(&a.1));
    counts.truncate(num);

    counts
}

pub fn save_words(path: &Path, words: &Vec<(String, u32)>) -> io::Result<()> {
    let mut out = try!(File::create(path));
    for &(ref word, count) in words {
        try!(out.write_all(format!("{}, {}\n", &word, count).as_bytes()));
    }

    Ok(())
}

pub fn load_most_common_words(filename: &str,
                              num: usize)
                              -> Result<Vec<(String, u32)>, Box<Error>> {
    let file = try!(File::open(&Path::new(filename)));
    let reader = BufReader::new(file);
    let mut words = vec![];
    for line in reader.lines().take(num) {
        if let Ok(line) = line {
            let mut columns = line.split(',');
            let word = columns.next().map(|w| w.trim().to_string());
            let num = columns.next().map(|n| n.trim().parse());

            match (word, num) {
                (Some(word), Some(num)) => words.push((word, try!(num))),
                _ => return Err(Box::new(FormatError)),
            }
        } else {
            return Err(Box::new(FormatError));
        }
    }

    Ok(words)
}

fn sentences<T: Read + 'static>(reader: BufReader<T>) -> Box<Iterator<Item = String>> {
    Box::new(reader.split('.' as u8)
                   .filter_map(|v| {
                       let lowercase = v.unwrap();
                       String::from_utf8(lowercase).ok().map(|s| s.to_lowercase())
                   }))
}

fn read_words<R: BufRead + 'static>(reader: R) -> Box<Iterator<Item = String>> {
    Box::new(reader.lines()
                   .filter_map(|line| line.ok())
                   .flat_map(|line| {
                       line.split(|c| {
                               match c {
                                   'a'...'z' | 'A'...'Z' => false,
                                   _ => true,
                               }
                           })
                           .filter(|word| !word.is_empty())
                           .map(|word| word.to_lowercase())
                           .collect::<Vec<_>>()
                           .into_iter()
                   }))
}

fn files(path: &Path) -> Box<Iterator<Item = BufReader<File>>> {
    Box::new(read_dir(path)
                 .unwrap()
                 .map(|path| path.unwrap().path())
                 .filter(|path| path.to_str().unwrap().ends_with(".txt"))
                 .map(|path| {
                     let file = File::open(path).unwrap();
                     BufReader::new(file)
                 }))
}

pub fn create_model(corpus: &Path, words: Vec<String>) -> LanguageModelBuilder {
    let mut builder = LanguageModelBuilder::new(10, words);

    for sentence in files(corpus).take(10).flat_map(sentences) {
        let mut acc = builder.new_sentence();

        let words = sentence.split(|c| {
                                match c {
                                    'a'...'z' => false,
                                    _ => true,
                                }
                            })
                            .filter(|w| !w.is_empty());
        for word in words {
            acc.add_word(word);
        }
    }

    builder
}
<|endoftext|>


<commit_before>type Stack<T> = Vec<T>;

#[derive(Default)]
pub struct Interpreter<T> {
    data_stack: Stack<T>,
}

impl<T> Interpreter<T> {

    fn push(&mut self, value: T) {
        self.data_stack.push(value)
    }

    fn pop(&mut self) -> Option<T> {
        self.data_stack.pop()
    }
}

struct Word<T> {
    entry: Box<Fn(&mut Interpreter<T>) -> ()>,
}

impl<T> Word<T> {
    fn eval_within(&self, i: &mut Interpreter<T>) {
        (self.entry)(i)
    }
}

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

    fn fixture_plus() -> Word<i32> {
        Word {
            entry: Box::new(move |i| {
                if let (Some(b), Some(a)) = (i.pop(), i.pop()) {
                    i.push(a + b)
                } else { panic!("Stack underflow") }
            })
        }
    }

    #[test]
    fn plus_word() {
        let mut interpreter = Interpreter::<i32>::default();
        let plus = fixture_plus();
        interpreter.push(42);
        interpreter.push(51);
        plus.eval_within(&mut interpreter);
        assert_eq!(Some(93), interpreter.pop())
    }

    #[test]
    fn pops_nothing() {
        let mut interpreter = Interpreter::<i32>::default();
        assert_eq!(None, interpreter.pop())
    }

    #[test]
    fn pops_as_pushed() {
        let mut interpreter = Interpreter::<i32>::default();
        interpreter.push(42);
        assert_eq!(Some(42), interpreter.pop());
        assert_eq!(None, interpreter.pop())
    }

    #[test]
    fn pops_in_reverse_order() {
        let mut interpreter = Interpreter::<i32>::default();
        interpreter.push(42);
        interpreter.push(51);
        assert_eq!(Some(51), interpreter.pop());
        assert_eq!(Some(42), interpreter.pop());
        assert_eq!(None, interpreter.pop())
    }
}
<commit_msg>Pushing literals<commit_after>use std::str::FromStr;

type Stack<T> = Vec<T>;

#[derive(Default)]
pub struct Interpreter<T> {
    data_stack: Stack<T>,
}

impl<T> Interpreter<T>
    where T: FromStr {

    fn push(&mut self, value: T) {
        self.data_stack.push(value)
    }

    fn pop(&mut self) -> Option<T> {
        self.data_stack.pop()
    }

    fn eval_token(&mut self, token: &str) {
        if let Ok(literal) = token.parse::<T>() {
            self.push(literal);
        }
    }
}

struct Word<T> {
    entry: Box<Fn(&mut Interpreter<T>) -> ()>,
}

impl<T> Word<T> {
    fn eval_within(&self, i: &mut Interpreter<T>) {
        (self.entry)(i)
    }
}

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

    fn fixture_plus() -> Word<i32> {
        Word {
            entry: Box::new(move |i| {
                if let (Some(b), Some(a)) = (i.pop(), i.pop()) {
                    i.push(a + b)
                } else { panic!("Stack underflow") }
            })
        }
    }

    #[test]
    fn plus_word() {
        let mut interpreter = Interpreter::<i32>::default();
        let plus = fixture_plus();
        interpreter.push(42);
        interpreter.push(51);
        plus.eval_within(&mut interpreter);
        assert_eq!(Some(93), interpreter.pop())
    }

    #[test]
    fn push_literal() {
        let mut interpreter = Interpreter::<i32>::default();
        interpreter.eval_token("42");
        assert_eq!(Some(42), interpreter.pop());
    }

    #[test]
    fn pops_nothing() {
        let mut interpreter = Interpreter::<i32>::default();
        assert_eq!(None, interpreter.pop())
    }

    #[test]
    fn pops_as_pushed() {
        let mut interpreter = Interpreter::<i32>::default();
        interpreter.push(42);
        assert_eq!(Some(42), interpreter.pop());
        assert_eq!(None, interpreter.pop())
    }

    #[test]
    fn pops_in_reverse_order() {
        let mut interpreter = Interpreter::<i32>::default();
        interpreter.push(42);
        interpreter.push(51);
        assert_eq!(Some(51), interpreter.pop());
        assert_eq!(Some(42), interpreter.pop());
        assert_eq!(None, interpreter.pop())
    }
}
<|endoftext|>