<commit_before>

use std::io::{self, Read, Write};

use hyper::{Get, Post, StatusCode, RequestUri, Decoder, Encoder, Next};
use hyper::header::ContentLength;
use hyper::net::HttpStream;

use hyper::server::Server;
use hyper::server::Handler as HyperHandler;
use hyper::server::Request as HyperRequest;
use hyper::server::Response as HyperResponse;

use std::result::Result as StdResult;
use std::error::Error as StdError;
use std::sync::Arc;
use std::marker::Reflect;
use std::clone::Clone;
use std::marker::PhantomData;

pub use request::Request;
pub use response::Response;
pub use router::Router;
pub use srouter::SRouter;
pub use shandler::SHandler;

#[derive(Debug, PartialEq)]
pub enum Error {
    BeforeError,
    HandlerError,
    AfterError,
    RouterConfigError,
    RedirectError,
    NotFoundError,
}

pub type Result<T> = ::std::result::Result<T, Error>;

#[derive(Clone)]
pub struct PathParams;

pub trait SModule {
    fn before(&self, &mut Request) -> Result<()>;

    fn after(&self, &Request, &mut Response) -> Result<()>;

    // here add routers ....
    fn router(&self, &mut SRouter) -> Result<()>;
    // fn router(&self, SRouter) -> Result<SRouter>;

}

pub trait SAppWrapper {
    fn before(&self, &mut Request) -> Result<()>;

    fn after(&self, &Request, &mut Response) -> Result<()>;

}

// later will add more fields
pub struct SApp<T: SModule + Send + 'static, W: SAppWrapper + Send + 'static> {
    pub address: String,
    pub port:    u32,
    // for app entry, global middeware
    pub wrapper: Option<W>,
    // for actually use to recognize
    pub routers: Router,
    // marker for type T
    pub _marker: PhantomData<T>,
}

impl<T, W> SApp<T, W>
    where   T: SModule + Send + Sync + Reflect + Clone + 'static,
            W: SAppWrapper + Send + Sync + Reflect + Clone + 'static
    {
    pub fn new() -> SApp<T, W> {
        SApp {
            address: String::new(),
            port: 0,
            wrapper: None,
            routers: Router::new(),
            _marker: PhantomData
        }
    }

    pub fn run(self) {

        let listen_addr = self.address.clone() + ":" + &self.port.to_string();
        let arc_sapp = Arc::new(Box::new(self));

        let server = Server::http(&listen_addr.parse().unwrap()).unwrap();
        let _guard = server.handle(move |_| {
            RequestHandler::new(arc_sapp.clone())
        });
    }

    pub fn with_wrapper(&mut self, w: W) -> &mut Self {
        self.wrapper = Some(w);
        self
    }

    pub fn address(&mut self, address: &str) -> &mut Self {
        self.address = address.to_owned();
        self
    }

    pub fn port(&mut self, port: u32) -> &mut Self {
        self.port = port;
        self
    }

    // add methods of this smodule
    // prefix:  such as '/user'
    pub fn add_module(&mut self, sm: T) -> &mut Self {

        let mut router = SRouter::new();
        // get the sm router
        // pass self.router in
        sm.router(&mut router).unwrap();
        // combile this router to global big router
        // create a new closure, containing
        //      0. execute sapp.before();
        //      1. execute sm.before();
        //      2. execute a_router map pair value part function;
        //      3. execute sm.after();
        //      4. execute sapp.after();
        // fill the self.routers finally
        // assign this new closure to the routers router map pair  prefix + url part

        // println!("router length: {}", router.into_router().len());
        // let wrapper = self.wrapper.clone();

        for (method, handler_vec) in router.into_router() {
            // add to wrapped router
            for &(glob, ref handler) in handler_vec.iter() {
                let method = method.clone();
                let glob = glob.clone();
                let handler = handler.clone();
                let sm = sm.clone();
                let wrapper = self.wrapper.clone().unwrap();
                self.routers.route(method, glob, Arc::new(Box::new(move |req: &mut Request| -> Result<Response> {
                    wrapper.before(req).unwrap();
                    sm.before(req).unwrap();
                    let res: Result<Response> = handler.handle(req);
                    let mut response = res.unwrap();
                    sm.after(req, &mut response).unwrap();
                    wrapper.after(req, &mut response).unwrap();
                    Ok(response)
                })));
            }
        }

        // self.modules.push(sm);

        self
    }
}

pub struct RequestHandler<
        T: SModule + Send + Sync + Reflect + Clone + 'static,
        W: SAppWrapper + Send + Sync + Reflect + Clone + 'static> {
    // router, keep the original handler function
    // pub router: SRouter,
    // wrapped router, keep the wrapped handler function
    // for actually use to recognize
    pub sapp: Arc<Box<SApp<T, W>>>,
    // response deliver
    pub response: Option<Response>,
}

impl<T, W> RequestHandler<T, W>
where   T: SModule + Send + Sync + Reflect + Clone + 'static,
        W: SAppWrapper + Send + Sync + Reflect + Clone + 'static
{
    pub fn new(sapp: Arc<Box<SApp<T, W>>>) -> RequestHandler<T, W> {
        RequestHandler {
            sapp: sapp,
            response: None
        }
    }

}

impl<T, W> HyperHandler<HttpStream> for RequestHandler<T, W>
where   T: SModule + Send + Sync + Reflect + Clone + 'static,
        W: SAppWrapper + Send + Sync + Reflect + Clone + 'static
 {
    fn on_request(&mut self, req: HyperRequest) -> Next {
        match *req.uri() {
            RequestUri::AbsolutePath(ref path) =>  {

                let path = &path[..];
                // make swiftrs request from hyper request
                let mut sreq = Request::new(
                    req.method().clone(),
                    req.version().clone(),
                    req.headers().clone(),
                    path);

                // XXX: Need more work
                // self.response = self.routers.handle_method(&mut sreq, &path).unwrap().ok();
                match self.sapp.routers.handle_method(&mut sreq, &path).unwrap() {
                    Ok(response) => self.response = Some(response),
                    Err(e) => {
                        if e == Error::NotFoundError {
                            self.response = None
                        }
                    }

                }
                // TODO: complete it later
                // .unwrap_or_else(||
                    // match req.method {
                    //     method::Options => Ok(self.handle_options(&path)),
                    //     // For HEAD, fall back to GET. Hyper ensures no response body is written.
                    //     method::Head => {
                    //         req.method = method::Get;
                    //         self.handle_method(req, &path).unwrap_or(
                    //             Err(IronError::new(NoRoute, status::NotFound))
                    //         )
                    //     }
                    //     _ => Err(IronError::new(NoRoute, status::NotFound))
                    // }
                // );

                Next::write()
            },
            _ => Next::write()
        }
    }
    fn on_request_readable(&mut self, transport: &mut Decoder<HttpStream>) -> Next {

        Next::write()
    }

    fn on_response(&mut self, res: &mut HyperResponse) -> Next {
        match self.response {
            Some(ref response) => {
                if let &Some(ref body) = response.body() {
                    // here, set hyper response status code, and headers
                    res.headers_mut().set(ContentLength(body.len() as u64));
                }
                Next::write()
            },
            None => {
                // Inner Error
                // end
                res.set_status(StatusCode::NotFound);
                res.headers_mut().set(ContentLength("404 Not Found".len() as u64));
                Next::write()
            }
        }

    }

    fn on_response_writable(&mut self, transport: &mut Encoder<HttpStream>) -> Next {
        match self.response {
            Some(ref response) => {
                if let &Some(ref body) = response.body() {
                    // write response.body.unwrap() to transport
                    transport.write(body.as_bytes()).unwrap();
                }
                Next::end()
            },
            None => {
                transport.write("404 Not Found".as_bytes()).unwrap();
                // end
                Next::end()
            }
        }

    }
}
<commit_msg>record.<commit_after>

use std::io::{self, Read, Write};

use hyper::{Get, Post, StatusCode, RequestUri, Decoder, Encoder, Next};
use hyper::header::ContentLength;
use hyper::net::HttpStream;

use hyper::server::Server;
use hyper::server::Handler as HyperHandler;
use hyper::server::Request as HyperRequest;
use hyper::server::Response as HyperResponse;

use std::result::Result as StdResult;
use std::error::Error as StdError;
use std::sync::Arc;
use std::marker::Reflect;
use std::clone::Clone;
use std::marker::PhantomData;

pub use request::Request;
pub use response::Response;
pub use router::Router;
pub use srouter::SRouter;
pub use shandler::SHandler;

#[derive(Debug, PartialEq)]
pub enum Error {
    BeforeError,
    HandlerError,
    AfterError,
    RouterConfigError,
    RedirectError,
    NotFoundError,
}

pub type Result<T> = ::std::result::Result<T, Error>;

#[derive(Clone)]
pub struct PathParams;

pub trait SModule {
    fn before(&self, &mut Request) -> Result<()>;

    fn after(&self, &Request, &mut Response) -> Result<()>;

    // here add routers ....
    fn router(&self, &mut SRouter) -> Result<()>;
    // fn router(&self, SRouter) -> Result<SRouter>;

}

pub trait SAppWrapper {
    fn before(&self, &mut Request) -> Result<()>;

    fn after(&self, &Request, &mut Response) -> Result<()>;

}

// later will add more fields
pub struct SApp<T: SModule + Send + 'static, W: SAppWrapper + Send + 'static> {
    pub address: String,
    pub port:    u32,
    // for app entry, global middeware
    pub wrapper: Option<W>,
    // for actually use to recognize
    pub routers: Router,
    // marker for type T
    pub _marker: PhantomData<T>,
}

impl<T, W> SApp<T, W>
    where   T: SModule + Send + Sync + Reflect + Clone + 'static,
            W: SAppWrapper + Send + Sync + Reflect + Clone + 'static
    {
    pub fn new() -> SApp<T, W> {
        SApp {
            address: String::new(),
            port: 0,
            wrapper: None,
            routers: Router::new(),
            _marker: PhantomData
        }
    }

    pub fn run(self) {

        let listen_addr = self.address.clone() + ":" + &self.port.to_string();
        let arc_sapp = Arc::new(Box::new(self));

        let server = Server::http(&listen_addr.parse().unwrap()).unwrap();
        let _guard = server.handle(move |_| {
            RequestHandler::new(arc_sapp.clone())
        });
    }

    pub fn with_wrapper(&mut self, w: W) -> &mut Self {
        self.wrapper = Some(w);
        self
    }

    pub fn address(&mut self, address: &str) -> &mut Self {
        self.address = address.to_owned();
        self
    }

    pub fn port(&mut self, port: u32) -> &mut Self {
        self.port = port;
        self
    }

    // add methods of this smodule
    // prefix:  such as '/user'
    pub fn add_module(&mut self, sm: T) -> &mut Self {

        let mut router = SRouter::new();
        // get the sm router
        // pass self.router in
        sm.router(&mut router).unwrap();
        // combile this router to global big router
        // create a new closure, containing
        //      0. execute sapp.before();
        //      1. execute sm.before();
        //      2. execute a_router map pair value part function;
        //      3. execute sm.after();
        //      4. execute sapp.after();
        // fill the self.routers finally
        // assign this new closure to the routers router map pair  prefix + url part

        // println!("router length: {}", router.into_router().len());
        // let wrapper = self.wrapper.clone();

        for (method, handler_vec) in router.into_router() {
            // add to wrapped router
            for &(glob, ref handler) in handler_vec.iter() {
                let method = method.clone();
                let glob = glob.clone();
                let handler = handler.clone();
                let sm = sm.clone();
                let wrapper = self.wrapper.clone().unwrap();
                self.routers.route(method, glob, Arc::new(Box::new(move |req: &mut Request| -> Result<Response> {
                    wrapper.before(req).unwrap();
                    sm.before(req).unwrap();
                    let res: Result<Response> = handler.handle(req);
                    let mut response = res.unwrap();
                    sm.after(req, &mut response).unwrap();
                    wrapper.after(req, &mut response).unwrap();
                    Ok(response)
                })));
            }
        }

        // self.modules.push(sm);

        self
    }
}

