<commit_before>use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::io;
use std::io::Seek;
use std::io::SeekFrom;

#[derive(Debug)]
pub enum InesError {
  Io(io::Error),
  InesFormat(String),
  Unsupported(String),
}

impl From<io::Error> for InesError {
    fn from(err: io::Error) -> InesError {
        InesError::Io(err)
    }
}
#[repr(C,packed)]
pub struct InesHeader {
  ines_identifier: u32,
  prg_rom_banks: u8,
  chr_rom_banks: u8,
  flags_6: u8,
  flags_7: u8,
  prg_ram_units: u8,
  padding: [u8;7],
}

// http://wiki.nesdev.com/w/index.php/INES
//
pub fn load_ines<P:AsRef<Path>>(file_path: P) -> Result<Vec<u8>,InesError> {
    let mut file = try!(File::open(&file_path));
    let metadata = try!(::std::fs::metadata(&file_path));
    if metadata.len() < ::std::mem::size_of::<InesHeader>() as u64 {
        return Err(InesError::InesFormat("File is smaller than the ines header.".to_string()));
    }

    let mut header_buf = [0u8;16];
    try!(file.read(&mut header_buf));
    let header = unsafe { ::std::mem::transmute::<_,InesHeader>(header_buf) };

    if header.ines_identifier != 0x1A53454E {
        return Err(InesError::InesFormat("Did not find ines header identifier".to_string()));
    }
    if header.flags_7 != 0 {
        return Err(InesError::Unsupported("This version of the ines format is not supported".to_string()));
    }
    if header.flags_6 & 0x04 != 0 {
        return Err(InesError::Unsupported("Loading trainers is not supported".to_string()));
    }

    try!(file.seek(SeekFrom::Start(0)));

    let mut file_bytes = Vec::<u8>::new();
    try!(file.read_to_end(&mut file_bytes));

    // https://en.wikibooks.org/wiki/NES_Programming/Memory_Map
    //
    let mut nes_bytes = Vec::<u8>::with_capacity(::std::u16::MAX as usize);
    nes_bytes.resize(::std::u16::MAX as usize,0);

    let prg_addr = 16;
    let prg_page_len = 0xBFFF - 0x8000;

    // NOTE: the below implementation is terrible.  I don't know how to memcpy from 1
    //       vector to another, so we do it manually.  As far as I'm concerned, this is
    //       *more* error prone than simply calling a memcpy function, but I'm still
    //       learning rust and it is what it is.
    //

    // nes has 2 prg-rom pages at 0x8000 and 0xC000
    // if the rom has only a single prg-rom page, then we mirror it
    //
    for i in 0..prg_page_len {
        nes_bytes[0x8000+i] = file_bytes[prg_addr+i];
        if header.prg_rom_banks == 1 {
            nes_bytes[0xC000+i] = file_bytes[prg_addr+i];
        }
        else {
            nes_bytes[0xC000+i] = file_bytes[prg_addr+prg_page_len+i];
        }
    }

    Ok(nes_bytes)
}

<commit_msg>made vector copies slightly prettier and probably more efficient.<commit_after>use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::io;
use std::io::Seek;
use std::io::SeekFrom;

#[derive(Debug)]
pub enum InesError {
  Io(io::Error),
  InesFormat(String),
  Unsupported(String),
}

impl From<io::Error> for InesError {
    fn from(err: io::Error) -> InesError {
        InesError::Io(err)
    }
}
#[repr(C,packed)]
pub struct InesHeader {
  ines_identifier: u32,
  prg_rom_banks: u8,
  chr_rom_banks: u8,
  flags_6: u8,
  flags_7: u8,
  prg_ram_units: u8,
  padding: [u8;7],
}

// http://wiki.nesdev.com/w/index.php/INES
//
pub fn load_ines<P:AsRef<Path>>(file_path: P) -> Result<Vec<u8>,InesError> {
    let mut file = try!(File::open(&file_path));
    let metadata = try!(::std::fs::metadata(&file_path));
    if metadata.len() < ::std::mem::size_of::<InesHeader>() as u64 {
        return Err(InesError::InesFormat("File is smaller than the ines header.".to_string()));
    }

    let mut header_buf = [0u8;16];
    try!(file.read(&mut header_buf));
    let header = unsafe { ::std::mem::transmute::<_,InesHeader>(header_buf) };

    if header.ines_identifier != 0x1A53454E {
        return Err(InesError::InesFormat("Did not find ines header identifier".to_string()));
    }
    if header.flags_7 != 0 {
        return Err(InesError::Unsupported("This version of the ines format is not supported".to_string()));
    }
    if header.flags_6 & 0x04 != 0 {
        return Err(InesError::Unsupported("Loading trainers is not supported".to_string()));
    }

    try!(file.seek(SeekFrom::Start(0)));

    let mut file_bytes = Vec::<u8>::new();
    try!(file.read_to_end(&mut file_bytes));

    // https://en.wikibooks.org/wiki/NES_Programming/Memory_Map
    //
    let mut nes_bytes = Vec::<u8>::with_capacity(::std::u16::MAX as usize);
    nes_bytes.resize(::std::u16::MAX as usize,0);

    let prg_addr = 16;
    let prg_page_len = 0xBFFF - 0x8000;

    // nes has 2 prg-rom pages at 0x8000 and 0xC000
    // if the rom has only a single prg-rom page, then we mirror it
    let file_page = &file_bytes[prg_addr..(prg_page_len+prg_addr)];
    let file_page2 = if header.prg_rom_banks == 1 {
        file_page
    } else {
        &file_bytes[prg_addr..(prg_addr+prg_page_len+prg_addr)]
    };

    &nes_bytes[0x8000..(prg_page_len+0x8000)].clone_from_slice(file_page);
    &nes_bytes[0xC000..(prg_page_len+0xC000)].clone_from_slice(file_page2);

    Ok(nes_bytes)
}

<|endoftext|>


<commit_before>use std::fmt::Show;
use std::collections::HashMap;
use http::method::Method;
use http::method;
use iron::{Middleware, Request, Response, Status, Continue, Unwind, Error};
use Recognizer = recognizer::Router;
use recognizer::Match;

/// `Router` provides an interface for creating complex routes as middleware
/// for the Iron framework.
#[deriving(Clone)]
pub struct Router {
    // The routers, specialized by method.
    routers: HashMap<Method, Recognizer<Box<Middleware + Send>>>
}

impl Router {
    /// `new` constructs a new, blank `Router`.
    pub fn new() -> Router { Router { routers: HashMap::new() } }
    /// Add a new route to a `Router`, matching both a method and glob pattern.
    ///
    /// `route` supports glob patterns: `*` for a single wildcard segment and
    /// `:param` for matching storing that segment of the request url in the `Params`
    /// object, which is stored on the request Alloy.
    ///
    /// For instance, to route `Get` requests on any route matching
    /// `/users/:userid/:friend` and store `userid` and `friend` in
    /// the exposed Params object:
    ///
    /// ```ignore
    /// router.route(http::method::Get, "/users/:userid/:friendid", controller);
    /// ```
    ///
    /// The controller provided to route can be any `Middleware`, which allows
    /// extreme flexibility when handling routes. For instance, you could provide
    /// a `Chain`, a `Middleware`, which contains an authorization middleware and
    /// a controller function, so that you can confirm that the request is
    /// authorized for this route before handling it.
    pub fn route<'a, M: Middleware + Send, S: Str>(&mut self, method: Method, glob: S, handler: M) -> &mut Router {
        self.routers
            .find_or_insert_with(method, |_| Recognizer::new())
            .add(glob.as_slice(), box handler as Box<Middleware + Send>);
        self
    }

    /// Like route, but specialized to the `Get` method.
    pub fn get<'a, M: Middleware + Send, S: Str>(&mut self, glob: S, handler: M) -> &mut Router {
        self.route(method::Get, glob, handler)
    }

    /// Like route, but specialized to the `Post` method.
    pub fn post<'a, M: Middleware + Send, S: Str>(&mut self, glob: S, handler: M) -> &mut Router {
        self.route(method::Post, glob, handler)
    }

    /// Like route, but specialized to the `Put` method.
    pub fn put<'a, M: Middleware + Send, S: Str>(&mut self, glob: S, handler: M) -> &mut Router {
        self.route(method::Put, glob, handler)
    }

    /// Like route, but specialized to the `Delete` method.
    pub fn delete<'a, M: Middleware + Send, S: Str>(&mut self, glob: S, handler: M) -> &mut Router {
        self.route(method::Delete, glob, handler)
    }

    /// Like route, but specialized to the `Head` method.
    pub fn head<'a, M: Middleware + Send, S: Str>(&mut self, glob: S, handler: M) -> &mut Router {
        self.route(method::Head, glob, handler)
    }

    /// Like route, but specialized to the `Patch` method.
    pub fn patch<'a, M: Middleware + Send, S: Str>(&mut self, glob: S, handler: M) -> &mut Router {
        self.route(method::Patch, glob, handler)
    }

    /// Like route, but specialized to the `Options` method.
    pub fn options<'a, M: Middleware + Send, S: Str>(&mut self, glob: S, handler: M) -> &mut Router {
        self.route(method::Options, glob, handler)
    }

    fn recognize<'a>(&'a self, method: &Method, path: &str)
                     -> Option<Match<&'a Box<Middleware + Send>>> {
        self.routers.find(method).and_then(|router| router.recognize(path).ok())
    }
}

impl Middleware for Router {
    fn enter(&mut self, req: &mut Request, res: &mut Response) -> Status {
        let matched = match self.recognize(&req.method, req.url.path.connect("/").as_slice()) {
            Some(matched) => matched,
            // No match.
            None => return Continue
        };

        req.alloy.insert(matched.params);
        let mut handler = matched.handler.clone_box();
        let mut handler_status = handler.enter(req, res);

        match handler_status {
            Error(ref mut e) => {
                let error: &mut Show = *e;
                let _ = handler.on_error(req, res, error);
            },
            _ => {
                let _ = handler.exit(req, res);
            }
        };

        return match handler_status {
            Continue => Unwind,
            otherwise => otherwise
        }
    }
}

<commit_msg>(fix) Updated for renaming of alloy to extensions.<commit_after>use std::fmt::Show;
use std::collections::HashMap;
use http::method::Method;
use http::method;
use iron::{Middleware, Request, Response, Status, Continue, Unwind, Error};
use Recognizer = recognizer::Router;
use recognizer::Match;

/// `Router` provides an interface for creating complex routes as middleware
/// for the Iron framework.
#[deriving(Clone)]
pub struct Router {
    // The routers, specialized by method.
    routers: HashMap<Method, Recognizer<Box<Middleware + Send>>>
}

impl Router {
    /// `new` constructs a new, blank `Router`.
    pub fn new() -> Router { Router { routers: HashMap::new() } }
    /// Add a new route to a `Router`, matching both a method and glob pattern.
    ///
    /// `route` supports glob patterns: `*` for a single wildcard segment and
    /// `:param` for matching storing that segment of the request url in the `Params`
    /// object, which is stored on the request Alloy.
    ///
    /// For instance, to route `Get` requests on any route matching
    /// `/users/:userid/:friend` and store `userid` and `friend` in
    /// the exposed Params object:
    ///
    /// ```ignore
    /// router.route(http::method::Get, "/users/:userid/:friendid", controller);
    /// ```
    ///
    /// The controller provided to route can be any `Middleware`, which allows
    /// extreme flexibility when handling routes. For instance, you could provide
    /// a `Chain`, a `Middleware`, which contains an authorization middleware and
    /// a controller function, so that you can confirm that the request is
    /// authorized for this route before handling it.
    pub fn route<'a, M: Middleware + Send, S: Str>(&mut self, method: Method, glob: S, handler: M) -> &mut Router {
        self.routers
            .find_or_insert_with(method, |_| Recognizer::new())
            .add(glob.as_slice(), box handler as Box<Middleware + Send>);
        self
    }

    /// Like route, but specialized to the `Get` method.
    pub fn get<'a, M: Middleware + Send, S: Str>(&mut self, glob: S, handler: M) -> &mut Router {
        self.route(method::Get, glob, handler)
    }

    /// Like route, but specialized to the `Post` method.
    pub fn post<'a, M: Middleware + Send, S: Str>(&mut self, glob: S, handler: M) -> &mut Router {
        self.route(method::Post, glob, handler)
    }

    /// Like route, but specialized to the `Put` method.
    pub fn put<'a, M: Middleware + Send, S: Str>(&mut self, glob: S, handler: M) -> &mut Router {
        self.route(method::Put, glob, handler)
    }

    /// Like route, but specialized to the `Delete` method.
    pub fn delete<'a, M: Middleware + Send, S: Str>(&mut self, glob: S, handler: M) -> &mut Router {
        self.route(method::Delete, glob, handler)
    }

    /// Like route, but specialized to the `Head` method.
    pub fn head<'a, M: Middleware + Send, S: Str>(&mut self, glob: S, handler: M) -> &mut Router {
        self.route(method::Head, glob, handler)
    }

    /// Like route, but specialized to the `Patch` method.
    pub fn patch<'a, M: Middleware + Send, S: Str>(&mut self, glob: S, handler: M) -> &mut Router {
        self.route(method::Patch, glob, handler)
    }

    /// Like route, but specialized to the `Options` method.
    pub fn options<'a, M: Middleware + Send, S: Str>(&mut self, glob: S, handler: M) -> &mut Router {
        self.route(method::Options, glob, handler)
    }

    fn recognize<'a>(&'a self, method: &Method, path: &str)
                     -> Option<Match<&'a Box<Middleware + Send>>> {
        self.routers.find(method).and_then(|router| router.recognize(path).ok())
    }
}

