<commit_before>use grain_capnp::{PowerboxCapability, UiView, UiSession};
use web_session_capnp::{WebSession};

use collections::hashmap::HashMap;
use capnp::capability::{ClientHook, FromServer};
use capnp::AnyPointer;
use capnp_rpc::rpc::{RpcConnectionState, SturdyRefRestorer};
use capnp_rpc::capability::{LocalClient};

use sqlite3;

pub struct UiViewImpl;

impl PowerboxCapability::Server for UiViewImpl {
    fn get_powerbox_info(&mut self, context : PowerboxCapability::GetPowerboxInfoContext) {
        context.done()
    }
}

impl UiView::Server for UiViewImpl {
    fn get_view_info(&mut self, context : UiView::GetViewInfoContext) {
        context.done()
    }

    fn new_session(&mut self, mut context : UiView::NewSessionContext) {
        println!("asked for a new session!");
        let (_, results) = context.get();

        let client : WebSession::Client = match WebSessionImpl::new() {
            Ok(session) => {
                FromServer::new(None::<LocalClient>, ~session)
            }
            Err(_e) => {
                return context.fail();
            }
        };
        // we need to do this dance to upcast.
        results.set_session(UiSession::Client { client : client.client});

        context.done()
    }
}

pub struct WebSessionImpl {
    db : sqlite3::Database,
}

impl WebSessionImpl {
    pub fn new() -> sqlite3::SqliteResult<WebSessionImpl> {
        let db = try!(sqlite3::open("/var/data.db"));
        db.set_busy_timeout(1000); // try for a least a second
        Ok(WebSessionImpl {
            db : db,
        })
    }
}

impl UiSession::Server for WebSessionImpl {

}

impl WebSessionImpl {

    fn is_word(&self, word : &str) -> sqlite3::SqliteResult<bool> {

        if ! word.is_alphanumeric() { return Ok(false); }

        let cursor = try!(self.db.prepare(
            format!("SELECT * FROM Words WHERE Word = \"{}\";", word),
            &None));

        return Ok(try!(cursor.step_row()).is_some());
    }

    fn validate_def(&self, word : &str, definition : &[&str]) -> sqlite3::SqliteResult<bool> {

        if definition.len() != word.len() { return Ok(false); }

        let mut idx = 0;
        for &d in definition.iter() {
            if !(try!(self.is_word(d)) && d.len() > 0 && d[0] == word[idx]) {
                return Ok(false);
            }

            idx += 1;
        }

        return Ok(true);
    }

    fn write_def(&self, word : &str, definition : &[&str]) -> sqlite3::SqliteResult<()> {

        let time : i64 = ::time::get_time().sec;
        let mut query = StrBuf::new();
        query.push_str(format!("BEGIN; DELETE FROM Definitions WHERE Definee =\"{}\"; ", word));
        query.push_str("INSERT INTO Definitions(Definee, Idx, Definer) VALUES");
        let mut idx = 0;
        for &d in definition.iter() {
            if idx != 0 { query.push_str(","); }
            query.push_str(format!("(\"{}\", {}, \"{}\")", word, idx, d));
            idx += 1;
        }
        query.push_str(";");
        query.push_str(format!("DELETE FROM Log WHERE Word=\"{}\";", word));
        query.push_str(format!("INSERT INTO Log(Word, Timestamp) VALUES(\"{}\",{});", word, time));
        query.push_str("COMMIT;");

        println!("query: {}", query);

        try!(self.db.exec(query.as_slice()));

        return Ok(());
    }