pub struct RequestHandler<
        T: SModule + Send + Sync + Reflect + Clone + 'static,
        W: SAppWrapper + Send + Sync + Reflect + Clone + 'static> {
    // router, keep the original handler function
    // pub router: SRouter,
    // wrapped router, keep the wrapped handler function
    // for actually use to recognize
    pub sapp: Arc<Box<SApp<T, W>>>,
    pub buf: Vec<u8>,
    pub body: String,
    pub body_length: Option<u64>,
    // response deliver
    pub response: Option<Response>,
}

impl<T, W> RequestHandler<T, W>
where   T: SModule + Send + Sync + Reflect + Clone + 'static,
        W: SAppWrapper + Send + Sync + Reflect + Clone + 'static
{
    pub fn new(sapp: Arc<Box<SApp<T, W>>>) -> RequestHandler<T, W> {
        RequestHandler {
            sapp: sapp,
            buf: vec![0; 2048],
            body: String::new(),
            body_length: None,
            response: None
        }
    }

}

impl<T, W> HyperHandler<HttpStream> for RequestHandler<T, W>
where   T: SModule + Send + Sync + Reflect + Clone + 'static,
        W: SAppWrapper + Send + Sync + Reflect + Clone + 'static
 {
    fn on_request(&mut self, req: HyperRequest) -> Next {
        match *req.uri() {
            RequestUri::AbsolutePath(ref path) =>  {

                let path = &path[..];
                // make swiftrs request from hyper request
                let mut sreq = Request::new(
                    req.method().clone(),
                    req.version().clone(),
                    req.headers().clone(),
                    path);

                if let Some(len) = req.headers().get::<ContentLength>() {
                    self.body_length = Some(**len);
                    Next::read_and_write()
                }
                else {
                    Next::write()
                }

                // XXX: Need more work
                // self.response = self.routers.handle_method(&mut sreq, &path).unwrap().ok();
                match self.sapp.routers.handle_method(&mut sreq, &path).unwrap() {
                    Ok(response) => self.response = Some(response),
                    Err(e) => {
                        if e == Error::NotFoundError {
                            self.response = None
                        }
                    }

                }
                // TODO: complete it later
                // .unwrap_or_else(||
                    // match req.method {
                    //     method::Options => Ok(self.handle_options(&path)),
                    //     // For HEAD, fall back to GET. Hyper ensures no response body is written.
                    //     method::Head => {
                    //         req.method = method::Get;
                    //         self.handle_method(req, &path).unwrap_or(
                    //             Err(IronError::new(NoRoute, status::NotFound))
                    //         )
                    //     }
                    //     _ => Err(IronError::new(NoRoute, status::NotFound))
                    // }
                // );
                // currently

                // if is_more {
                //     Next::read_and_write()
                // } else {
                //     Next::write()
                // }

                // Next::read_and_write()
                // Next::write()
            },
            _ => Next::write()
        }
    }
    fn on_request_readable(&mut self, transport: &mut Decoder<HttpStream>) -> Next {
        match self.body_length {
            Some(len) => {
                match transport.read(&mut self.buf) {
                    Ok(0) => {
                        debug!("Read 0, eof");

                        Next::write()
                    },
                    Ok(n) => {
                        self.read_pos += n;
                        self.body.push_str(str::from_utf8(self.buf));
                        Next::read_and_write()
                    }
                    Err(e) => match e.kind() {
                        io::ErrorKind::WouldBlock => Next::read_and_write(),
                        _ => {
                            println!("read error {:?}", e);
                            Next::end()
                        }
                    }
                }

            },
            None => {
                Next::write()
            }

        }

        Next::write()
    }

    fn on_response(&mut self, res: &mut HyperResponse) -> Next {
        match self.response {
            Some(ref response) => {
                if let &Some(ref body) = response.body() {
                    // here, set hyper response status code, and headers
                    res.headers_mut().set(ContentLength(body.len() as u64));
                }
                Next::write()
            },
            None => {
                // Inner Error
                // end
                res.set_status(StatusCode::NotFound);
                res.headers_mut().set(ContentLength("404 Not Found".len() as u64));
                Next::write()
            }
        }

    }

    fn on_response_writable(&mut self, transport: &mut Encoder<HttpStream>) -> Next {
        match self.response {
            Some(ref response) => {
                if let &Some(ref body) = response.body() {
                    // write response.body.unwrap() to transport
                    transport.write(body.as_bytes()).unwrap();
                }
                Next::end()
            },
            None => {
                transport.write("404 Not Found".as_bytes()).unwrap();
                // end
                Next::end()
            }
        }

    }
}
<|endoftext|>


<commit_before>// (c) 2016 Productize SPRL <joost@productize.be>

use std::fmt;
use std::result;
use std::str::FromStr;

use str_error;
use Result;

// like Into trait but works from a ref avoiding consumption or expensive clone
pub trait IntoSexp {
    fn into_sexp(&self) -> Sexp;
}

#[derive(Debug, Clone)]
pub enum Sexp {
    String(String),
    List(Vec<Sexp>),
    Empty,
}

/*

Following the KiCad file formats specification chapter 4.4 - Identifiers and Strings:
A string may not contain an actual newline or carriage return, but it may use an escape sequence to encode a
newline, such as \n.
If a string has any of the following conditions, then it must be quoted with a leading and trailing double quote
character, otherwise it is acceptable to not quote the string:
1. has one or more of the following 4 separator bytes: ASCII space, tab, '(', or ')'.
2. has one or more of the following bytes: '%', '{', or '}'.
3. has a length of zero bytes, and you need a place holder for the field, then use "".
4. includes a byte of '-', and this byte is not in the first position of the string.
*/

pub fn encode_string(s:&str) -> String {
    fn rule_4(s:&str) -> bool {
        s.contains('-') && s.len() > 1 && s.as_bytes()[0] != 45
    }
    if s.contains('(') || s.contains(' ') || s.contains(')') || s.contains('\t') || s.contains('{') || s.contains('}') || s.contains('}') || s.contains('%') || s.is_empty() || rule_4(s) {
        format!("\"{}\"", s)
    } else {
        String::from(s)
    }
}

impl Sexp {

    pub fn new_empty() -> Sexp {
        Sexp::Empty
    }

    pub fn new_string<T>(s:T) -> Sexp where T:fmt::Display {
        Sexp::String(format!("{}", s))
    }

    pub fn new_list(v:Vec<Sexp>) -> Sexp {
        Sexp::List(v)
    }

    pub fn new_named(name:&str, value:&str) -> Sexp {
        let v = vec![Sexp::new_string(name), Sexp::new_string(value)];
        Sexp::List(v)
    }

    pub fn from<T:IntoSexp>(t:&T) -> Sexp {
        t.into_sexp()
    }

    pub fn list(&self) -> Result<&Vec<Sexp> > {
        match *self {
            Sexp::List(ref v) => Ok(v),
            _ => str_error(format!("not a list: {}", self))
        }
    }

    pub fn string(&self) -> Result<&String> {
        match *self {
            Sexp::String(ref s) => Ok(s),
            _ => str_error(format!("not a string: {}", self))
        }
    }

    pub fn f(&self) -> Result<f64> {
        let s = try!(self.string());
        match f64::from_str(s) {
            Ok(f) => Ok(f),
            _ => str_error("Error parsing float".to_string())
        }
    }

    pub fn i(&self) -> Result<i64> {
        let s = try!(self.string());
        match i64::from_str(s) {
            Ok(f) => Ok(f),
            _ => str_error("Error parsing int".to_string())
        }
    }

    pub fn list_name(&self) -> Result<&String> {
        let l = try!(self.list());
        let l = &l[..];
        let a = try!(l[0].string());
        Ok(a)
    }

    pub fn slice_atom(&self, s:&str) -> Result<&[Sexp]> {
        let v = try!(self.list());
        let v2 =&v[..];
        let st = try!(v2[0].string());
        if st != s {
            return str_error(format!("list {} doesn't start with {}, but with {}", self, s, st))
        };
        Ok(&v[1..])
    }

    pub fn named_value(&self, s:&str) -> Result<&Sexp> {
        let v = try!(self.list());
        if v.len() != 2 {
            return str_error(format!("list {} is not a named_value", s))
        }
        let l = try!(self.slice_atom(s));
        Ok(&l[0])
    }

    pub fn named_value_i(&self, s:&str) -> Result<i64> {
        try!(self.named_value(s)).i()
    }

    pub fn named_value_f(&self, s:&str) -> Result<f64> {
        try!(self.named_value(s)).f()
    }

    pub fn named_value_string(&self, s:&str) -> Result<&String> {
        try!(self.named_value(s)).string()
    }

    pub fn slice_atom_num(&self, s:&str, num:usize) -> Result<&[Sexp]> {
        let v = try!(self.list());
        let v2 =&v[..];
        let st = try!(v2[0].string());
        if st != s {
            return str_error(format!("list doesn't start with {}, but with {}", s, st))
        };
        if v.len() != (num+1) {
            return str_error(format!("list ({}) doesn't have {} elements but {}", s, num, v.len()-1))
        }
        Ok(&v[1..])
    }
}

impl fmt::Display for Sexp {
    fn fmt(&self, f: &mut fmt::Formatter) -> result::Result<(), fmt::Error> {
        match *self {
            Sexp::String(ref s) => {
                write!(f, "{}", encode_string(s))
            },
            Sexp::List(ref v) => {
                try!(write!(f, "("));
                let l = v.len();
                for (i,x) in v.iter().enumerate() {
                    if i < l-1 {
                        try!(write!(f, "{} ", x));
                    } else {
                        try!(write!(f, "{}", x));
                    }
                }
                write!(f, ")")
            },
            Sexp::Empty => Ok(())
        }
    }
}
<commit_msg>generalize new_named<commit_after>// (c) 2016 Productize SPRL <joost@productize.be>

use std::fmt;
use std::result;
use std::str::FromStr;

use str_error;
use Result;

// like Into trait but works from a ref avoiding consumption or expensive clone
pub trait IntoSexp {
    fn into_sexp(&self) -> Sexp;
}

#[derive(Debug, Clone)]
pub enum Sexp {
    String(String),
    List(Vec<Sexp>),
    Empty,
}

/*

Following the KiCad file formats specification chapter 4.4 - Identifiers and Strings:
A string may not contain an actual newline or carriage return, but it may use an escape sequence to encode a
newline, such as \n.
If a string has any of the following conditions, then it must be quoted with a leading and trailing double quote
character, otherwise it is acceptable to not quote the string:
1. has one or more of the following 4 separator bytes: ASCII space, tab, '(', or ')'.
2. has one or more of the following bytes: '%', '{', or '}'.
3. has a length of zero bytes, and you need a place holder for the field, then use "".
4. includes a byte of '-', and this byte is not in the first position of the string.
*/

pub fn encode_string(s:&str) -> String {
    fn rule_4(s:&str) -> bool {
        s.contains('-') && s.len() > 1 && s.as_bytes()[0] != 45
    }
    if s.contains('(') || s.contains(' ') || s.contains(')') || s.contains('\t') || s.contains('{') || s.contains('}') || s.contains('}') || s.contains('%') || s.is_empty() || rule_4(s) {
        format!("\"{}\"", s)
    } else {
        String::from(s)
    }
}

impl Sexp {

    pub fn new_empty() -> Sexp {
        Sexp::Empty
    }

    pub fn new_string<T>(s:T) -> Sexp where T:fmt::Display {
        Sexp::String(format!("{}", s))
    }

    pub fn new_list(v:Vec<Sexp>) -> Sexp {
        Sexp::List(v)
    }