impl Middleware for Router {
    fn enter(&mut self, req: &mut Request, res: &mut Response) -> Status {
        let matched = match self.recognize(&req.method, req.url.path.connect("/").as_slice()) {
            Some(matched) => matched,
            // No match.
            None => return Continue
        };

        req.extensions.insert(matched.params);
        let mut handler = matched.handler.clone_box();
        let mut handler_status = handler.enter(req, res);

        match handler_status {
            Error(ref mut e) => {
                let error: &mut Show = *e;
                let _ = handler.on_error(req, res, error);
            },
            _ => {
                let _ = handler.exit(req, res);
            }
        };

        return match handler_status {
            Continue => Unwind,
            otherwise => otherwise
        }
    }
}

<|endoftext|>


<commit_before>use std::io::Read;

use outcome::{self, IntoOutcome};
use outcome::Outcome::*;
use http::Status;
use request::Request;
use data::Data;

/// Type alias for the `Outcome` of a `FromData` conversion.
pub type Outcome<S, E> = outcome::Outcome<S, (Status, E), Data>;

impl<'a, S, E> IntoOutcome<S, (Status, E), Data> for Result<S, E> {
    #[inline]
    fn into_outcome(self) -> Outcome<S, E> {
        match self {
            Ok(val) => Success(val),
            Err(err) => Failure((Status::InternalServerError, err))
        }
    }
}

/// Trait used to derive an object from incoming request data.
///
/// Types that implement this trait can be used as a target for the `data =
/// "<param>"` route parmater, as illustrated below:
///
/// ```rust,ignore
/// #[post("/submit", data = "<var>")]
/// fn submit(var: T) -> ... { ... }
/// ```
///
/// In this example, `T` can be any type that implements `FromData`.
///
/// # Outcomes
///
/// The returned [Outcome](/rocket/outcome/index.html) of a `from_data` call
/// determines how the incoming request will be processed.
///
/// * **Success**(S)
///
///   If the `Outcome` is `Success`, then the `Success` value will be used as
///   the value for the data parameter.  As long as all other parsed types
///   succeed, the request will be handled by the requesting handler.
///
/// * **Failure**(Status, E)
///
///   If the `Outcome` is `Failure`, the request will fail with the given status
///   code and error. The designated error
///   [Catcher](/rocket/struct.Catcher.html) will be used to respond to the
///   request. Note that users can request types of `Result<S, E>` and
///   `Option<S>` to catch `Failure`s and retrieve the error value.
///
/// * **Forward**(Data)
///
///   If the `Outcome` is `Forward`, the request will be forwarded to the next
///   matching request. This requires that no data has been read from the `Data`
///   parameter. Note that users can request an `Option<S>` to catch `Forward`s.
///
/// # Example
///
/// Say that you have a custom type, `Person`:
///
/// ```rust
/// # #[allow(dead_code)]
/// struct Person {
///     name: String,
///     age: u16
/// }
/// ```
///
/// `Person` has a custom serialization format, so the built-in `JSON` type
/// doesn't suffice. The format is `<name>:<age>` with `Content-Type:
/// application/x-person`. You'd like to use `Person` as a `FromData` type so
/// that you can retrieve it directly from a client's request body:
///
/// ```rust,ignore
/// #[post("/person", data = "<person>")]
/// fn person(person: Person) -> &'static str {
///     "Saved the new person to the database!"
/// }
/// ```
///
/// A `FromData` implementation allowing this looks like:
///
/// ```rust
/// # #![allow(unused_attributes)]
/// # #![allow(unused_variables)]
/// # #![feature(plugin)]
/// # #![plugin(rocket_codegen)]
/// # extern crate rocket;
/// #
/// # #[derive(Debug)]
/// # struct Person { name: String, age: u16 }
/// #
/// use std::io::Read;
/// use rocket::{Request, Data, Outcome};
/// use rocket::data::{self, FromData};
/// use rocket::http::{Status, ContentType};
/// use rocket::Outcome::*;
///
/// impl FromData for Person {
///     type Error = String;
///
///     fn from_data(req: &Request, data: Data) -> data::Outcome<Self, String> {
///         // Ensure the content type is correct before opening the data.
///         let person_ct = ContentType::new("application", "x-person");
///         if req.content_type() != Some(person_ct) {
///             return Outcome::Forward(data);
///         }
///
///         // Read the data into a String.
///         let mut string = String::new();
///         if let Err(e) = data.open().read_to_string(&mut string) {
///             return Failure((Status::InternalServerError, format!("{:?}", e)));
///         }
///
///         // Split the string into two pieces at ':'.
///         let (name, age) = match string.find(':') {
///             Some(i) => (&string[..i], &string[(i + 1)..]),
///             None => return Failure((Status::UnprocessableEntity, "':'".into()))
///         };
///
///         // Parse the age.
///         let age: u16 = match age.parse() {
///             Ok(age) => age,
///             Err(_) => return Failure((Status::UnprocessableEntity, "Age".into()))
///         };
///
///         // Return successfully.
///         Success(Person {
///             name: name.into(),
///             age: age
///         })
///     }
/// }
/// #
/// # #[post("/person", data = "<person>")]
/// # fn person(person: Person) {  }
/// # #[post("/person", data = "<person>")]
/// # fn person2(person: Result<Person, String>) {  }
/// # fn main() {  }
/// ```
pub trait FromData: Sized {
    /// The associated error to be returned when parsing fails.
    type Error;

    /// Parses an instance of `Self` from the incoming request body data.
    ///
    /// If the parse is successful, an outcome of `Success` is returned. If the
    /// data does not correspond to the type of `Self`, `Forward` is returned.
    /// If parsing fails, `Failure` is returned.
    fn from_data(request: &Request, data: Data) -> Outcome<Self, Self::Error>;
}

/// The identity implementation of `FromData`. Always returns `Success`.
impl FromData for Data {
    type Error = ();
    fn from_data(_: &Request, data: Data) -> Outcome<Self, Self::Error> {
        Success(data)
    }
}

impl<T: FromData> FromData for Result<T, T::Error> {
    type Error = ();

    fn from_data(request: &Request, data: Data) -> Outcome<Self, Self::Error> {
        match T::from_data(request, data) {
            Success(val) => Success(Ok(val)),
            Failure((_, val)) => Success(Err(val)),
            Forward(data) => Forward(data),
        }
    }
}

impl<T: FromData> FromData for Option<T> {
    type Error = ();

    fn from_data(request: &Request, data: Data) -> Outcome<Self, Self::Error> {
        match T::from_data(request, data) {
            Success(val) => Success(Some(val)),
            Failure(_) | Forward(_) => Success(None),
        }
    }
}

impl FromData for String {
    type Error = ();

    // FIXME: Doc.
    fn from_data(_: &Request, data: Data) -> Outcome<Self, Self::Error> {
        let mut string = String::new();
        match data.open().read_to_string(&mut string) {
            Ok(_) => Success(string),
            Err(_) => Failure((Status::UnprocessableEntity, ()))
        }
    }
}
<commit_msg>Implement FromData for Vec<u8>.<commit_after>use std::io::{self, Read};

use outcome::{self, IntoOutcome};
use outcome::Outcome::*;
use http::Status;
use request::Request;
use data::Data;

/// Type alias for the `Outcome` of a `FromData` conversion.
pub type Outcome<S, E> = outcome::Outcome<S, (Status, E), Data>;

impl<'a, S, E> IntoOutcome<S, (Status, E), Data> for Result<S, E> {
    #[inline]
    fn into_outcome(self) -> Outcome<S, E> {
        match self {
            Ok(val) => Success(val),
            Err(err) => Failure((Status::InternalServerError, err))
        }
    }
}

/// Trait used to derive an object from incoming request data.
///
/// Types that implement this trait can be used as a target for the `data =
/// "<param>"` route parmater, as illustrated below:
///
/// ```rust,ignore
/// #[post("/submit", data = "<var>")]
/// fn submit(var: T) -> ... { ... }
/// ```
///
/// In this example, `T` can be any type that implements `FromData`.
///
/// # Outcomes
///
/// The returned [Outcome](/rocket/outcome/index.html) of a `from_data` call
/// determines how the incoming request will be processed.
///
/// * **Success**(S)
///
///   If the `Outcome` is `Success`, then the `Success` value will be used as
///   the value for the data parameter.  As long as all other parsed types
///   succeed, the request will be handled by the requesting handler.
///
/// * **Failure**(Status, E)
///
///   If the `Outcome` is `Failure`, the request will fail with the given status
///   code and error. The designated error
///   [Catcher](/rocket/struct.Catcher.html) will be used to respond to the
///   request. Note that users can request types of `Result<S, E>` and
///   `Option<S>` to catch `Failure`s and retrieve the error value.
///
/// * **Forward**(Data)
///
///   If the `Outcome` is `Forward`, the request will be forwarded to the next
///   matching request. This requires that no data has been read from the `Data`
///   parameter. Note that users can request an `Option<S>` to catch `Forward`s.
///
/// # Example
///
/// Say that you have a custom type, `Person`:
///
/// ```rust
/// # #[allow(dead_code)]
/// struct Person {
///     name: String,
///     age: u16
/// }
/// ```
///
/// `Person` has a custom serialization format, so the built-in `JSON` type
/// doesn't suffice. The format is `<name>:<age>` with `Content-Type:
/// application/x-person`. You'd like to use `Person` as a `FromData` type so
/// that you can retrieve it directly from a client's request body:
///
/// ```rust,ignore
/// #[post("/person", data = "<person>")]
/// fn person(person: Person) -> &'static str {
///     "Saved the new person to the database!"
/// }
/// ```
///
/// A `FromData` implementation allowing this looks like:
///
/// ```rust
/// # #![allow(unused_attributes)]
/// # #![allow(unused_variables)]
/// # #![feature(plugin)]
/// # #![plugin(rocket_codegen)]
/// # extern crate rocket;
/// #
/// # #[derive(Debug)]
/// # struct Person { name: String, age: u16 }
/// #
/// use std::io::Read;
/// use rocket::{Request, Data, Outcome};
/// use rocket::data::{self, FromData};
/// use rocket::http::{Status, ContentType};
/// use rocket::Outcome::*;
///
/// impl FromData for Person {
///     type Error = String;
///
///     fn from_data(req: &Request, data: Data) -> data::Outcome<Self, String> {
///         // Ensure the content type is correct before opening the data.
///         let person_ct = ContentType::new("application", "x-person");
///         if req.content_type() != Some(person_ct) {
///             return Outcome::Forward(data);
///         }
///
///         // Read the data into a String.
///         let mut string = String::new();
///         if let Err(e) = data.open().read_to_string(&mut string) {
///             return Failure((Status::InternalServerError, format!("{:?}", e)));
///         }
///
///         // Split the string into two pieces at ':'.
///         let (name, age) = match string.find(':') {
///             Some(i) => (&string[..i], &string[(i + 1)..]),
///             None => return Failure((Status::UnprocessableEntity, "':'".into()))
///         };
///
///         // Parse the age.
///         let age: u16 = match age.parse() {
///             Ok(age) => age,
///             Err(_) => return Failure((Status::UnprocessableEntity, "Age".into()))
///         };
///
///         // Return successfully.
///         Success(Person {
///             name: name.into(),
///             age: age
///         })
///     }
/// }
/// #
/// # #[post("/person", data = "<person>")]
/// # fn person(person: Person) {  }
/// # #[post("/person", data = "<person>")]
/// # fn person2(person: Result<Person, String>) {  }
/// # fn main() {  }
/// ```
pub trait FromData: Sized {
    /// The associated error to be returned when parsing fails.
    type Error;