    fn get_def(&self, word : &str) -> sqlite3::SqliteResult<~str> {

        let cursor = try!(self.db.prepare(
            format!("SELECT * FROM Definitions WHERE Definee = \"{}\";", word),
            &None));

        let mut map = HashMap::<int, ~str>::new();

        loop {
            match try!(cursor.step_row()) {
                None => break,
                Some(row) => {
                    let definer = match row.get(&~"Definer") { &sqlite3::Text(ref t) => t.clone(), _ => fail!(), };
                    let idx = match row.get(&~"Idx") { &sqlite3::Integer(ref i) => i.clone(), _ => fail!(), };

                    map.insert(idx, definer);
                }
            }
        }

        if map.len() != word.len() {
            return Ok(~"
this word has no definition yet
");
        } else {

            let mut result = StrBuf::new();
            result.push_str("
");
            for idx in range::<int>(0, word.len() as int) {
                let definer : &str = map.get(&idx).as_slice();
                result.push_str(format!(" {word} ", word=definer));
            }
            result.push_str("
");
            return Ok(result.into_owned());
        }
    }

    fn count_defs(&self) -> sqlite3::SqliteResult<(int, int, Vec<~str>)> {
        let cursor = try!(self.db.prepare("SELECT COUNT(*) FROM Words;", &None));
        assert!(cursor.step() == sqlite3::SQLITE_ROW);
        let num_words = cursor.get_int(0);

        let cursor = try!(self.db.prepare("SELECT COUNT(*) FROM Definitions WHERE Idx = 0;", &None));
        assert!(cursor.step() == sqlite3::SQLITE_ROW);
        let defined_words = cursor.get_int(0);

        let mut recent_words = Vec::new();
        let cursor = try!(
            self.db.prepare("SELECT Word, Timestamp FROM Log ORDER BY Timestamp DESC LIMIT 5;", &None));
        loop {
            match try!(cursor.step_row()) {
                None => break,
                Some(row) => {
                    let word : ~str = match row.get(&~"Word") {&sqlite3::Text(ref t) => t.clone(), _ => fail!(),};
                    recent_words.push(word);
                }
            }
        }
        Ok((defined_words, num_words, recent_words))

    }

    fn construct_page_data(&self, path : &::url::Path) -> sqlite3::SqliteResult<PageData> {
        if path.path.as_slice() == "define" {

            let mut query_map = HashMap::<~str, ~str>::new();
            for &(ref k, ref v) in path.query.iter() {
                query_map.insert(k.clone(), v.clone());
            }

            let word : ~str = match query_map.find(&~"word") {
                Some(w) if try!(self.is_word(*w)) => {
                    w.clone()
                }
                _ => {
                    return Ok(Error(~"that's not a word"))
                }
            };

            match query_map.find(&~"definition") {
                None => {
                    let def_div = try!(self.get_def(word));

                    return Ok(WordAndDef(word, def_div, None));
                }
                Some(def_query) => {

                    let definition : ~[&str] = def_query.split('+').collect();

                    if try!(self.validate_def(word, definition)) {

                        try!(self.write_def(word, definition));
                        let def_div = try!(self.get_def(word));
                        return Ok(WordAndDef(word,
                                             def_div,
                                             None));
                    } else {
                        let def_div = try!(self.get_def(word));
                        return Ok(WordAndDef(word, def_div, Some(~"invalid definition")))
                    }
                }
            }

        } else {
            let (num_defined, total, recent) = try!(self.count_defs());
            return Ok(HomePage(num_defined, total, recent));
        }
    }

}

static main_css : &'static str =
    "body { font-family: Helvetica, Sans, Arial;
            font-size: medium;
             margin-left: auto;
             margin-right: auto;
             width: 600px;
             text-align: center;
     }
     div {
          padding-bottom: 10pt;
     }
    .word {
        text-align: center;
        font-size: 500%;
     }
     .err {
       font-size: 90%;
       color: #AA0000;
     }
     .title {
       text-align: center;
       font-size:500%;
     }
     ";

static header : &'static str =
  r#"<title> acronymy </title><link rel="stylesheet" type="text/css" href="main.css" >
 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
  "#;

static lookup_form : &'static str =
      r#"<form action="define" method="get">
          <input name="word" maxlength="100"/><button>find word</button></form>"#;

fn define_form(word :&str) -> ~str {
       format!("<form action=\"define\" method=\"get\">
               <input name=\"word\" value=\"{word}\" type=\"hidden\"/>
               <input name=\"definition\" maxlength=\"2000\"/>
                   <button>submit definition</button></form>", word=word)
}

enum PageData {
    Error(~str),
    WordAndDef(~str, ~str, Option<~str>),
    HomePage(int, int, Vec<~str>),
}

fn construct_html(page_data : PageData) -> ~str {
    let mut result = StrBuf::new();
    result.push_str(format!("{}", header));

    static home_link : &'static str = "home";
    match page_data {
        Error(e) => {
            result.push_str(format!("
 {}
", e));
            result.push_str(lookup_form);
            result.push_str(home_link);
        }
        WordAndDef(word, def_div, err) => {
            result.push_str(format!("
{}
", word));

            result.push_str(def_div);

            match err {
                None => {}
                Some(e) => {
                    result.push_str(format!("
{}
", e));
                }
            }

            result.push_str(define_form(word));
            result.push_str(home_link);
        }
        HomePage(num_defined, total, recent) => {
            result.push_str("
Acronymy
");
            result.push_str("
A user-editable, acronym-only dictionary.
");
            result.push_str(format!("
So far, we have defined {} out of {} words.
",
                                    num_defined, total));
            if recent.len() > 0 {
                result.push_str("
Recently modified words: ");
                let mut idx = 0;
                for w in recent.iter() {
                    if idx != 0 {
                        result.push_str(", ");
                    }
                    result.push_str(format!("{word}", word=*w));
                    idx += 1;
                }
                result.push_str(".
");
            }
            result.push_str(lookup_form);
        }
    }

    result.push_str("");
    result.into_owned()
}

impl WebSession::Server for WebSessionImpl {
    fn get(&mut self, mut context : WebSession::GetContext) {
        println!("GET");
        let (params, results) = context.get();
        let raw_path = params.get_path();
        let content = results.init_content();
        content.set_mime_type("text/html");

        let path = match ::url::path_from_str(raw_path) {
            Err(_e) => ::url::Path::new("".to_owned(), Vec::new(), None),
            Ok(p) => p,
        };

        println!("path = {}", raw_path);

        if raw_path == "main.css" {
            content.get_body().set_bytes(main_css.as_bytes())
        } else {
            let page_data = match self.construct_page_data(&path) {
                Err(e) => { Error(format!("database error: {} ({})", e, self.db.get_errmsg())) }
                Ok(page_data) => { page_data }
            };
            content.get_body().set_bytes(construct_html(page_data).as_bytes());
        }
        context.done()
    }
    fn post(&mut self, context : WebSession::PostContext) {
        println!("POST");
        context.done()
    }
    fn put(&mut self, context : WebSession::PutContext) {
        println!("PUT");
        context.done()
    }
    fn delete(&mut self, context : WebSession::DeleteContext) {
        println!("DELETE");
        context.done()
    }
    fn open_web_socket(&mut self, context : WebSession::OpenWebSocketContext) {
        println!("OPEN WEB SOCKET");
        context.done()
    }
}

pub struct FdStream {
    inner : ~::std::rt::rtio::RtioFileStream:Send,
}

impl FdStream {
    pub fn new(fd : ::libc::c_int) -> ::std::io::IoResult<FdStream> {
        ::std::rt::rtio::LocalIo::maybe_raise(|io| {
            Ok (FdStream { inner : io.fs_from_raw_fd(fd, ::std::rt::rtio::DontClose) })
        })
    }
}

impl Reader for FdStream {
    fn read(&mut self, buf : &mut [u8]) -> ::std::io::IoResult<uint> {
        self.inner.read(buf).map(|i| i as uint)
    }
}

impl Writer for FdStream {
    fn write(&mut self, buf : &[u8]) -> ::std::io::IoResult<()> {
        self.inner.write(buf)
    }
}

pub struct Restorer;

impl SturdyRefRestorer for Restorer {
    fn restore(&self, obj_id : AnyPointer::Reader) -> Option<~ClientHook:Send> {
        if obj_id.is_null() {
            let client : UiView::Client = FromServer::new(None::<LocalClient>, ~UiViewImpl);
            Some(client.client.hook)
        } else {
            None
        }
    }
}

pub fn main() -> ::std::io::IoResult<()> {

    let args = ::std::os::args();

    if args.len() == 4 && args[1].as_slice() == "--init" {
        println!("initializing...");
        let initdb_path = ::std::path::Path::new(args[2].as_slice());
        let proddb_path = ::std::path::Path::new(args[3].as_slice());
        println!("copying database from {} to {}", args[2], args[3]);
        try!(::std::io::fs::copy(&initdb_path, &proddb_path));
        println!("success!");
    }

    // sandstorm launches us with a connection file descriptor 3
    let ifs = try!(FdStream::new(3));
    let ofs = try!(FdStream::new(3));

    let connection_state = RpcConnectionState::new();
    connection_state.run(ifs, ofs, Restorer);

    Ok(())
}

<commit_msg>detilde<commit_after>use grain_capnp::{PowerboxCapability, UiView, UiSession};
use web_session_capnp::{WebSession};

use collections::hashmap::HashMap;
use capnp::capability::{ClientHook, FromServer};
use capnp::AnyPointer;
use capnp_rpc::rpc::{RpcConnectionState, SturdyRefRestorer};
use capnp_rpc::capability::{LocalClient};

use sqlite3;

pub struct UiViewImpl;

impl PowerboxCapability::Server for UiViewImpl {
    fn get_powerbox_info(&mut self, context : PowerboxCapability::GetPowerboxInfoContext) {
        context.done()
    }
}

impl UiView::Server for UiViewImpl {
    fn get_view_info(&mut self, context : UiView::GetViewInfoContext) {
        context.done()
    }

    fn new_session(&mut self, mut context : UiView::NewSessionContext) {
        println!("asked for a new session!");
        let (_, results) = context.get();

        let client : WebSession::Client = match WebSessionImpl::new() {
            Ok(session) => {
                FromServer::new(None::<LocalClient>, box session)
            }
            Err(_e) => {
                return context.fail();
            }
        };
        // we need to do this dance to upcast.
        results.set_session(UiSession::Client { client : client.client});

        context.done()
    }
}

pub struct WebSessionImpl {
    db : sqlite3::Database,
}

impl WebSessionImpl {
    pub fn new() -> sqlite3::SqliteResult<WebSessionImpl> {
        let db = try!(sqlite3::open("/var/data.db"));
        db.set_busy_timeout(1000); // try for a least a second
        Ok(WebSessionImpl {
            db : db,
        })
    }
}

impl UiSession::Server for WebSessionImpl {

}

impl WebSessionImpl {

    fn is_word(&self, word : &str) -> sqlite3::SqliteResult<bool> {

        if ! word.is_alphanumeric() { return Ok(false); }

        let cursor = try!(self.db.prepare(
            format!("SELECT * FROM Words WHERE Word = \"{}\";", word),
            &None));

        return Ok(try!(cursor.step_row()).is_some());
    }

    fn validate_def(&self, word : &str, definition : &[&str]) -> sqlite3::SqliteResult<bool> {

        if definition.len() != word.len() { return Ok(false); }

        let mut idx = 0;
        for &d in definition.iter() {
            if !(try!(self.is_word(d)) && d.len() > 0 && d[0] == word[idx]) {
                return Ok(false);
            }

            idx += 1;
        }

        return Ok(true);
    }

    fn write_def(&self, word : &str, definition : &[&str]) -> sqlite3::SqliteResult<()> {

        let time : i64 = ::time::get_time().sec;
        let mut query = StrBuf::new();
        query.push_str(format!("BEGIN; DELETE FROM Definitions WHERE Definee =\"{}\"; ", word));
        query.push_str("INSERT INTO Definitions(Definee, Idx, Definer) VALUES");
        let mut idx = 0;
        for &d in definition.iter() {
            if idx != 0 { query.push_str(","); }
            query.push_str(format!("(\"{}\", {}, \"{}\")", word, idx, d));
            idx += 1;
        }
        query.push_str(";");
        query.push_str(format!("DELETE FROM Log WHERE Word=\"{}\";", word));
        query.push_str(format!("INSERT INTO Log(Word, Timestamp) VALUES(\"{}\",{});", word, time));
        query.push_str("COMMIT;");

        println!("query: {}", query);

        try!(self.db.exec(query.as_slice()));

        return Ok(());
    }

    fn get_def(&self, word : &str) -> sqlite3::SqliteResult<~str> {

        let cursor = try!(self.db.prepare(
            format!("SELECT * FROM Definitions WHERE Definee = \"{}\";", word),
            &None));

        let mut map = HashMap::<int, ~str>::new();

        loop {
            match try!(cursor.step_row()) {
                None => break,
                Some(row) => {
                    let definer = match row.get(&"Definer".to_owned()) { &sqlite3::Text(ref t) => t.clone(), _ => fail!(), };
                    let idx = match row.get(&"Idx".to_owned()) { &sqlite3::Integer(ref i) => i.clone(), _ => fail!(), };

                    map.insert(idx, definer);
                }
            }
        }

        if map.len() != word.len() {
            return Ok("
this word has no definition yet
".to_owned());
        } else {

            let mut result = StrBuf::new();
            result.push_str("
");
            for idx in range::<int>(0, word.len() as int) {
                let definer : &str = map.get(&idx).as_slice();
                result.push_str(format!(" {word} ", word=definer));
            }
            result.push_str("
");
            return Ok(result.into_owned());
        }
    }

    fn count_defs(&self) -> sqlite3::SqliteResult<(int, int, Vec<~str>)> {
        let cursor = try!(self.db.prepare("SELECT COUNT(*) FROM Words;", &None));
        assert!(cursor.step() == sqlite3::SQLITE_ROW);
        let num_words = cursor.get_int(0);

        let cursor = try!(self.db.prepare("SELECT COUNT(*) FROM Definitions WHERE Idx = 0;", &None));
        assert!(cursor.step() == sqlite3::SQLITE_ROW);
        let defined_words = cursor.get_int(0);

        let mut recent_words = Vec::new();
        let cursor = try!(
            self.db.prepare("SELECT Word, Timestamp FROM Log ORDER BY Timestamp DESC LIMIT 5;", &None));
        loop {
            match try!(cursor.step_row()) {
                None => break,
                Some(row) => {
                    let word : ~str = match row.get(&"Word".to_owned()) {&sqlite3::Text(ref t) => t.clone(), _ => fail!(),};
                    recent_words.push(word);
                }
            }
        }
        Ok((defined_words, num_words, recent_words))

    }

    fn construct_page_data(&self, path : &::url::Path) -> sqlite3::SqliteResult<PageData> {
        if path.path.as_slice() == "define" {

            let mut query_map = HashMap::<~str, ~str>::new();
            for &(ref k, ref v) in path.query.iter() {
                query_map.insert(k.clone(), v.clone());
            }

            let word : ~str = match query_map.find(&"word".to_owned()) {
                Some(w) if try!(self.is_word(*w)) => {
                    w.clone()
                }
                _ => {
                    return Ok(Error("that's not a word".to_owned()))
                }
            };

            match query_map.find(&"definition".to_owned()) {
                None => {
                    let def_div = try!(self.get_def(word));

                    return Ok(WordAndDef(word, def_div, None));
                }
                Some(def_query) => {

                    let definition : ~[&str] = def_query.split('+').collect();

                    if try!(self.validate_def(word, definition)) {

                        try!(self.write_def(word, definition));
                        let def_div = try!(self.get_def(word));
                        return Ok(WordAndDef(word,
                                             def_div,
                                             None));
                    } else {
                        let def_div = try!(self.get_def(word));
                        return Ok(WordAndDef(word, def_div, Some("invalid definition".to_owned())))
                    }
                }
            }

        } else {
            let (num_defined, total, recent) = try!(self.count_defs());
            return Ok(HomePage(num_defined, total, recent));
        }
    }

}

static main_css : &'static str =
    "body { font-family: Helvetica, Sans, Arial;
            font-size: medium;
             margin-left: auto;
             margin-right: auto;
             width: 600px;
             text-align: center;
     }
     div {
          padding-bottom: 10pt;
     }
    .word {
        text-align: center;
        font-size: 500%;
     }
     .err {
       font-size: 90%;
       color: #AA0000;
     }
     .title {
       text-align: center;
       font-size:500%;
     }
     ";

static header : &'static str =
  r#"<title> acronymy </title><link rel="stylesheet" type="text/css" href="main.css" >
 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
  "#;

static lookup_form : &'static str =
      r#"<form action="define" method="get">
          <input name="word" maxlength="100"/><button>find word</button></form>"#;

fn define_form(word :&str) -> ~str {
       format!("<form action=\"define\" method=\"get\">
               <input name=\"word\" value=\"{word}\" type=\"hidden\"/>
               <input name=\"definition\" maxlength=\"2000\"/>
                   <button>submit definition</button></form>", word=word)
}

enum PageData {
    Error(~str),
    WordAndDef(~str, ~str, Option<~str>),
    HomePage(int, int, Vec<~str>),
}

fn construct_html(page_data : PageData) -> ~str {
    let mut result = StrBuf::new();
    result.push_str(format!("{}", header));

    static home_link : &'static str = "home";
    match page_data {
        Error(e) => {
            result.push_str(format!("
 {}
", e));
            result.push_str(lookup_form);
            result.push_str(home_link);
        }
        WordAndDef(word, def_div, err) => {
            result.push_str(format!("
{}
", word));

            result.push_str(def_div);

            match err {
                None => {}
                Some(e) => {
                    result.push_str(format!("
{}
", e));
                }
            }

            result.push_str(define_form(word));
            result.push_str(home_link);
        }
        HomePage(num_defined, total, recent) => {
            result.push_str("
Acronymy
");
            result.push_str("
A user-editable, acronym-only dictionary.
");
            result.push_str(format!("
So far, we have defined {} out of {} words.
",
                                    num_defined, total));
            if recent.len() > 0 {
                result.push_str("
Recently modified words: ");
                let mut idx = 0;
                for w in recent.iter() {
                    if idx != 0 {
                        result.push_str(", ");
                    }
                    result.push_str(format!("{word}", word=*w));
                    idx += 1;
                }
                result.push_str(".
");
            }
            result.push_str(lookup_form);
        }
    }

    result.push_str("");
    result.into_owned()
}

impl WebSession::Server for WebSessionImpl {
    fn get(&mut self, mut context : WebSession::GetContext) {
        println!("GET");
        let (params, results) = context.get();
        let raw_path = params.get_path();
        let content = results.init_content();
        content.set_mime_type("text/html");

        let path = match ::url::path_from_str(raw_path) {
            Err(_e) => ::url::Path::new("".to_owned(), Vec::new(), None),
            Ok(p) => p,
        };

        println!("path = {}", raw_path);

        if raw_path == "main.css" {
            content.get_body().set_bytes(main_css.as_bytes())
        } else {
            let page_data = match self.construct_page_data(&path) {
                Err(e) => { Error(format!("database error: {} ({})", e, self.db.get_errmsg())) }
                Ok(page_data) => { page_data }
            };
            content.get_body().set_bytes(construct_html(page_data).as_bytes());
        }
        context.done()
    }
    fn post(&mut self, context : WebSession::PostContext) {
        println!("POST");
        context.done()
    }
    fn put(&mut self, context : WebSession::PutContext) {
        println!("PUT");
        context.done()
    }
    fn delete(&mut self, context : WebSession::DeleteContext) {
        println!("DELETE");
        context.done()
    }
    fn open_web_socket(&mut self, context : WebSession::OpenWebSocketContext) {
        println!("OPEN WEB SOCKET");
        context.done()
    }
}

pub struct FdStream {
    inner : Box<::std::rt::rtio::RtioFileStream:Send>,
}

impl FdStream {
    pub fn new(fd : ::libc::c_int) -> ::std::io::IoResult<FdStream> {
        ::std::rt::rtio::LocalIo::maybe_raise(|io| {
            Ok (FdStream { inner : io.fs_from_raw_fd(fd, ::std::rt::rtio::DontClose) })
        })
    }
}

impl Reader for FdStream {
    fn read(&mut self, buf : &mut [u8]) -> ::std::io::IoResult<uint> {
        self.inner.read(buf).map(|i| i as uint)
    }
}

impl Writer for FdStream {
    fn write(&mut self, buf : &[u8]) -> ::std::io::IoResult<()> {
        self.inner.write(buf)
    }
}

pub struct Restorer;

impl SturdyRefRestorer for Restorer {
    fn restore(&self, obj_id : AnyPointer::Reader) -> Option<Box<ClientHook:Send>> {
        if obj_id.is_null() {
            let client : UiView::Client = FromServer::new(None::<LocalClient>, box UiViewImpl);
            Some(client.client.hook)
        } else {
            None
        }
    }
}

pub fn main() -> ::std::io::IoResult<()> {

    let args = ::std::os::args();

    if args.len() == 4 && args[1].as_slice() == "--init" {
        println!("initializing...");
        let initdb_path = ::std::path::Path::new(args[2].as_slice());
        let proddb_path = ::std::path::Path::new(args[3].as_slice());
        println!("copying database from {} to {}", args[2], args[3]);
        try!(::std::io::fs::copy(&initdb_path, &proddb_path));
        println!("success!");
    }

    // sandstorm launches us with a connection file descriptor 3
    let ifs = try!(FdStream::new(3));
    let ofs = try!(FdStream::new(3));

    let connection_state = RpcConnectionState::new();
    connection_state.run(ifs, ofs, Restorer);

    Ok(())
}

<|endoftext|>


<commit_before>use std::ptr;
use super::gl_lib as gl;
use super::gl_lib::types::*;
use super::context::Context;
use super::types::GLError;

pub struct Shader {
    gl_id: GLuint
}

impl Shader {
    pub fn gl_id(&self) -> GLuint {
        self.gl_id
    }
}

impl Drop for Shader {
    fn drop(&mut self) {
        unsafe {
            gl::DeleteShader(self.gl_id);
        }
    }
}

unsafe fn _get_shader_iv(shader: &Shader,
                         pname: GLenum,
                         params: *mut GLint)
{
    gl::GetShaderiv(shader.gl_id(), pname, params);
    dbg_gl_sanity_check! {
        GLError::InvalidEnum => "`pname` is not an accepted value",
        GLError::InvalidValue => "`shader` is not a value generated by OpenGL",
        GLError::InvalidOperation => "`shader` is not a shader object, or `pname` is GL_COMPILE_STATUS, GL_INFO_LOG_LENGTH or GL_SHADER_SOURCE_LENGTH but a shader compiler is not supported",
        _ => "Unknown error"
    }
}

impl Context {
    pub fn create_shader(&self, shader_type: ShaderType) -> Result<Shader, ()> {
        unsafe {
            let id = gl::CreateShader(shader_type as GLenum);
            dbg_gl_sanity_check! {
                GLError::InvalidEnum => "`shaderType` is not an accepted value",
                _ => "Unknown error"
            }
            if id > 0 {
                Ok(Shader { gl_id: id })
            }
            else {
                Err(())
            }
        }
    }

    pub fn shader_source(&self, shader: &mut Shader, source: &str) {
        unsafe {
            let source_ptr = source.as_ptr() as *const GLchar;
            let source_len = source.len() as GLint;

            gl::ShaderSource(shader.gl_id(), 1,
                             &source_ptr as *const *const GLchar,
                             &source_len as *const GLint);
            dbg_gl_error! {
                GLError::InvalidOperation => "`shader` is not a shader object or shader compiler is not supported",
                GLError::InvalidValue => "`shader` is not a value generated by OpenGL or `count` < 0",
                _ => "Unknown error"
            }
        }
    }

    pub fn compile_shader(&self, shader: &mut Shader) -> Result<(), GLError> {
        let success = unsafe {
            gl::CompileShader(shader.gl_id());
            dbg_gl_error! {
                GLError::InvalidOperation => "`shader` is not a shader object or shader compiler is not supported",
                GLError::InvalidValue => "`shader` is not a value generated by OpenGL",
                _ => "Unknown error"
            }

            let mut compile_status : GLint = 0;
            _get_shader_iv(shader,
                           gl::COMPILE_STATUS,
                           &mut compile_status as *mut GLint);

            compile_status == gl::TRUE as GLint
        };

        if success {
            Ok(())
        }
        else {
            unsafe {
                let mut info_length : GLint = 0;
                _get_shader_iv(shader,
                               gl::INFO_LOG_LENGTH,
                               &mut info_length as *mut GLint);

                let mut bytes = Vec::<u8>::with_capacity(info_length as usize);

                gl::GetShaderInfoLog(shader.gl_id(),
                                     info_length,
                                     ptr::null_mut(),
                                     bytes.as_mut_ptr() as *mut GLchar);
                dbg_gl_sanity_check! {
                    GLError::InvalidValue => "`shader` is not a value generated by OpenGL, or `maxLength` < 0",
                    GLError::InvalidOperation => "`shader` is not a shader object",
                    _ => "Unknown error"
                }

                bytes.set_len((info_length - 1) as usize);

                let msg = String::from_utf8(bytes)
                                 .unwrap_or(String::from("<Unknown error>"));

                Err(GLError::Message(msg))
            }
        }
    }
}

#[derive(Debug, Clone, Copy)]
#[allow(non_camel_case_types)]
pub enum ShaderType {
    VERTEX_SHADER = gl::VERTEX_SHADER as isize,
    FRAGMENT_SHADER = gl::FRAGMENT_SHADER as isize
}
pub use self::ShaderType::*;
<commit_msg>Add `Context.get_shader_info_log()`<commit_after>use std::ptr;
use super::gl_lib as gl;
use super::gl_lib::types::*;
use super::context::Context;
use super::types::GLError;

pub struct Shader {
    gl_id: GLuint
}

impl Shader {
    pub fn gl_id(&self) -> GLuint {
        self.gl_id
    }
}

impl Drop for Shader {
    fn drop(&mut self) {
        unsafe {
            gl::DeleteShader(self.gl_id);
        }
    }
}

unsafe fn _get_shader_iv(shader: &Shader,
                         pname: GLenum,
                         params: *mut GLint)
{
    gl::GetShaderiv(shader.gl_id(), pname, params);
    dbg_gl_sanity_check! {
        GLError::InvalidEnum => "`pname` is not an accepted value",
        GLError::InvalidValue => "`shader` is not a value generated by OpenGL",
        GLError::InvalidOperation => "`shader` is not a shader object, or `pname` is GL_COMPILE_STATUS, GL_INFO_LOG_LENGTH or GL_SHADER_SOURCE_LENGTH but a shader compiler is not supported",
        _ => "Unknown error"
    }
}

impl Context {
    pub fn create_shader(&self, shader_type: ShaderType) -> Result<Shader, ()> {
        unsafe {
            let id = gl::CreateShader(shader_type as GLenum);
            dbg_gl_sanity_check! {
                GLError::InvalidEnum => "`shaderType` is not an accepted value",
                _ => "Unknown error"
            }
            if id > 0 {
                Ok(Shader { gl_id: id })
            }
            else {
                Err(())
            }
        }
    }

    pub fn shader_source(&self, shader: &mut Shader, source: &str) {
        unsafe {
            let source_ptr = source.as_ptr() as *const GLchar;
            let source_len = source.len() as GLint;

            gl::ShaderSource(shader.gl_id(), 1,
                             &source_ptr as *const *const GLchar,
                             &source_len as *const GLint);
            dbg_gl_error! {
                GLError::InvalidOperation => "`shader` is not a shader object or shader compiler is not supported",
                GLError::InvalidValue => "`shader` is not a value generated by OpenGL or `count` < 0",
                _ => "Unknown error"
            }
        }
    }

    pub fn compile_shader(&self, shader: &mut Shader) -> Result<(), GLError> {
        let success = unsafe {
            gl::CompileShader(shader.gl_id());
            dbg_gl_error! {
                GLError::InvalidOperation => "`shader` is not a shader object or shader compiler is not supported",
                GLError::InvalidValue => "`shader` is not a value generated by OpenGL",
                _ => "Unknown error"
            }

            let mut compile_status : GLint = 0;
            _get_shader_iv(shader,
                           gl::COMPILE_STATUS,
                           &mut compile_status as *mut GLint);

            compile_status == gl::TRUE as GLint
        };

        if success {
            Ok(())
        }
        else {
            let msg = match self.get_shader_info_log(&shader) {
                Some(s) => { s },
                None => { String::from("[Unknown shader error]") }
            };
            Err(GLError::Message(msg))
        }
    }

    pub fn get_shader_info_log(&self, shader: &Shader) -> Option<String> {
        unsafe {
            let mut info_length : GLint = 0;
            _get_shader_iv(shader,
                           gl::INFO_LOG_LENGTH,
                           &mut info_length as *mut GLint);

            if info_length > 0 {
                let mut bytes = Vec::<u8>::with_capacity(info_length as usize);

                gl::GetShaderInfoLog(shader.gl_id(),
                                     info_length,
                                     ptr::null_mut(),
                                     bytes.as_mut_ptr() as *mut GLchar);
                dbg_gl_sanity_check! {
                    GLError::InvalidValue => "`shader` is not a value generated by OpenGL, or `maxLength` < 0",
                    GLError::InvalidOperation => "`shader` is not a shader object",
                    _ => "Unknown error"
                }

                bytes.set_len((info_length - 1) as usize);

                String::from_utf8(bytes).ok()
            }
            else {
                None
            }
        }
    }
}

#[derive(Debug, Clone, Copy)]
#[allow(non_camel_case_types)]
pub enum ShaderType {
    VERTEX_SHADER = gl::VERTEX_SHADER as isize,
    FRAGMENT_SHADER = gl::FRAGMENT_SHADER as isize
}
pub use self::ShaderType::*;
<|endoftext|>


<commit_before>use std::ops::Deref;
use syntax::ast::*;
use syntax::codemap::Span;
use syntax::visit::FnKind;

use rustc::lint::{Context, LintArray, LintPass};
use rustc::middle::def::Def::{DefVariant, DefStruct};

use utils::{in_external_macro, snippet, span_lint, span_note_and_lint};

declare_lint!(pub SHADOW_SAME, Allow,
    "rebinding a name to itself, e.g. `let mut x = &mut x`");
declare_lint!(pub SHADOW_REUSE, Allow,
    "rebinding a name to an expression that re-uses the original value, e.g. \
    `let x = x + 1`");
declare_lint!(pub SHADOW_UNRELATED, Warn,
    "The name is re-bound without even using the original value");

#[derive(Copy, Clone)]
pub struct ShadowPass;

impl LintPass for ShadowPass {
    fn get_lints(&self) -> LintArray {
        lint_array!(SHADOW_SAME, SHADOW_REUSE, SHADOW_UNRELATED)
    }

    fn check_fn(&mut self, cx: &Context, _: FnKind, decl: &FnDecl,
            block: &Block, _: Span, _: NodeId) {
        if in_external_macro(cx, block.span) { return; }
        check_fn(cx, decl, block);
    }
}

fn check_fn(cx: &Context, decl: &FnDecl, block: &Block) {
    let mut bindings = Vec::new();
    for arg in &decl.inputs {
        if let PatIdent(_, ident, _) = arg.pat.node {
            bindings.push(ident.node.name)
        }
    }
    check_block(cx, block, &mut bindings);
}

fn check_block(cx: &Context, block: &Block, bindings: &mut Vec<Name>) {
    let len = bindings.len();
    for stmt in &block.stmts {
        match stmt.node {
            StmtDecl(ref decl, _) => check_decl(cx, decl, bindings),
            StmtExpr(ref e, _) | StmtSemi(ref e, _) =>
                check_expr(cx, e, bindings),
            _ => ()
        }
    }
    if let Some(ref o) = block.expr { check_expr(cx, o, bindings); }
    bindings.truncate(len);
}

fn check_decl(cx: &Context, decl: &Decl, bindings: &mut Vec<Name>) {
    if in_external_macro(cx, decl.span) { return; }
    if let DeclLocal(ref local) = decl.node {
        let Local{ ref pat, ref ty, ref init, id: _, span } = **local;
        if let &Some(ref t) = ty { check_ty(cx, t, bindings) }
        if let &Some(ref o) = init {
            check_expr(cx, o, bindings);
            check_pat(cx, pat, &Some(o), span, bindings);
        } else {
            check_pat(cx, pat, &None, span, bindings);
        }
    }
}

fn is_binding(cx: &Context, pat: &Pat) -> bool {
    match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
        Some(DefVariant(..)) | Some(DefStruct(..)) => false,
        _ => true
    }
}

fn check_pat(cx: &Context, pat: &Pat, init: &Option<&Expr>, span: Span,
        bindings: &mut Vec<Name>) {
    //TODO: match more stuff / destructuring
    match pat.node {
        PatIdent(_, ref ident, ref inner) => {
            let name = ident.node.name;
            if is_binding(cx, pat) {
                if bindings.contains(&name) {
                    lint_shadow(cx, name, span, pat.span, init);
                } else {
                    bindings.push(name);
                }
            }
            if let Some(ref p) = *inner { check_pat(cx, p, init, span, bindings); }
        },
        //PatEnum(Path, Option<Vec<P<Pat>>>),
        PatStruct(_, ref pfields, _) =>
            if let Some(ref init_struct) = *init {
                if let ExprStruct(_, ref efields, _) = init_struct.node {
                    for field in pfields {
                        let ident = field.node.ident;
                        let efield = efields.iter()
                            .find(|ref f| f.ident.node == ident)
                            .map(|f| &*f.expr);
                        check_pat(cx, &field.node.pat, &efield, span, bindings);
                    }
                } else {
                    for field in pfields {
                        check_pat(cx, &field.node.pat, init, span, bindings);
                    }
                }
            } else {
                for field in pfields {
                    check_pat(cx, &field.node.pat, &None, span, bindings);
                }
            },
        PatTup(ref inner) =>
            if let Some(ref init_tup) = *init {
                if let ExprTup(ref tup) = init_tup.node {
                    for (i, p) in inner.iter().enumerate() {
                        check_pat(cx, p, &Some(&tup[i]), p.span, bindings);
                    }
                } else {
                    for p in inner {
                        check_pat(cx, p, init, span, bindings);
                    }
                }
            } else {
                for p in inner {
                    check_pat(cx, p, &None, span, bindings);
                }
            },
        PatBox(ref inner) => {
            if let Some(ref initp) = *init {
                if let ExprBox(_, ref inner_init) = initp.node {
                    check_pat(cx, inner, &Some(&**inner_init), span, bindings);
                } else {
                    check_pat(cx, inner, init, span, bindings);
                }
            } else {
                check_pat(cx, inner, init, span, bindings);
            }
        },
        PatRegion(ref inner, _) =>
            check_pat(cx, inner, init, span, bindings),
        //PatRange(P<Expr>, P<Expr>),
        //PatVec(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>),
        _ => (),
    }
}

fn lint_shadow<T>(cx: &Context, name: Name, span: Span, lspan: Span, init:
        &Option<T>) where T: Deref<Target=Expr> {
    if let Some(ref expr) = *init {
        if is_self_shadow(name, expr) {
            span_lint(cx, SHADOW_SAME, span, &format!(
                "{} is shadowed by itself in {}",
                snippet(cx, lspan, "_"),
                snippet(cx, expr.span, "..")));
        } else {
            if contains_self(name, expr) {
                span_note_and_lint(cx, SHADOW_REUSE, lspan, &format!(
                    "{} is shadowed by {} which reuses the original value",
                    snippet(cx, lspan, "_"),
                    snippet(cx, expr.span, "..")),
                    expr.span, "initialization happens here");
            } else {
                span_note_and_lint(cx, SHADOW_UNRELATED, lspan, &format!(
                    "{} is shadowed by {}",
                    snippet(cx, lspan, "_"),
                    snippet(cx, expr.span, "..")),
                    expr.span, "initialization happens here");
            }
        }
    } else {
        span_lint(cx, SHADOW_UNRELATED, span, &format!(
            "{} shadows a previous declaration", snippet(cx, lspan, "_")));
    }
}

fn check_expr(cx: &Context, expr: &Expr, bindings: &mut Vec<Name>) {
    if in_external_macro(cx, expr.span) { return; }
    match expr.node {
        ExprUnary(_, ref e) | ExprParen(ref e) | ExprField(ref e, _) |
        ExprTupField(ref e, _) | ExprAddrOf(_, ref e) | ExprBox(None, ref e)
            => { check_expr(cx, e, bindings) },
        ExprBox(Some(ref place), ref e) => {
            check_expr(cx, place, bindings); check_expr(cx, e, bindings) }
        ExprBlock(ref block) | ExprLoop(ref block, _) =>
            { check_block(cx, block, bindings) },
        //ExprCall
        //ExprMethodCall
        ExprVec(ref v) | ExprTup(ref v) =>
            for ref e in v { check_expr(cx, e, bindings) },
        ExprIf(ref cond, ref then, ref otherwise) => {
            check_expr(cx, cond, bindings);
            check_block(cx, then, bindings);
            if let &Some(ref o) = otherwise { check_expr(cx, o, bindings); }
        },
        ExprWhile(ref cond, ref block, _) => {
            check_expr(cx, cond, bindings);
            check_block(cx, block, bindings);
        },
        ExprMatch(ref init, ref arms, _) => {
            check_expr(cx, init, bindings);
            let len = bindings.len();
            for ref arm in arms {
                for ref pat in &arm.pats {
                    check_pat(cx, &pat, &Some(&**init), pat.span, bindings);
                    //TODO: This is ugly, but needed to get the right type
                }
                if let Some(ref guard) = arm.guard {
                    check_expr(cx, guard, bindings);
                }
                check_expr(cx, &arm.body, bindings);
                bindings.truncate(len);
            }
        },
        _ => ()
    }
}

fn check_ty(cx: &Context, ty: &Ty, bindings: &mut Vec<Name>) {
    match ty.node {
        TyParen(ref sty) | TyObjectSum(ref sty, _) |
        TyVec(ref sty) => check_ty(cx, sty, bindings),
        TyFixedLengthVec(ref fty, ref expr) => {
            check_ty(cx, fty, bindings);
            check_expr(cx, expr, bindings);
        },
        TyPtr(MutTy{ ty: ref mty, .. }) |
        TyRptr(_, MutTy{ ty: ref mty, .. }) => check_ty(cx, mty, bindings),
        TyTup(ref tup) => { for ref t in tup { check_ty(cx, t, bindings) } },
        TyTypeof(ref expr) => check_expr(cx, expr, bindings),
        _ => (),
    }
}

fn is_self_shadow(name: Name, expr: &Expr) -> bool {
    match expr.node {
        ExprBox(_, ref inner) |
        ExprParen(ref inner) |
        ExprAddrOf(_, ref inner) => is_self_shadow(name, inner),
        ExprBlock(ref block) => block.stmts.is_empty() && block.expr.as_ref().
            map_or(false, |ref e| is_self_shadow(name, e)),
        ExprUnary(op, ref inner) => (UnUniq == op || UnDeref == op) &&
            is_self_shadow(name, inner),
        ExprPath(_, ref path) => path_eq_name(name, path),
        _ => false,
    }
}

fn path_eq_name(name: Name, path: &Path) -> bool {
    !path.global && path.segments.len() == 1 &&
        path.segments[0].identifier.name == name
}

fn contains_self(name: Name, expr: &Expr) -> bool {
    match expr.node {
        ExprUnary(_, ref e) | ExprParen(ref e) | ExprField(ref e, _) |
        ExprTupField(ref e, _) | ExprAddrOf(_, ref e) | ExprBox(_, ref e)
            => contains_self(name, e),
        ExprBinary(_, ref l, ref r) =>
            contains_self(name, l) || contains_self(name, r),
        ExprBlock(ref block) | ExprLoop(ref block, _) =>
            contains_block_self(name, block),
        ExprCall(ref fun, ref args) => contains_self(name, fun) ||
            args.iter().any(|ref a| contains_self(name, a)),
        ExprMethodCall(_, _, ref args) =>
            args.iter().any(|ref a| contains_self(name, a)),
        ExprVec(ref v) | ExprTup(ref v) =>
            v.iter().any(|ref e| contains_self(name, e)),
        ExprIf(ref cond, ref then, ref otherwise) =>
            contains_self(name, cond) || contains_block_self(name, then) ||
            otherwise.as_ref().map_or(false, |ref e| contains_self(name, e)),
        ExprWhile(ref e, ref block, _)  =>
            contains_self(name, e) || contains_block_self(name, block),
        ExprMatch(ref e, ref arms, _) =>
            arms.iter().any(|ref arm| arm.pats.iter().any(|ref pat|
                contains_pat_self(name, pat))) || contains_self(name, e),
        ExprPath(_, ref path) => path_eq_name(name, path),
        _ => false
    }
}

fn contains_block_self(name: Name, block: &Block) -> bool {
    for stmt in &block.stmts {
        match stmt.node {
            StmtDecl(ref decl, _) =>
            if let DeclLocal(ref local) = decl.node {
                //TODO: We don't currently handle the case where the name
                //is shadowed wiithin the block; this means code including this
                //degenerate pattern will get the wrong warning.
                if let Some(ref init) = local.init {
                    if contains_self(name, init) { return true; }
                }
            },
            StmtExpr(ref e, _) | StmtSemi(ref e, _) =>
                if contains_self(name, e) { return true },
            _ => ()
        }
    }
    if let Some(ref e) = block.expr { contains_self(name, e) } else { false }
}

fn contains_pat_self(name: Name, pat: &Pat) -> bool {
    match pat.node {
        PatIdent(_, ref ident, ref inner) => name == ident.node.name ||
            inner.as_ref().map_or(false, |ref p| contains_pat_self(name, p)),
        PatEnum(_, ref opats) => opats.as_ref().map_or(false,
            |pats| pats.iter().any(|p| contains_pat_self(name, p))),
        PatQPath(_, ref path) => path_eq_name(name, path),
        PatStruct(_, ref fieldpats, _) => fieldpats.iter().any(
            |ref fp| contains_pat_self(name, &fp.node.pat)),
        PatTup(ref ps) => ps.iter().any(|ref p| contains_pat_self(name, p)),
        PatBox(ref p) |
        PatRegion(ref p, _) => contains_pat_self(name, p),
        PatRange(ref from, ref until) =>
            contains_self(name, from) || contains_self(name, until),
        PatVec(ref pre, ref opt, ref post) =>
            pre.iter().any(|ref p| contains_pat_self(name, p)) ||
                opt.as_ref().map_or(false, |ref p| contains_pat_self(name, p)) ||
                post.iter().any(|ref p| contains_pat_self(name, p)),
        _ => false,
    }
}
<commit_msg>shadow: complete coverage of "contains_self" checker<commit_after>use std::ops::Deref;
use syntax::ast::*;
use syntax::codemap::Span;
use syntax::visit::FnKind;

use rustc::lint::{Context, LintArray, LintPass};
use rustc::middle::def::Def::{DefVariant, DefStruct};

use utils::{in_external_macro, snippet, span_lint, span_note_and_lint};

declare_lint!(pub SHADOW_SAME, Allow,
    "rebinding a name to itself, e.g. `let mut x = &mut x`");
declare_lint!(pub SHADOW_REUSE, Allow,
    "rebinding a name to an expression that re-uses the original value, e.g. \
    `let x = x + 1`");
declare_lint!(pub SHADOW_UNRELATED, Warn,
    "The name is re-bound without even using the original value");

#[derive(Copy, Clone)]
pub struct ShadowPass;

impl LintPass for ShadowPass {
    fn get_lints(&self) -> LintArray {
        lint_array!(SHADOW_SAME, SHADOW_REUSE, SHADOW_UNRELATED)
    }

    fn check_fn(&mut self, cx: &Context, _: FnKind, decl: &FnDecl,
            block: &Block, _: Span, _: NodeId) {
        if in_external_macro(cx, block.span) { return; }
        check_fn(cx, decl, block);
    }
}

fn check_fn(cx: &Context, decl: &FnDecl, block: &Block) {
    let mut bindings = Vec::new();
    for arg in &decl.inputs {
        if let PatIdent(_, ident, _) = arg.pat.node {
            bindings.push(ident.node.name)
        }
    }
    check_block(cx, block, &mut bindings);
}

fn check_block(cx: &Context, block: &Block, bindings: &mut Vec<Name>) {
    let len = bindings.len();
    for stmt in &block.stmts {
        match stmt.node {
            StmtDecl(ref decl, _) => check_decl(cx, decl, bindings),
            StmtExpr(ref e, _) | StmtSemi(ref e, _) =>
                check_expr(cx, e, bindings),
            _ => ()
        }
    }
    if let Some(ref o) = block.expr { check_expr(cx, o, bindings); }
    bindings.truncate(len);
}

fn check_decl(cx: &Context, decl: &Decl, bindings: &mut Vec<Name>) {
    if in_external_macro(cx, decl.span) { return; }
    if let DeclLocal(ref local) = decl.node {
        let Local{ ref pat, ref ty, ref init, id: _, span } = **local;
        if let &Some(ref t) = ty { check_ty(cx, t, bindings) }
        if let &Some(ref o) = init {
            check_expr(cx, o, bindings);
            check_pat(cx, pat, &Some(o), span, bindings);
        } else {
            check_pat(cx, pat, &None, span, bindings);
        }
    }
}

fn is_binding(cx: &Context, pat: &Pat) -> bool {
    match cx.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def()) {
        Some(DefVariant(..)) | Some(DefStruct(..)) => false,
        _ => true
    }
}

fn check_pat(cx: &Context, pat: &Pat, init: &Option<&Expr>, span: Span,
        bindings: &mut Vec<Name>) {
    //TODO: match more stuff / destructuring
    match pat.node {
        PatIdent(_, ref ident, ref inner) => {
            let name = ident.node.name;
            if is_binding(cx, pat) {
                if bindings.contains(&name) {
                    lint_shadow(cx, name, span, pat.span, init);
                } else {
                    bindings.push(name);
                }
            }
            if let Some(ref p) = *inner { check_pat(cx, p, init, span, bindings); }
        },
        //PatEnum(Path, Option<Vec<P<Pat>>>),
        PatStruct(_, ref pfields, _) =>
            if let Some(ref init_struct) = *init {
                if let ExprStruct(_, ref efields, _) = init_struct.node {
                    for field in pfields {
                        let ident = field.node.ident;
                        let efield = efields.iter()
                            .find(|ref f| f.ident.node == ident)
                            .map(|f| &*f.expr);
                        check_pat(cx, &field.node.pat, &efield, span, bindings);
                    }
                } else {
                    for field in pfields {
                        check_pat(cx, &field.node.pat, init, span, bindings);
                    }
                }
            } else {
                for field in pfields {
                    check_pat(cx, &field.node.pat, &None, span, bindings);
                }
            },
        PatTup(ref inner) =>
            if let Some(ref init_tup) = *init {
                if let ExprTup(ref tup) = init_tup.node {
                    for (i, p) in inner.iter().enumerate() {
                        check_pat(cx, p, &Some(&tup[i]), p.span, bindings);
                    }
                } else {
                    for p in inner {
                        check_pat(cx, p, init, span, bindings);
                    }
                }
            } else {
                for p in inner {
                    check_pat(cx, p, &None, span, bindings);
                }
            },
        PatBox(ref inner) => {
            if let Some(ref initp) = *init {
                if let ExprBox(_, ref inner_init) = initp.node {
                    check_pat(cx, inner, &Some(&**inner_init), span, bindings);
                } else {
                    check_pat(cx, inner, init, span, bindings);
                }
            } else {
                check_pat(cx, inner, init, span, bindings);
            }
        },
        PatRegion(ref inner, _) =>
            check_pat(cx, inner, init, span, bindings),
        //PatRange(P<Expr>, P<Expr>),
        //PatVec(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>),
        _ => (),
    }
}

fn lint_shadow<T>(cx: &Context, name: Name, span: Span, lspan: Span, init:
        &Option<T>) where T: Deref<Target=Expr> {
    if let Some(ref expr) = *init {
        if is_self_shadow(name, expr) {
            span_lint(cx, SHADOW_SAME, span, &format!(
                "{} is shadowed by itself in {}",
                snippet(cx, lspan, "_"),
                snippet(cx, expr.span, "..")));
        } else {
            if contains_self(name, expr) {
                span_note_and_lint(cx, SHADOW_REUSE, lspan, &format!(
                    "{} is shadowed by {} which reuses the original value",
                    snippet(cx, lspan, "_"),
                    snippet(cx, expr.span, "..")),
                    expr.span, "initialization happens here");
            } else {
                span_note_and_lint(cx, SHADOW_UNRELATED, lspan, &format!(
                    "{} is shadowed by {}",
                    snippet(cx, lspan, "_"),
                    snippet(cx, expr.span, "..")),
                    expr.span, "initialization happens here");
            }
        }
    } else {
        span_lint(cx, SHADOW_UNRELATED, span, &format!(
            "{} shadows a previous declaration", snippet(cx, lspan, "_")));
    }
}

fn check_expr(cx: &Context, expr: &Expr, bindings: &mut Vec<Name>) {
    if in_external_macro(cx, expr.span) { return; }
    match expr.node {
        ExprUnary(_, ref e) | ExprParen(ref e) | ExprField(ref e, _) |
        ExprTupField(ref e, _) | ExprAddrOf(_, ref e) | ExprBox(None, ref e)
            => { check_expr(cx, e, bindings) },
        ExprBox(Some(ref place), ref e) => {
            check_expr(cx, place, bindings); check_expr(cx, e, bindings) }
        ExprBlock(ref block) | ExprLoop(ref block, _) =>
            { check_block(cx, block, bindings) },
        //ExprCall
        //ExprMethodCall
        ExprVec(ref v) | ExprTup(ref v) =>
            for ref e in v { check_expr(cx, e, bindings) },
        ExprIf(ref cond, ref then, ref otherwise) => {
            check_expr(cx, cond, bindings);
            check_block(cx, then, bindings);
            if let &Some(ref o) = otherwise { check_expr(cx, o, bindings); }
        },
        ExprWhile(ref cond, ref block, _) => {
            check_expr(cx, cond, bindings);
            check_block(cx, block, bindings);
        },
        ExprMatch(ref init, ref arms, _) => {
            check_expr(cx, init, bindings);
            let len = bindings.len();
            for ref arm in arms {
                for ref pat in &arm.pats {
                    check_pat(cx, &pat, &Some(&**init), pat.span, bindings);
                    //TODO: This is ugly, but needed to get the right type
                }
                if let Some(ref guard) = arm.guard {
                    check_expr(cx, guard, bindings);
                }
                check_expr(cx, &arm.body, bindings);
                bindings.truncate(len);
            }
        },
        _ => ()
    }
}

fn check_ty(cx: &Context, ty: &Ty, bindings: &mut Vec<Name>) {
    match ty.node {
        TyParen(ref sty) | TyObjectSum(ref sty, _) |
        TyVec(ref sty) => check_ty(cx, sty, bindings),
        TyFixedLengthVec(ref fty, ref expr) => {
            check_ty(cx, fty, bindings);
            check_expr(cx, expr, bindings);
        },
        TyPtr(MutTy{ ty: ref mty, .. }) |
        TyRptr(_, MutTy{ ty: ref mty, .. }) => check_ty(cx, mty, bindings),
        TyTup(ref tup) => { for ref t in tup { check_ty(cx, t, bindings) } },
        TyTypeof(ref expr) => check_expr(cx, expr, bindings),
        _ => (),
    }
}

fn is_self_shadow(name: Name, expr: &Expr) -> bool {
    match expr.node {
        ExprBox(_, ref inner) |
        ExprParen(ref inner) |
        ExprAddrOf(_, ref inner) => is_self_shadow(name, inner),
        ExprBlock(ref block) => block.stmts.is_empty() && block.expr.as_ref().
            map_or(false, |ref e| is_self_shadow(name, e)),
        ExprUnary(op, ref inner) => (UnUniq == op || UnDeref == op) &&
            is_self_shadow(name, inner),
        ExprPath(_, ref path) => path_eq_name(name, path),
        _ => false,
    }
}

fn path_eq_name(name: Name, path: &Path) -> bool {
    !path.global && path.segments.len() == 1 &&
        path.segments[0].identifier.name == name
}

fn contains_self(name: Name, expr: &Expr) -> bool {
    match expr.node {
        // the "self" name itself (maybe)
        ExprPath(_, ref path) => path_eq_name(name, path),
        // no subexprs
        ExprLit(_) => false,
        // one subexpr
        ExprUnary(_, ref e) | ExprParen(ref e) | ExprField(ref e, _) |
        ExprTupField(ref e, _) | ExprAddrOf(_, ref e) | ExprBox(_, ref e) |
        ExprCast(ref e, _) =>
            contains_self(name, e),
        // two subexprs
        ExprBinary(_, ref l, ref r) | ExprIndex(ref l, ref r) |
        ExprAssign(ref l, ref r) | ExprAssignOp(_, ref l, ref r) |
        ExprRepeat(ref l, ref r) =>
            contains_self(name, l) || contains_self(name, r),
        // one optional subexpr
        ExprRet(ref oe) =>
            oe.as_ref().map_or(false, |ref e| contains_self(name, e)),
        // two optional subexprs
        ExprRange(ref ol, ref or) =>
            ol.as_ref().map_or(false, |ref e| contains_self(name, e)) ||
            or.as_ref().map_or(false, |ref e| contains_self(name, e)),
        // one subblock
        ExprBlock(ref block) | ExprLoop(ref block, _) |
        ExprClosure(_, _, ref block) =>
            contains_block_self(name, block),
        // one vec
        ExprMethodCall(_, _, ref v) | ExprVec(ref v) | ExprTup(ref v) =>
            v.iter().any(|ref a| contains_self(name, a)),
        // one expr, one vec
        ExprCall(ref fun, ref args) =>
            contains_self(name, fun) ||
            args.iter().any(|ref a| contains_self(name, a)),
        // special ones
        ExprIf(ref cond, ref then, ref otherwise) =>
            contains_self(name, cond) || contains_block_self(name, then) ||
            otherwise.as_ref().map_or(false, |ref e| contains_self(name, e)),
        ExprWhile(ref e, ref block, _)  =>
            contains_self(name, e) || contains_block_self(name, block),
        ExprMatch(ref e, ref arms, _) =>
            contains_self(name, e) ||
            arms.iter().any(
                |ref arm|
                arm.pats.iter().any(|ref pat| contains_pat_self(name, pat)) ||
                arm.guard.as_ref().map_or(false, |ref g| contains_self(name, g)) ||
                contains_self(name, &arm.body)),
        ExprStruct(_, ref fields, ref other) =>
            fields.iter().any(|ref f| contains_self(name, &f.expr)) ||
            other.as_ref().map_or(false, |ref e| contains_self(name, e)),
        _ => false,
    }
}

fn contains_block_self(name: Name, block: &Block) -> bool {
    for stmt in &block.stmts {
        match stmt.node {
            StmtDecl(ref decl, _) =>
            if let DeclLocal(ref local) = decl.node {
                //TODO: We don't currently handle the case where the name
                //is shadowed wiithin the block; this means code including this
                //degenerate pattern will get the wrong warning.
                if let Some(ref init) = local.init {
                    if contains_self(name, init) { return true; }
                }
            },
            StmtExpr(ref e, _) | StmtSemi(ref e, _) =>
                if contains_self(name, e) { return true },
            _ => ()
        }
    }
    if let Some(ref e) = block.expr { contains_self(name, e) } else { false }
}

fn contains_pat_self(name: Name, pat: &Pat) -> bool {
    match pat.node {
        PatIdent(_, ref ident, ref inner) => name == ident.node.name ||
            inner.as_ref().map_or(false, |ref p| contains_pat_self(name, p)),
        PatEnum(_, ref opats) => opats.as_ref().map_or(false,
            |pats| pats.iter().any(|p| contains_pat_self(name, p))),
        PatQPath(_, ref path) => path_eq_name(name, path),
        PatStruct(_, ref fieldpats, _) => fieldpats.iter().any(
            |ref fp| contains_pat_self(name, &fp.node.pat)),
        PatTup(ref ps) => ps.iter().any(|ref p| contains_pat_self(name, p)),
        PatBox(ref p) |
        PatRegion(ref p, _) => contains_pat_self(name, p),
        PatRange(ref from, ref until) =>
            contains_self(name, from) || contains_self(name, until),
        PatVec(ref pre, ref opt, ref post) =>
            pre.iter().any(|ref p| contains_pat_self(name, p)) ||
                opt.as_ref().map_or(false, |ref p| contains_pat_self(name, p)) ||
                post.iter().any(|ref p| contains_pat_self(name, p)),
        _ => false,
    }
}
<|endoftext|>


<commit_before>use metadata;
use frame;
use subframe;

use metadata::{Metadata, StreamInfo};
use frame::frame_parser;
use utility::{
  ErrorKind, ByteStream, ReadStream, Sample, StreamProducer, many_metadata,
};

use std::io;
use std::usize;
use std::fs::File;

/// FLAC stream that decodes and hold file information.
pub struct Stream
 {
  info: StreamInfo,
  metadata: Vec<Metadata>,
  producer: P,
}

/// Alias for a FLAC stream produced from `Read`.
pub type StreamReader<R>  = Stream<ReadStream<R>>;

/// Alias for a FLAC stream produced from a byte stream buffer.
pub type StreamBuffer<'a> = Stream<ByteStream<'a>>;

impl
 Stream
 where P: StreamProducer {
  /// Constructor for the default state of a FLAC stream.
  #[inline]
  pub fn new<R: io::Read>(reader: R) -> Result<StreamReader<R>, ErrorKind> {
    let producer = ReadStream::new(reader);

    Stream::from_stream_producer(producer)
  }

  /// Returns information for the current stream.
  #[inline]
  pub fn info(&self) -> StreamInfo {
    self.info
  }

  /// Returns a slice of `Metadata`
  ///
  /// This slice excludes `StreamInfo`, which is located in `Stream::info`.
  /// Everything else is related to metadata for the FLAC stream is in the
  /// slice.
  #[inline]
  pub fn metadata(&self) -> &[Metadata] {
    &self.metadata
  }

  /// Constructs a decoder with the given file name.
  ///
  /// # Failures
  ///
  /// * `ErrorKind::IO(io::ErrorKind::NotFound)` is returned when the given
  ///   filename isn't found.
  /// * `ErrorKind::IO(io::ErrorKind::InvalidData)` is returned when the data
  ///   within the file isn't valid FLAC data.
  /// * Several different parser specific errors that are structured as
  ///   `ErrorKind::<parser_name>Parser`.
  /// * Several different invalidation specific errors that are
  ///   structured as `ErrorKind::Invalid<invalidation_name>`.
  #[inline]
  pub fn from_file(filename: &str) -> Result<StreamReader<File>, ErrorKind> {
    File::open(filename).map_err(|e| ErrorKind::IO(e.kind()))
                        .and_then(|file| {
      let producer = ReadStream::new(file);

      Stream::from_stream_producer(producer)
    })
  }

  /// Constructs a decoder with the given buffer.
  ///
  /// This constructor assumes that an entire FLAC file is in the buffer.
  ///
  /// # Failures
  ///
  /// * `ErrorKind::IO(io::ErrorKind::InvalidData)` is returned when the data
  ///   within the file isn't valid FLAC data.
  /// * Several different parser specific errors that are structured as
  ///   `ErrorKind::<parser_name>Parser`.
  /// * Several different invalidation specific errors that are
  ///   structured as `ErrorKind::Invalid<invalidation_name>`.
  #[inline]
  pub fn from_buffer(buffer: &[u8]) -> Result<StreamBuffer, ErrorKind> {
    let producer = ByteStream::new(buffer);

    Stream::from_stream_producer(producer)
  }

  fn from_stream_producer(mut producer: P) -> Result<Self, ErrorKind> {
    let mut stream_info = StreamInfo::new();
    let mut metadata    = Vec::new();

    many_metadata(&mut producer, |block| {
      if let metadata::Data::StreamInfo(info) = block.data {
        stream_info = info;
      } else {
        metadata.push(block);
      }
    }).map(|_| {
      Stream {
        info: stream_info,
        metadata: metadata,
        producer: producer,
      }
    })
  }

  /// Returns an iterator over the decoded samples.
  #[inline]
  pub fn iter<S: Sample>(&mut self) -> Iter
 {
    let samples_left = self.info.total_samples;
    let channels     = self.info.channels as usize;
    let block_size   = self.info.max_block_size as usize;
    let buffer_size  = block_size * channels;

    Iter {
      stream: self,
      channel: 0,
      block_size: 0,
      sample_index: 0,
      samples_left: samples_left,
      buffer: vec![S::from_i8(0); buffer_size]
    }
  }

  fn next_frame<S>(&mut self, buffer: &mut [S]) -> Option<usize>
   where S: Sample {
    let stream_info = &self.info;

    loop {
      match self.producer.parse(|i| frame_parser(i, stream_info, buffer)) {
        Ok(frame)                  => {
          let channels    = frame.header.channels as usize;
          let block_size  = frame.header.block_size as usize;
          let mut channel = 0;

          for subframe in &frame.subframes[0..channels] {
            let start  = channel * block_size;
            let end    = (channel + 1) * block_size;
            let output = &mut buffer[start..end];

            subframe::decode(&subframe, block_size, output);

            channel += 1;
          }

          frame::decode(frame.header.channel_assignment, buffer);

          return Some(block_size);
        }
        Err(ErrorKind::EndOfInput) => return None,
        Err(ErrorKind::Continue)   => continue,
        Err(_)                     => return None,
      }
    }
  }
}

/// An iterator over a reference of the decoded FLAC stream.
pub struct Iter<'a, P, S>
 where P: 'a + StreamProducer,
       S: Sample{
  stream: &'a mut Stream
,
  channel: usize,
  block_size: usize,
  sample_index: usize,
  samples_left: u64,
  buffer: Vec<S>,
}

impl<'a, P, S> Iterator for Iter<'a, P, S>
 where P: StreamProducer,
       S: Sample {
  type Item = S::Normal;

  fn next(&mut self) -> Option<Self::Item> {
    if self.sample_index == self.block_size {
      let buffer = &mut self.buffer;

      if let Some(block_size) = self.stream.next_frame(buffer) {
        self.sample_index = 0;
        self.block_size   = block_size;
      } else {
        return None;
      }
    }

    let channels = self.stream.info.channels as usize;
    let index    = self.sample_index + (self.channel * self.block_size);
    let sample   = self.buffer[index];

    self.channel += 1;

    // Reset current channel
    if self.channel == channels {
      self.channel       = 0;
      self.sample_index += 1;
      self.samples_left -= 1;
    }

    S::to_normal(sample)
  }

  fn size_hint(&self) -> (usize, Option<usize>) {
    let samples_left = self.samples_left as usize;
    let max_value    = usize::max_value() as u64;

    // There is a chance that samples_left will be larger than a usize since
    // it is a u64. Make the upper bound None when it is.
    if self.samples_left > max_value {
      (samples_left, None)
    } else {
      (samples_left, Some(samples_left))
    }
  }
}

impl<'a, P> IntoIterator for &'a mut Stream

 where P: StreamProducer {
  type Item     = i32;
  type IntoIter = Iter<'a, P>;

  #[inline]
  fn into_iter(self) -> Self::IntoIter {
    self.iter()
  }
}
<commit_msg>Remove IntoIterator for the time being<commit_after>use metadata;
use frame;
use subframe;

use metadata::{Metadata, StreamInfo};
use frame::frame_parser;
use utility::{
  ErrorKind, ByteStream, ReadStream, Sample, StreamProducer, many_metadata,
};

use std::io;
use std::usize;
use std::fs::File;

/// FLAC stream that decodes and hold file information.
pub struct Stream
 {
  info: StreamInfo,
  metadata: Vec<Metadata>,
  producer: P,
}

/// Alias for a FLAC stream produced from `Read`.
pub type StreamReader<R>  = Stream<ReadStream<R>>;

/// Alias for a FLAC stream produced from a byte stream buffer.
pub type StreamBuffer<'a> = Stream<ByteStream<'a>>;

impl
 Stream
 where P: StreamProducer {
  /// Constructor for the default state of a FLAC stream.
  #[inline]
  pub fn new<R: io::Read>(reader: R) -> Result<StreamReader<R>, ErrorKind> {
    let producer = ReadStream::new(reader);

    Stream::from_stream_producer(producer)
  }

  /// Returns information for the current stream.
  #[inline]
  pub fn info(&self) -> StreamInfo {
    self.info
  }

  /// Returns a slice of `Metadata`
  ///
  /// This slice excludes `StreamInfo`, which is located in `Stream::info`.
  /// Everything else is related to metadata for the FLAC stream is in the
  /// slice.
  #[inline]
  pub fn metadata(&self) -> &[Metadata] {
    &self.metadata
  }

  /// Constructs a decoder with the given file name.
  ///
  /// # Failures
  ///
  /// * `ErrorKind::IO(io::ErrorKind::NotFound)` is returned when the given
  ///   filename isn't found.
  /// * `ErrorKind::IO(io::ErrorKind::InvalidData)` is returned when the data
  ///   within the file isn't valid FLAC data.
  /// * Several different parser specific errors that are structured as
  ///   `ErrorKind::<parser_name>Parser`.
  /// * Several different invalidation specific errors that are
  ///   structured as `ErrorKind::Invalid<invalidation_name>`.
  #[inline]
  pub fn from_file(filename: &str) -> Result<StreamReader<File>, ErrorKind> {
    File::open(filename).map_err(|e| ErrorKind::IO(e.kind()))
                        .and_then(|file| {
      let producer = ReadStream::new(file);

      Stream::from_stream_producer(producer)
    })
  }

  /// Constructs a decoder with the given buffer.
  ///
  /// This constructor assumes that an entire FLAC file is in the buffer.
  ///
  /// # Failures
  ///
  /// * `ErrorKind::IO(io::ErrorKind::InvalidData)` is returned when the data
  ///   within the file isn't valid FLAC data.
  /// * Several different parser specific errors that are structured as
  ///   `ErrorKind::<parser_name>Parser`.
  /// * Several different invalidation specific errors that are
  ///   structured as `ErrorKind::Invalid<invalidation_name>`.
  #[inline]
  pub fn from_buffer(buffer: &[u8]) -> Result<StreamBuffer, ErrorKind> {
    let producer = ByteStream::new(buffer);

    Stream::from_stream_producer(producer)
  }

  fn from_stream_producer(mut producer: P) -> Result<Self, ErrorKind> {
    let mut stream_info = StreamInfo::new();
    let mut metadata    = Vec::new();

    many_metadata(&mut producer, |block| {
      if let metadata::Data::StreamInfo(info) = block.data {
        stream_info = info;
      } else {
        metadata.push(block);
      }
    }).map(|_| {
      Stream {
        info: stream_info,
        metadata: metadata,
        producer: producer,
      }
    })
  }

  /// Returns an iterator over the decoded samples.
  #[inline]
  pub fn iter<S: Sample>(&mut self) -> Iter
 {
    let samples_left = self.info.total_samples;
    let channels     = self.info.channels as usize;
    let block_size   = self.info.max_block_size as usize;
    let buffer_size  = block_size * channels;

    Iter {
      stream: self,
      channel: 0,
      block_size: 0,
      sample_index: 0,
      samples_left: samples_left,
      buffer: vec![S::from_i8(0); buffer_size]
    }
  }

  fn next_frame<S>(&mut self, buffer: &mut [S]) -> Option<usize>
   where S: Sample {
    let stream_info = &self.info;

    loop {
      match self.producer.parse(|i| frame_parser(i, stream_info, buffer)) {
        Ok(frame)                  => {
          let channels    = frame.header.channels as usize;
          let block_size  = frame.header.block_size as usize;
          let mut channel = 0;

          for subframe in &frame.subframes[0..channels] {
            let start  = channel * block_size;
            let end    = (channel + 1) * block_size;
            let output = &mut buffer[start..end];

            subframe::decode(&subframe, block_size, output);

            channel += 1;
          }

          frame::decode(frame.header.channel_assignment, buffer);

          return Some(block_size);
        }
        Err(ErrorKind::EndOfInput) => return None,
        Err(ErrorKind::Continue)   => continue,
        Err(_)                     => return None,
      }
    }
  }
}

/// An iterator over a reference of the decoded FLAC stream.
pub struct Iter<'a, P, S>
 where P: 'a + StreamProducer,
       S: Sample{
  stream: &'a mut Stream
,
  channel: usize,
  block_size: usize,
  sample_index: usize,
  samples_left: u64,
  buffer: Vec<S>,
}

impl<'a, P, S> Iterator for Iter<'a, P, S>
 where P: StreamProducer,
       S: Sample {
  type Item = S::Normal;

  fn next(&mut self) -> Option<Self::Item> {
    if self.sample_index == self.block_size {
      let buffer = &mut self.buffer;

      if let Some(block_size) = self.stream.next_frame(buffer) {
        self.sample_index = 0;
        self.block_size   = block_size;
      } else {
        return None;
      }
    }

    let channels = self.stream.info.channels as usize;
    let index    = self.sample_index + (self.channel * self.block_size);
    let sample   = self.buffer[index];

    self.channel += 1;

    // Reset current channel
    if self.channel == channels {
      self.channel       = 0;
      self.sample_index += 1;
      self.samples_left -= 1;
    }

    S::to_normal(sample)
  }

  fn size_hint(&self) -> (usize, Option<usize>) {
    let samples_left = self.samples_left as usize;
    let max_value    = usize::max_value() as u64;

    // There is a chance that samples_left will be larger than a usize since
    // it is a u64. Make the upper bound None when it is.
    if self.samples_left > max_value {
      (samples_left, None)
    } else {
      (samples_left, Some(samples_left))
    }
  }
}

//impl<'a, P, S> IntoIterator for &'a mut Stream

// where P: StreamProducer,
//       S: Sample {
//  type Item     = S::Normal;
//  type IntoIter = Iter<'a, P, S>;
//
//  #[inline]
//  fn into_iter(self) -> Self::IntoIter {
//    self.iter()
//  }
//}
<|endoftext|>


<commit_before>use std::path::Path;
use piston_window::{PistonWindow, G2d, Glyphs};
use conrod::{self, Theme, Graphics};

type Backend = (<G2d<'static> as Graphics>::Texture, Glyphs);
pub type Ui = conrod::Ui<Backend>;

pub fn create_ui(window: &PistonWindow, font_path: &Path) -> Ui {
    let theme = Theme::default();
    let glyph_cache = Glyphs::new(&font_path, window.factory.borrow().clone());
    Ui::new(glyph_cache.unwrap(), theme)
}
<commit_msg>'private type in public interface' warning fix<commit_after>use std::path::Path;
use piston_window::{PistonWindow, G2d, Glyphs};
use conrod::{self, Theme, Graphics};

pub type Backend = (<G2d<'static> as Graphics>::Texture, Glyphs);
pub type Ui = conrod::Ui<Backend>;

pub fn create_ui(window: &PistonWindow, font_path: &Path) -> Ui {
    let theme = Theme::default();
    let glyph_cache = Glyphs::new(&font_path, window.factory.borrow().clone());
    Ui::new(glyph_cache.unwrap(), theme)
}
<|endoftext|>


<commit_before>use std::collections::HashMap;

use serialize::{Decodable, Decoder, Encoder, Encodable};
use semver;
use dependency::Kind as DependencyKind;

use keyword::Keyword as CrateKeyword;
use krate::Crate;

#[deriving(Decodable, Encodable)]
pub struct NewCrate {
    pub name: CrateName,
    pub vers: CrateVersion,
    pub deps: Vec<CrateDependency>,
    pub features: HashMap<CrateName, Vec<CrateName>>,
    pub authors: Vec<String>,
    pub description: Option<String>,
    pub homepage: Option<String>,
    pub documentation: Option<String>,
    pub readme: Option<String>,
    pub keywords: Option<KeywordList>,
    pub license: Option<String>,
    pub repository: Option<String>,
}

#[deriving(PartialEq, Eq, Hash)]
pub struct CrateName(pub String);
pub struct CrateVersion(pub semver::Version);
pub struct CrateVersionReq(pub semver::VersionReq);
pub struct KeywordList(pub Vec<Keyword>);
pub struct Keyword(pub String);
pub struct Feature(pub String);

#[deriving(Decodable, Encodable)]
pub struct CrateDependency {
    pub optional: bool,
    pub default_features: bool,
    pub name: CrateName,
    pub features: Vec<Feature>,
    pub version_req: CrateVersionReq,
    pub target: Option<String>,
    pub kind: Option<DependencyKind>,
}

impl<E, D: Decoder<E>> Decodable<D, E> for CrateName {
    fn decode(d: &mut D) -> Result<CrateName, E> {
        let s = raw_try!(d.read_str());
        if !Crate::valid_name(s.as_slice()) {
            return Err(d.error(format!("invalid crate name specified: {}",
                                       s).as_slice()))
        }
        Ok(CrateName(s))
    }
}

impl<E, D: Decoder<E>> Decodable<D, E> for Keyword {
    fn decode(d: &mut D) -> Result<Keyword, E> {
        let s = raw_try!(d.read_str());
        if !CrateKeyword::valid_name(s.as_slice()) {
            return Err(d.error(format!("invalid keyword specified: {}",
                                       s).as_slice()))
        }
        Ok(Keyword(s))
    }
}

impl<E, D: Decoder<E>> Decodable<D, E> for Feature {
    fn decode(d: &mut D) -> Result<Feature, E> {
        let s = raw_try!(d.read_str());
        if !Crate::valid_feature_name(s.as_slice()) {
            return Err(d.error(format!("invalid feature name specified: {}",
                                       s).as_slice()))
        }
        Ok(Feature(s))
    }
}

impl<E, D: Decoder<E>> Decodable<D, E> for CrateVersion {
    fn decode(d: &mut D) -> Result<CrateVersion, E> {
        let s = raw_try!(d.read_str());
        match semver::Version::parse(s.as_slice()) {
            Ok(v) => Ok(CrateVersion(v)),
            Err(..) => Err(d.error(format!("invalid semver: {}", s).as_slice())),
        }
    }
}

impl<E, D: Decoder<E>> Decodable<D, E> for CrateVersionReq {
    fn decode(d: &mut D) -> Result<CrateVersionReq, E> {
        let s = raw_try!(d.read_str());
        match semver::VersionReq::parse(s.as_slice()) {
            Ok(v) => Ok(CrateVersionReq(v)),
            Err(..) => Err(d.error(format!("invalid version req: {}",
                                           s).as_slice())),
        }
    }
}

impl<E, D: Decoder<E>> Decodable<D, E> for KeywordList {
    fn decode(d: &mut D) -> Result<KeywordList, E> {
        let inner: Vec<Keyword> = raw_try!(Decodable::decode(d));
        if inner.len() > 5 {
            return Err(d.error("a maximum of 5 keywords per crate are allowed"))
        }
        for val in inner.iter() {
            if val.len() > 20 {
                return Err(d.error("keywords must contain less than 20 \
                                    characters"))
            }
        }
        Ok(KeywordList(inner))
    }
}

impl<E, D: Decoder<E>> Decodable<D, E> for DependencyKind {
    fn decode(d: &mut D) -> Result<DependencyKind, E> {
        let s: String = raw_try!(Decodable::decode(d));
        match s.as_slice() {
            "dev" => Ok(DependencyKind::Dev),
            "build" => Ok(DependencyKind::Build),
            "normal" => Ok(DependencyKind::Normal),
            s => Err(d.error(format!("invalid dependency kind `{}`, must be \
                                      one of dev, build, or normal",
                                     s).as_slice())),
        }
    }
}

impl<E, D: Encoder<E>> Encodable<D, E> for CrateName {
    fn encode(&self, d: &mut D) -> Result<(), E> {
        d.emit_str(self.as_slice())
    }
}

impl<E, D: Encoder<E>> Encodable<D, E> for Keyword {
    fn encode(&self, d: &mut D) -> Result<(), E> {
        d.emit_str(self.as_slice())
    }
}

impl<E, D: Encoder<E>> Encodable<D, E> for Feature {
    fn encode(&self, d: &mut D) -> Result<(), E> {
        d.emit_str(self.as_slice())
    }
}

impl<E, D: Encoder<E>> Encodable<D, E> for CrateVersion {
    fn encode(&self, d: &mut D) -> Result<(), E> {
        d.emit_str((**self).to_string().as_slice())
    }
}

impl<E, D: Encoder<E>> Encodable<D, E> for CrateVersionReq {
    fn encode(&self, d: &mut D) -> Result<(), E> {
        d.emit_str((**self).to_string().as_slice())
    }
}

impl<E, D: Encoder<E>> Encodable<D, E> for KeywordList {
    fn encode(&self, d: &mut D) -> Result<(), E> {
        let KeywordList(ref inner) = *self;
        inner.encode(d)
    }
}

impl<E, D: Encoder<E>> Encodable<D, E> for DependencyKind {
    fn encode(&self, d: &mut D) -> Result<(), E> {
        match *self {
            DependencyKind::Normal => "normal".encode(d),
            DependencyKind::Build => "build".encode(d),
            DependencyKind::Dev => "dev".encode(d),
        }
    }
}

impl Deref<str> for CrateName {
    fn deref<'a>(&'a self) -> &'a str {
        let CrateName(ref s) = *self;
        s.as_slice()
    }
}

impl Deref<str> for Keyword {
    fn deref<'a>(&'a self) -> &'a str {
        let Keyword(ref s) = *self;
        s.as_slice()
    }
}

impl Deref<str> for Feature {
    fn deref<'a>(&'a self) -> &'a str {
        let Feature(ref s) = *self;
        s.as_slice()
    }
}

impl Deref<semver::Version> for CrateVersion {
    fn deref<'a>(&'a self) -> &'a semver::Version {
        let CrateVersion(ref s) = *self; s
    }
}

impl Deref<semver::VersionReq> for CrateVersionReq {
    fn deref<'a>(&'a self) -> &'a semver::VersionReq {
        let CrateVersionReq(ref s) = *self; s
    }
}

impl Deref<[Keyword]> for KeywordList {
    fn deref<'a>(&'a self) -> &'a [Keyword] {
        let KeywordList(ref s) = *self;
        s.as_slice()
    }
}
<commit_msg>The features map uploaded maps to features!<commit_after>use std::collections::HashMap;

use serialize::{Decodable, Decoder, Encoder, Encodable};
use semver;
use dependency::Kind as DependencyKind;

use keyword::Keyword as CrateKeyword;
use krate::Crate;

#[deriving(Decodable, Encodable)]
pub struct NewCrate {
    pub name: CrateName,
    pub vers: CrateVersion,
    pub deps: Vec<CrateDependency>,
    pub features: HashMap<CrateName, Vec<Feature>>,
    pub authors: Vec<String>,
    pub description: Option<String>,
    pub homepage: Option<String>,
    pub documentation: Option<String>,
    pub readme: Option<String>,
    pub keywords: Option<KeywordList>,
    pub license: Option<String>,
    pub repository: Option<String>,
}

#[deriving(PartialEq, Eq, Hash)]
pub struct CrateName(pub String);
pub struct CrateVersion(pub semver::Version);
pub struct CrateVersionReq(pub semver::VersionReq);
pub struct KeywordList(pub Vec<Keyword>);
pub struct Keyword(pub String);
pub struct Feature(pub String);

#[deriving(Decodable, Encodable)]
pub struct CrateDependency {
    pub optional: bool,
    pub default_features: bool,
    pub name: CrateName,
    pub features: Vec<Feature>,
    pub version_req: CrateVersionReq,
    pub target: Option<String>,
    pub kind: Option<DependencyKind>,
}

impl<E, D: Decoder<E>> Decodable<D, E> for CrateName {
    fn decode(d: &mut D) -> Result<CrateName, E> {
        let s = raw_try!(d.read_str());
        if !Crate::valid_name(s.as_slice()) {
            return Err(d.error(format!("invalid crate name specified: {}",
                                       s).as_slice()))
        }
        Ok(CrateName(s))
    }
}

impl<E, D: Decoder<E>> Decodable<D, E> for Keyword {
    fn decode(d: &mut D) -> Result<Keyword, E> {
        let s = raw_try!(d.read_str());
        if !CrateKeyword::valid_name(s.as_slice()) {
            return Err(d.error(format!("invalid keyword specified: {}",
                                       s).as_slice()))
        }
        Ok(Keyword(s))
    }
}

impl<E, D: Decoder<E>> Decodable<D, E> for Feature {
    fn decode(d: &mut D) -> Result<Feature, E> {
        let s = raw_try!(d.read_str());
        if !Crate::valid_feature_name(s.as_slice()) {
            return Err(d.error(format!("invalid feature name specified: {}",
                                       s).as_slice()))
        }
        Ok(Feature(s))
    }
}

impl<E, D: Decoder<E>> Decodable<D, E> for CrateVersion {
    fn decode(d: &mut D) -> Result<CrateVersion, E> {
        let s = raw_try!(d.read_str());
        match semver::Version::parse(s.as_slice()) {
            Ok(v) => Ok(CrateVersion(v)),
            Err(..) => Err(d.error(format!("invalid semver: {}", s).as_slice())),
        }
    }
}

impl<E, D: Decoder<E>> Decodable<D, E> for CrateVersionReq {
    fn decode(d: &mut D) -> Result<CrateVersionReq, E> {
        let s = raw_try!(d.read_str());
        match semver::VersionReq::parse(s.as_slice()) {
            Ok(v) => Ok(CrateVersionReq(v)),
            Err(..) => Err(d.error(format!("invalid version req: {}",
                                           s).as_slice())),
        }
    }
}

impl<E, D: Decoder<E>> Decodable<D, E> for KeywordList {
    fn decode(d: &mut D) -> Result<KeywordList, E> {
        let inner: Vec<Keyword> = raw_try!(Decodable::decode(d));
        if inner.len() > 5 {
            return Err(d.error("a maximum of 5 keywords per crate are allowed"))
        }
        for val in inner.iter() {
            if val.len() > 20 {
                return Err(d.error("keywords must contain less than 20 \
                                    characters"))
            }
        }
        Ok(KeywordList(inner))
    }
}

impl<E, D: Decoder<E>> Decodable<D, E> for DependencyKind {
    fn decode(d: &mut D) -> Result<DependencyKind, E> {
        let s: String = raw_try!(Decodable::decode(d));
        match s.as_slice() {
            "dev" => Ok(DependencyKind::Dev),
            "build" => Ok(DependencyKind::Build),
            "normal" => Ok(DependencyKind::Normal),
            s => Err(d.error(format!("invalid dependency kind `{}`, must be \
                                      one of dev, build, or normal",
                                     s).as_slice())),
        }
    }
}

impl<E, D: Encoder<E>> Encodable<D, E> for CrateName {
    fn encode(&self, d: &mut D) -> Result<(), E> {
        d.emit_str(self.as_slice())
    }
}

impl<E, D: Encoder<E>> Encodable<D, E> for Keyword {
    fn encode(&self, d: &mut D) -> Result<(), E> {
        d.emit_str(self.as_slice())
    }
}

impl<E, D: Encoder<E>> Encodable<D, E> for Feature {
    fn encode(&self, d: &mut D) -> Result<(), E> {
        d.emit_str(self.as_slice())
    }
}

impl<E, D: Encoder<E>> Encodable<D, E> for CrateVersion {
    fn encode(&self, d: &mut D) -> Result<(), E> {
        d.emit_str((**self).to_string().as_slice())
    }
}

impl<E, D: Encoder<E>> Encodable<D, E> for CrateVersionReq {
    fn encode(&self, d: &mut D) -> Result<(), E> {
        d.emit_str((**self).to_string().as_slice())
    }
}

impl<E, D: Encoder<E>> Encodable<D, E> for KeywordList {
    fn encode(&self, d: &mut D) -> Result<(), E> {
        let KeywordList(ref inner) = *self;
        inner.encode(d)
    }
}

impl<E, D: Encoder<E>> Encodable<D, E> for DependencyKind {
    fn encode(&self, d: &mut D) -> Result<(), E> {
        match *self {
            DependencyKind::Normal => "normal".encode(d),
            DependencyKind::Build => "build".encode(d),
            DependencyKind::Dev => "dev".encode(d),
        }
    }
}

impl Deref<str> for CrateName {
    fn deref<'a>(&'a self) -> &'a str {
        let CrateName(ref s) = *self;
        s.as_slice()
    }
}

impl Deref<str> for Keyword {
    fn deref<'a>(&'a self) -> &'a str {
        let Keyword(ref s) = *self;
        s.as_slice()
    }
}

impl Deref<str> for Feature {
    fn deref<'a>(&'a self) -> &'a str {
        let Feature(ref s) = *self;
        s.as_slice()
    }
}

impl Deref<semver::Version> for CrateVersion {
    fn deref<'a>(&'a self) -> &'a semver::Version {
        let CrateVersion(ref s) = *self; s
    }
}

impl Deref<semver::VersionReq> for CrateVersionReq {
    fn deref<'a>(&'a self) -> &'a semver::VersionReq {
        let CrateVersionReq(ref s) = *self; s
    }
}

impl Deref<[Keyword]> for KeywordList {
    fn deref<'a>(&'a self) -> &'a [Keyword] {
        let KeywordList(ref s) = *self;
        s.as_slice()
    }
}
<|endoftext|>