    pub fn new_named<T>(name:&str, value:T) -> Sexp where T:fmt::Display {
        let v = vec![Sexp::new_string(name), Sexp::new_string(value)];
        Sexp::List(v)
    }

    pub fn from<T:IntoSexp>(t:&T) -> Sexp {
        t.into_sexp()
    }

    pub fn list(&self) -> Result<&Vec<Sexp> > {
        match *self {
            Sexp::List(ref v) => Ok(v),
            _ => str_error(format!("not a list: {}", self))
        }
    }

    pub fn string(&self) -> Result<&String> {
        match *self {
            Sexp::String(ref s) => Ok(s),
            _ => str_error(format!("not a string: {}", self))
        }
    }

    pub fn f(&self) -> Result<f64> {
        let s = try!(self.string());
        match f64::from_str(s) {
            Ok(f) => Ok(f),
            _ => str_error("Error parsing float".to_string())
        }
    }

    pub fn i(&self) -> Result<i64> {
        let s = try!(self.string());
        match i64::from_str(s) {
            Ok(f) => Ok(f),
            _ => str_error("Error parsing int".to_string())
        }
    }

    pub fn list_name(&self) -> Result<&String> {
        let l = try!(self.list());
        let l = &l[..];
        let a = try!(l[0].string());
        Ok(a)
    }

    pub fn slice_atom(&self, s:&str) -> Result<&[Sexp]> {
        let v = try!(self.list());
        let v2 =&v[..];
        let st = try!(v2[0].string());
        if st != s {
            return str_error(format!("list {} doesn't start with {}, but with {}", self, s, st))
        };
        Ok(&v[1..])
    }

    pub fn named_value(&self, s:&str) -> Result<&Sexp> {
        let v = try!(self.list());
        if v.len() != 2 {
            return str_error(format!("list {} is not a named_value", s))
        }
        let l = try!(self.slice_atom(s));
        Ok(&l[0])
    }

    pub fn named_value_i(&self, s:&str) -> Result<i64> {
        try!(self.named_value(s)).i()
    }

    pub fn named_value_f(&self, s:&str) -> Result<f64> {
        try!(self.named_value(s)).f()
    }

    pub fn named_value_string(&self, s:&str) -> Result<&String> {
        try!(self.named_value(s)).string()
    }

    pub fn slice_atom_num(&self, s:&str, num:usize) -> Result<&[Sexp]> {
        let v = try!(self.list());
        let v2 =&v[..];
        let st = try!(v2[0].string());
        if st != s {
            return str_error(format!("list doesn't start with {}, but with {}", s, st))
        };
        if v.len() != (num+1) {
            return str_error(format!("list ({}) doesn't have {} elements but {}", s, num, v.len()-1))
        }
        Ok(&v[1..])
    }
}

impl fmt::Display for Sexp {
    fn fmt(&self, f: &mut fmt::Formatter) -> result::Result<(), fmt::Error> {
        match *self {
            Sexp::String(ref s) => {
                write!(f, "{}", encode_string(s))
            },
            Sexp::List(ref v) => {
                try!(write!(f, "("));
                let l = v.len();
                for (i,x) in v.iter().enumerate() {
                    if i < l-1 {
                        try!(write!(f, "{} ", x));
                    } else {
                        try!(write!(f, "{}", x));
                    }
                }
                write!(f, ")")
            },
            Sexp::Empty => Ok(())
        }
    }
}
<|endoftext|>


<commit_before>//! Contains the `Snes` struct, which wields the combined power of this project.

use apu::Apu;
use cpu::Cpu;
use dma::{do_dma, DmaChannel};
use frontend::{self, Renderer};
use input::Input;
use log_util::LogOnPanic;
use ppu::Ppu;
use rom::Rom;

const WRAM_SIZE: usize = 128 * 1024;
byte_array!(Wram[WRAM_SIZE]);

/// Contains everything connected to the CPU via one of the two address buses. All memory accesses
/// will be directed through this (the CPU already takes access time into account).
pub struct Peripherals {
    apu: Apu,
    ppu: Ppu,
    rom: Rom,
    /// The 128 KB of working RAM of the SNES (separate from cartridge RAM)
    wram: Wram,
    input: Input,

    pub dma: [DmaChannel; 8],
    /// `$420c` - HDMAEN: HDMA enable flags
    /// (Note that general DMA doesn't have a register here, since all transactions are started
    /// immediately and the register can't be read)
    hdmaen: u8,
    /// `$4200` - NMITIMEN: Interrupt enable flags
    /// `n-xy---a`
    /// * `n`: Enable NMI on V-Blank
    /// * `x`: Enable IRQ on H-Counter match
    /// * `y`: Enable IRQ on V-Counter match
    /// * `a`: Enable auto-joypad read
    nmien: u8,
    /// `$4210` NMI flag and 5A22 Version
    /// `n---vvvv`
    /// * `n`: `self.nmi`
    /// * `v`: Version
    nmi: bool,

    /// Additional cycles spent doing IO (in master clock cycles). This is reset before each CPU
    /// instruction and added to the cycle count returned by the CPU.
    cy: u32,
}

impl Peripherals {
    pub fn new(rom: Rom) -> Peripherals {
        Peripherals {
            rom: rom,
            apu: Apu::new(),
            ppu: Ppu::new(),
            wram: Wram::default(),
            input: Input::default(),
            dma: [DmaChannel::new(); 8],
            hdmaen: 0x00,
            nmien: 0x00,
            nmi: false,
            cy: 0,
        }
    }

    pub fn load(&mut self, bank: u8, addr: u16) -> u8 {
        match bank {
            0x00 ... 0x3f | 0x80 ... 0xbf => match addr {
                // Mirror of first 8k of WRAM
                0x0000 ... 0x1fff => self.wram[addr as usize],
                // PPU
                0x2100 ... 0x2133 => panic!("read from write-only PPU register ${:04X}", addr),
                0x2138 ... 0x213f => self.ppu.load(addr),
                // APU IO registers
                0x2140 ... 0x217f => self.apu.read_port((addr & 0b11) as u8),
                0x4210 => {
                    const CPU_VERSION: u8 = 2;  // FIXME Is 2 okay in all cases? Does anyone care?
                    let nmi = if self.nmi {1} else {0} << 7;
                    nmi | CPU_VERSION
                }
                0x4218 ... 0x421f => self.input.load(addr),
                // DMA channels (0x43xr, where x is the channel and r is the channel register)
                0x4300 ... 0x43ff => self.dma[(addr as usize & 0x00f0) >> 4].load(addr as u8 & 0xf),
                0x8000 ... 0xffff => self.rom.loadb(bank, addr),
                _ => panic!("invalid/unimplemented load from ${:02X}:{:04X}", bank, addr)
            },
            // WRAM banks. The first 8k are mapped into the start of all banks.
            0x7e | 0x7f => self.wram[(bank as usize - 0x7e) * 65536 + addr as usize],
            0x40 ... 0x7d | 0xc0 ... 0xff => self.rom.loadb(bank, addr),
            _ => unreachable!(),    // Rust should know this!
        }
    }

    pub fn store(&mut self, bank: u8, addr: u16, value: u8) {
        match bank {
            0x00 ... 0x3f | 0x80 ... 0xbf => match addr {
                0x0000 ... 0x1fff => self.wram[addr as usize] = value,
                // PPU registers. Let it deal with the access.
                0x2100 ... 0x2133 => self.ppu.store(addr, value),
                0x2138 ... 0x213f => panic!("store to read-only PPU register ${:04X}", addr),
                // APU IO registers.
                0x2140 ... 0x217f => self.apu.store_port((addr & 0b11) as u8, value),
                0x2180 ... 0x2183 => panic!("NYI: WRAM registers"),
                0x4200 => {
                    // NMITIMEN - NMI/IRQ enable
                    // E-HV---J
                    // E: Enable NMI
                    // H: Enable IRQ on H-Counter
                    // V: Enable IRQ on V-Counter
                    // J: Enable Auto-Joypad-Read
                    if value & 0x20 != 0 { panic!("NYI: IRQ-H") }
                    if value & 0x10 != 0 { panic!("NYI: IRQ-V") }
                    // Check useless bits
                    if value & 0x4e != 0 { panic!("Invalid value for NMIEN: ${:02X}", value) }
                    self.nmien = value;
                }
                // MDMAEN - Party enable
                0x420b => self.cy += do_dma(self, value),
                0x420c => {
                    // HDMAEN - HDMA enable
                    if value != 0 { panic!("NYI: HDMA") }
                    self.hdmaen = value;
                }
                // DMA channels (0x43xr, where x is the channel and r is the channel register)
                0x4300 ... 0x43ff => {
                    self.dma[(addr as usize & 0x00f0) >> 4].store(addr as u8 & 0xf, value);
                }
                0x8000 ... 0xffff => self.rom.storeb(bank, addr, value),
                _ => panic!("invalid store: ${:02X} to ${:02X}:{:04X}", value, bank, addr)
            },
            // WRAM main banks
            0x7e | 0x7f => self.wram[(bank as usize - 0x7e) * 65536 + addr as usize] = value,
            0x40 ... 0x7d | 0xc0 ... 0xff => self.rom.storeb(bank, addr, value),
            _ => unreachable!(),    // Rust should know this!
        }
    }

    fn nmi_enabled(&self) -> bool { self.nmien & 0x80 != 0 }
}

pub struct Snes {
    cpu: Cpu,
    renderer: Box<Renderer>,
}

impl Snes {
    pub fn new(rom: Rom) -> Snes {
        Snes {
            cpu: Cpu::new(Peripherals::new(rom)),
            renderer: Box::new(frontend::SdlRenderer::new(&::sdl2::init().unwrap())),
        }
    }

    pub fn run(&mut self) {
        /// Exit after this number of master clock cycles
        const CY_LIMIT: u64 = 100_000_000;
        /// Start tracing at this master cycle (0 to trace everything)
        const TRACE_START: u64 = CY_LIMIT * 2;

        const MASTER_CLOCK_FREQ: i32 = 21_477_000;
        /// APU clock speed. On real hardware, this can vary quite a bit (I think it uses a ceramic
        /// resonator instead of a quartz).
        const APU_CLOCK_FREQ: i32 = 1_024_000;
        /// Approximated APU clock divider. It's actually somewhere around 20.9..., which is why we
        /// can't directly use `MASTER_CLOCK_FREQ / APU_CLOCK_FREQ` (it would round down, which
        /// might not be critical, but better safe than sorry).
        const APU_DIVIDER: i32 = 21;

        // Master cycle counter, used only for debugging atm
        let mut master_cy: u64 = 0;
        let mut total_apu_cy: u64 = 0;
        let mut total_ppu_cy: u64 = 0;
        // Master clock cycles for the APU not yet accounted for (can be negative)
        let mut apu_master_cy_debt = 0;
        let mut ppu_master_cy_debt = 0;
        let working_cy = LogOnPanic::new(0);

        while master_cy < CY_LIMIT {
            if master_cy >= TRACE_START {
                self.cpu.trace = true;
                self.cpu.mem.apu.trace = true;
            }

            // Run a CPU instruction and calculate the master cycles elapsed
            self.cpu.mem.cy = 0;
            let cpu_master_cy = self.cpu.dispatch() as i32 + self.cpu.mem.cy as i32;
            master_cy += cpu_master_cy as u64;

            // Now we "owe" the other components a few cycles:
            apu_master_cy_debt += cpu_master_cy;
            ppu_master_cy_debt += cpu_master_cy;

            // Run all components until we no longer owe them:
            while apu_master_cy_debt > APU_DIVIDER {
                // (Since the APU uses lots of cycles to do stuff - lower clock rate and such - we
                // only run it if we owe it `APU_DIVIDER` master cycles - or one SPC700 cycle)
                let apu_master_cy = self.cpu.mem.apu.dispatch() as i32 * APU_DIVIDER;
                apu_master_cy_debt -= apu_master_cy;
                total_apu_cy += apu_master_cy as u64;
            }
            while ppu_master_cy_debt > 0 {
                let (cy, result) = self.cpu.mem.ppu.update();
                ppu_master_cy_debt -= cy as i32;
                total_ppu_cy += cy as u64;

                if result.hblank {
                    // TODO Do HDMA
                }
                if result.vblank {
                    // FIXME We should render the frame earlier (result.vblank is set after the
                    // hblank of the last frame is left, which is later than necessary)
                    self.renderer.render(&*self.cpu.mem.ppu.framebuf);

                    // XXX we assume that joypads are always autoread
                    self.cpu.mem.input.update();
                    if self.cpu.mem.nmi_enabled() {
                        //trace!("V-Blank NMI triggered! Trace started!");
                        //self.cpu.trace = true;
                        self.cpu.mem.nmi = true;
                        self.cpu.trigger_nmi();
                        // XXX Break to handle the NMI immediately. Let's hope we don't owe the PPU
                        // too many cycles.
                        break;
                    }
                }
            }

            working_cy.set(master_cy);
        }

        info!("EXITING. Master cycle count: {}, APU: {}, PPU: {}",
            master_cy, total_apu_cy, total_ppu_cy);
    }
}
<commit_msg>IRQ flag<commit_after>//! Contains the `Snes` struct, which wields the combined power of this project.