    /// Parses an instance of `Self` from the incoming request body data.
    ///
    /// If the parse is successful, an outcome of `Success` is returned. If the
    /// data does not correspond to the type of `Self`, `Forward` is returned.
    /// If parsing fails, `Failure` is returned.
    fn from_data(request: &Request, data: Data) -> Outcome<Self, Self::Error>;
}

/// The identity implementation of `FromData`. Always returns `Success`.
impl FromData for Data {
    type Error = ();
    fn from_data(_: &Request, data: Data) -> Outcome<Self, Self::Error> {
        Success(data)
    }
}

impl<T: FromData> FromData for Result<T, T::Error> {
    type Error = ();

    fn from_data(request: &Request, data: Data) -> Outcome<Self, Self::Error> {
        match T::from_data(request, data) {
            Success(val) => Success(Ok(val)),
            Failure((_, val)) => Success(Err(val)),
            Forward(data) => Forward(data),
        }
    }
}

impl<T: FromData> FromData for Option<T> {
    type Error = ();

    fn from_data(request: &Request, data: Data) -> Outcome<Self, Self::Error> {
        match T::from_data(request, data) {
            Success(val) => Success(Some(val)),
            Failure(_) | Forward(_) => Success(None),
        }
    }
}

impl FromData for String {
    type Error = io::Error;

    // FIXME: Doc.
    fn from_data(_: &Request, data: Data) -> Outcome<Self, Self::Error> {
        let mut string = String::new();
        match data.open().read_to_string(&mut string) {
            Ok(_) => Success(string),
            Err(e) => Failure((Status::BadRequest, e))
        }
    }
}

// FIXME Implement this.
impl FromData for Vec<u8> {
    type Error = io::Error;

    // FIXME: Doc.
    fn from_data(_: &Request, data: Data) -> Outcome<Self, Self::Error> {
        let mut bytes = Vec::new();
        match data.open().read_to_end(&mut bytes) {
            Ok(_) => Success(bytes),
            Err(e) => Failure((Status::BadRequest, e))
        }
    }
}
<|endoftext|>


<commit_before>//! Routes are used for ratelimiting. These are to differentiate between the
//! different _types_ of routes - such as getting the current user's channels -
//! for the most part, with the exception being major parameters.
//!
//! [Taken from] the Discord docs, major parameters are:
//!
//! > Additionally, rate limits take into account major parameters in the URL.
//! > For example, `/channels/:channel_id` and
//! > `/channels/:channel_id/messages/:message_id` both take `channel_id` into
//! > account when generating rate limits since it's the major parameter. The
//! only current major parameters are `channel_id` and `guild_id`.
//!
//! This results in the two URIs of `GET /channels/4/messages/7` and
//! `GET /channels/5/messages/8` being rate limited _separately_. However, the
//! two URIs of `GET /channels/10/messages/11` and
//! `GET /channels/10/messages/12` will count towards the "same ratelimit", as
//! the major parameter - `10` is equivilant in both URIs' format.
//!
//! # Examples
//!
//! First: taking the first two URIs - `GET /channels/4/messages/7` and
//! `GET /channels/5/messages/8` - and assuming both buckets have a `limit` of
//! `10`, requesting the first URI will result in the response containing a
//! `remaining` of `9`. Immediately after - prior to buckets resetting -
//! performing a request to the _second_ URI will also contain a `remaining` of
//! `9` in the response, as the major parameter - `channel_id` - is different
//! in the two requests (`4` and `5`).
//!
//! Second: take for example the last two URIs. Assuming the bucket's `limit` is
//! `10`, requesting the first URI will return a `remaining` of `9` in the
//! response. Immediately after - prior to buckets resetting - performing a
//! request to the _second_ URI will return a `remaining` of `8` in the
//! response, as the major parameter - `channel_id` - is equivilant for the two
//! requests (`10`).
//!
//!
//! With the examples out of the way: major parameters are why some variants
//! (i.e. all of the channel/guild variants) have an associated u64 as data.
//! This is the Id of the parameter, differentiating between different
//! ratelimits.

use hyper::client::{RequestBuilder, Response};
use hyper::header::Headers;
use hyper::status::StatusCode;
use std::collections::HashMap;
use std::str;
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
use time;
use ::internal::prelude::*;

lazy_static! {
    static ref GLOBAL: Arc<Mutex<RateLimit>> = Arc::new(Mutex::new(RateLimit::default()));
    static ref ROUTES: Arc<Mutex<HashMap<Route, RateLimit>>> = Arc::new(Mutex::new(HashMap::default()));
}

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum Route {
    ChannelsId(u64),
    ChannelsIdInvites(u64),
    ChannelsIdMessages(u64),
    ChannelsIdMessagesBulkDelete(u64),
    ChannelsIdMessagesId(u64),
    ChannelsIdMessagesIdAck(u64),
    ChannelsIdMessagesIdReactions(u64),
    ChannelsIdMessagesIdReactionsUserIdType(u64),
    ChannelsIdPermissionsOverwriteId(u64),
    ChannelsIdPins(u64),
    ChannelsIdPinsMessageId(u64),
    ChannelsIdTyping(u64),
    ChannelsIdWebhooks(u64),
    Gateway,
    GatewayBot,
    Guilds,
    GuildsId(u64),
    GuildsIdBans(u64),
    GuildsIdBansUserId(u64),
    GuildsIdChannels(u64),
    GuildsIdEmbed(u64),
    GuildsIdEmojis(u64),
    GuildsIdEmojisId(u64),
    GuildsIdIntegrations(u64),
    GuildsIdIntegrationsId(u64),
    GuildsIdIntegrationsIdSync(u64),
    GuildsIdInvites(u64),
    GuildsIdMembersId(u64),
    GuildsIdMembersIdRolesId(u64),
    GuildsIdMembersMeNick(u64),
    GuildsIdPrune(u64),
    GuildsIdRegions(u64),
    GuildsIdRoles(u64),
    GuildsIdRolesId(u64),
    GuildsIdWebhooks(u64),
    InvitesCode,
    UsersId,
    UsersMe,
    UsersMeChannels,
    UsersMeConnections,
    UsersMeGuilds,
    UsersMeGuildsId,
    VoiceRegions,
    WebhooksId,
    None,
}

pub fn perform<'a, F>(route: Route, f: F) -> Result<Response>
    where F: Fn() -> RequestBuilder<'a> {
    // Keeping the global lock poisoned here for the duration of the function
    // will ensure that requests are synchronous, which will further ensure
    // that 429s are _never_ hit.
    //
    // This would otherwise cause the potential for 429s to be hit while
    // requests are open.
    let mut global = GLOBAL.lock().expect("global route lock poisoned");

    loop {
        // Perform pre-checking here:
        //
        // - get the route's relevant rate
        // - sleep if that route's already rate-limited until the end of the
        //   'reset' time;
        // - get the global rate;
        // - sleep if there is 0 remaining
        // - then, perform the request
        global.pre_hook();

        if route != Route::None {
            if let Some(route) = ROUTES.lock().expect("routes poisoned").get_mut(&route) {
                route.pre_hook();
            }
        }

        let response = try!(super::retry(&f));

        // Check if the request got ratelimited by checking for status 429,
        // and if so, sleep for the value of the header 'retry-after' -
        // which is in milliseconds - and then `continue` to try again
        //
        // If it didn't ratelimit, subtract one from the RateLimit's
        // 'remaining'
        //
        // Update the 'reset' with the value of the 'x-ratelimit-reset'
        // header
        //
        // It _may_ be possible for the limit to be raised at any time,
        // so check if it did from the value of the 'x-ratelimit-limit'
        // header. If the limit was 5 and is now 7, add 2 to the 'remaining'

        if route != Route::None {
            let redo = if response.headers.get_raw("x-ratelimit-global").is_some() {
                global.post_hook(&response)
            } else {
                ROUTES.lock()
                    .expect("routes poisoned")
                    .entry(route)
                    .or_insert_with(RateLimit::default)
                    .post_hook(&response)
            };

            if redo.unwrap_or(false) {
                continue;
            }
        }

        return Ok(response);
    }
}

#[derive(Clone, Debug, Default)]
pub struct RateLimit {
    limit: i64,
    remaining: i64,
    reset: i64,
}

impl RateLimit {
    pub fn pre_hook(&mut self) {
        if self.limit == 0 {
            return;
        }

        let current_time = time::get_time().sec;

        // The reset was in the past, so we're probably good.
        if current_time > self.reset {
            self.remaining = self.limit;

            return;
        }

        let diff = (self.reset - current_time) as u64;

        if self.remaining == 0 {
            let delay = (diff * 1000) + 500;

            debug!("Pre-emptive ratelimit for {:?}ms", delay);
            thread::sleep(Duration::from_millis(delay));

            return;
        }

        self.remaining -= 1;
    }

    pub fn post_hook(&mut self, response: &Response) -> Result<bool> {
        if let Some(limit) = try!(get_header(&response.headers, "x-ratelimit-limit")) {
            self.limit = limit;
        }

        if let Some(remaining) = try!(get_header(&response.headers, "x-ratelimit-remaining")) {
            self.remaining = remaining;
        }

        if let Some(reset) = try!(get_header(&response.headers, "x-ratelimit-reset")) {
            self.reset = reset;
        }

        Ok(if response.status != StatusCode::TooManyRequests {
            false
        } else if let Some(retry_after) = try!(get_header(&response.headers, "retry-after")) {
            debug!("Ratelimited: {:?}ms", retry_after);
            thread::sleep(Duration::from_millis(retry_after as u64));

            true
        } else {
            false
        })
    }
}

fn get_header(headers: &Headers, header: &str) -> Result<Option<i64>> {
    match headers.get_raw(header) {
        Some(header) => match str::from_utf8(&header[0]) {
            Ok(v) => match v.parse::<i64>() {
                Ok(v) => Ok(Some(v)),
                Err(_why) => Err(Error::Client(ClientError::RateLimitI64)),
            },
            Err(_why) => Err(Error::Client(ClientError::RateLimitUtf8)),
        },
        None => Ok(None),
    }
}
<commit_msg>Don't block entirely on HTTP requests<commit_after>//! Routes are used for ratelimiting. These are to differentiate between the
//! different _types_ of routes - such as getting the current user's channels -
//! for the most part, with the exception being major parameters.
//!
//! [Taken from] the Discord docs, major parameters are:
//!
//! > Additionally, rate limits take into account major parameters in the URL.
//! > For example, `/channels/:channel_id` and
//! > `/channels/:channel_id/messages/:message_id` both take `channel_id` into
//! > account when generating rate limits since it's the major parameter. The
//! only current major parameters are `channel_id` and `guild_id`.
//!
//! This results in the two URIs of `GET /channels/4/messages/7` and
//! `GET /channels/5/messages/8` being rate limited _separately_. However, the
//! two URIs of `GET /channels/10/messages/11` and
//! `GET /channels/10/messages/12` will count towards the "same ratelimit", as
//! the major parameter - `10` is equivilant in both URIs' format.
//!
//! # Examples
//!
//! First: taking the first two URIs - `GET /channels/4/messages/7` and
//! `GET /channels/5/messages/8` - and assuming both buckets have a `limit` of
//! `10`, requesting the first URI will result in the response containing a
//! `remaining` of `9`. Immediately after - prior to buckets resetting -
//! performing a request to the _second_ URI will also contain a `remaining` of
//! `9` in the response, as the major parameter - `channel_id` - is different
//! in the two requests (`4` and `5`).
//!
//! Second: take for example the last two URIs. Assuming the bucket's `limit` is
//! `10`, requesting the first URI will return a `remaining` of `9` in the
//! response. Immediately after - prior to buckets resetting - performing a
//! request to the _second_ URI will return a `remaining` of `8` in the
//! response, as the major parameter - `channel_id` - is equivilant for the two
//! requests (`10`).
//!
//!
//! With the examples out of the way: major parameters are why some variants
//! (i.e. all of the channel/guild variants) have an associated u64 as data.
//! This is the Id of the parameter, differentiating between different
//! ratelimits.

use hyper::client::{RequestBuilder, Response};
use hyper::header::Headers;
use hyper::status::StatusCode;
use std::collections::HashMap;
use std::str;
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
use time;
use ::internal::prelude::*;