use apu::Apu;
use cpu::Cpu;
use dma::{do_dma, DmaChannel};
use frontend::{self, Renderer};
use input::Input;
use log_util::LogOnPanic;
use ppu::Ppu;
use rom::Rom;

const WRAM_SIZE: usize = 128 * 1024;
byte_array!(Wram[WRAM_SIZE]);

/// Contains everything connected to the CPU via one of the two address buses. All memory accesses
/// will be directed through this (the CPU already takes access time into account).
pub struct Peripherals {
    apu: Apu,
    ppu: Ppu,
    rom: Rom,
    /// The 128 KB of working RAM of the SNES (separate from cartridge RAM)
    wram: Wram,
    input: Input,

    pub dma: [DmaChannel; 8],
    /// `$420c` - HDMAEN: HDMA enable flags
    /// (Note that general DMA doesn't have a register here, since all transactions are started
    /// immediately and the register can't be read)
    hdmaen: u8,
    /// `$4200` - NMITIMEN: Interrupt enable flags
    /// `n-xy---a`
    /// * `n`: Enable NMI on V-Blank
    /// * `x`: Enable IRQ on H-Counter match
    /// * `y`: Enable IRQ on V-Counter match
    /// * `a`: Enable auto-joypad read
    nmien: u8,
    /// `$4210` NMI flag and 5A22 Version
    /// `n---vvvv`
    /// * `n`: `self.nmi`
    /// * `v`: Version
    nmi: bool,
    /// `$4211` TIMEUP - IRQ flag
    /// `i-------`
    /// * `i`: IRQ flag (cleared on read)
    irq: bool,

    /// Additional cycles spent doing IO (in master clock cycles). This is reset before each CPU
    /// instruction and added to the cycle count returned by the CPU.
    cy: u32,
}

impl Peripherals {
    pub fn new(rom: Rom) -> Peripherals {
        Peripherals {
            rom: rom,
            apu: Apu::new(),
            ppu: Ppu::new(),
            wram: Wram::default(),
            input: Input::default(),
            dma: [DmaChannel::new(); 8],
            hdmaen: 0x00,
            nmien: 0x00,
            nmi: false,
            irq: false,
            cy: 0,
        }
    }

    pub fn load(&mut self, bank: u8, addr: u16) -> u8 {
        match bank {
            0x00 ... 0x3f | 0x80 ... 0xbf => match addr {
                // Mirror of first 8k of WRAM
                0x0000 ... 0x1fff => self.wram[addr as usize],
                // PPU
                0x2100 ... 0x2133 => panic!("read from write-only PPU register ${:04X}", addr),
                0x2138 ... 0x213f => self.ppu.load(addr),
                // APU IO registers
                0x2140 ... 0x217f => self.apu.read_port((addr & 0b11) as u8),
                0x4210 => {
                    const CPU_VERSION: u8 = 2;  // FIXME Is 2 okay in all cases? Does anyone care?
                    let nmi = if self.nmi {1} else {0} << 7;
                    self.nmi = false;   // Cleared on read
                    nmi | CPU_VERSION
                }
                0x4211 => {
                    let val = if self.irq { 0x80 } else { 0 };
                    self.irq = false;
                    val
                }
                0x4218 ... 0x421f => self.input.load(addr),
                // DMA channels (0x43xr, where x is the channel and r is the channel register)
                0x4300 ... 0x43ff => self.dma[(addr as usize & 0x00f0) >> 4].load(addr as u8 & 0xf),
                0x8000 ... 0xffff => self.rom.loadb(bank, addr),
                _ => panic!("invalid/unimplemented load from ${:02X}:{:04X}", bank, addr)
            },
            // WRAM banks. The first 8k are mapped into the start of all banks.
            0x7e | 0x7f => self.wram[(bank as usize - 0x7e) * 65536 + addr as usize],
            0x40 ... 0x7d | 0xc0 ... 0xff => self.rom.loadb(bank, addr),
            _ => unreachable!(),    // Rust should know this!
        }
    }

    pub fn store(&mut self, bank: u8, addr: u16, value: u8) {
        match bank {
            0x00 ... 0x3f | 0x80 ... 0xbf => match addr {
                0x0000 ... 0x1fff => self.wram[addr as usize] = value,
                // PPU registers. Let it deal with the access.
                0x2100 ... 0x2133 => self.ppu.store(addr, value),
                0x2138 ... 0x213f => panic!("store to read-only PPU register ${:04X}", addr),
                // APU IO registers.
                0x2140 ... 0x217f => self.apu.store_port((addr & 0b11) as u8, value),
                0x2180 ... 0x2183 => panic!("NYI: WRAM registers"),
                0x4200 => {
                    // NMITIMEN - NMI/IRQ enable
                    // E-HV---J
                    // E: Enable NMI
                    // H: Enable IRQ on H-Counter
                    // V: Enable IRQ on V-Counter
                    // J: Enable Auto-Joypad-Read
                    if value & 0x20 != 0 { panic!("NYI: IRQ-H") }
                    if value & 0x10 != 0 { panic!("NYI: IRQ-V") }
                    // Check useless bits
                    if value & 0x4e != 0 { panic!("Invalid value for NMIEN: ${:02X}", value) }
                    self.nmien = value;
                }
                // MDMAEN - Party enable
                0x420b => self.cy += do_dma(self, value),
                0x420c => {
                    // HDMAEN - HDMA enable
                    if value != 0 { panic!("NYI: HDMA") }
                    self.hdmaen = value;
                }
                // DMA channels (0x43xr, where x is the channel and r is the channel register)
                0x4300 ... 0x43ff => {
                    self.dma[(addr as usize & 0x00f0) >> 4].store(addr as u8 & 0xf, value);
                }
                0x8000 ... 0xffff => self.rom.storeb(bank, addr, value),
                _ => panic!("invalid store: ${:02X} to ${:02X}:{:04X}", value, bank, addr)
            },
            // WRAM main banks
            0x7e | 0x7f => self.wram[(bank as usize - 0x7e) * 65536 + addr as usize] = value,
            0x40 ... 0x7d | 0xc0 ... 0xff => self.rom.storeb(bank, addr, value),
            _ => unreachable!(),    // Rust should know this!
        }
    }

    fn nmi_enabled(&self) -> bool { self.nmien & 0x80 != 0 }
}

pub struct Snes {
    cpu: Cpu,
    renderer: Box<Renderer>,
}

impl Snes {
    pub fn new(rom: Rom) -> Snes {
        Snes {
            cpu: Cpu::new(Peripherals::new(rom)),
            renderer: Box::new(frontend::SdlRenderer::new(&::sdl2::init().unwrap())),
        }
    }