lazy_static! {
    static ref GLOBAL: Arc<Mutex<RateLimit>> = Arc::new(Mutex::new(RateLimit::default()));
    static ref ROUTES: Arc<Mutex<HashMap<Route, RateLimit>>> = Arc::new(Mutex::new(HashMap::default()));
}

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum Route {
    ChannelsId(u64),
    ChannelsIdInvites(u64),
    ChannelsIdMessages(u64),
    ChannelsIdMessagesBulkDelete(u64),
    ChannelsIdMessagesId(u64),
    ChannelsIdMessagesIdAck(u64),
    ChannelsIdMessagesIdReactions(u64),
    ChannelsIdMessagesIdReactionsUserIdType(u64),
    ChannelsIdPermissionsOverwriteId(u64),
    ChannelsIdPins(u64),
    ChannelsIdPinsMessageId(u64),
    ChannelsIdTyping(u64),
    ChannelsIdWebhooks(u64),
    Gateway,
    GatewayBot,
    Guilds,
    GuildsId(u64),
    GuildsIdBans(u64),
    GuildsIdBansUserId(u64),
    GuildsIdChannels(u64),
    GuildsIdEmbed(u64),
    GuildsIdEmojis(u64),
    GuildsIdEmojisId(u64),
    GuildsIdIntegrations(u64),
    GuildsIdIntegrationsId(u64),
    GuildsIdIntegrationsIdSync(u64),
    GuildsIdInvites(u64),
    GuildsIdMembersId(u64),
    GuildsIdMembersIdRolesId(u64),
    GuildsIdMembersMeNick(u64),
    GuildsIdPrune(u64),
    GuildsIdRegions(u64),
    GuildsIdRoles(u64),
    GuildsIdRolesId(u64),
    GuildsIdWebhooks(u64),
    InvitesCode,
    UsersId,
    UsersMe,
    UsersMeChannels,
    UsersMeConnections,
    UsersMeGuilds,
    UsersMeGuildsId,
    VoiceRegions,
    WebhooksId,
    None,
}

pub fn perform<'a, F>(route: Route, f: F) -> Result<Response>
    where F: Fn() -> RequestBuilder<'a> {

    loop {
        // Perform pre-checking here:
        //
        // - get the route's relevant rate
        // - sleep if that route's already rate-limited until the end of the
        //   'reset' time;
        // - get the global rate;
        // - sleep if there is 0 remaining
        // - then, perform the request
        {
            let mut global = GLOBAL.lock().expect("global route lock poisoned");
            global.pre_hook();
        }

        if route != Route::None {
            if let Some(route) = ROUTES.lock().expect("routes poisoned").get_mut(&route) {
                route.pre_hook();
            }
        }

        let response = try!(super::retry(&f));

        // Check if the request got ratelimited by checking for status 429,
        // and if so, sleep for the value of the header 'retry-after' -
        // which is in milliseconds - and then `continue` to try again
        //
        // If it didn't ratelimit, subtract one from the RateLimit's
        // 'remaining'
        //
        // Update the 'reset' with the value of the 'x-ratelimit-reset'
        // header
        //
        // It _may_ be possible for the limit to be raised at any time,
        // so check if it did from the value of the 'x-ratelimit-limit'
        // header. If the limit was 5 and is now 7, add 2 to the 'remaining'

        if route != Route::None {
            let redo = if response.headers.get_raw("x-ratelimit-global").is_some() {
                let mut global = GLOBAL.lock().expect("global route lock poisoned");
                global.post_hook(&response)
            } else {
                ROUTES.lock()
                    .expect("routes poisoned")
                    .entry(route)
                    .or_insert_with(RateLimit::default)
                    .post_hook(&response)
            };

            if redo.unwrap_or(false) {
                continue;
            }
        }

        return Ok(response);
    }
}

#[derive(Clone, Debug, Default)]
pub struct RateLimit {
    limit: i64,
    remaining: i64,
    reset: i64,
}

impl RateLimit {
    pub fn pre_hook(&mut self) {
        if self.limit == 0 {
            return;
        }

        let current_time = time::get_time().sec;

        // The reset was in the past, so we're probably good.
        if current_time > self.reset {
            self.remaining = self.limit;

            return;
        }

        let diff = (self.reset - current_time) as u64;

        if self.remaining == 0 {
            let delay = (diff * 1000) + 500;

            debug!("Pre-emptive ratelimit for {:?}ms", delay);
            thread::sleep(Duration::from_millis(delay));

            return;
        }

        self.remaining -= 1;
    }

    pub fn post_hook(&mut self, response: &Response) -> Result<bool> {
        if let Some(limit) = try!(get_header(&response.headers, "x-ratelimit-limit")) {
            self.limit = limit;
        }

        if let Some(remaining) = try!(get_header(&response.headers, "x-ratelimit-remaining")) {
            self.remaining = remaining;
        }

        if let Some(reset) = try!(get_header(&response.headers, "x-ratelimit-reset")) {
            self.reset = reset;
        }

        Ok(if response.status != StatusCode::TooManyRequests {
            false
        } else if let Some(retry_after) = try!(get_header(&response.headers, "retry-after")) {
            debug!("Ratelimited: {:?}ms", retry_after);
            thread::sleep(Duration::from_millis(retry_after as u64));

            true
        } else {
            false
        })
    }
}

fn get_header(headers: &Headers, header: &str) -> Result<Option<i64>> {
    match headers.get_raw(header) {
        Some(header) => match str::from_utf8(&header[0]) {
            Ok(v) => match v.parse::<i64>() {
                Ok(v) => Ok(Some(v)),
                Err(_why) => Err(Error::Client(ClientError::RateLimitI64)),
            },
            Err(_why) => Err(Error::Client(ClientError::RateLimitUtf8)),
        },
        None => Ok(None),
    }
}
<|endoftext|>


<commit_before>use mio::*;
use mio::unix::*;
use mio::util::Slab;
use std::path::PathBuf;
use std::io::{self,Read,Write,ErrorKind};
use std::iter::repeat;
use std::thread;
use std::str::from_utf8;
use std::fs;
use std::os::unix::fs::PermissionsExt;
use std::collections::HashMap;
use std::sync::mpsc;
use log;
use rustc_serialize::json::{decode,encode};
use rustc_serialize::{Encodable,Decodable,Encoder,Decoder};
use nom::{IResult,HexDisplay};

use yxorp::network::{ProxyOrder,ServerMessage};
use yxorp::network::buffer::Buffer;
use yxorp::messages::Command;

use state::{HttpProxy,TlsProxy,ConfigState};

const SERVER: Token = Token(0);

#[derive(Debug,Clone,Copy,PartialEq,Eq,Hash)]
pub enum ListenerType {
  HTTP,
  HTTPS,
  TCP
}

impl Encodable for ListenerType {
  fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
    match *self {
      ListenerType::HTTP  => e.emit_str("HTTP"),
      ListenerType::HTTPS => e.emit_str("HTTPS"),
      ListenerType::TCP   => e.emit_str("TCP"),
    }
  }
}

impl Decodable for ListenerType {
  fn decode<D: Decoder>(decoder: &mut D) -> Result<ListenerType, D::Error> {
    let tag = try!(decoder.read_str());
    match &tag[..] {
      "HTTP"  => Ok(ListenerType::HTTP),
      "HTTPS" => Ok(ListenerType::HTTPS),
      "TCP"   => Ok(ListenerType::TCP),
      _       => Err(decoder.error("unrecognized listener type"))
    }
  }
}

pub struct Listener {
  pub tag:           String,
  pub listener_type: ListenerType,
  pub sender:        Sender<ProxyOrder>,
  pub receiver:      mpsc::Receiver<ServerMessage>,
  pub state:         ConfigState,
}

impl Listener {
  pub fn new(tag: String, listener_type: ListenerType, ip_address: String, port: u16, sender: Sender<ProxyOrder>, receiver: mpsc::Receiver<ServerMessage>) -> Listener {
    let state = match listener_type {
      ListenerType::HTTP  => ConfigState::Http(HttpProxy::new(ip_address, port)),
      ListenerType::HTTPS => ConfigState::Tls(TlsProxy::new(ip_address, port)),
      _                   => unimplemented!(),
    };

    Listener {
      tag:           tag,
      listener_type: listener_type,
      sender:        sender,
      receiver:      receiver,
      state:         state,
    }
  }
}

impl Encodable for Listener {
  fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
    e.emit_map(3, |e| {
      try!(e.emit_map_elt_key(0, |e| "tag".encode(e)));
      try!(e.emit_map_elt_val(0, |e| self.tag.encode(e)));
      try!(e.emit_map_elt_key(1, |e| "listener_type".encode(e)));
      try!(e.emit_map_elt_val(1, |e| self.listener_type.encode(e)));
      try!(e.emit_map_elt_key(2, |e| "state".encode(e)));
      try!(e.emit_map_elt_val(2, |e| self.state.encode(e)));
      Ok(())
    })
  }
}

#[derive(Debug,Clone,PartialEq,Eq,Hash, RustcDecodable, RustcEncodable)]
pub struct ConfigMessage {
    pub id:       String,
    pub listener: String,
    pub command:  Command
}

struct CommandClient {
  sock:        UnixStream,
  buf:         Buffer,
  back_buf:    Buffer,
  token:       Option<Token>,
  message_ids: Vec<String>,
  write_timeout: Option<Timeout>,
}

impl CommandClient {
  fn new(sock: UnixStream) -> CommandClient {
    CommandClient {
      sock:        sock,
      buf:         Buffer::with_capacity(1024),
      back_buf:    Buffer::with_capacity(10000),
      token:       None,
      message_ids: Vec::new(),
      write_timeout: None,
    }
  }

  fn add_message_id(&mut self, id: String) {
    self.message_ids.push(id);
    self.message_ids.sort();
  }

  fn has_message_id(&self, id: &String) ->Option<usize> {
    self.message_ids.binary_search(&id).ok()
  }

  fn remove_message_id(&mut self, index: usize) {
    self.message_ids.remove(index);
  }

  fn reregister(&self,  event_loop: &mut EventLoop<CommandServer>, tok: Token) {
    let mut interest = EventSet::hup();
    interest.insert(EventSet::readable());
    interest.insert(EventSet::writable());
    event_loop.register(&self.sock, tok, interest, PollOpt::edge() | PollOpt::oneshot());
  }

  fn conn_readable(&mut self, event_loop: &mut EventLoop<CommandServer>, tok: Token) -> Option<Vec<ConfigMessage>>{
    trace!("server conn readable; tok={:?}", tok);
    match self.sock.read(self.buf.space()) {
      Ok(0) => {
        self.reregister(event_loop, tok);
        return None;
      },
      Err(e) => {
        log!(log::LogLevel::Error, "UNIX CLIENT[{}] read error: {:?}", tok.as_usize(), e);
        return None;
      },
      Ok(r) => {
        self.buf.fill(r);
        debug!("UNIX CLIENT[{}] sent {} bytes: {:?}", tok.as_usize(), r, from_utf8(self.buf.data()));
      },
    };

    let mut res: Option<Vec<ConfigMessage>> = None;
    let mut offset = 0usize;
    match parse(self.buf.data()) {
      IResult::Incomplete(_) => {
        return Some(Vec::new());
      },
      IResult::Error(e)      => {
        log!(log::LogLevel::Error, "UNIX CLIENT[{}] read error: {:?}", tok.as_usize(), e);
        return None;
      },
      IResult::Done(i, v)    => {
        offset = self.buf.data().offset(i);
        res = Some(v);
      }
    }
    debug!("parsed {} bytes, result: {:?}", offset, res);
    self.buf.consume(offset);
    return res;
  }

  fn conn_writable(&mut self, event_loop: &mut EventLoop<CommandServer>, tok: Token) {
    if self.write_timeout.is_some() {
      trace!("server conn writable; tok={:?}; waiting for timeout", tok.as_usize());
      return;
    }

    trace!("server conn writable; tok={:?}", tok);
    match self.sock.write(self.back_buf.data()) {
      Ok(0) => {
        //println!("[{}] setting timeout!", tok.as_usize());
        self.write_timeout = event_loop.timeout_ms(self.token.unwrap().as_usize(), 700).ok();
      },
      Ok(r) => {
        self.back_buf.consume(r);
      },
      Err(e) => log!(log::LogLevel::Error,"UNIX CLIENT[{}] read error: {:?}", tok.as_usize(), e),
    }
    let mut interest = EventSet::hup();
    interest.insert(EventSet::readable());
    interest.insert(EventSet::writable());
    event_loop.register(&self.sock, tok, interest, PollOpt::edge() | PollOpt::oneshot());
  }
}