    pub fn run(&mut self) {
        /// Exit after this number of master clock cycles
        const CY_LIMIT: u64 = 100_000_000;
        /// Start tracing at this master cycle (0 to trace everything)
        const TRACE_START: u64 = CY_LIMIT * 2;

        const MASTER_CLOCK_FREQ: i32 = 21_477_000;
        /// APU clock speed. On real hardware, this can vary quite a bit (I think it uses a ceramic
        /// resonator instead of a quartz).
        const APU_CLOCK_FREQ: i32 = 1_024_000;
        /// Approximated APU clock divider. It's actually somewhere around 20.9..., which is why we
        /// can't directly use `MASTER_CLOCK_FREQ / APU_CLOCK_FREQ` (it would round down, which
        /// might not be critical, but better safe than sorry).
        const APU_DIVIDER: i32 = 21;

        // Master cycle counter, used only for debugging atm
        let mut master_cy: u64 = 0;
        let mut total_apu_cy: u64 = 0;
        let mut total_ppu_cy: u64 = 0;
        // Master clock cycles for the APU not yet accounted for (can be negative)
        let mut apu_master_cy_debt = 0;
        let mut ppu_master_cy_debt = 0;
        let working_cy = LogOnPanic::new(0);

        while master_cy < CY_LIMIT {
            if master_cy >= TRACE_START {
                self.cpu.trace = true;
                self.cpu.mem.apu.trace = true;
            }

            // Run a CPU instruction and calculate the master cycles elapsed
            self.cpu.mem.cy = 0;
            let cpu_master_cy = self.cpu.dispatch() as i32 + self.cpu.mem.cy as i32;
            master_cy += cpu_master_cy as u64;

            // Now we "owe" the other components a few cycles:
            apu_master_cy_debt += cpu_master_cy;
            ppu_master_cy_debt += cpu_master_cy;

            // Run all components until we no longer owe them:
            while apu_master_cy_debt > APU_DIVIDER {
                // (Since the APU uses lots of cycles to do stuff - lower clock rate and such - we
                // only run it if we owe it `APU_DIVIDER` master cycles - or one SPC700 cycle)
                let apu_master_cy = self.cpu.mem.apu.dispatch() as i32 * APU_DIVIDER;
                apu_master_cy_debt -= apu_master_cy;
                total_apu_cy += apu_master_cy as u64;
            }
            while ppu_master_cy_debt > 0 {
                let (cy, result) = self.cpu.mem.ppu.update();
                ppu_master_cy_debt -= cy as i32;
                total_ppu_cy += cy as u64;

                if result.hblank {
                    // TODO Do HDMA
                }
                if result.vblank {
                    // FIXME We should render the frame earlier (result.vblank is set after the
                    // hblank of the last frame is left, which is later than necessary)
                    self.renderer.render(&*self.cpu.mem.ppu.framebuf);

                    // XXX we assume that joypads are always autoread
                    self.cpu.mem.input.update();
                    if self.cpu.mem.nmi_enabled() {
                        //trace!("V-Blank NMI triggered! Trace started!");
                        //self.cpu.trace = true;
                        self.cpu.mem.nmi = true;
                        self.cpu.trigger_nmi();
                        // XXX Break to handle the NMI immediately. Let's hope we don't owe the PPU
                        // too many cycles.
                        break;
                    }
                }
                if result.new_frame {
                    self.cpu.mem.nmi = false;   // Flag cleared on read or end of VBlank
                }
            }

            working_cy.set(master_cy);
        }

        info!("EXITING. Master cycle count: {}, APU: {}, PPU: {}",
            master_cy, total_apu_cy, total_ppu_cy);
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Implementation of the `test` subcommand. Just a stub for now.

use subcommand::Subcommand;
use error::CliResult;
use error::CommandResult;
use term::Term;
use book;
use std::io::{Command, File};
use std::os;

struct Test;

pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> {
    if name == "test" {
        Some(box Test as Box<Subcommand>)
    } else {
        None
    }
}

impl Subcommand for Test {
    fn parse_args(&mut self, _: &[String]) -> CliResult<()> {
        Ok(())
    }
    fn usage(&self) {}
    fn execute(&mut self, term: &mut Term) -> CommandResult<()> {
        let cwd = os::getcwd().unwrap();
        let src = cwd.clone();

        let summary = File::open(&src.join("SUMMARY.md"));
        match book::parse_summary(summary, &src) {
            Ok(book) => {
                for (_, item) in book.iter() {
                    let output_result = Command::new("rustdoc")
                        .arg(&item.path)
                        .arg("--test")
                        .output();
                    match output_result {
                        Ok(output) => {
                            if !output.output.is_empty() || !output.error.is_empty() {
                                term.err(format!("{}\n{}",
                                         String::from_utf8_lossy(output.output[]),
                                         String::from_utf8_lossy(output.error[]))[]);
                            }
                        }
                        Err(e) => {
                            term.err(format!("Could not execute `rustdoc`: {}", e)[]);
                        }
                    }
                }
            }
            Err(errors) => {
                for err in errors.into_iter() {
                    term.err(err[]);
                }
            }
        }

        Ok(()) // lol
    }
}
<commit_msg>Failing tests == failing rustbook test<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Implementation of the `test` subcommand. Just a stub for now.

use subcommand::Subcommand;
use error::CliResult;
use error::CommandResult;
use error::Error;
use term::Term;
use book;
use std::io::{Command, File};
use std::os;

struct Test;

pub fn parse_cmd(name: &str) -> Option<Box<Subcommand>> {
    if name == "test" {
        Some(box Test as Box<Subcommand>)
    } else {
        None
    }
}

impl Subcommand for Test {
    fn parse_args(&mut self, _: &[String]) -> CliResult<()> {
        Ok(())
    }
    fn usage(&self) {}
    fn execute(&mut self, term: &mut Term) -> CommandResult<()> {
        let cwd = os::getcwd().unwrap();
        let src = cwd.clone();

        let summary = File::open(&src.join("SUMMARY.md"));
        match book::parse_summary(summary, &src) {
            Ok(book) => {
                for (_, item) in book.iter() {
                    let output_result = Command::new("rustdoc")
                        .arg(&item.path)
                        .arg("--test")
                        .output();
                    match output_result {
                        Ok(output) => {
                            if !output.status.success() {
                                term.err(format!("{}\n{}",
                                         String::from_utf8_lossy(output.output[]),
                                         String::from_utf8_lossy(output.error[]))[]);
                                return Err(box "Some tests failed." as Box<Error>);
                            }

                        }
                        Err(e) => {
                            return Err(box format!("Could not execute `rustdoc`: {}", e) as Box<Error>);
                        }
                    }
                }
            }
            Err(errors) => {
                for err in errors.into_iter() {
                    term.err(err[]);
                }
                return Err(box "There was an error." as Box<Error>);
            }
        }
        Ok(()) // lol
    }
}
<|endoftext|>


<commit_before>use super::{AsStr, Element, XmlReader, XmlWriter};
use super::Event::*;
use super::error::ResultPos;
use std::str::from_utf8;
use std::io::Cursor;

macro_rules! next_eq {
    ($r: expr, $($t:path, $bytes:expr),*) => {
        $(
            match $r.next() {
                Some(Ok($t(ref e))) => {
                    assert!(e.name() == $bytes, "expecting {:?}, found {:?}",
                            from_utf8($bytes), e.content().as_str());
                },
                Some(Ok(e)) => {
                    assert!(false, "expecting {:?}, found {:?}",
                            $t(Element::from_buffer($bytes.to_vec(),
                                                    0,
                                                    $bytes.len(),
                                                    $bytes.len())),
                            e);
                },
                Some(Err((e, pos))) => {
                    assert!(false, "{:?} at buffer position {}", e, pos);
                },
                p => {
                    assert!(false, "expecting {:?}, found {:?}",
                            $t(Element::from_buffer($bytes.to_vec(),
                                                    0,
                                                    $bytes.len(),
                                                    $bytes.len())),
                            p);
                }
            }
        )*
    }
}

#[test]
fn test_start() {
    let mut r = XmlReader::from("").trim_text(true);
    next_eq!(r, Start, b"a");
}

#[test]
fn test_start_end() {
    let mut r = XmlReader::from("").trim_text(true);
    next_eq!(r, Start, b"a", End, b"a");
}

#[test]
fn test_start_end_attr() {
    let mut r = XmlReader::from("").trim_text(true);
    next_eq!(r, Start, b"a", End, b"a");
}

#[test]
fn test_start_end_comment() {
    let mut r = XmlReader::from(" ")
        .trim_text(true);
    next_eq!(r,
             Start,
             b"b",
             Start,
             b"a",
             End,
             b"a",
             Start,
             b"a",
             End,
             b"a",
             Comment,
             b"t",
             End,
             b"b");
}

#[test]
fn test_start_txt_end() {
    let mut r = XmlReader::from("test").trim_text(true);
    next_eq!(r, Start, b"a", Text, b"test", End, b"a");
}

#[test]
fn test_comment() {
    let mut r = XmlReader::from("").trim_text(true);
    next_eq!(r, Comment, b"test");
}

#[test]
fn test_xml_decl() {
    let mut r = XmlReader::from("<?xml version=\"1.0\" encoding='utf-8'?>")
        .trim_text(true);
    match r.next() {
        Some(Ok(Decl(ref e))) => {
            match e.version() {
                Ok(v) => {
                    assert!(v == b"1.0",
                            "expecting version '1.0', got '{:?}",
                            v.as_str())
                }
                Err(e) => assert!(false, "{:?}", e),
            }
            match e.encoding() {
                Some(Ok(v)) => {
                    assert!(v == b"utf-8",
                            "expecting encoding 'utf-8', got '{:?}",
                            v.as_str())
                }
                Some(Err(e)) => assert!(false, "{:?}", e),
                None => assert!(false, "cannot find encoding"),
            }
            match e.standalone() {
                None => assert!(true),
                e => assert!(false, "doesn't expect standalone, got {:?}", e),
            }
        }
        Some(Err((e, pos))) => {
            assert!(false, "{:?} at buffer position {}", e, pos);
        }
        _ => assert!(false, "unable to parse XmlDecl"),
    }
}

#[test]
fn test_trim_test() {
    let txt = "  ";
    let mut r = XmlReader::from(txt).trim_text(true);
    next_eq!(r, Start, b"a", Start, b"b", End, b"b", End, b"a");

    let mut r = XmlReader::from(txt).trim_text(false);
    next_eq!(r,
             Text,
             b"",
             Start,
             b"a",
             Text,
             b"",
             Start,
             b"b",
             Text,
             b"  ",
             End,
             b"b",
             Text,
             b"",
             End,
             b"a");
}

#[test]
fn test_cdata() {
    let mut r = XmlReader::from("<![CDATA[test]]>").trim_text(true);
    next_eq!(r, CData, b"test");
}

#[test]
fn test_cdata_open_close() {
    let mut r = XmlReader::from("<![CDATA[test <> test]]>").trim_text(true);
    next_eq!(r, CData, b"test <> test");
}

#[test]
fn test_start_attr() {
    let mut r = XmlReader::from("").trim_text(true);
    next_eq!(r, Start, b"a");
}

#[test]
fn test_nested() {
    let mut r = XmlReader::from("test<c/>").trim_text(true);
    next_eq!(r,
             Start,
             b"a",
             Start,
             b"b",
             Text,
             b"test",
             End,
             b"b",
             Start,
             b"c",
             End,
             b"c",
             End,
             b"a");
}

#[test]
fn test_writer() {
    let txt = r#"<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.github.sample" android:versionName="Lollipop" android:versionCode="5.1"><application android:label="SampleApplication"></application></manifest>"#;
    let reader = XmlReader::from(txt).trim_text(true);
    let mut writer = XmlWriter::new(Cursor::new(Vec::new()));
    for event in reader {
        assert!(writer.write(event.unwrap()).is_ok());
    }

    let result = writer.into_inner().into_inner();
    assert_eq!(result, txt.as_bytes());
}

#[test]
fn test_write_empty_element_attrs() {
    let str_from = r#"<source attr="val"/>"#;
    let expected = r#"<source attr="val"></source>"#;
    let reader = XmlReader::from(str_from);
    let mut writer = XmlWriter::new(Cursor::new(Vec::new()));
    for event in reader {
        assert!(writer.write(event.unwrap()).is_ok());
    }

    let result = writer.into_inner().into_inner();
    assert_eq!(String::from_utf8(result).unwrap(), expected);
}

#[test]
fn test_write_attrs() {
    let str_from = r#"<source attr="val"></source>"#;
    let expected = r#"<copy attr="val" a="b" c="d" x="y"></copy>"#;
    let reader = XmlReader::from(str_from).trim_text(true);
    let mut writer = XmlWriter::new(Cursor::new(Vec::new()));
    for event in reader {
        let event = event.unwrap();
        let event = match event {
            Start(elem) => {
                let mut attrs = elem.attributes()
                    .collect::<ResultPos<Vec<_>>>().unwrap();
                attrs.extend_from_slice(&[(b"a", b"b"), (b"c", b"d")]);
                let mut elem = Element::new("copy").with_attributes(attrs);
                elem.push_attribute("x", "y");
                Start(elem)
            }
            End(_elem) => End(Element::new("copy")),
            _ => event,
        };
        assert!(writer.write(event).is_ok());
    }

    let result = writer.into_inner().into_inner();
    assert_eq!(result, expected.as_bytes());
}

#[test]
fn test_buf_position() {
    let mut r = XmlReader::from("")
        .trim_text(true)
        .with_check(true);

    match r.next() {
        Some(Err((_, 2))) => assert!(true), // error at char 2: no opening tag
        Some(Err((e, n))) => assert!(false,
                                     "expecting buf_pos = 2, found {}, err: {:?}", n, e),
        e => assert!(false, "expecting error, found {:?}", e),
    }

    r = XmlReader::from(" tag found
        Some(Err((e, n))) => assert!(false,
                                     "expecting buf_pos = 2, found {}, err: {:?}", n, e),
        e => assert!(false, "expecting error, found {:?}", e),
    }

}

#[test]
fn test_namespace() {
    let mut r = XmlReader::from("<myns:b>in namespace!</myns:b>")
        .trim_text(true)
        .namespaced();;

    if let Some(Ok((None, Start(_)))) = r.next() {
    } else {
        assert!(false, "expecting start element with no namespace");
    }

    if let Some(Ok((Some(a), Start(_)))) = r.next() {
        if &*a == b"www1" {
            assert!(true);
        } else {
            assert!(false, "expecting namespace to resolve to 'www1'");
        }
    } else {
        assert!(false, "expecting namespace resolution");
    }
}

#[test]
fn test_escaped_content() {
    let mut r = XmlReader::from("<test>").trim_text(true);
    next_eq!(r, Start, b"a");
    match r.next() {
        Some(Ok(Text(ref e))) => {
            if e.content() != b"<test>" {
                panic!("content unexpected: expecting '<test>', got '{:?}'",
                       e.content().as_str());
            }
            match e.unescaped_content() {
                Ok(ref c) => {
                    if &**c != b"<test>" {
                        panic!("unescaped content unexpected: expecting '<test<', got '{:?}'",
                               c.as_str())
                    }
                }
                Err((e, i)) => panic!("cannot escape content at position {}: {:?}", i, e),
            }
        }
        Some(Ok(ref e)) => panic!("Expecting text event, got {:?}", e),
        Some(Err((e, i))) => panic!("Cannot get next event at position {}: {:?}", i, e),
        None => panic!("Expecting text event, got None"),
    }
    next_eq!(r, End, b"a");
}
<commit_msg>Add failing read/write roundtrip test<commit_after>use super::{AsStr, Element, XmlReader, XmlWriter};
use super::Event::*;
use super::error::ResultPos;
use std::str::from_utf8;
use std::io::Cursor;

macro_rules! next_eq {
    ($r: expr, $($t:path, $bytes:expr),*) => {
        $(
            match $r.next() {
                Some(Ok($t(ref e))) => {
                    assert!(e.name() == $bytes, "expecting {:?}, found {:?}",
                            from_utf8($bytes), e.content().as_str());
                },
                Some(Ok(e)) => {
                    assert!(false, "expecting {:?}, found {:?}",
                            $t(Element::from_buffer($bytes.to_vec(),
                                                    0,
                                                    $bytes.len(),
                                                    $bytes.len())),
                            e);
                },
                Some(Err((e, pos))) => {
                    assert!(false, "{:?} at buffer position {}", e, pos);
                },
                p => {
                    assert!(false, "expecting {:?}, found {:?}",
                            $t(Element::from_buffer($bytes.to_vec(),
                                                    0,
                                                    $bytes.len(),
                                                    $bytes.len())),
                            p);
                }
            }
        )*
    }
}

#[test]
fn test_start() {
    let mut r = XmlReader::from("").trim_text(true);
    next_eq!(r, Start, b"a");
}

#[test]
fn test_start_end() {
    let mut r = XmlReader::from("").trim_text(true);
    next_eq!(r, Start, b"a", End, b"a");
}

#[test]
fn test_start_end_attr() {
    let mut r = XmlReader::from("").trim_text(true);
    next_eq!(r, Start, b"a", End, b"a");
}

#[test]
fn test_start_end_comment() {
    let mut r = XmlReader::from(" ")
        .trim_text(true);
    next_eq!(r,
             Start,
             b"b",
             Start,
             b"a",
             End,
             b"a",
             Start,
             b"a",
             End,
             b"a",
             Comment,
             b"t",
             End,
             b"b");
}

#[test]
fn test_start_txt_end() {
    let mut r = XmlReader::from("test").trim_text(true);
    next_eq!(r, Start, b"a", Text, b"test", End, b"a");
}

#[test]
fn test_comment() {
    let mut r = XmlReader::from("").trim_text(true);
    next_eq!(r, Comment, b"test");
}

#[test]
fn test_xml_decl() {
    let mut r = XmlReader::from("<?xml version=\"1.0\" encoding='utf-8'?>")
        .trim_text(true);
    match r.next() {
        Some(Ok(Decl(ref e))) => {
            match e.version() {
                Ok(v) => {
                    assert!(v == b"1.0",
                            "expecting version '1.0', got '{:?}",
                            v.as_str())
                }
                Err(e) => assert!(false, "{:?}", e),
            }
            match e.encoding() {
                Some(Ok(v)) => {
                    assert!(v == b"utf-8",
                            "expecting encoding 'utf-8', got '{:?}",
                            v.as_str())
                }
                Some(Err(e)) => assert!(false, "{:?}", e),
                None => assert!(false, "cannot find encoding"),
            }
            match e.standalone() {
                None => assert!(true),
                e => assert!(false, "doesn't expect standalone, got {:?}", e),
            }
        }
        Some(Err((e, pos))) => {
            assert!(false, "{:?} at buffer position {}", e, pos);
        }
        _ => assert!(false, "unable to parse XmlDecl"),
    }
}

#[test]
fn test_trim_test() {
    let txt = "  ";
    let mut r = XmlReader::from(txt).trim_text(true);
    next_eq!(r, Start, b"a", Start, b"b", End, b"b", End, b"a");

    let mut r = XmlReader::from(txt).trim_text(false);
    next_eq!(r,
             Text,
             b"",
             Start,
             b"a",
             Text,
             b"",
             Start,
             b"b",
             Text,
             b"  ",
             End,
             b"b",
             Text,
             b"",
             End,
             b"a");
}

#[test]
fn test_cdata() {
    let mut r = XmlReader::from("<![CDATA[test]]>").trim_text(true);
    next_eq!(r, CData, b"test");
}

#[test]
fn test_cdata_open_close() {
    let mut r = XmlReader::from("<![CDATA[test <> test]]>").trim_text(true);
    next_eq!(r, CData, b"test <> test");
}

#[test]
fn test_start_attr() {
    let mut r = XmlReader::from("").trim_text(true);
    next_eq!(r, Start, b"a");
}

#[test]
fn test_nested() {
    let mut r = XmlReader::from("test<c/>").trim_text(true);
    next_eq!(r,
             Start,
             b"a",
             Start,
             b"b",
             Text,
             b"test",
             End,
             b"b",
             Start,
             b"c",
             End,
             b"c",
             End,
             b"a");
}

#[test]
fn test_writer() {
    let txt = r#"<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.github.sample" android:versionName="Lollipop" android:versionCode="5.1"><application android:label="SampleApplication"></application></manifest>"#;
    let reader = XmlReader::from(txt).trim_text(true);
    let mut writer = XmlWriter::new(Cursor::new(Vec::new()));
    for event in reader {
        assert!(writer.write(event.unwrap()).is_ok());
    }

    let result = writer.into_inner().into_inner();
    assert_eq!(result, txt.as_bytes());
}

#[test]
fn test_write_empty_element_attrs() {
    let str_from = r#"<source attr="val"/>"#;
    let expected = r#"<source attr="val"></source>"#;
    let reader = XmlReader::from(str_from);
    let mut writer = XmlWriter::new(Cursor::new(Vec::new()));
    for event in reader {
        assert!(writer.write(event.unwrap()).is_ok());
    }

    let result = writer.into_inner().into_inner();
    assert_eq!(String::from_utf8(result).unwrap(), expected);
}

#[test]
fn test_write_attrs() {
    let str_from = r#"<source attr="val"></source>"#;
    let expected = r#"<copy attr="val" a="b" c="d" x="y"></copy>"#;
    let reader = XmlReader::from(str_from).trim_text(true);
    let mut writer = XmlWriter::new(Cursor::new(Vec::new()));
    for event in reader {
        let event = event.unwrap();
        let event = match event {
            Start(elem) => {
                let mut attrs = elem.attributes()
                    .collect::<ResultPos<Vec<_>>>().unwrap();
                attrs.extend_from_slice(&[(b"a", b"b"), (b"c", b"d")]);
                let mut elem = Element::new("copy").with_attributes(attrs);
                elem.push_attribute("x", "y");
                Start(elem)
            }
            End(_elem) => End(Element::new("copy")),
            _ => event,
        };
        assert!(writer.write(event).is_ok());
    }

    let result = writer.into_inner().into_inner();
    assert_eq!(result, expected.as_bytes());
}

#[test]
fn test_buf_position() {
    let mut r = XmlReader::from("")
        .trim_text(true)
        .with_check(true);

    match r.next() {
        Some(Err((_, 2))) => assert!(true), // error at char 2: no opening tag
        Some(Err((e, n))) => assert!(false,
                                     "expecting buf_pos = 2, found {}, err: {:?}", n, e),
        e => assert!(false, "expecting error, found {:?}", e),
    }

    r = XmlReader::from(" tag found
        Some(Err((e, n))) => assert!(false,
                                     "expecting buf_pos = 2, found {}, err: {:?}", n, e),
        e => assert!(false, "expecting error, found {:?}", e),
    }

}

#[test]
fn test_namespace() {
    let mut r = XmlReader::from("<myns:b>in namespace!</myns:b>")
        .trim_text(true)
        .namespaced();;

    if let Some(Ok((None, Start(_)))) = r.next() {
    } else {
        assert!(false, "expecting start element with no namespace");
    }

    if let Some(Ok((Some(a), Start(_)))) = r.next() {
        if &*a == b"www1" {
            assert!(true);
        } else {
            assert!(false, "expecting namespace to resolve to 'www1'");
        }
    } else {
        assert!(false, "expecting namespace resolution");
    }
}

#[test]
fn test_escaped_content() {
    let mut r = XmlReader::from("<test>").trim_text(true);
    next_eq!(r, Start, b"a");
    match r.next() {
        Some(Ok(Text(ref e))) => {
            if e.content() != b"<test>" {
                panic!("content unexpected: expecting '<test>', got '{:?}'",
                       e.content().as_str());
            }
            match e.unescaped_content() {
                Ok(ref c) => {
                    if &**c != b"<test>" {
                        panic!("unescaped content unexpected: expecting '<test<', got '{:?}'",
                               c.as_str())
                    }
                }
                Err((e, i)) => panic!("cannot escape content at position {}: {:?}", i, e),
            }
        }
        Some(Ok(ref e)) => panic!("Expecting text event, got {:?}", e),
        Some(Err((e, i))) => panic!("Cannot get next event at position {}: {:?}", i, e),
        None => panic!("Expecting text event, got None"),
    }
    next_eq!(r, End, b"a");
}

#[test]
fn test_read_write_roundtrip_results_in_identity() {
    let input = r#"
        <?xml version="1.0" encoding="UTF-8"?>

data

    "#;

    let reader = XmlReader::from(input);
    let mut writer = XmlWriter::new(Cursor::new(Vec::new()));
    for event in reader {
        assert!(writer.write(event.unwrap()).is_ok());
    }

    let result = writer.into_inner().into_inner();
    assert_eq!(result, input.as_bytes());
}
<|endoftext|>


<commit_before>#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Tile {
	Wall,
	Floor,
	Void,
}
<commit_msg>added hash to tiles derive<commit_after>#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub enum Tile {
	Wall,
	Floor,
	Void,
}
<|endoftext|>


<commit_before>//! # UART for the LM4F120H5QR

// ****************************************************************************
//
// Imports
//
// ****************************************************************************

use core::fmt;
use core::intrinsics::{volatile_load, volatile_store};

use embedded_serial::{self, BlockingTx, NonBlockingRx};
use cortex_m::asm::nop;

use super::gpio;
use super::pll;
use super::registers as reg;

// ****************************************************************************
//
// Public Types
//
// ****************************************************************************

/// This chip has 8 UARTs
#[derive(PartialEq, Clone, Copy)]
#[allow(missing_docs)]
pub enum UartId {
    Uart0,
    Uart1,
    Uart2,
    Uart3,
    Uart4,
    Uart5,
    Uart6,
    Uart7,
}

/// Controls a single UART
/// Only supports 8/N/1 - who needs anything else?
pub struct Uart {
    id: UartId,
    baud: u32,
    nl_mode: NewlineMode,
    reg: &'static mut reg::UartRegisters,
}

/// writeln!() emits LF chars, so this is useful
/// if you're writing text with your UART
#[derive(PartialEq, Clone, Copy)]
pub enum NewlineMode {
    /// Emit octets as received
    Binary,
    /// Emit an extra CR before every LF
    SwapLFtoCRLF,
}

// ****************************************************************************
//
// Private Types
//
// ****************************************************************************

// None

// ****************************************************************************
//
// Public Data
//
// ****************************************************************************

// None

// ****************************************************************************
//
// Public Functions
//
// ****************************************************************************

/// Represents a single UART on the LM4F120
impl Uart {
    /// Create a new Uart object. The caller is responsible for ensuring
    /// that only one object exists per UartId. The UART is set to
    /// 8 data bits, 1 stop bit, no parity and is not configurable.
    /// Optionally, newline translation can be performed on outbound data
    /// - this will cause writeln!() to emit a CRLF.
    pub fn new(id: UartId, baud: u32, nl_mode: NewlineMode) -> Uart {
        let mut uart = Uart {
            id: id,
            baud: baud,
            nl_mode: nl_mode,
            reg: get_uart_registers(id),
        };
        uart.init();
        uart
    }