fn parse(input: &[u8]) -> IResult<&[u8], Vec<ConfigMessage>> {
  many0!(input,
    complete!(terminated!(map_res!(map_res!(is_not!("\0"), from_utf8), decode), char!('\0')))
  )
}

struct CommandServer {
  sock:  UnixListener,
  conns: Slab<CommandClient>,
  listeners: HashMap<String, Listener>,
}

impl CommandServer {
  fn accept(&mut self, event_loop: &mut EventLoop<CommandServer>) -> io::Result<()> {
    debug!("server accepting socket");

    let sock = self.sock.accept().unwrap().unwrap();
    let conn = CommandClient::new(sock);
    let tok = self.conns.insert(conn)
      .ok().expect("could not add connection to slab");

    // Register the connection
    self.conns[tok].token = Some(tok);
    let mut interest = EventSet::hup();
    interest.insert(EventSet::readable());
    interest.insert(EventSet::writable());
    event_loop.register(&self.conns[tok].sock, tok, interest, PollOpt::edge())
      .ok().expect("could not register socket with event loop");

    let accept_interest = EventSet::readable();
    event_loop.reregister(&self.sock, SERVER, accept_interest, PollOpt::edge());
    Ok(())
  }

  fn conn<'a>(&'a mut self, tok: Token) -> &'a mut CommandClient {
    &mut self.conns[tok]
  }

  fn dispatch(&mut self, token: Token, v: Vec<ConfigMessage>) {
    for message in &v {
      let command = message.command.clone();
      if let Some(ref mut listener) = self.listeners.get_mut (&message.listener) {
        if message.command == Command::DumpConfiguration {
          self.conns[token].back_buf.write(&encode(*listener).unwrap().into_bytes());
          self.conns[token].back_buf.write(&b"\0"[..]);
        } else {
          self.conns[token].add_message_id(message.id.clone());
          listener.state.handle_command(&command);
          listener.sender.send(ProxyOrder::Command(message.id.clone(), command));
        }
      } else {
        log!(log::LogLevel::Error, "no listener found for tag: {}", message.listener);
      }
    }
  }

  fn new(srv: UnixListener, listeners: HashMap<String, Listener>) -> CommandServer {
    CommandServer {
      sock:  srv,
      conns: Slab::new_starting_at(Token(1), 128),
      listeners: listeners,
    }
  }
}

impl Handler for CommandServer {
	type Timeout = usize;
	type Message = ();

	fn ready(&mut self, event_loop: &mut EventLoop<CommandServer>, token: Token, events: EventSet) {
    //trace!("ready: {:?} -> {:?}", token, events);
    if events.is_readable() {
      match token {
        SERVER => self.accept(event_loop).unwrap(),
        _      => {
          if self.conns.contains(token) {
            let opt_v = self.conns[token].conn_readable(event_loop, token);
            if let Some(v) = opt_v {
              self.dispatch(token, v);
            }
          }
        }
      };
    }

    if events.is_writable() {
      match token {
        SERVER => panic!("received writable for token 0"),
        _      => {
          if self.conns.contains(token) {
            self.conns[token].conn_writable(event_loop, token)
          }
        }
      };
    }

    if events.is_hup() {
      if self.conns.contains(token) {
        event_loop.deregister(&self.conns[token].sock);
        self.conns.remove(token);
        trace!("closed client [{}]", token.as_usize());
      }
    }
  }

  fn notify(&mut self, event_loop: &mut EventLoop<Self>, message: Self::Message) {
    // TODO: dispatch here to clients the list of messages you want to display
    info!("notify");
  }

  fn timeout(&mut self, event_loop: &mut EventLoop<Self>, timeout: Self::Timeout) {
    if timeout == 0 {
      for listener in self.listeners.values() {
        while let Ok(msg) = listener.receiver.try_recv() {
          //println!("got msg: {:?}", msg);
          for client in self.conns.iter_mut() {
            if let Some(index) = client.has_message_id(&msg.id) {
              client.back_buf.write(&encode(&msg).unwrap().into_bytes());
              client.back_buf.write(&b"\0"[..]);
              client.remove_message_id(index);
            }
          }
        }
      }
      event_loop.timeout_ms(0, 700);
    } else {
      let token = Token(timeout);
      if self.conns.contains(token) {
        //println!("[{}] timeout ended, registering for writes", timeout);
        self.conns[token].write_timeout = None;
        let mut interest = EventSet::hup();
        interest.insert(EventSet::readable());
        interest.insert(EventSet::writable());
        event_loop.register(&self.conns[token].sock, token, interest, PollOpt::edge() | PollOpt::oneshot());
      }
    }
  }

}

pub fn start(path: String, listeners: HashMap<String, Listener>) {
  thread::spawn(move || {
    let mut event_loop = EventLoop::new().unwrap();
    let addr = PathBuf::from(path);
    if let Err(e) = fs::remove_file(&addr) {
      match e.kind() {
        ErrorKind::NotFound => {},
        _ => {
          log!(log::LogLevel::Error, "could not delete previous socket at {:?}: {:?}", addr, e);
          return;
        }
      }
    }
    match UnixListener::bind(&addr) {
      Ok(srv) => {
        if let Err(e) =  fs::set_permissions(&addr, fs::Permissions::from_mode(0o600)) {
          log!( log::LogLevel::Error, "could not set the unix socket permissions: {:?}", e);
          fs::remove_file(&addr);
          return;
        }
        info!("listen for connections");
        event_loop.register(&srv, SERVER, EventSet::readable(), PollOpt::edge() | PollOpt::oneshot()).unwrap();
        event_loop.timeout_ms(0, 700);

        event_loop.run(&mut CommandServer::new(srv, listeners)).unwrap()
      },
      Err(e) => {
        log!(log::LogLevel::Error, "could not create unix socket: {:?}", e);
      }
    }
  });
}

#[cfg(test)]
mod tests {
  use super::*;
  use rustc_serialize::json;
  use yxorp::messages::{Command,HttpFront};

  #[test]
  fn config_message_test() {
    let raw_json = r#"{ "id": "ID_TEST", "listener": "HTTP", "command":{"type": "ADD_HTTP_FRONT", "data": {"app_id": "xxx", "hostname": "yyy", "path_begin": "xxx", "port": 4242}} }"#;
    let config: ConfigMessage = json::decode(raw_json).unwrap();
    println!("{:?}", config);
    assert_eq!(config.listener, "HTTP");
    assert_eq!(config.command, Command::AddHttpFront(HttpFront{
      app_id: String::from("xxx"),
      hostname: String::from("yyy"),
      path_begin: String::from("xxx"),
      port: 4242
    }));
  }
}
<commit_msg>show the correlation id for the configuration dump<commit_after>use mio::*;
use mio::unix::*;
use mio::util::Slab;
use std::path::PathBuf;
use std::io::{self,Read,Write,ErrorKind};
use std::iter::repeat;
use std::thread;
use std::str::from_utf8;
use std::fs;
use std::os::unix::fs::PermissionsExt;
use std::collections::HashMap;
use std::sync::mpsc;
use log;
use rustc_serialize::json::{decode,encode};
use rustc_serialize::{Encodable,Decodable,Encoder,Decoder};
use nom::{IResult,HexDisplay};

use yxorp::network::{ProxyOrder,ServerMessage};
use yxorp::network::buffer::Buffer;
use yxorp::messages::Command;

use state::{HttpProxy,TlsProxy,ConfigState};

const SERVER: Token = Token(0);

#[derive(Debug,Clone,Copy,PartialEq,Eq,Hash)]
pub enum ListenerType {
  HTTP,
  HTTPS,
  TCP
}

impl Encodable for ListenerType {
  fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
    match *self {
      ListenerType::HTTP  => e.emit_str("HTTP"),
      ListenerType::HTTPS => e.emit_str("HTTPS"),
      ListenerType::TCP   => e.emit_str("TCP"),
    }
  }
}

impl Decodable for ListenerType {
  fn decode<D: Decoder>(decoder: &mut D) -> Result<ListenerType, D::Error> {
    let tag = try!(decoder.read_str());
    match &tag[..] {
      "HTTP"  => Ok(ListenerType::HTTP),
      "HTTPS" => Ok(ListenerType::HTTPS),
      "TCP"   => Ok(ListenerType::TCP),
      _       => Err(decoder.error("unrecognized listener type"))
    }
  }
}

pub struct Listener {
  pub tag:           String,
  pub listener_type: ListenerType,
  pub sender:        Sender<ProxyOrder>,
  pub receiver:      mpsc::Receiver<ServerMessage>,
  pub state:         ConfigState,
}

impl Listener {
  pub fn new(tag: String, listener_type: ListenerType, ip_address: String, port: u16, sender: Sender<ProxyOrder>, receiver: mpsc::Receiver<ServerMessage>) -> Listener {
    let state = match listener_type {
      ListenerType::HTTP  => ConfigState::Http(HttpProxy::new(ip_address, port)),
      ListenerType::HTTPS => ConfigState::Tls(TlsProxy::new(ip_address, port)),
      _                   => unimplemented!(),
    };

    Listener {
      tag:           tag,
      listener_type: listener_type,
      sender:        sender,
      receiver:      receiver,
      state:         state,
    }
  }
}

impl Encodable for Listener {
  fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
    e.emit_map(3, |e| {
      try!(e.emit_map_elt_key(0, |e| "tag".encode(e)));
      try!(e.emit_map_elt_val(0, |e| self.tag.encode(e)));
      try!(e.emit_map_elt_key(1, |e| "listener_type".encode(e)));
      try!(e.emit_map_elt_val(1, |e| self.listener_type.encode(e)));
      try!(e.emit_map_elt_key(2, |e| "state".encode(e)));
      try!(e.emit_map_elt_val(2, |e| self.state.encode(e)));
      Ok(())
    })
  }
}

pub struct ListenerConfiguration<'a> {
  id:       String,
  listener: &'a Listener,
}

impl<'a> Encodable for ListenerConfiguration<'a> {
  fn encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
    e.emit_map(2, |e| {
      try!(e.emit_map_elt_key(0, |e| "id".encode(e)));
      try!(e.emit_map_elt_val(0, |e| self.id.encode(e)));
      try!(e.emit_map_elt_key(1, |e| "listener".encode(e)));
      try!(e.emit_map_elt_val(1, |e| self.listener.encode(e)));
      Ok(())
    })
  }
}

#[derive(Debug,Clone,PartialEq,Eq,Hash, RustcDecodable, RustcEncodable)]
pub struct ConfigMessage {
    pub id:       String,
    pub listener: String,
    pub command:  Command
}

struct CommandClient {
  sock:        UnixStream,
  buf:         Buffer,
  back_buf:    Buffer,
  token:       Option<Token>,
  message_ids: Vec<String>,
  write_timeout: Option<Timeout>,
}

impl CommandClient {
  fn new(sock: UnixStream) -> CommandClient {
    CommandClient {
      sock:        sock,
      buf:         Buffer::with_capacity(1024),
      back_buf:    Buffer::with_capacity(10000),
      token:       None,
      message_ids: Vec::new(),
      write_timeout: None,
    }
  }

  fn add_message_id(&mut self, id: String) {
    self.message_ids.push(id);
    self.message_ids.sort();
  }

  fn has_message_id(&self, id: &String) ->Option<usize> {
    self.message_ids.binary_search(&id).ok()
  }

  fn remove_message_id(&mut self, index: usize) {
    self.message_ids.remove(index);
  }

  fn reregister(&self,  event_loop: &mut EventLoop<CommandServer>, tok: Token) {
    let mut interest = EventSet::hup();
    interest.insert(EventSet::readable());
    interest.insert(EventSet::writable());
    event_loop.register(&self.sock, tok, interest, PollOpt::edge() | PollOpt::oneshot());
  }

  fn conn_readable(&mut self, event_loop: &mut EventLoop<CommandServer>, tok: Token) -> Option<Vec<ConfigMessage>>{
    trace!("server conn readable; tok={:?}", tok);
    match self.sock.read(self.buf.space()) {
      Ok(0) => {
        self.reregister(event_loop, tok);
        return None;
      },
      Err(e) => {
        log!(log::LogLevel::Error, "UNIX CLIENT[{}] read error: {:?}", tok.as_usize(), e);
        return None;
      },
      Ok(r) => {
        self.buf.fill(r);
        debug!("UNIX CLIENT[{}] sent {} bytes: {:?}", tok.as_usize(), r, from_utf8(self.buf.data()));
      },
    };

    let mut res: Option<Vec<ConfigMessage>> = None;
    let mut offset = 0usize;
    match parse(self.buf.data()) {
      IResult::Incomplete(_) => {
        return Some(Vec::new());
      },
      IResult::Error(e)      => {
        log!(log::LogLevel::Error, "UNIX CLIENT[{}] read error: {:?}", tok.as_usize(), e);
        return None;
      },
      IResult::Done(i, v)    => {
        offset = self.buf.data().offset(i);
        res = Some(v);
      }
    }
    debug!("parsed {} bytes, result: {:?}", offset, res);
    self.buf.consume(offset);
    return res;
  }

  fn conn_writable(&mut self, event_loop: &mut EventLoop<CommandServer>, tok: Token) {
    if self.write_timeout.is_some() {
      trace!("server conn writable; tok={:?}; waiting for timeout", tok.as_usize());
      return;
    }

    trace!("server conn writable; tok={:?}", tok);
    match self.sock.write(self.back_buf.data()) {
      Ok(0) => {
        //println!("[{}] setting timeout!", tok.as_usize());
        self.write_timeout = event_loop.timeout_ms(self.token.unwrap().as_usize(), 700).ok();
      },
      Ok(r) => {
        self.back_buf.consume(r);
      },
      Err(e) => log!(log::LogLevel::Error,"UNIX CLIENT[{}] read error: {:?}", tok.as_usize(), e),
    }
    let mut interest = EventSet::hup();
    interest.insert(EventSet::readable());
    interest.insert(EventSet::writable());
    event_loop.register(&self.sock, tok, interest, PollOpt::edge() | PollOpt::oneshot());
  }
}

fn parse(input: &[u8]) -> IResult<&[u8], Vec<ConfigMessage>> {
  many0!(input,
    complete!(terminated!(map_res!(map_res!(is_not!("\0"), from_utf8), decode), char!('\0')))
  )
}

struct CommandServer {
  sock:  UnixListener,
  conns: Slab<CommandClient>,
  listeners: HashMap<String, Listener>,
}

impl CommandServer {
  fn accept(&mut self, event_loop: &mut EventLoop<CommandServer>) -> io::Result<()> {
    debug!("server accepting socket");

    let sock = self.sock.accept().unwrap().unwrap();
    let conn = CommandClient::new(sock);
    let tok = self.conns.insert(conn)
      .ok().expect("could not add connection to slab");

    // Register the connection
    self.conns[tok].token = Some(tok);
    let mut interest = EventSet::hup();
    interest.insert(EventSet::readable());
    interest.insert(EventSet::writable());
    event_loop.register(&self.conns[tok].sock, tok, interest, PollOpt::edge())
      .ok().expect("could not register socket with event loop");

    let accept_interest = EventSet::readable();
    event_loop.reregister(&self.sock, SERVER, accept_interest, PollOpt::edge());
    Ok(())
  }

  fn conn<'a>(&'a mut self, tok: Token) -> &'a mut CommandClient {
    &mut self.conns[tok]
  }

  fn dispatch(&mut self, token: Token, v: Vec<ConfigMessage>) {
    for message in &v {
      let command = message.command.clone();
      if let Some(ref mut listener) = self.listeners.get_mut (&message.listener) {
        if message.command == Command::DumpConfiguration {
          let conf = ListenerConfiguration {
            id: message.id.clone(),
            listener: listener,
          };
          self.conns[token].back_buf.write(&encode(&conf).unwrap().into_bytes());
          self.conns[token].back_buf.write(&b"\0"[..]);
        } else {
          self.conns[token].add_message_id(message.id.clone());
          listener.state.handle_command(&command);
          listener.sender.send(ProxyOrder::Command(message.id.clone(), command));
        }
      } else {
        log!(log::LogLevel::Error, "no listener found for tag: {}", message.listener);
      }
    }
  }

  fn new(srv: UnixListener, listeners: HashMap<String, Listener>) -> CommandServer {
    CommandServer {
      sock:  srv,
      conns: Slab::new_starting_at(Token(1), 128),
      listeners: listeners,
    }
  }
}

impl Handler for CommandServer {
	type Timeout = usize;
	type Message = ();

	fn ready(&mut self, event_loop: &mut EventLoop<CommandServer>, token: Token, events: EventSet) {
    //trace!("ready: {:?} -> {:?}", token, events);
    if events.is_readable() {
      match token {
        SERVER => self.accept(event_loop).unwrap(),
        _      => {
          if self.conns.contains(token) {
            let opt_v = self.conns[token].conn_readable(event_loop, token);
            if let Some(v) = opt_v {
              self.dispatch(token, v);
            }
          }
        }
      };
    }

    if events.is_writable() {
      match token {
        SERVER => panic!("received writable for token 0"),
        _      => {
          if self.conns.contains(token) {
            self.conns[token].conn_writable(event_loop, token)
          }
        }
      };
    }

    if events.is_hup() {
      if self.conns.contains(token) {
        event_loop.deregister(&self.conns[token].sock);
        self.conns.remove(token);
        trace!("closed client [{}]", token.as_usize());
      }
    }
  }

  fn notify(&mut self, event_loop: &mut EventLoop<Self>, message: Self::Message) {
    // TODO: dispatch here to clients the list of messages you want to display
    info!("notify");
  }

  fn timeout(&mut self, event_loop: &mut EventLoop<Self>, timeout: Self::Timeout) {
    if timeout == 0 {
      for listener in self.listeners.values() {
        while let Ok(msg) = listener.receiver.try_recv() {
          //println!("got msg: {:?}", msg);
          for client in self.conns.iter_mut() {
            if let Some(index) = client.has_message_id(&msg.id) {
              client.back_buf.write(&encode(&msg).unwrap().into_bytes());
              client.back_buf.write(&b"\0"[..]);
              client.remove_message_id(index);
            }
          }
        }
      }
      event_loop.timeout_ms(0, 700);
    } else {
      let token = Token(timeout);
      if self.conns.contains(token) {
        //println!("[{}] timeout ended, registering for writes", timeout);
        self.conns[token].write_timeout = None;
        let mut interest = EventSet::hup();
        interest.insert(EventSet::readable());
        interest.insert(EventSet::writable());
        event_loop.register(&self.conns[token].sock, token, interest, PollOpt::edge() | PollOpt::oneshot());
      }
    }
  }

}

pub fn start(path: String, listeners: HashMap<String, Listener>) {
  thread::spawn(move || {
    let mut event_loop = EventLoop::new().unwrap();
    let addr = PathBuf::from(path);
    if let Err(e) = fs::remove_file(&addr) {
      match e.kind() {
        ErrorKind::NotFound => {},
        _ => {
          log!(log::LogLevel::Error, "could not delete previous socket at {:?}: {:?}", addr, e);
          return;
        }
      }
    }
    match UnixListener::bind(&addr) {
      Ok(srv) => {
        if let Err(e) =  fs::set_permissions(&addr, fs::Permissions::from_mode(0o600)) {
          log!( log::LogLevel::Error, "could not set the unix socket permissions: {:?}", e);
          fs::remove_file(&addr);
          return;
        }
        info!("listen for connections");
        event_loop.register(&srv, SERVER, EventSet::readable(), PollOpt::edge() | PollOpt::oneshot()).unwrap();
        event_loop.timeout_ms(0, 700);

        event_loop.run(&mut CommandServer::new(srv, listeners)).unwrap()
      },
      Err(e) => {
        log!(log::LogLevel::Error, "could not create unix socket: {:?}", e);
      }
    }
  });
}

#[cfg(test)]
mod tests {
  use super::*;
  use rustc_serialize::json;
  use yxorp::messages::{Command,HttpFront};

  #[test]
  fn config_message_test() {
    let raw_json = r#"{ "id": "ID_TEST", "listener": "HTTP", "command":{"type": "ADD_HTTP_FRONT", "data": {"app_id": "xxx", "hostname": "yyy", "path_begin": "xxx", "port": 4242}} }"#;
    let config: ConfigMessage = json::decode(raw_json).unwrap();
    println!("{:?}", config);
    assert_eq!(config.listener, "HTTP");
    assert_eq!(config.command, Command::AddHttpFront(HttpFront{
      app_id: String::from("xxx"),
      hostname: String::from("yyy"),
      path_begin: String::from("xxx"),
      port: 4242
    }));
  }
}
<|endoftext|>


<commit_before>use super::*;
use byteorder::BigEndian;
use byteorder::ByteOrder;
use native::storage::*;
#[derive(Clone)]

pub struct SimpleStorage {
    uint_value: Scalar,
    string_value: Scalar,
    array_value: Array,
    map_value: Map,
    output: Vec<u8>,
}

impl Contract for SimpleStorage {
    fn exec(&mut self, params: ActionParams, ext: &mut Ext) -> Result<GasLeft, evm::Error> {
        let signature = BigEndian::read_u32(params.clone().data.unwrap().get(0..4).unwrap());
        match signature {
            0 => self.init(params, ext),
            0xaa91543e => self.uint_set(params, ext),
            0x832b4580 => self.uint_get(params, ext),
            0xc9615770 => self.string_set(params, ext),
            0xe3135d14 => self.string_get(params, ext),
            0x118b229c => self.array_set(params, ext),
            0x180a4bbf => self.array_get(params, ext),
            0xaaf27175 => self.map_set(params, ext),
            0xc567dff6 => self.map_get(params, ext),
            _ => Err(evm::Error::OutOfGas),
        }
    }
    fn create(&self) -> Box<Contract> {
        Box::new(SimpleStorage::default())
    }
}

impl Default for SimpleStorage {
    fn default() -> Self {
        SimpleStorage {
            output: Vec::new(),
            uint_value: Scalar::new(H256::from(0)),
            string_value: Scalar::new(H256::from(1)),
            array_value: Array::new(H256::from(2)),
            map_value: Map::new(H256::from(3)),
        }
    }
}

impl SimpleStorage {
    fn init(&mut self, _params: ActionParams, _ext: &mut Ext) -> Result<GasLeft, evm::Error> {
        Ok(GasLeft::Known(U256::from(100)))
    }
    // 1) uint
    fn uint_set(&mut self, params: ActionParams, ext: &mut Ext) -> Result<GasLeft, evm::Error> {
        let value = U256::from(params.data.expect("invalid data").get(4..36).expect("no enough data"));
        self.uint_value.set(ext, value)?;
        Ok(GasLeft::Known(U256::from(100)))
    }
    fn uint_get(&mut self, _params: ActionParams, ext: &mut Ext) -> Result<GasLeft, evm::Error> {
        self.output.resize(32, 0);
        self.uint_value.get(ext)?.to_big_endian(self.output.as_mut_slice());
        Ok(GasLeft::NeedsReturn(U256::from(100), self.output.as_slice()))
    }

    // 2) string
    fn string_set(&mut self, params: ActionParams, ext: &mut Ext) -> Result<GasLeft, evm::Error> {
        let data = params.data.expect("invalid data");
        let index = U256::from(data.get(4..36).expect("no enough data")).low_u64() as usize + 4;
        let length = U256::from(data.get(index..(index + 32)).expect("no enough data")).low_u64() as usize;
        let index = index + 32;
        let value = String::from_utf8(Vec::from(data.get(index..index + length).expect("no enough data"))).unwrap();

        self.string_value.set_bytes(ext, value)?;
        Ok(GasLeft::Known(U256::from(100)))
    }
    fn string_get(&mut self, _params: ActionParams, ext: &mut Ext) -> Result<GasLeft, evm::Error> {
        self.output.resize(0, 0);
        let str = self.string_value.get_bytes::<String>(ext)?;
        for i in U256::from(32).0.iter().rev() {
            serialize_into::<_, _, _, BigEndian>(&mut self.output, &i, Infinite).expect("failed to serialize u64");
        }
        for i in U256::from(str.len()).0.iter().rev() {
            serialize_into::<_, _, _, BigEndian>(&mut self.output, &i, Infinite).expect("failed to serialize u64");
        }

        for i in str.bytes() {
            serialize_into::<_, _, _, BigEndian>(&mut self.output, &i, Infinite).expect("failed to serialize ");
        }
        self.output.write(&vec![0u8; 32 - str.len() % 32]).expect("failed to write [u8]");
        Ok(GasLeft::NeedsReturn(U256::from(100), self.output.as_slice()))
    }