    /// Configure the hardware
    fn init(&mut self) -> () {
        // Do GPIO pin muxing
        gpio::enable_uart(self.id);
        // Enable UART module in RCGUART register p306
        unsafe {
            self.enable_clock();

            // Disable UART and all features
            self.reg.ctl.write(0);
            // Calculate the baud rate values
            // baud_div = CLOCK_RATE / (16 * baud_rate);
            // baud_int = round(baud_div * 64)
            let baud_int: u32 = (((pll::get_clock_hz() * 8) / self.baud) + 1) / 2;
            // Store the upper and lower parts of the divider
            self.reg.ibrd.write((baud_int / 64) as usize);
            self.reg.fbrd.write((baud_int % 64) as usize);
            // Set the UART Line Control register value
            // 8N1 + FIFO enabled
            self.reg.lcrh.write(reg::UART_LCRH_WLEN_8 | reg::UART_LCRH_FEN);
            // Clear the flags
            self.reg.rf.write(0);
            // Enable
            self.reg.ctl.write(reg::UART_CTL_RXE | reg::UART_CTL_TXE | reg::UART_CTL_UARTEN);
        }
    }

    /// Select which bits to enable in the clock gating register
    fn get_clock_gating_mask(&self) -> usize {
        match self.id {
            UartId::Uart0 => reg::SYSCTL_RCGCUART_R0,
            UartId::Uart1 => reg::SYSCTL_RCGCUART_R1,
            UartId::Uart2 => reg::SYSCTL_RCGCUART_R2,
            UartId::Uart3 => reg::SYSCTL_RCGCUART_R3,
            UartId::Uart4 => reg::SYSCTL_RCGCUART_R4,
            UartId::Uart5 => reg::SYSCTL_RCGCUART_R5,
            UartId::Uart6 => reg::SYSCTL_RCGCUART_R6,
            UartId::Uart7 => reg::SYSCTL_RCGCUART_R7,
        }
    }

    /// Enable the module in the real-time clock gating registers.
    unsafe fn enable_clock(&mut self) {
        volatile_store(reg::SYSCTL_RCGCUART_R, self.get_clock_gating_mask());
        while volatile_load(reg::SYSCTL_RCGCUART_R) != self.get_clock_gating_mask() {
            nop();
        }
    }

    #[deprecated]
    pub fn read_single(&mut self) -> Option<u8> {
        self.getc_try().unwrap()
    }
}

impl embedded_serial::BlockingTx for Uart {
    type Error = !;

    /// Emit a single octet, busy-waiting if the FIFO is full.
    /// Never returns `Err`.
    fn putc(&mut self, value: u8) -> Result<(), Self::Error>{
        while (self.reg.rf.read() & reg::UART_FR_TXFF) != 0 {
            nop();
        }
        self.reg.data.write(value as usize);
        Ok(())
    }
}

impl embedded_serial::NonBlockingTx for Uart {
    type Error = !;

    /// Attempts to write to the UART. Returns `Err(())`
    /// if the transmit not ready, or `Ok(())`.
    fn putc_try(&mut self, value: u8) -> Result<Option<()>, Self::Error>{
        if (self.reg.rf.read() & reg::UART_FR_TXFF) != 0 {
            Ok(None)
        } else {
            self.reg.data.write(value as usize);
            Ok(Some(()))
        }
    }
}

impl embedded_serial::BlockingRx for Uart {
    type Error = !;

    /// Reads from the UART. Never returns `Err`.
    fn getc(&mut self) -> Result<u8, Self::Error> {
        while (self.reg.rf.read() & reg::UART_FR_RXFE) != 0 {
            nop();
        }
        Ok(self.reg.data.read() as u8)
    }
}

impl embedded_serial::NonBlockingRx for Uart {
    type Error = !;

    /// Attempts to read from the UART. Returns `Err(())`
    /// if the FIFO is empty, or `Ok(octet)`.
    fn getc_try(&mut self) -> Result<Option<u8>, Self::Error> {
        if (self.reg.rf.read() & reg::UART_FR_RXFE) != 0 {
            Ok(None)
        } else {
            Ok(Some(self.reg.data.read() as u8))
        }
    }
}

/// Allows the Uart to be passed to 'write!()' and friends.
impl fmt::Write for Uart {
    fn write_str(&mut self, s: &str) -> fmt::Result {
        match self.nl_mode {
            NewlineMode::Binary => {
                for byte in s.bytes() {
                    self.putc(byte).unwrap()
                }
            }
            NewlineMode::SwapLFtoCRLF => {
                for byte in s.bytes() {
                    if byte == 0x0A {
                        // Prefix every \n with a \r
                        self.putc(0x0D).unwrap()
                    }
                    self.putc(byte).unwrap()
                }
            }
        }
        Ok(())
    }
}

/// Called when UART 0 interrupt fires
pub unsafe extern "C" fn uart0_isr() {}

// ****************************************************************************
//
// Private Functions
//
// ****************************************************************************

/// Get a reference to the UART control register struct in the chip.
fn get_uart_registers(uart_id: UartId) -> &'static mut reg::UartRegisters {
    unsafe {
        match uart_id {
            UartId::Uart0 => &mut *(reg::UART0_DR_R as *mut reg::UartRegisters),
            UartId::Uart1 => &mut *(reg::UART1_DR_R as *mut reg::UartRegisters),
            UartId::Uart2 => &mut *(reg::UART2_DR_R as *mut reg::UartRegisters),
            UartId::Uart3 => &mut *(reg::UART3_DR_R as *mut reg::UartRegisters),
            UartId::Uart4 => &mut *(reg::UART4_DR_R as *mut reg::UartRegisters),
            UartId::Uart5 => &mut *(reg::UART5_DR_R as *mut reg::UartRegisters),
            UartId::Uart6 => &mut *(reg::UART6_DR_R as *mut reg::UartRegisters),
            UartId::Uart7 => &mut *(reg::UART7_DR_R as *mut reg::UartRegisters),
        }
    }
}

// ****************************************************************************
//
// End Of File
//
// ****************************************************************************
<commit_msg>Fix comments. Implement latest trait definition.<commit_after>//! # UART for the LM4F120H5QR

// ****************************************************************************
//
// Imports
//
// ****************************************************************************

use core::fmt;
use core::intrinsics::{volatile_load, volatile_store};

use embedded_serial::{self, BlockingTx, NonBlockingRx};
use cortex_m::asm::nop;

use super::gpio;
use super::pll;
use super::registers as reg;

// ****************************************************************************
//
// Public Types
//
// ****************************************************************************

/// This chip has 8 UARTs
#[derive(PartialEq, Clone, Copy)]
#[allow(missing_docs)]
pub enum UartId {
    Uart0,
    Uart1,
    Uart2,
    Uart3,
    Uart4,
    Uart5,
    Uart6,
    Uart7,
}

/// Controls a single UART
/// Only supports 8/N/1 - who needs anything else?
pub struct Uart {
    id: UartId,
    baud: u32,
    nl_mode: NewlineMode,
    reg: &'static mut reg::UartRegisters,
}

/// writeln!() emits LF chars, so this is useful
/// if you're writing text with your UART
#[derive(PartialEq, Clone, Copy)]
pub enum NewlineMode {
    /// Emit octets as received
    Binary,
    /// Emit an extra CR before every LF
    SwapLFtoCRLF,
}

// ****************************************************************************
//
// Private Types
//
// ****************************************************************************

// None

// ****************************************************************************
//
// Public Data
//
// ****************************************************************************

// None

// ****************************************************************************
//
// Public Functions
//
// ****************************************************************************

/// Represents a single UART on the LM4F120
impl Uart {
    /// Create a new Uart object. The caller is responsible for ensuring
    /// that only one object exists per UartId. The UART is set to
    /// 8 data bits, 1 stop bit, no parity and is not configurable.
    /// Optionally, newline translation can be performed on outbound data
    /// - this will cause writeln!() to emit a CRLF.
    pub fn new(id: UartId, baud: u32, nl_mode: NewlineMode) -> Uart {
        let mut uart = Uart {
            id: id,
            baud: baud,
            nl_mode: nl_mode,
            reg: get_uart_registers(id),
        };
        uart.init();
        uart
    }

    /// Configure the hardware
    fn init(&mut self) -> () {
        // Do GPIO pin muxing
        gpio::enable_uart(self.id);
        // Enable UART module in RCGUART register p306
        unsafe {
            self.enable_clock();

            // Disable UART and all features
            self.reg.ctl.write(0);
            // Calculate the baud rate values
            // baud_div = CLOCK_RATE / (16 * baud_rate);
            // baud_int = round(baud_div * 64)
            let baud_int: u32 = (((pll::get_clock_hz() * 8) / self.baud) + 1) / 2;
            // Store the upper and lower parts of the divider
            self.reg.ibrd.write((baud_int / 64) as usize);
            self.reg.fbrd.write((baud_int % 64) as usize);
            // Set the UART Line Control register value
            // 8N1 + FIFO enabled
            self.reg.lcrh.write(reg::UART_LCRH_WLEN_8 | reg::UART_LCRH_FEN);
            // Clear the flags
            self.reg.rf.write(0);
            // Enable
            self.reg.ctl.write(reg::UART_CTL_RXE | reg::UART_CTL_TXE | reg::UART_CTL_UARTEN);
        }
    }

    /// Select which bits to enable in the clock gating register
    fn get_clock_gating_mask(&self) -> usize {
        match self.id {
            UartId::Uart0 => reg::SYSCTL_RCGCUART_R0,
            UartId::Uart1 => reg::SYSCTL_RCGCUART_R1,
            UartId::Uart2 => reg::SYSCTL_RCGCUART_R2,
            UartId::Uart3 => reg::SYSCTL_RCGCUART_R3,
            UartId::Uart4 => reg::SYSCTL_RCGCUART_R4,
            UartId::Uart5 => reg::SYSCTL_RCGCUART_R5,
            UartId::Uart6 => reg::SYSCTL_RCGCUART_R6,
            UartId::Uart7 => reg::SYSCTL_RCGCUART_R7,
        }
    }

    /// Enable the module in the real-time clock gating registers.
    unsafe fn enable_clock(&mut self) {
        volatile_store(reg::SYSCTL_RCGCUART_R, self.get_clock_gating_mask());
        while volatile_load(reg::SYSCTL_RCGCUART_R) != self.get_clock_gating_mask() {
            nop();
        }
    }

    #[deprecated]
    pub fn read_single(&mut self) -> Option<u8> {
        self.getc().unwrap()
    }
}

impl embedded_serial::BlockingTx for Uart {
    type Error = !;

    /// Emit a single octet, busy-waiting if the FIFO is full.
    /// Never returns `Err`.
    fn putc(&mut self, value: u8) -> Result<(), Self::Error>{
        while (self.reg.rf.read() & reg::UART_FR_TXFF) != 0 {
            nop();
        }
        self.reg.data.write(value as usize);
        Ok(())
    }
}

impl embedded_serial::NonBlockingTx for Uart {
    type Error = !;

    /// Attempts to write to the UART. Returns `Ok(None)` if the transmiter
    /// not ready, or `Ok(Some(value))`. Never returns `Err`.
    fn putc(&mut self, value: u8) -> Result<Option<u8>, Self::Error>{
        if (self.reg.rf.read() & reg::UART_FR_TXFF) != 0 {
            Ok(None)
        } else {
            self.reg.data.write(value as usize);
            Ok(Some(value))
        }
    }
}

impl embedded_serial::BlockingRx for Uart {
    type Error = !;

    /// Read a single octet, busy-waiting if the FIFO is empty.
    /// Never returns `Err`.
    fn getc(&mut self) -> Result<u8, Self::Error> {
        while (self.reg.rf.read() & reg::UART_FR_RXFE) != 0 {
            nop();
        }
        Ok(self.reg.data.read() as u8)
    }
}

impl embedded_serial::NonBlockingRx for Uart {
    type Error = !;

    /// Attempts to read from the UART. Returns `Ok(None)` if the FIFO is
    /// empty, or `Ok(octet)`. Never returns `Err`.
    fn getc(&mut self) -> Result<Option<u8>, Self::Error> {
        if (self.reg.rf.read() & reg::UART_FR_RXFE) != 0 {
            Ok(None)
        } else {
            Ok(Some(self.reg.data.read() as u8))
        }
    }
}

/// Allows the Uart to be passed to 'write!()' and friends.
impl fmt::Write for Uart {
    fn write_str(&mut self, s: &str) -> fmt::Result {
        match self.nl_mode {
            NewlineMode::Binary => {
                for byte in s.bytes() {
                    self.putc(byte).unwrap()
                }
            }
            NewlineMode::SwapLFtoCRLF => {
                for byte in s.bytes() {
                    if byte == 0x0A {
                        // Prefix every \n with a \r
                        self.putc(0x0D).unwrap()
                    }
                    self.putc(byte).unwrap()
                }
            }
        }
        Ok(())
    }
}

/// Called when UART 0 interrupt fires
pub unsafe extern "C" fn uart0_isr() {}

// ****************************************************************************
//
// Private Functions
//
// ****************************************************************************

/// Get a reference to the UART control register struct in the chip.
fn get_uart_registers(uart_id: UartId) -> &'static mut reg::UartRegisters {
    unsafe {
        match uart_id {
            UartId::Uart0 => &mut *(reg::UART0_DR_R as *mut reg::UartRegisters),
            UartId::Uart1 => &mut *(reg::UART1_DR_R as *mut reg::UartRegisters),
            UartId::Uart2 => &mut *(reg::UART2_DR_R as *mut reg::UartRegisters),
            UartId::Uart3 => &mut *(reg::UART3_DR_R as *mut reg::UartRegisters),
            UartId::Uart4 => &mut *(reg::UART4_DR_R as *mut reg::UartRegisters),
            UartId::Uart5 => &mut *(reg::UART5_DR_R as *mut reg::UartRegisters),
            UartId::Uart6 => &mut *(reg::UART6_DR_R as *mut reg::UartRegisters),
            UartId::Uart7 => &mut *(reg::UART7_DR_R as *mut reg::UartRegisters),
        }
    }
}

// ****************************************************************************
//
// End Of File
//
// ****************************************************************************
<|endoftext|>


<commit_before>
use std::io;
use std::net::TcpListener;

/// Find a TCP port number to use. This is racy but see
/// https://bugzilla.mozilla.org/show_bug.cgi?id=1240830
///
/// If port is Some, check if we can bind to the given port. Otherwise
/// pick a random port.
pub fn check_tcp_port(port: Option<u16>) -> io::Result<u16> {
    TcpListener::bind(&("localhost", port.unwrap_or(0)))
        .and_then(|stream| stream.local_addr())
        .map(|x| x.port())
}

<commit_msg>Add util::{merge_json, merge_json_mut}.<commit_after>//! Small utilities.

use serde_json::Value as JsonValue;
use std::io;
use std::net::TcpListener;

/// Find a TCP port number to use. This is racy but see
/// https://bugzilla.mozilla.org/show_bug.cgi?id=1240830
///
/// If port is Some, check if we can bind to the given port. Otherwise
/// pick a random port.
pub (crate) fn check_tcp_port(port: Option<u16>) -> io::Result<u16> {
    TcpListener::bind(&("localhost", port.unwrap_or(0)))
        .and_then(|stream| stream.local_addr())
        .map(|x| x.port())
}

/// Recursively merge serde_json::Value's from a then b into a new
/// returned value.
///
/// # Example
///
/// ```
/// # #[macro_use] extern crate serde_json;
/// # extern crate webdriver_client;
/// #
/// # use webdriver_client::util::merge_json;
/// # fn main() {
/// #
/// let a = json!({
///     "a": "only in a",
///     "overwritten": "value in a",
///     "child_object": { "x": "value in a" },
///     "array": ["value 1 in a", "value 2 in a"],
///     "different_types": 5
/// });
/// let b = json!({
///     "b": "only in b",
///     "overwritten": "value in b",
///     "child_object": { "x": "value in b" },
///     "array": ["value in b"],
///     "different_types": true
/// });
/// let merged = merge_json(&a, &b);
///
/// assert_eq!(merged, json!({
///     // When only one input contains the key, the value is cloned.
///     "a": "only in a",
///     "b": "only in b",
///
///     // When both inputs contain a key, the value from b is cloned.
///     "overwritten": "value in b",
///
///     // When a child object is present in both values, it is recursively
///     // merged.
///     "child_object": { "x": "value in b" },
///
///     // If both values are an array, the value from b is cloned.
///     "array": ["value in b"],
///
///     // If the two values have different types, the value from b is cloned.
///     "different_types": true
/// }));
/// #
/// # } // Close main.
pub fn merge_json(a: &JsonValue, b: &JsonValue) -> JsonValue {
    let mut out = a.clone();
    merge_json_mut(&mut out, b);
    out
}

/// Recursively merge serde_json::Value's from b into a.
pub fn merge_json_mut(a: &mut JsonValue, b: &JsonValue) {
    match (a, b) {
        // Recurse when a and b are both objects.
        (&mut JsonValue::Object(ref mut a), &JsonValue::Object(ref b)) => {
            for (k, v) in b {
                let a_entry = a.entry(k.clone()).or_insert(JsonValue::Null);
                merge_json_mut(a_entry, v);
            }
        }
        // When a and b aren't both objects, overwrite a.
        (a, b) => {
            *a = b.clone();
        }
    }
}
<|endoftext|>


<commit_before>use rand::{SeedableRng, Rng, rngs::SmallRng};

// Having more than 1 test does seem to make a difference
// (i.e., this calls ptr::swap which having just one test does not).
#[test]
fn simple1() {
    assert_eq!(4, 4);
}

#[test]
fn simple2() {
    assert_ne!(42, 24);
}

// A test that won't work on miri (tests disabling tests).
#[test]
#[cfg_attr(miri, ignore)]
fn does_not_work_on_miri() {
    let x = 0u8;
    assert!(&x as *const _ as usize % 4 < 4);
}

// We also use this to test some external crates, that we cannot depend on in the compiletest suite.

#[test]
fn entropy_rng() {
    // Try seeding with "real" entropy.
    let mut rng = SmallRng::from_entropy();
    let _val = rng.gen::<i32>();
    let _val = rng.gen::<isize>();
    let _val = rng.gen::<i128>();

    // Also try per-thread RNG.
    let mut rng = rand::thread_rng();
    let _val = rng.gen::<i32>();
    let _val = rng.gen::<isize>();
    let _val = rng.gen::<i128>();
}

#[test]
fn num_cpus() {
    assert_eq!(num_cpus::get(), 1);
}

// FIXME: Remove this `cfg` once we fix https://github.com/rust-lang/miri/issues/1059.
// We cfg-gate the `should_panic` attribute and the `panic!` itself, so that the test
// stdout does not depend on the target.
#[test]
#[cfg_attr(not(windows), should_panic(expected="Explicit panic"))]
fn do_panic() { // In large, friendly letters :)
    #[cfg(not(windows))]
    panic!("Explicit panic from test!");
}

// FIXME: see above
#[test]
#[allow(unconditional_panic)]
#[cfg_attr(not(windows), should_panic(expected="the len is 0 but the index is 42"))]
fn fail_index_check() {
    #[cfg(not(windows))]
    [][42]
}
<commit_msg>Auto merge of #1546 - Aaron1011:fix/windows-panic, r=RalfJung<commit_after>use rand::{SeedableRng, Rng, rngs::SmallRng};

// Having more than 1 test does seem to make a difference
// (i.e., this calls ptr::swap which having just one test does not).
#[test]
fn simple1() {
    assert_eq!(4, 4);
}

#[test]
fn simple2() {
    assert_ne!(42, 24);
}

// A test that won't work on miri (tests disabling tests).
#[test]
#[cfg_attr(miri, ignore)]
fn does_not_work_on_miri() {
    let x = 0u8;
    assert!(&x as *const _ as usize % 4 < 4);
}

// We also use this to test some external crates, that we cannot depend on in the compiletest suite.

#[test]
fn entropy_rng() {
    // Try seeding with "real" entropy.
    let mut rng = SmallRng::from_entropy();
    let _val = rng.gen::<i32>();
    let _val = rng.gen::<isize>();
    let _val = rng.gen::<i128>();

    // Also try per-thread RNG.
    let mut rng = rand::thread_rng();
    let _val = rng.gen::<i32>();
    let _val = rng.gen::<isize>();
    let _val = rng.gen::<i128>();
}

#[test]
fn num_cpus() {
    assert_eq!(num_cpus::get(), 1);
}

#[test]
#[should_panic(expected="Explicit panic")]
fn do_panic() { // In large, friendly letters :)
    panic!("Explicit panic from test!");
}

#[test]
#[allow(unconditional_panic)]
#[should_panic(expected="the len is 0 but the index is 42")]
fn fail_index_check() {
    [][42]
}
<|endoftext|>


<commit_before>extern crate gooddata_fs;

use gooddata_fs::*;

fn connect() -> gd::GoodDataClient {
    let mut gd = gd::GoodDataClient::new(gooddata_fs::rest::url::SERVER.to_string());
    gd.connect("tomas.korcak+gem_tester@gooddata.com", "jindrisska");
    gd
}

#[test]
fn it_creates_client() {
    let gd = gd::GoodDataClient::new(gooddata_fs::rest::url::SERVER.to_string());
    assert_eq!(gd.projects.is_some(), false);
    assert_eq!(gd.user.is_some(), false);
    assert_eq!(gd.token_updated.is_some(), false);
}

#[test]
fn client_can_connect() {
    let gd = connect();

    assert_eq!(gd.projects.is_some(), false);
    assert_eq!(gd.user.is_some(), true);
    assert_eq!(gd.token_updated.is_some(), true);
}

#[test]
fn client_can_disconnect() {
    let mut gd = connect();
    gd.disconnect();

    assert_eq!(gd.projects.is_some(), false);
    assert_eq!(gd.user.is_some(), false);
    assert_eq!(gd.token_updated.is_some(), false);
}

#[test]
fn client_can_get_projects() {
    let mut gd = connect();
    gd.projects_fetch();

    assert_eq!(gd.projects.is_some(), true);
    assert_eq!(gd.user.is_some(), true);
    assert_eq!(gd.token_updated.is_some(), true);

    gd.disconnect();
}
<commit_msg>Fix tests<commit_after>extern crate gooddata_fs;

use gooddata_fs::*;

fn connect() -> gd::GoodDataClient {
    let mut gd = gd::GoodDataClient::new(gooddata_fs::rest::url::SERVER.to_string(), None);
    gd.connect("tomas.korcak+gem_tester@gooddata.com", "jindrisska");
    gd
}

#[test]
fn it_creates_client() {
    let gd = gd::GoodDataClient::new(gooddata_fs::rest::url::SERVER.to_string(), None);
    assert_eq!(gd.projects.is_some(), false);
    assert_eq!(gd.user.is_some(), false);
    assert_eq!(gd.token_updated.is_some(), false);
}

#[test]
fn client_can_connect() {
    let gd = connect();

    assert_eq!(gd.projects.is_some(), false);
    assert_eq!(gd.user.is_some(), true);
    assert_eq!(gd.token_updated.is_some(), true);
}

#[test]
fn client_can_disconnect() {
    let mut gd = connect();
    gd.disconnect();

    assert_eq!(gd.projects.is_some(), false);
    assert_eq!(gd.user.is_some(), false);
    assert_eq!(gd.token_updated.is_some(), false);
}

#[test]
fn client_can_get_projects() {
    let mut gd = connect();
    gd.projects_fetch();

    assert_eq!(gd.projects.is_some(), true);
    assert_eq!(gd.user.is_some(), true);
    assert_eq!(gd.token_updated.is_some(), true);

    gd.disconnect();
}
<|endoftext|>