    // 3) array
    fn array_set(&mut self, params: ActionParams, ext: &mut Ext) -> Result<GasLeft, evm::Error> {
        let data = params.data.expect("invalid data");
        let mut pilot = 4;
        let index = U256::from(data.get(pilot..pilot + 32).expect("no enough data")).low_u64();
        pilot += 32;
        let value = U256::from(data.get(pilot..pilot + 32).expect("no enough data"));
        self.array_value.set(ext, index, &value)?;
        Ok(GasLeft::Known(U256::from(100)))
    }
    fn array_get(&mut self, params: ActionParams, ext: &mut Ext) -> Result<GasLeft, evm::Error> {
        let data = params.data.expect("invalid data");
        let index = U256::from(data.get(4..4 + 32).expect("no enough data")).low_u64();
        for i in self.array_value.get(ext, index)?.0.iter().rev() {
            serialize_into::<_, _, _, BigEndian>(&mut self.output, &i, Infinite).expect("failed to serialize u64");
        }
        Ok(GasLeft::NeedsReturn(U256::from(100), self.output.as_slice()))
    }

    // 4) map
    fn map_set(&mut self, params: ActionParams, ext: &mut Ext) -> Result<GasLeft, evm::Error> {
        let data = params.data.expect("invalid data");
        let mut pilot = 4;
        let key = U256::from(data.get(pilot..pilot + 32).expect("no enough data"));
        pilot += 32;
        let value = U256::from(data.get(pilot..pilot + 32).expect("no enough data"));
        self.map_value.set(ext, key, value)?;
        Ok(GasLeft::Known(U256::from(100)))
    }
    fn map_get(&mut self, params: ActionParams, ext: &mut Ext) -> Result<GasLeft, evm::Error> {
        let data = params.data.expect("invalid data");
        let key = U256::from(data.get(4..4 + 32).expect("no enough data"));
        for i in self.map_value.get(ext, key)?.0.iter().rev() {
            serialize_into::<_, _, _, BigEndian>(&mut self.output, &i, Infinite).expect("failed to serialize u64");
        }
        Ok(GasLeft::NeedsReturn(U256::from(100), self.output.as_slice()))
    }
}
//use byteorder::{};
extern crate bincode;
use self::bincode::Infinite;
use self::bincode::internal::deserialize_from;
use self::bincode::internal::serialize_into;
use evm::tests::FakeExt;
use std::io::Write;
use util::{H256, U256, Address};
#[test]
fn test_native_contract() {
    let factory = Factory::default();
    let mut ext = FakeExt::new();
    let native_addr = Address::from_str("0x0000000000000000000000000000000000000400").unwrap();
    let value = U256::from(0x1234);
    {
        let mut params = ActionParams::default();
        let mut input = Vec::new();
        let index = 0xaa91543eu32;
        serialize_into::<_, _, _, BigEndian>(&mut input, &index, Infinite).expect("failed to serialize u32");
        for i in value.0.iter().rev() {
            serialize_into::<_, _, _, BigEndian>(&mut input, &i, Infinite).expect("failed to serialize u64");
        }
        params.data = Some(input);
        let mut contract = factory.new_contract(native_addr).unwrap();
        let output = contract.exec(params, &mut ext).unwrap();
        println!("===={:?}", output);
    }
    {
        let mut params = ActionParams::default();
        let mut input = Vec::new();
        let index = 0x832b4580u32;
        serialize_into::<_, _, _, BigEndian>(&mut input, &index, Infinite).expect("failed to serialize u32");
        params.data = Some(input);

        let mut contract = factory.new_contract(native_addr).unwrap();
        match contract.exec(params, &mut ext) {
            Ok(GasLeft::NeedsReturn(_, mut data)) => {
                let mut real = U256::zero();
                for i in real.0.iter_mut().rev() {
                    //*i = deserialize_from::<&[u8], _, Infinite, BigEndian>(&mut data.get(index..(index + 8)).unwrap(), Infinite).expect("failed to serialize u64");
                    *i = deserialize_from::<&[u8], _, Infinite, BigEndian>(&mut data, Infinite).expect("failed to serialize u64");
                }
                assert!(real == value);
            }
            _ => assert!(false, "no output data"),
        };
    }
}
<commit_msg>fix test fail<commit_after>use super::*;
use byteorder::BigEndian;
use byteorder::ByteOrder;
use native::storage::*;
#[derive(Clone)]

pub struct SimpleStorage {
    uint_value: Scalar,
    string_value: Scalar,
    array_value: Array,
    map_value: Map,
    output: Vec<u8>,
}

impl Contract for SimpleStorage {
    fn exec(&mut self, params: ActionParams, ext: &mut Ext) -> Result<GasLeft, evm::Error> {
        let signature = BigEndian::read_u32(params.clone().data.unwrap().get(0..4).unwrap());
        match signature {
            0 => self.init(params, ext),
            0xaa91543e => self.uint_set(params, ext),
            0x832b4580 => self.uint_get(params, ext),
            0xc9615770 => self.string_set(params, ext),
            0xe3135d14 => self.string_get(params, ext),
            0x118b229c => self.array_set(params, ext),
            0x180a4bbf => self.array_get(params, ext),
            0xaaf27175 => self.map_set(params, ext),
            0xc567dff6 => self.map_get(params, ext),
            _ => Err(evm::Error::OutOfGas),
        }
    }
    fn create(&self) -> Box<Contract> {
        Box::new(SimpleStorage::default())
    }
}

impl Default for SimpleStorage {
    fn default() -> Self {
        SimpleStorage {
            output: Vec::new(),
            uint_value: Scalar::new(H256::from(0)),
            string_value: Scalar::new(H256::from(1)),
            array_value: Array::new(H256::from(2)),
            map_value: Map::new(H256::from(3)),
        }
    }
}

impl SimpleStorage {
    fn init(&mut self, _params: ActionParams, _ext: &mut Ext) -> Result<GasLeft, evm::Error> {
        Ok(GasLeft::Known(U256::from(100)))
    }
    // 1) uint
    fn uint_set(&mut self, params: ActionParams, ext: &mut Ext) -> Result<GasLeft, evm::Error> {
        let value = U256::from(params.data.expect("invalid data").get(4..36).expect("no enough data"));
        self.uint_value.set(ext, value)?;
        Ok(GasLeft::Known(U256::from(100)))
    }
    fn uint_get(&mut self, _params: ActionParams, ext: &mut Ext) -> Result<GasLeft, evm::Error> {
        self.output.resize(32, 0);
        self.uint_value.get(ext)?.to_big_endian(self.output.as_mut_slice());
        Ok(GasLeft::NeedsReturn(U256::from(100), self.output.as_slice()))
    }

    // 2) string
    fn string_set(&mut self, params: ActionParams, ext: &mut Ext) -> Result<GasLeft, evm::Error> {
        let data = params.data.expect("invalid data");
        let index = U256::from(data.get(4..36).expect("no enough data")).low_u64() as usize + 4;
        let length = U256::from(data.get(index..(index + 32)).expect("no enough data")).low_u64() as usize;
        let index = index + 32;
        let value = String::from_utf8(Vec::from(data.get(index..index + length).expect("no enough data"))).unwrap();

        self.string_value.set_bytes(ext, value)?;
        Ok(GasLeft::Known(U256::from(100)))
    }
    fn string_get(&mut self, _params: ActionParams, ext: &mut Ext) -> Result<GasLeft, evm::Error> {
        self.output.resize(0, 0);
        let str = self.string_value.get_bytes::<String>(ext)?;
        for i in U256::from(32).0.iter().rev() {
            serialize_into::<_, _, _, BigEndian>(&mut self.output, &i, Infinite).expect("failed to serialize u64");
        }
        for i in U256::from(str.len()).0.iter().rev() {
            serialize_into::<_, _, _, BigEndian>(&mut self.output, &i, Infinite).expect("failed to serialize u64");
        }

        for i in str.bytes() {
            serialize_into::<_, _, _, BigEndian>(&mut self.output, &i, Infinite).expect("failed to serialize ");
        }
        self.output.write(&vec![0u8; 32 - str.len() % 32]).expect("failed to write [u8]");
        Ok(GasLeft::NeedsReturn(U256::from(100), self.output.as_slice()))
    }

    // 3) array
    fn array_set(&mut self, params: ActionParams, ext: &mut Ext) -> Result<GasLeft, evm::Error> {
        let data = params.data.expect("invalid data");
        let mut pilot = 4;
        let index = U256::from(data.get(pilot..pilot + 32).expect("no enough data")).low_u64();
        pilot += 32;
        let value = U256::from(data.get(pilot..pilot + 32).expect("no enough data"));
        self.array_value.set(ext, index, &value)?;
        Ok(GasLeft::Known(U256::from(100)))
    }
    fn array_get(&mut self, params: ActionParams, ext: &mut Ext) -> Result<GasLeft, evm::Error> {
        let data = params.data.expect("invalid data");
        let index = U256::from(data.get(4..4 + 32).expect("no enough data")).low_u64();
        for i in self.array_value.get(ext, index)?.0.iter().rev() {
            serialize_into::<_, _, _, BigEndian>(&mut self.output, &i, Infinite).expect("failed to serialize u64");
        }
        Ok(GasLeft::NeedsReturn(U256::from(100), self.output.as_slice()))
    }

    // 4) map
    fn map_set(&mut self, params: ActionParams, ext: &mut Ext) -> Result<GasLeft, evm::Error> {
        let data = params.data.expect("invalid data");
        let mut pilot = 4;
        let key = U256::from(data.get(pilot..pilot + 32).expect("no enough data"));
        pilot += 32;
        let value = U256::from(data.get(pilot..pilot + 32).expect("no enough data"));
        self.map_value.set(ext, key, value)?;
        Ok(GasLeft::Known(U256::from(100)))
    }
    fn map_get(&mut self, params: ActionParams, ext: &mut Ext) -> Result<GasLeft, evm::Error> {
        let data = params.data.expect("invalid data");
        let key = U256::from(data.get(4..4 + 32).expect("no enough data"));
        for i in self.map_value.get(ext, key)?.0.iter().rev() {
            serialize_into::<_, _, _, BigEndian>(&mut self.output, &i, Infinite).expect("failed to serialize u64");
        }
        Ok(GasLeft::NeedsReturn(U256::from(100), self.output.as_slice()))
    }
}
//use byteorder::{};
extern crate bincode;
use self::bincode::Infinite;
use self::bincode::internal::deserialize_from;
use self::bincode::internal::serialize_into;
use evm::tests::FakeExt;
use std::io::Write;
use util::{H256, U256, Address};
use std::str::FromStr;
#[test]
fn test_native_contract() {
    let factory = Factory::default();
    let mut ext = FakeExt::new();
    let native_addr = Address::from_str("0x0000000000000000000000000000000000000400").unwrap();
    let value = U256::from(0x1234);
    {
        let mut params = ActionParams::default();
        let mut input = Vec::new();
        let index = 0xaa91543eu32;
        serialize_into::<_, _, _, BigEndian>(&mut input, &index, Infinite).expect("failed to serialize u32");
        for i in value.0.iter().rev() {
            serialize_into::<_, _, _, BigEndian>(&mut input, &i, Infinite).expect("failed to serialize u64");
        }
        params.data = Some(input);
        let mut contract = factory.new_contract(native_addr).unwrap();
        let output = contract.exec(params, &mut ext).unwrap();
        println!("===={:?}", output);
    }
    {
        let mut params = ActionParams::default();
        let mut input = Vec::new();
        let index = 0x832b4580u32;
        serialize_into::<_, _, _, BigEndian>(&mut input, &index, Infinite).expect("failed to serialize u32");
        params.data = Some(input);

        let mut contract = factory.new_contract(native_addr).unwrap();
        match contract.exec(params, &mut ext) {
            Ok(GasLeft::NeedsReturn(_, mut data)) => {
                let mut real = U256::zero();
                for i in real.0.iter_mut().rev() {
                    //*i = deserialize_from::<&[u8], _, Infinite, BigEndian>(&mut data.get(index..(index + 8)).unwrap(), Infinite).expect("failed to serialize u64");
                    *i = deserialize_from::<&[u8], _, Infinite, BigEndian>(&mut data, Infinite).expect("failed to serialize u64");
                }
                assert!(real == value);
            }
            _ => assert!(false, "no output data"),
        };
    }
}
<|endoftext|>


<commit_before>//! Iterative application of a differential dataflow fragment.
//!
//! The `iterate` operator takes as an argument a closure from a differential dataflow collection
//! to a collection of the same type. The output collection is the result of applying this closure
//! an unbounded number of times.
//!
//! The implementation of `iterate` does not directly apply the closure, but rather establishes an
//! iterative timely dataflow subcomputation, in which differences circulate until they dissipate
//! (indicating that the computation has reached fixed point), or until some number of iterations
//! have passed.
//!
//! **Note**: The dataflow assembled by `iterate` does not automatically insert `consolidate` for
//! you. This means that either (i) you should insert one yourself, (ii) you should be certain that
//! all paths from the input to the output of the loop involve consolidation, or (iii) you should
//! be worried that logically cancelable differences may circulate indefinitely.
//!
//! #Details
//!
//! The `iterate` method is written using a `Variable`, which lets you define your own iterative
//! computations when `iterate` itself is not sufficient. This can happen when you have two
//! collections that should evolve simultaneously, or when you would like to rotate your loop and
//! return an intermediate result.
//!
//! Using `Variable` requires more explicit arrangement of your computation, but isn't much more
//! complicated. You must define a new variable from an existing stream (its initial value), and
//! then set it to be a function of this variable (and perhaps other collections and variables).
//!
//! A `Variable` dereferences to a `Collection`, the one corresponding to its value in each iteration,
//! and it can be used in most situations where a collection can be used. The act of setting a
//! `Variable` consumes it and returns the corresponding `Collection`, preventing you from setting
//! it multiple times.

use std::fmt::Debug;
use std::ops::Deref;

use timely::progress::nested::product::Product;

use timely::dataflow::*;
use timely::dataflow::scopes::Child;
use timely::dataflow::operators::*;
use timely::dataflow::operators::feedback::Handle;

use ::{Data, Collection, Diff};
use lattice::Lattice;

/// An extension trait for the `iterate` method.
pub trait Iterate<G: Scope, D: Data, R: Diff> {
    /// Iteratively apply `logic` to the source collection until convergence.
    ///
    /// # Examples
    ///
    /// ```
    /// extern crate timely;
    /// extern crate differential_dataflow;
    ///
    /// use differential_dataflow::input::Input;
    /// use differential_dataflow::operators::Iterate;
    /// use differential_dataflow::operators::Consolidate;
    ///
    /// fn main() {
    ///     ::timely::example(|scope| {
    ///
    ///         scope.new_collection_from(1 .. 10u32).1
    ///              .iterate(|values| {
    ///                  values.map(|x| if x % 2 == 0 { x/2 } else { x })
    ///                        .consolidate()
    ///              });
    ///     });
    /// }
    /// ```
    fn iterate<F>(&self, logic: F) -> Collection<G, D, R>
        where G::Timestamp: Lattice,
              for<'a> F: FnOnce(&Collection<Child<'a, G, u64>, D, R>)->Collection<Child<'a, G, u64>, D, R>;
}

impl<G: Scope, D: Ord+Data+Debug, R: Diff> Iterate<G, D, R> for Collection<G, D, R> {
    fn iterate<F>(&self, logic: F) -> Collection<G, D, R>
        where G::Timestamp: Lattice,
              for<'a> F: FnOnce(&Collection<Child<'a, G, u64>, D, R>)->Collection<Child<'a, G, u64>, D, R> {

        self.inner.scope().scoped(|subgraph| {
            // create a new variable, apply logic, bind variable, return.
            //
            // this could be much more succinct if we returned the collection
            // wrapped by `variable`, but it also results in substantially more
            // diffs produced; `result` is post-consolidation, and means fewer
            // records are yielded out of the loop.
            let variable = Variable::from(self.enter(subgraph));
            let result = logic(&variable);
            variable.set(&result);
            result.leave()
        })
    }
}

/// A differential dataflow collection variable
///
/// The `Variable` struct allows differential dataflow programs requiring more sophisticated
/// iterative patterns than singly recursive iteration. For example: in mutual recursion two
/// collections evolve simultaneously.
///
/// # Examples
///
/// The following example is equivalent to the example for the `Iterate` trait.
///
/// ```
/// extern crate timely;
/// extern crate differential_dataflow;
///
/// use timely::dataflow::Scope;
///
/// use differential_dataflow::input::Input;
/// use differential_dataflow::operators::iterate::Variable;
/// use differential_dataflow::operators::Consolidate;
///
/// fn main() {
///     ::timely::example(|scope| {
///
///         let numbers = scope.new_collection_from(1 .. 10u32).1;
///
///         scope.scoped(|nested| {
///             let variable = Variable::from(numbers.enter(nested));
///             let result = variable.map(|x| if x % 2 == 0 { x/2 } else { x })
///                                  .consolidate();
///             variable.set(&result)
///                     .leave()
///         });
///     })
/// }
/// ```
pub struct Variable<'a, G: Scope, D: Data, R: Diff>
where G::Timestamp: Lattice {
    collection: Collection<Child<'a, G, u64>, D, R>,
    feedback: Handle<G::Timestamp, u64,(D, Product<G::Timestamp, u64>, R)>,
    source: Collection<Child<'a, G, u64>, D, R>,
}

impl<'a, G: Scope, D: Data, R: Diff> Variable<'a, G, D, R> where G::Timestamp: Lattice {
    /// Creates a new `Variable` and a `Stream` representing its output, from a supplied `source` stream.
    pub fn from(source: Collection<Child<'a, G, u64>, D, R>) -> Variable<'a, G, D, R> {
        let (feedback, updates) = source.inner.scope().loop_variable(u64::max_value(), 1);
        let collection = Collection::new(updates).concat(&source);
        Variable { collection: collection, feedback: feedback, source: source }
    }
    /// Adds a new source of data to the `Variable`.
    pub fn set(self, result: &Collection<Child<'a, G, u64>, D, R>) -> Collection<Child<'a, G, u64>, D, R> {
        self.source.negate()
                   .concat(result)
                   .inner
                   .map(|(x,t,d)| (x, Product::new(t.outer, t.inner+1), d))
                   .connect_loop(self.feedback);

        self.collection
    }
}

impl<'a, G: Scope, D: Data, R: Diff> Deref for Variable<'a, G, D, R> where G::Timestamp: Lattice {
    type Target = Collection<Child<'a, G, u64>, D, R>;
    fn deref(&self) -> &Self::Target {
        &self.collection
    }
}
<commit_msg>general variable<commit_after>//! Iterative application of a differential dataflow fragment.
//!
//! The `iterate` operator takes as an argument a closure from a differential dataflow collection
//! to a collection of the same type. The output collection is the result of applying this closure
//! an unbounded number of times.
//!
//! The implementation of `iterate` does not directly apply the closure, but rather establishes an
//! iterative timely dataflow subcomputation, in which differences circulate until they dissipate
//! (indicating that the computation has reached fixed point), or until some number of iterations
//! have passed.
//!
//! **Note**: The dataflow assembled by `iterate` does not automatically insert `consolidate` for
//! you. This means that either (i) you should insert one yourself, (ii) you should be certain that
//! all paths from the input to the output of the loop involve consolidation, or (iii) you should
//! be worried that logically cancelable differences may circulate indefinitely.
//!
//! #Details
//!
//! The `iterate` method is written using a `Variable`, which lets you define your own iterative
//! computations when `iterate` itself is not sufficient. This can happen when you have two
//! collections that should evolve simultaneously, or when you would like to rotate your loop and
//! return an intermediate result.
//!
//! Using `Variable` requires more explicit arrangement of your computation, but isn't much more
//! complicated. You must define a new variable from an existing stream (its initial value), and
//! then set it to be a function of this variable (and perhaps other collections and variables).
//!
//! A `Variable` dereferences to a `Collection`, the one corresponding to its value in each iteration,
//! and it can be used in most situations where a collection can be used. The act of setting a
//! `Variable` consumes it and returns the corresponding `Collection`, preventing you from setting
//! it multiple times.

use std::fmt::Debug;
use std::ops::Deref;

use timely::progress::nested::product::Product;

use timely::dataflow::*;
use timely::dataflow::scopes::Child;
use timely::dataflow::operators::*;
use timely::dataflow::operators::feedback::Handle;

use ::{Data, Collection, Diff};
use lattice::Lattice;

/// An extension trait for the `iterate` method.
pub trait Iterate<G: Scope, D: Data, R: Diff> {
    /// Iteratively apply `logic` to the source collection until convergence.
    ///
    /// # Examples
    ///
    /// ```
    /// extern crate timely;
    /// extern crate differential_dataflow;
    ///
    /// use differential_dataflow::input::Input;
    /// use differential_dataflow::operators::Iterate;
    /// use differential_dataflow::operators::Consolidate;
    ///
    /// fn main() {
    ///     ::timely::example(|scope| {
    ///
    ///         scope.new_collection_from(1 .. 10u32).1
    ///              .iterate(|values| {
    ///                  values.map(|x| if x % 2 == 0 { x/2 } else { x })
    ///                        .consolidate()
    ///              });
    ///     });
    /// }
    /// ```
    fn iterate<F>(&self, logic: F) -> Collection<G, D, R>
        where G::Timestamp: Lattice,
              for<'a> F: FnOnce(&Collection<Child<'a, G, u64>, D, R>)->Collection<Child<'a, G, u64>, D, R>;
}

impl<G: Scope, D: Ord+Data+Debug, R: Diff> Iterate<G, D, R> for Collection<G, D, R> {
    fn iterate<F>(&self, logic: F) -> Collection<G, D, R>
        where G::Timestamp: Lattice,
              for<'a> F: FnOnce(&Collection<Child<'a, G, u64>, D, R>)->Collection<Child<'a, G, u64>, D, R> {

        self.inner.scope().scoped(|subgraph| {
            // create a new variable, apply logic, bind variable, return.
            //
            // this could be much more succinct if we returned the collection
            // wrapped by `variable`, but it also results in substantially more
            // diffs produced; `result` is post-consolidation, and means fewer
            // records are yielded out of the loop.
            let variable = Variable::from(self.enter(subgraph));
            let result = logic(&variable);
            variable.set(&result);
            result.leave()
        })
    }
}

/// A differential dataflow collection variable
///
/// The `Variable` struct allows differential dataflow programs requiring more sophisticated
/// iterative patterns than singly recursive iteration. For example: in mutual recursion two
/// collections evolve simultaneously.
///
/// # Examples
///
/// The following example is equivalent to the example for the `Iterate` trait.
///
/// ```
/// extern crate timely;
/// extern crate differential_dataflow;
///
/// use timely::dataflow::Scope;
///
/// use differential_dataflow::input::Input;
/// use differential_dataflow::operators::iterate::Variable;
/// use differential_dataflow::operators::Consolidate;
///
/// fn main() {
///     ::timely::example(|scope| {
///
///         let numbers = scope.new_collection_from(1 .. 10u32).1;
///
///         scope.scoped(|nested| {
///             let variable = Variable::from(numbers.enter(nested));
///             let result = variable.map(|x| if x % 2 == 0 { x/2 } else { x })
///                                  .consolidate();
///             variable.set(&result)
///                     .leave()
///         });
///     })
/// }
/// ```
pub struct Variable<'a, G: Scope, D: Data, R: Diff>
where G::Timestamp: Lattice {
    collection: Collection<Child<'a, G, u64>, D, R>,
    feedback: Handle<G::Timestamp, u64,(D, Product<G::Timestamp, u64>, R)>,
    source: Collection<Child<'a, G, u64>, D, R>,
}

impl<'a, G: Scope, D: Data, R: Diff> Variable<'a, G, D, R> where G::Timestamp: Lattice {
    /// Creates a new `Variable` and a `Stream` representing its output, from a supplied `source` stream.
    pub fn from_args(max_steps: u64, step: u64, source: Collection<Child<'a, G, u64>, D, R>) -> Variable<'a, G, D, R> {
        let (feedback, updates) = source.inner.scope().loop_variable(max_steps, step);
        let collection = Collection::new(updates).concat(&source);
        Variable { collection: collection, feedback: feedback, source: source }
    }
    /// Creates a new `Variable` and a `Stream` representing its output, from a supplied `source` stream.
    pub fn from(source: Collection<Child<'a, G, u64>, D, R>) -> Variable<'a, G, D, R> {
        Self::from_args(u64::max_value(), 1, source)
    }
    /// Adds a new source of data to the `Variable`.
    pub fn set(self, result: &Collection<Child<'a, G, u64>, D, R>) -> Collection<Child<'a, G, u64>, D, R> {
        self.source.negate()
                   .concat(result)
                   .inner
                   .map(|(x,t,d)| (x, Product::new(t.outer, t.inner+1), d))
                   .connect_loop(self.feedback);

        self.collection
    }
}

impl<'a, G: Scope, D: Data, R: Diff> Deref for Variable<'a, G, D, R> where G::Timestamp: Lattice {
    type Target = Collection<Child<'a, G, u64>, D, R>;
    fn deref(&self) -> &Self::Target {
        &self.collection
    }
}
<|endoftext|>