<commit_before>use std::io::{fs, IoResult};
use file::{File, GREY};

#[cfg(feature="git")] use ansi_term::ANSIString;
#[cfg(feature="git")] use ansi_term::Colour::*;
#[cfg(feature="git")] use git2;

/// A **Dir** provides a cached list of the file paths in a directory that's
/// being listed.
///
/// This object gets passed to the Files themselves, in order for them to
/// check the existence of surrounding files, then highlight themselves
/// accordingly. (See `File#get_source_files`)
pub struct Dir {
    contents: Vec<Path>,
    path: Path,
    git: Option<Git>,
}

impl Dir {
    /// Create a new Dir object filled with all the files in the directory
    /// pointed to by the given path. Fails if the directory can't be read, or
    /// isn't actually a directory.
    pub fn readdir(path: Path) -> IoResult<Dir> {
        fs::readdir(&path).map(|paths| Dir {
            contents: paths,
            path: path.clone(),
            git: Git::scan(&path).ok(),
        })
    }

    /// Produce a vector of File objects from an initialised directory,
    /// printing out an error if any of the Files fail to be created.
    pub fn files(&self) -> Vec<File> {
        let mut files = vec![];

        for path in self.contents.iter() {
            match File::from_path(path, Some(self)) {
                Ok(file) => files.push(file),
                Err(e)   => println!("{}: {}", path.display(), e),
            }
        }

        files
    }

    /// Whether this directory contains a file with the given path.
    pub fn contains(&self, path: &Path) -> bool {
        self.contents.contains(path)
    }

    /// Append a path onto the path specified by this directory.
    pub fn join(&self, child: Path) -> Path {
        self.path.join(child)
    }

    /// Return whether there's a Git repository on or above this directory.
    pub fn has_git_repo(&self) -> bool {
        self.git.is_some()
    }

    /// Get a string describing the Git status of the given file.
    pub fn git_status(&self, path: &Path, prefix_lookup: bool) -> String {
        match (&self.git, prefix_lookup) {
            (&Some(ref git), false) => git.status(path),
            (&Some(ref git), true)  => git.dir_status(path),
            (&None, _)              => GREY.paint("--").to_string(),
        }
    }
}

/// Container of Git statuses for all the files in this folder's Git repository.
#[cfg(feature="git")]
struct Git {
    statuses: Vec<(Vec<u8>, git2::Status)>,
}

#[cfg(feature="git")]
impl Git {

    /// Discover a Git repository on or above this directory, scanning it for
    /// the files' statuses if one is found.
    fn scan(path: &Path) -> Result<Git, git2::Error> {
        let repo = try!(git2::Repository::discover(path));
        let statuses = try!(repo.statuses(None)).iter()
                                                .map(|e| (e.path_bytes().to_vec(), e.status()))
                                                .collect();
        Ok(Git { statuses: statuses })
    }

    /// Get the status for the file at the given path, if present.
    fn status(&self, path: &Path) -> String {
        let status = self.statuses.iter()
                                  .find(|p| p.0 == path.as_vec());
        match status {
            Some(&(_, s)) => format!("{}{}", Git::index_status(s), Git::working_tree_status(s)),
            None => GREY.paint("--").to_string(),
        }
    }

    /// Get the combined status for all the files whose paths begin with the
    /// path that gets passed in. This is used for getting the status of
    /// directories, which don't really have an 'official' status.
    fn dir_status(&self, dir: &Path) -> String {
        let status = self.statuses.iter()
                                  .filter(|p| p.0.starts_with(dir.as_vec()))
                                  .fold(git2::Status::empty(), |a, b| a | b.1);
        match status {
            s => format!("{}{}", Git::index_status(s), Git::working_tree_status(s)),
        }
    }

    /// The character to display if the file has been modified, but not staged.
    fn working_tree_status(status: git2::Status) -> ANSIString<'static> {
        match status {
            s if s.contains(git2::STATUS_WT_NEW) => Green.paint("A"),
            s if s.contains(git2::STATUS_WT_MODIFIED) => Blue.paint("M"),
            s if s.contains(git2::STATUS_WT_DELETED) => Red.paint("D"),
            s if s.contains(git2::STATUS_WT_RENAMED) => Yellow.paint("R"),
            s if s.contains(git2::STATUS_WT_TYPECHANGE) => Purple.paint("T"),
            _ => GREY.paint("-"),
        }
    }

    /// The character to display if the file has been modified, and the change
    /// has been staged.
    fn index_status(status: git2::Status) -> ANSIString<'static> {
        match status {
            s if s.contains(git2::STATUS_INDEX_NEW) => Green.paint("A"),
            s if s.contains(git2::STATUS_INDEX_MODIFIED) => Blue.paint("M"),
            s if s.contains(git2::STATUS_INDEX_DELETED) => Red.paint("D"),
            s if s.contains(git2::STATUS_INDEX_RENAMED) => Yellow.paint("R"),
            s if s.contains(git2::STATUS_INDEX_TYPECHANGE) => Purple.paint("T"),
            _ => GREY.paint("-"),
        }
    }
}

#[cfg(not(feature="git"))]
struct Git;

#[cfg(not(feature="git"))]
impl Git {
    fn scan(_: &Path) -> Result<Git, ()> {
        // Don't do anything without Git support
        Err(())
    }

    fn status(&self, _: &Path) -> String {
        // The Err above means that this should never happen
        panic!("Tried to access a Git repo without Git support!");
    }
}
<commit_msg>Oops, fix --no-default-features compilation<commit_after>use std::io::{fs, IoResult};
use file::{File, GREY};

#[cfg(feature="git")] use ansi_term::ANSIString;
#[cfg(feature="git")] use ansi_term::Colour::*;
#[cfg(feature="git")] use git2;

/// A **Dir** provides a cached list of the file paths in a directory that's
/// being listed.
///
/// This object gets passed to the Files themselves, in order for them to
/// check the existence of surrounding files, then highlight themselves
/// accordingly. (See `File#get_source_files`)
pub struct Dir {
    contents: Vec<Path>,
    path: Path,
    git: Option<Git>,
}

impl Dir {
    /// Create a new Dir object filled with all the files in the directory
    /// pointed to by the given path. Fails if the directory can't be read, or
    /// isn't actually a directory.
    pub fn readdir(path: Path) -> IoResult<Dir> {
        fs::readdir(&path).map(|paths| Dir {
            contents: paths,
            path: path.clone(),
            git: Git::scan(&path).ok(),
        })
    }

    /// Produce a vector of File objects from an initialised directory,
    /// printing out an error if any of the Files fail to be created.
    pub fn files(&self) -> Vec<File> {
        let mut files = vec![];

        for path in self.contents.iter() {
            match File::from_path(path, Some(self)) {
                Ok(file) => files.push(file),
                Err(e)   => println!("{}: {}", path.display(), e),
            }
        }

        files
    }

    /// Whether this directory contains a file with the given path.
    pub fn contains(&self, path: &Path) -> bool {
        self.contents.contains(path)
    }

    /// Append a path onto the path specified by this directory.
    pub fn join(&self, child: Path) -> Path {
        self.path.join(child)
    }

    /// Return whether there's a Git repository on or above this directory.
    pub fn has_git_repo(&self) -> bool {
        self.git.is_some()
    }

    /// Get a string describing the Git status of the given file.
    pub fn git_status(&self, path: &Path, prefix_lookup: bool) -> String {
        match (&self.git, prefix_lookup) {
            (&Some(ref git), false) => git.status(path),
            (&Some(ref git), true)  => git.dir_status(path),
            (&None, _)              => GREY.paint("--").to_string(),
        }
    }
}

/// Container of Git statuses for all the files in this folder's Git repository.
#[cfg(feature="git")]
struct Git {
    statuses: Vec<(Vec<u8>, git2::Status)>,
}

#[cfg(feature="git")]
impl Git {

    /// Discover a Git repository on or above this directory, scanning it for
    /// the files' statuses if one is found.
    fn scan(path: &Path) -> Result<Git, git2::Error> {
        let repo = try!(git2::Repository::discover(path));
        let statuses = try!(repo.statuses(None)).iter()
                                                .map(|e| (e.path_bytes().to_vec(), e.status()))
                                                .collect();
        Ok(Git { statuses: statuses })
    }

    /// Get the status for the file at the given path, if present.
    fn status(&self, path: &Path) -> String {
        let status = self.statuses.iter()
                                  .find(|p| p.0 == path.as_vec());
        match status {
            Some(&(_, s)) => format!("{}{}", Git::index_status(s), Git::working_tree_status(s)),
            None => GREY.paint("--").to_string(),
        }
    }

    /// Get the combined status for all the files whose paths begin with the
    /// path that gets passed in. This is used for getting the status of
    /// directories, which don't really have an 'official' status.
    fn dir_status(&self, dir: &Path) -> String {
        let status = self.statuses.iter()
                                  .filter(|p| p.0.starts_with(dir.as_vec()))
                                  .fold(git2::Status::empty(), |a, b| a | b.1);
        match status {
            s => format!("{}{}", Git::index_status(s), Git::working_tree_status(s)),
        }
    }

    /// The character to display if the file has been modified, but not staged.
    fn working_tree_status(status: git2::Status) -> ANSIString<'static> {
        match status {
            s if s.contains(git2::STATUS_WT_NEW) => Green.paint("A"),
            s if s.contains(git2::STATUS_WT_MODIFIED) => Blue.paint("M"),
            s if s.contains(git2::STATUS_WT_DELETED) => Red.paint("D"),
            s if s.contains(git2::STATUS_WT_RENAMED) => Yellow.paint("R"),
            s if s.contains(git2::STATUS_WT_TYPECHANGE) => Purple.paint("T"),
            _ => GREY.paint("-"),
        }
    }

    /// The character to display if the file has been modified, and the change
    /// has been staged.
    fn index_status(status: git2::Status) -> ANSIString<'static> {
        match status {
            s if s.contains(git2::STATUS_INDEX_NEW) => Green.paint("A"),
            s if s.contains(git2::STATUS_INDEX_MODIFIED) => Blue.paint("M"),
            s if s.contains(git2::STATUS_INDEX_DELETED) => Red.paint("D"),
            s if s.contains(git2::STATUS_INDEX_RENAMED) => Yellow.paint("R"),
            s if s.contains(git2::STATUS_INDEX_TYPECHANGE) => Purple.paint("T"),
            _ => GREY.paint("-"),
        }
    }
}

#[cfg(not(feature="git"))]
struct Git;

#[cfg(not(feature="git"))]
impl Git {
    fn scan(_: &Path) -> Result<Git, ()> {
        // Don't do anything without Git support
        Err(())
    }

    fn status(&self, _: &Path) -> String {
        // The Err above means that this should never happen
        panic!("Tried to access a Git repo without Git support!");
    }

    fn dir_status(&self, path: &Path) -> String {
        self.status(path)
    }
}
<|endoftext|>


<commit_before><commit_msg>custom impl for Show trait for prettier-printing<commit_after><|endoftext|>


<commit_before><commit_msg>Add SpanAsError trait<commit_after><|endoftext|>


<commit_before><commit_msg>Add LTECell and related changes<commit_after><|endoftext|>


<commit_before><commit_msg>Fix decoding EOF issues.<commit_after><|endoftext|>


<commit_before><commit_msg>version work<commit_after><|endoftext|>


<commit_before><commit_msg>Remove unnecessary extern crates.<commit_after><|endoftext|>


<commit_before><commit_msg>`IXAudio2Voice::GetChannelVolumes()`<commit_after><|endoftext|>


<commit_before><commit_msg>Clean up lib.rs<commit_after><|endoftext|>


<commit_before><commit_msg>forgot to commit src dir in previous<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2015 Johan Johansson
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! Capture the screen with xlib

extern crate x11;

#[test]
fn test() {
	use x11::xlib;
	use std::{ ptr, thread };

	unsafe {

	println!("Init\n");

	// use the information from the environment variable DISPLAY to create the X connection:
	let display = match xlib::XOpenDisplay(ptr::null_mut()) {
		null if null.is_null() => panic!("Unable to connect X server"),
		display => display,
	};

	let screen_num = xlib::XDefaultScreen(display);
	let (black_pixel, white_pixel) = (xlib::XBlackPixel(display, screen_num),
		xlib::XWhitePixel(display, screen_num));
	println!("Screen: {}, Black: {}, White: {}", screen_num, black_pixel, white_pixel);

	// Once the display is initialized, create the window
	let (x, y) = (0, 0);
	let (width, height, border_width) = (400, 500, 5);
	let (border_color, background_color) = (black_pixel, white_pixel);
	let window = xlib::XCreateSimpleWindow(display,
		xlib::XRootWindow(display, screen_num),
		x, y,
		width, height, border_width,
		border_color, background_color);
	println!("Window: {}", window);

	// this routine determines which types of input are allowed in the input.
	xlib::XSelectInput(display, window,
		xlib::ExposureMask | xlib::ButtonPressMask | xlib::KeyPressMask);

	// create the Graphics Context
	let graphics_context = xlib::XCreateGC(display, window, 0, ptr::null_mut());

	xlib::XMapWindow(display, window);
	xlib::XFlush(display);

	thread::sleep_ms(3000);

	println!("Close");
	// it is good programming practice to return system resources to the system...
	xlib::XFreeGC(display, graphics_context);
	xlib::XDestroyWindow(display, window);
	xlib::XCloseDisplay(display);

	}
}<|endoftext|>


<commit_before><commit_msg>depot_tools work<commit_after><|endoftext|>


<commit_before><commit_msg>Implement Slide iterator<commit_after><|endoftext|>


<commit_before><commit_msg>fixed bug in 64/32 bit check<commit_after><|endoftext|>


<commit_before><commit_msg>added test<commit_after><|endoftext|>


<commit_before><commit_msg>fixed check_rr in tests<commit_after><|endoftext|>


<commit_before><commit_msg>PackedStorage use shortcut<commit_after><|endoftext|>


<commit_before>#![feature(io)]

extern crate xml;

use std::ascii::AsciiExt;
use std::default::Default;
use std::iter::IteratorExt;
use std::io;
use xml::{Element, ElementBuilder, Parser, Xml};

fn elem_with_text(tag_name: &'static str, chars: &str) -> Element {
    let mut elem = Element::new(tag_name, None, &[]);
    elem.text(chars);
    elem
}

trait ViaXml {
    fn to_xml(&self) -> Element;
    fn from_xml(element: Element) -> Self;
}

/// RSS
///
/// "At the top level, a RSS document is a \<rss\> element, with a mandatory attribute called
/// version, that specifies the version of RSS that the document conforms to. If it conforms to
/// this specification, the version attribute must be 2.0."
///
/// [RSS 2.0 Specification § RSS]
/// (http://cyber.law.harvard.edu/rss/rss.html#whatIsRss)
#[derive(Default)]
pub struct Rss(pub Channel);

impl ViaXml for Rss {
    fn to_xml(&self) -> Element {
        let mut rss = Element::new("rss", None, &[("version", None, "2.0")]);

        let &Rss(ref channel) = self;
        rss.tag(channel.to_xml());

        rss
    }

    fn from_xml(element: Element) -> Self {
        if element.name.to_ascii_lowercase() != "rss" {
            panic!("Expected <rss>, found <{}>", element.name);
        }

        let channel_element = element.get_child("channel", None).unwrap();
        let channel = ViaXml::from_xml(channel_element.clone());

        Rss(channel)
    }
}

impl Rss {
    fn to_string(&self) -> String {
        let mut ret = format!("{}", Xml::PINode("xml version='1.0' encoding='UTF-8'".to_string()));
        ret.push_str(&format!("{}", self.to_xml()));
        ret
    }

    fn from_read(reader: &mut io::Read) -> Self {
        let mut rss_string = String::new();

        match reader.read_to_string(&mut rss_string) {
            Ok(..) => (),
            Err(..) => panic!("Error reading string from reader"),
        }

        let mut parser = Parser::new();
        parser.feed_str(&rss_string);

        let mut builder = ElementBuilder::new();

        for event in parser {
            match builder.push_event(event) {
                Ok(Some(element)) => return ViaXml::from_xml(element),
                _ => (),
            }
        }

        panic!("RSS read error")
    }
}

/// Channel
///
/// "Subordinate to the \<rss\> element is a single \<channel\> element, which contains information
/// about the channel (metadata) and its contents."
///
/// [RSS 2.0 Specification § Channel]
/// (http://cyber.law.harvard.edu/rss/rss.html#requiredChannelElements)
///
/// ## Examples
///
/// ```
/// use rss::Channel;
///
/// let channel = Channel {
///     title: "My Blog".to_string(),
///     link: "http://myblog.com".to_string(),
///     description: "Where I write stuff".to_string(),
///     items: vec![],
/// };
/// ```
#[derive(Default)]
pub struct Channel {
    pub title: String,
    pub link: String,
    pub description: String,
    pub items: Vec<Item>,
    // pub language: Option<String>,
    // pub copyright: Option<String>,
    // pub managing_editor: Option<String>,
    // pub web_master: Option<String>,
    // pub pub_date: Option<String>,
    // pub last_build_date: Option<String>,
    // pub category:
    // pub generator: Option<String>,
    // pub docs: Option<String>,
    // pub cloud:
    // pub ttl:
    // pub image: Option<String>,
    // pub rating: Option<String>,
    // pub text_input:
    // pub skip_hours: Option<String>,
    // pub skip_days: Option<String>,
}

impl ViaXml for Channel {
    fn to_xml(&self) -> Element {
        let mut channel = Element::new("channel", None, &[]);

        channel.tag(elem_with_text("title", &self.title));
        channel.tag(elem_with_text("link", &self.link));
        channel.tag(elem_with_text("description", &self.description));

        for item in &self.items {
            channel.tag(item.to_xml());
        }

        channel
    }

    fn from_xml(element: Element) -> Self {
        let mut channel: Channel = Default::default();

        match element.get_child("title", None) {
            Some(element) => channel.title = element.content_str(),
            None => (),
        }

        match element.get_child("link", None) {
            Some(element) => channel.link = element.content_str(),
            None => (),
        }

        match element.get_child("description", None) {
            Some(element) => channel.description = element.content_str(),
            None => (),
        }

        channel.items = element.get_children("item", None)
            .into_iter()
            .map(|e| ViaXml::from_xml(e.clone()))
            .collect();

        channel
    }
}

#[derive(Default)]
pub struct Item {
    pub title: Option<String>,
    pub link: Option<String>,
    pub description: Option<String>,
    // pub author
    // pub category
    // pub comments
    // pub enclosure
    // pub guid
    // pub pubDate
    // pub source
}

impl ViaXml for Item {
    fn to_xml(&self) -> Element {
        let mut item = Element::new("item", None, &[]);

        if let Some(ref s) = self.title {
            item.tag(elem_with_text("title", s));
        }

        if let Some(ref s) = self.link {
            item.tag(elem_with_text("link", s));
        }

        if let Some(ref s) = self.description {
            item.tag(elem_with_text("description", s));
        }

        item
    }

    fn from_xml(element: Element) -> Self {
        let mut item: Item = Default::default();

        match element.get_child("title", None) {
            Some(element) => item.title = Some(element.content_str()),
            None => (),
        }

        match element.get_child("link", None) {
            Some(element) => item.link = Some(element.content_str()),
            None => (),
        }

        match element.get_child("description", None) {
            Some(element) => item.description = Some(element.content_str()),
            None => (),
        }

        item
    }
}

#[cfg(test)]
mod test {
    use super::{Rss, Item, Channel};

    #[test]
    fn test_basic_to_string() {
        let item = Item {
            title: Some("My first post!".to_string()),
            link: Some("http://myblog.com/post1".to_string()),
            description: Some("This is my first post".to_string()),
        };

        let channel = Channel {
            title: "My Blog".to_string(),
            link: "http://myblog.com".to_string(),
            description: "Where I write stuff".to_string(),
            items: vec![item],
        };

        let rss = Rss(channel);
        assert_eq!(rss.to_string(), "<?xml version=\'1.0\' encoding=\'UTF-8\'?><rss version=\'2.0\'><channel><title>My Blog</title><link>http://myblog.com</link><description>Where I write stuff</description><item><title>My first post!</title><link>http://myblog.com/post1</link><description>This is my first post</description></item></channel></rss>");
    }

    #[test]
    fn test_from_file() {
        let mut file = File::open("test-data/pinboard.xml").unwrap();
        let Rss(channel) = Rss::from_read(&mut file);
    }

    #[test]
    #[should_fail]
    fn test_from_read_no_channels() {
        let mut rss_bytes = "<rss></rss>".as_bytes();
        let Rss(channel) = Rss::from_read(&mut rss_bytes);
    }

    #[test]
    fn test_from_read_one_channel() {
        let mut rss_bytes = "<rss><channel></channel></rss>".as_bytes();
        let Rss(channel) = Rss::from_read(&mut rss_bytes);
    }

    #[test]
    fn test_from_read_one_channel_with_title() {
        let mut rss_bytes = "<rss><channel><title>Hello world!</title></channel></rss>".as_bytes();
        let Rss(channel) = Rss::from_read(&mut rss_bytes);
        assert_eq!("Hello world!", channel.title);
    }
}
<commit_msg>Add necessary import in tests module<commit_after>#![feature(fs, io)]

extern crate xml;

use std::ascii::AsciiExt;
use std::default::Default;
use std::iter::IteratorExt;
use std::io;
use xml::{Element, ElementBuilder, Parser, Xml};

fn elem_with_text(tag_name: &'static str, chars: &str) -> Element {
    let mut elem = Element::new(tag_name, None, &[]);
    elem.text(chars);
    elem
}

trait ViaXml {
    fn to_xml(&self) -> Element;
    fn from_xml(element: Element) -> Self;
}

/// RSS
///
/// "At the top level, a RSS document is a \<rss\> element, with a mandatory attribute called
/// version, that specifies the version of RSS that the document conforms to. If it conforms to
/// this specification, the version attribute must be 2.0."
///
/// [RSS 2.0 Specification § RSS]
/// (http://cyber.law.harvard.edu/rss/rss.html#whatIsRss)
#[derive(Default)]
pub struct Rss(pub Channel);

impl ViaXml for Rss {
    fn to_xml(&self) -> Element {
        let mut rss = Element::new("rss", None, &[("version", None, "2.0")]);

        let &Rss(ref channel) = self;
        rss.tag(channel.to_xml());

        rss
    }

    fn from_xml(element: Element) -> Self {
        if element.name.to_ascii_lowercase() != "rss" {
            panic!("Expected <rss>, found <{}>", element.name);
        }

        let channel_element = element.get_child("channel", None).unwrap();
        let channel = ViaXml::from_xml(channel_element.clone());

        Rss(channel)
    }
}

impl Rss {
    fn to_string(&self) -> String {
        let mut ret = format!("{}", Xml::PINode("xml version='1.0' encoding='UTF-8'".to_string()));
        ret.push_str(&format!("{}", self.to_xml()));
        ret
    }

    fn from_read(reader: &mut io::Read) -> Self {
        let mut rss_string = String::new();

        match reader.read_to_string(&mut rss_string) {
            Ok(..) => (),
            Err(..) => panic!("Error reading string from reader"),
        }

        let mut parser = Parser::new();
        parser.feed_str(&rss_string);

        let mut builder = ElementBuilder::new();

        for event in parser {
            match builder.push_event(event) {
                Ok(Some(element)) => return ViaXml::from_xml(element),
                _ => (),
            }
        }

        panic!("RSS read error")
    }
}

/// Channel
///
/// "Subordinate to the \<rss\> element is a single \<channel\> element, which contains information
/// about the channel (metadata) and its contents."
///
/// [RSS 2.0 Specification § Channel]
/// (http://cyber.law.harvard.edu/rss/rss.html#requiredChannelElements)
///
/// ## Examples
///
/// ```
/// use rss::Channel;
///
/// let channel = Channel {
///     title: "My Blog".to_string(),
///     link: "http://myblog.com".to_string(),
///     description: "Where I write stuff".to_string(),
///     items: vec![],
/// };
/// ```
#[derive(Default)]
pub struct Channel {
    pub title: String,
    pub link: String,
    pub description: String,
    pub items: Vec<Item>,
    // pub language: Option<String>,
    // pub copyright: Option<String>,
    // pub managing_editor: Option<String>,
    // pub web_master: Option<String>,
    // pub pub_date: Option<String>,
    // pub last_build_date: Option<String>,
    // pub category:
    // pub generator: Option<String>,
    // pub docs: Option<String>,
    // pub cloud:
    // pub ttl:
    // pub image: Option<String>,
    // pub rating: Option<String>,
    // pub text_input:
    // pub skip_hours: Option<String>,
    // pub skip_days: Option<String>,
}

impl ViaXml for Channel {
    fn to_xml(&self) -> Element {
        let mut channel = Element::new("channel", None, &[]);

        channel.tag(elem_with_text("title", &self.title));
        channel.tag(elem_with_text("link", &self.link));
        channel.tag(elem_with_text("description", &self.description));

        for item in &self.items {
            channel.tag(item.to_xml());
        }

        channel
    }

    fn from_xml(element: Element) -> Self {
        let mut channel: Channel = Default::default();

        match element.get_child("title", None) {
            Some(element) => channel.title = element.content_str(),
            None => (),
        }

        match element.get_child("link", None) {
            Some(element) => channel.link = element.content_str(),
            None => (),
        }

        match element.get_child("description", None) {
            Some(element) => channel.description = element.content_str(),
            None => (),
        }

        channel.items = element.get_children("item", None)
            .into_iter()
            .map(|e| ViaXml::from_xml(e.clone()))
            .collect();

        channel
    }
}

#[derive(Default)]
pub struct Item {
    pub title: Option<String>,
    pub link: Option<String>,
    pub description: Option<String>,
    // pub author
    // pub category
    // pub comments
    // pub enclosure
    // pub guid
    // pub pubDate
    // pub source
}

impl ViaXml for Item {
    fn to_xml(&self) -> Element {
        let mut item = Element::new("item", None, &[]);

        if let Some(ref s) = self.title {
            item.tag(elem_with_text("title", s));
        }

        if let Some(ref s) = self.link {
            item.tag(elem_with_text("link", s));
        }

        if let Some(ref s) = self.description {
            item.tag(elem_with_text("description", s));
        }

        item
    }

    fn from_xml(element: Element) -> Self {
        let mut item: Item = Default::default();

        match element.get_child("title", None) {
            Some(element) => item.title = Some(element.content_str()),
            None => (),
        }

        match element.get_child("link", None) {
            Some(element) => item.link = Some(element.content_str()),
            None => (),
        }

        match element.get_child("description", None) {
            Some(element) => item.description = Some(element.content_str()),
            None => (),
        }

        Ok(item)
    }
}

#[cfg(test)]
mod test {
    use std::fs::File;
    use super::{Rss, Item, Channel};

    #[test]
    fn test_basic_to_string() {
        let item = Item {
            title: Some("My first post!".to_string()),
            link: Some("http://myblog.com/post1".to_string()),
            description: Some("This is my first post".to_string()),
        };

        let channel = Channel {
            title: "My Blog".to_string(),
            link: "http://myblog.com".to_string(),
            description: "Where I write stuff".to_string(),
            items: vec![item],
        };

        let rss = Rss(channel);
        assert_eq!(rss.to_string(), "<?xml version=\'1.0\' encoding=\'UTF-8\'?><rss version=\'2.0\'><channel><title>My Blog</title><link>http://myblog.com</link><description>Where I write stuff</description><item><title>My first post!</title><link>http://myblog.com/post1</link><description>This is my first post</description></item></channel></rss>");
    }

    #[test]
    fn test_from_file() {
        let mut file = File::open("test-data/pinboard.xml").unwrap();
        let Rss(channel) = Rss::from_read(&mut file);
    }

    #[test]
    #[should_fail]
    fn test_from_read_no_channels() {
        let mut rss_bytes = "<rss></rss>".as_bytes();
        let Rss(channel) = Rss::from_read(&mut rss_bytes);
    }

    #[test]
    fn test_from_read_one_channel() {
        let mut rss_bytes = "<rss><channel></channel></rss>".as_bytes();
        let Rss(channel) = Rss::from_read(&mut rss_bytes);
    }

    #[test]
    fn test_from_read_one_channel_with_title() {
        let mut rss_bytes = "<rss><channel><title>Hello world!</title></channel></rss>".as_bytes();
        let Rss(channel) = Rss::from_read(&mut rss_bytes);
        assert_eq!("Hello world!", channel.title);
    }
}
<|endoftext|>


<commit_before><commit_msg>Remove references to UNIX epoch.<commit_after><|endoftext|>


<commit_before>extern crate zip;
extern crate quick_xml;
extern crate encoding;
extern crate byteorder;
#[macro_use]
extern crate error_chain;

#[macro_use]
extern crate log;

mod errors;
mod vba;

use std::path::Path;
use std::fs::File;
use std::io::BufReader;
use std::collections::HashMap;
use std::slice::Chunks;

pub use errors::*;
use vba::VbaProject;

use zip::read::{ZipFile, ZipArchive};
use zip::result::ZipError;
use quick_xml::{XmlReader, Event, AsStr};

macro_rules! unexp {
    ($pat: expr) => {
        {
            return Err($pat.into());
        }
    };
    ($pat: expr, $($args: expr)* ) => {
        {
            return Err(format!($pat, $($args)*).into());
        }
    };
}

#[derive(Debug, Clone)]
pub enum DataType {
    Int(i64),
    Float(f64),
    String(String),
    Empty,
}

pub struct Excel {
    zip: ZipArchive<File>,
    strings: Vec<String>,
    /// Map of sheet names/sheet path within zip archive
    sheets: HashMap<String, String>,
}

#[derive(Debug, Default)]
pub struct Range {
    position: (u32, u32),
    size: (usize, usize),
    inner: Vec<DataType>,
}

/// An iterator to read `Range` struct row by row
pub struct Rows<'a> {
    inner: Chunks<'a, DataType>,
}

impl Excel {

    /// Opens a new workbook
    pub fn open<P: AsRef<Path>>(path: P) -> Result<Excel> {
        let f = try!(File::open(path));
        let zip = try!(ZipArchive::new(f));
        Ok(Excel { zip: zip, strings: vec![], sheets: HashMap::new() })
    }

    /// Does the workbook contain a vba project
    pub fn has_vba(&mut self) -> bool {
        self.zip.by_name("xl/vbaProject.bin").is_ok()
    }

    /// Gets vba project
    pub fn vba_project(&mut self) -> Result<VbaProject> {
        let f = try!(self.zip.by_name("xl/vbaProject.bin"));
        VbaProject::new(f)
    }

    /// Get all data from `Worksheet`
    pub fn worksheet_range(&mut self, name: &str) -> Result<Range> {
        try!(self.read_shared_strings());
        try!(self.read_sheets_names());
        let strings = &self.strings;
        let ws = match self.sheets.get(name) {
            Some(p) => try!(self.zip.by_name(p)),
            None => unexp!("Sheet '{}' does not exist", name),
        };
        Range::from_worksheet(ws, strings)
    }

    /// Loop through all archive files and opens 'xl/worksheets' files
    /// Store sheet name and path into self.sheets
    fn read_sheets_names(&mut self) -> Result<()> {
        if self.sheets.is_empty() {
            let sheets = {
                let mut sheets = HashMap::new();
                for i in 0..self.zip.len() {
                    let f = try!(self.zip.by_index(i));
                    let name = f.name().to_string();
                    if name.starts_with("xl/worksheets/") {
                        let xml = XmlReader::from_reader(BufReader::new(f))
                            .with_check(false)
                            .trim_text(false);
                        'xml_loop: for res_event in xml {
                            if let Ok(Event::Start(ref e)) = res_event {
                                if e.name() == b"sheetPr" {
                                    for a in e.attributes() {
                                        if let Ok((b"codeName", v)) = a {
                                            sheets.insert(try!(v.as_str()).to_string(), name);
                                            break 'xml_loop;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                sheets
            };
            self.sheets = sheets;
        }
        Ok(())
    }

    /// Read shared string list
    fn read_shared_strings(&mut self) -> Result<()> {
        if self.strings.is_empty() {
            match self.zip.by_name("xl/sharedStrings.xml") {
                Ok(f) => {
                    let mut xml = XmlReader::from_reader(BufReader::new(f))
                        .with_check(false)
                        .trim_text(false);

                    let mut strings = Vec::new();
                    while let Some(res_event) = xml.next() {
                        match res_event {
                            Ok(Event::Start(ref e)) if e.name() == b"t" => {
                                strings.push(try!(xml.read_text(b"t")));
                            }
                            Err(e) => return Err(e.into()),
                            _ => (),
                        }
                    }
                    self.strings = strings;
                },
                Err(ZipError::FileNotFound) => (),
                Err(e) => return Err(e.into()),
            }
        }

        Ok(())
    }

}

impl Range {

    /// open a xml `ZipFile` reader and read content of *sheetData* and *dimension* node
    fn from_worksheet(xml: ZipFile, strings: &[String]) -> Result<Range> {
        let mut xml = XmlReader::from_reader(BufReader::new(xml))
            .with_check(false)
            .trim_text(false);
        let mut data = Range::default();
        while let Some(res_event) = xml.next() {
            match res_event {
                Err(e) => return Err(e.into()),
                Ok(Event::Start(ref e)) => {
                    match e.name() {
                        b"dimension" => match e.attributes().filter_map(|a| a.ok())
                                .find(|&(key, _)| key == b"ref") {
                            Some((_, dim)) => {
                                let (position, size) = try!(get_dimension(try!(dim.as_str())));
                                data.position = position;
                                data.size = (size.0 as usize, size.1 as usize);
                                data.inner.reserve_exact(data.size.0 * data.size.1);
                            },
                            None => unexp!("Expecting dimension, got {:?}", e),
                        },
                        b"sheetData" => {
                            let _ = try!(data.read_sheet_data(&mut xml, strings));
                        }
                        _ => (),
                    }
                },
                _ => (),
            }
        }
        data.inner.shrink_to_fit();
        Ok(data)
    }

    /// get worksheet position (row, column)
    pub fn get_position(&self) -> (u32, u32) {
        self.position
    }

    /// get size
    pub fn get_size(&self) -> (usize, usize) {
        self.size
    }

    /// get cell value
    pub fn get_value(&self, i: usize, j: usize) -> &DataType {
        let idx = i * self.size.0 + j;
        &self.inner[idx]
    }

    /// get an iterator over inner rows
    pub fn rows(&self) -> Rows {
        let width = self.size.0;
        Rows { inner: self.inner.chunks(width) }
    }

    /// read sheetData node
    fn read_sheet_data(&mut self, xml: &mut XmlReader<BufReader<ZipFile>>, strings: &[String])
        -> Result<()>
    {
        while let Some(res_event) = xml.next() {
            match res_event {
                Err(e) => return Err(e.into()),
                Ok(Event::Start(ref c_element)) => {
                    if c_element.name() == b"c" {
                        loop {
                            match xml.next() {
                                Some(Err(e)) => return Err(e.into()),
                                Some(Ok(Event::Start(ref e))) => {
                                    if e.name() == b"v" {
                                        let v = try!(xml.read_text(b"v"));
                                        let value = match c_element.attributes()
                                            .filter_map(|a| a.ok())
                                            .find(|&(k, _)| k == b"t") {
                                                Some((_, b"s")) => {
                                                    let idx: usize = try!(v.parse());
                                                    DataType::String(strings[idx].clone())
                                                },
                                                // TODO: check in styles to know which type is
                                                // supposed to be used
                                                _ => match v.parse() {
                                                    Ok(i) => DataType::Int(i),
                                                    Err(_) => try!(v.parse()
                                                                   .map(DataType::Float)),
                                                },
                                            };
                                        self.inner.push(value);
                                        break;
                                    } else {
                                        unexp!("not v node");
                                    }
                                },
                                Some(Ok(Event::End(ref e))) => {
                                    if e.name() == b"c" {
                                        self.inner.push(DataType::Empty);
                                        break;
                                    }
                                }
                                None => unexp!("End of xml"),
                                _ => (),
                            }
                        }
                    }
                },
                Ok(Event::End(ref e)) if e.name() == b"sheetData" => return Ok(()),
                _ => (),
            }
        }
        unexp!("Could not find </sheetData>")
    }

}

impl<'a> Iterator for Rows<'a> {
    type Item = &'a [DataType];
    fn next(&mut self) -> Option<&'a [DataType]> {
        self.inner.next()
    }
}

/// converts a text representation (e.g. "A6:G67") of a dimension into integers
/// - top left (row, column),
/// - size (width, height)
fn get_dimension(dimension: &str) -> Result<((u32, u32), (u32, u32))> {
    match dimension.chars().position(|c| c == ':') {
        None => {
            get_row_column(dimension).map(|position| (position, (1, 1)))
        },
        Some(p) => {
            let top_left = try!(get_row_column(&dimension[..p]));
            let bottom_right = try!(get_row_column(&dimension[p + 1..]));
            Ok((top_left, (bottom_right.0 - top_left.0 + 1, bottom_right.1 - top_left.1 + 1)))
        }
    }
}

/// converts a text range name into its position (row, column)
fn get_row_column(range: &str) -> Result<(u32, u32)> {
    let mut col = 0;
    let mut pow = 1;
    let mut rowpos = range.len();
    let mut readrow = true;
    for c in range.chars().rev() {
        match c {
            '0'...'9' => {
                if readrow {
                    rowpos -= 1;
                } else {
                    unexp!("Numeric character are only allowed at the end of the range: {}", c);
                }
            }
            c @ 'A'...'Z' => {
                readrow = false;
                col += ((c as u8 - b'A') as u32 + 1) * pow;
                pow *= 26;
            },
            c @ 'a'...'z' => {
                readrow = false;
                col += ((c as u8 - b'a') as u32 + 1) * pow;
                pow *= 26;
            },
            _ => unexp!("Expecting alphanumeric character, got {:?}", c),
        }
    }
    let row = try!(range[rowpos..].parse());
    Ok((row, col))
}

#[cfg(test)]
mod tests {

    extern crate env_logger;

    use super::Excel;

    #[test]
    fn test_range_sample() {
        let mut xl = Excel::open("/home/jtuffe/download/DailyValo_FX_Rates_Credit_05 25 16.xlsm")
            .expect("cannot open excel file");
        println!("{:?}", xl.sheets);
        let data = xl.worksheet_range("Sheet1");
        assert!(data.is_ok());
        for (i, r) in data.unwrap().rows().enumerate() {
            println!("Row {}: {:?}", i, r);
        }
    }

    #[test]
    fn test_vba() {

        env_logger::init().unwrap();

//         let path = "/home/jtuffe/download/test_vba.xlsm";
        let path = "/home/jtuffe/download/Extractions Simples.xlsb";
        let path = "/home/jtuffe/download/test_xl/ReportRDM_CVA VF_v3.xlsm";
        let mut xl = Excel::open(path).expect("cannot open excel file");
        let vba_project = xl.vba_project().unwrap();
        let vba = vba_project.read_vba();
        let (references, modules) = vba.unwrap();
        println!("references: {:#?}", references);
        for module in &modules {
            let data = vba_project.read_module(module).unwrap();
            println!("module {}:\r\n{}", module.name, data);
        }

    }
}
<commit_msg>pub vba<commit_after>extern crate zip;
extern crate quick_xml;
extern crate encoding;
extern crate byteorder;
#[macro_use]
extern crate error_chain;

#[macro_use]
extern crate log;

mod errors;
pub mod vba;

use std::path::Path;
use std::fs::File;
use std::io::BufReader;
use std::collections::HashMap;
use std::slice::Chunks;

pub use errors::*;
use vba::VbaProject;

use zip::read::{ZipFile, ZipArchive};
use zip::result::ZipError;
use quick_xml::{XmlReader, Event, AsStr};

macro_rules! unexp {
    ($pat: expr) => {
        {
            return Err($pat.into());
        }
    };
    ($pat: expr, $($args: expr)* ) => {
        {
            return Err(format!($pat, $($args)*).into());
        }
    };
}

#[derive(Debug, Clone)]
pub enum DataType {
    Int(i64),
    Float(f64),
    String(String),
    Empty,
}

pub struct Excel {
    zip: ZipArchive<File>,
    strings: Vec<String>,
    /// Map of sheet names/sheet path within zip archive
    sheets: HashMap<String, String>,
}

#[derive(Debug, Default)]
pub struct Range {
    position: (u32, u32),
    size: (usize, usize),
    inner: Vec<DataType>,
}

/// An iterator to read `Range` struct row by row
pub struct Rows<'a> {
    inner: Chunks<'a, DataType>,
}

impl Excel {

    /// Opens a new workbook
    pub fn open<P: AsRef<Path>>(path: P) -> Result<Excel> {
        let f = try!(File::open(path));
        let zip = try!(ZipArchive::new(f));
        Ok(Excel { zip: zip, strings: vec![], sheets: HashMap::new() })
    }

    /// Does the workbook contain a vba project
    pub fn has_vba(&mut self) -> bool {
        self.zip.by_name("xl/vbaProject.bin").is_ok()
    }

    /// Gets vba project
    pub fn vba_project(&mut self) -> Result<VbaProject> {
        let f = try!(self.zip.by_name("xl/vbaProject.bin"));
        VbaProject::new(f)
    }

    /// Get all data from `Worksheet`
    pub fn worksheet_range(&mut self, name: &str) -> Result<Range> {
        try!(self.read_shared_strings());
        try!(self.read_sheets_names());
        let strings = &self.strings;
        let ws = match self.sheets.get(name) {
            Some(p) => try!(self.zip.by_name(p)),
            None => unexp!("Sheet '{}' does not exist", name),
        };
        Range::from_worksheet(ws, strings)
    }

    /// Loop through all archive files and opens 'xl/worksheets' files
    /// Store sheet name and path into self.sheets
    fn read_sheets_names(&mut self) -> Result<()> {
        if self.sheets.is_empty() {
            let sheets = {
                let mut sheets = HashMap::new();
                for i in 0..self.zip.len() {
                    let f = try!(self.zip.by_index(i));
                    let name = f.name().to_string();
                    if name.starts_with("xl/worksheets/") {
                        let xml = XmlReader::from_reader(BufReader::new(f))
                            .with_check(false)
                            .trim_text(false);
                        'xml_loop: for res_event in xml {
                            if let Ok(Event::Start(ref e)) = res_event {
                                if e.name() == b"sheetPr" {
                                    for a in e.attributes() {
                                        if let Ok((b"codeName", v)) = a {
                                            sheets.insert(try!(v.as_str()).to_string(), name);
                                            break 'xml_loop;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                sheets
            };
            self.sheets = sheets;
        }
        Ok(())
    }

    /// Read shared string list
    fn read_shared_strings(&mut self) -> Result<()> {
        if self.strings.is_empty() {
            match self.zip.by_name("xl/sharedStrings.xml") {
                Ok(f) => {
                    let mut xml = XmlReader::from_reader(BufReader::new(f))
                        .with_check(false)
                        .trim_text(false);

                    let mut strings = Vec::new();
                    while let Some(res_event) = xml.next() {
                        match res_event {
                            Ok(Event::Start(ref e)) if e.name() == b"t" => {
                                strings.push(try!(xml.read_text(b"t")));
                            }
                            Err(e) => return Err(e.into()),
                            _ => (),
                        }
                    }
                    self.strings = strings;
                },
                Err(ZipError::FileNotFound) => (),
                Err(e) => return Err(e.into()),
            }
        }

        Ok(())
    }

}

impl Range {

    /// open a xml `ZipFile` reader and read content of *sheetData* and *dimension* node
    fn from_worksheet(xml: ZipFile, strings: &[String]) -> Result<Range> {
        let mut xml = XmlReader::from_reader(BufReader::new(xml))
            .with_check(false)
            .trim_text(false);
        let mut data = Range::default();
        while let Some(res_event) = xml.next() {
            match res_event {
                Err(e) => return Err(e.into()),
                Ok(Event::Start(ref e)) => {
                    match e.name() {
                        b"dimension" => match e.attributes().filter_map(|a| a.ok())
                                .find(|&(key, _)| key == b"ref") {
                            Some((_, dim)) => {
                                let (position, size) = try!(get_dimension(try!(dim.as_str())));
                                data.position = position;
                                data.size = (size.0 as usize, size.1 as usize);
                                data.inner.reserve_exact(data.size.0 * data.size.1);
                            },
                            None => unexp!("Expecting dimension, got {:?}", e),
                        },
                        b"sheetData" => {
                            let _ = try!(data.read_sheet_data(&mut xml, strings));
                        }
                        _ => (),
                    }
                },
                _ => (),
            }
        }
        data.inner.shrink_to_fit();
        Ok(data)
    }

    /// get worksheet position (row, column)
    pub fn get_position(&self) -> (u32, u32) {
        self.position
    }

    /// get size
    pub fn get_size(&self) -> (usize, usize) {
        self.size
    }

    /// get cell value
    pub fn get_value(&self, i: usize, j: usize) -> &DataType {
        let idx = i * self.size.0 + j;
        &self.inner[idx]
    }

    /// get an iterator over inner rows
    pub fn rows(&self) -> Rows {
        let width = self.size.0;
        Rows { inner: self.inner.chunks(width) }
    }

    /// read sheetData node
    fn read_sheet_data(&mut self, xml: &mut XmlReader<BufReader<ZipFile>>, strings: &[String])
        -> Result<()>
    {
        while let Some(res_event) = xml.next() {
            match res_event {
                Err(e) => return Err(e.into()),
                Ok(Event::Start(ref c_element)) => {
                    if c_element.name() == b"c" {
                        loop {
                            match xml.next() {
                                Some(Err(e)) => return Err(e.into()),
                                Some(Ok(Event::Start(ref e))) => {
                                    if e.name() == b"v" {
                                        let v = try!(xml.read_text(b"v"));
                                        let value = match c_element.attributes()
                                            .filter_map(|a| a.ok())
                                            .find(|&(k, _)| k == b"t") {
                                                Some((_, b"s")) => {
                                                    let idx: usize = try!(v.parse());
                                                    DataType::String(strings[idx].clone())
                                                },
                                                // TODO: check in styles to know which type is
                                                // supposed to be used
                                                _ => match v.parse() {
                                                    Ok(i) => DataType::Int(i),
                                                    Err(_) => try!(v.parse()
                                                                   .map(DataType::Float)),
                                                },
                                            };
                                        self.inner.push(value);
                                        break;
                                    } else {
                                        unexp!("not v node");
                                    }
                                },
                                Some(Ok(Event::End(ref e))) => {
                                    if e.name() == b"c" {
                                        self.inner.push(DataType::Empty);
                                        break;
                                    }
                                }
                                None => unexp!("End of xml"),
                                _ => (),
                            }
                        }
                    }
                },
                Ok(Event::End(ref e)) if e.name() == b"sheetData" => return Ok(()),
                _ => (),
            }
        }
        unexp!("Could not find </sheetData>")
    }

}

impl<'a> Iterator for Rows<'a> {
    type Item = &'a [DataType];
    fn next(&mut self) -> Option<&'a [DataType]> {
        self.inner.next()
    }
}

/// converts a text representation (e.g. "A6:G67") of a dimension into integers
/// - top left (row, column),
/// - size (width, height)
fn get_dimension(dimension: &str) -> Result<((u32, u32), (u32, u32))> {
    match dimension.chars().position(|c| c == ':') {
        None => {
            get_row_column(dimension).map(|position| (position, (1, 1)))
        },
        Some(p) => {
            let top_left = try!(get_row_column(&dimension[..p]));
            let bottom_right = try!(get_row_column(&dimension[p + 1..]));
            Ok((top_left, (bottom_right.0 - top_left.0 + 1, bottom_right.1 - top_left.1 + 1)))
        }
    }
}

/// converts a text range name into its position (row, column)
fn get_row_column(range: &str) -> Result<(u32, u32)> {
    let mut col = 0;
    let mut pow = 1;
    let mut rowpos = range.len();
    let mut readrow = true;
    for c in range.chars().rev() {
        match c {
            '0'...'9' => {
                if readrow {
                    rowpos -= 1;
                } else {
                    unexp!("Numeric character are only allowed at the end of the range: {}", c);
                }
            }
            c @ 'A'...'Z' => {
                readrow = false;
                col += ((c as u8 - b'A') as u32 + 1) * pow;
                pow *= 26;
            },
            c @ 'a'...'z' => {
                readrow = false;
                col += ((c as u8 - b'a') as u32 + 1) * pow;
                pow *= 26;
            },
            _ => unexp!("Expecting alphanumeric character, got {:?}", c),
        }
    }
    let row = try!(range[rowpos..].parse());
    Ok((row, col))
}

#[cfg(test)]
mod tests {

    extern crate env_logger;

    use super::Excel;

    #[test]
    fn test_range_sample() {
        let mut xl = Excel::open("/home/jtuffe/download/DailyValo_FX_Rates_Credit_05 25 16.xlsm")
            .expect("cannot open excel file");
        println!("{:?}", xl.sheets);
        let data = xl.worksheet_range("Sheet1");
        assert!(data.is_ok());
        for (i, r) in data.unwrap().rows().enumerate() {
            println!("Row {}: {:?}", i, r);
        }
    }

    #[test]
    fn test_vba() {

        env_logger::init().unwrap();

//         let path = "/home/jtuffe/download/test_vba.xlsm";
        let path = "/home/jtuffe/download/Extractions Simples.xlsb";
        let path = "/home/jtuffe/download/test_xl/ReportRDM_CVA VF_v3.xlsm";
        let mut xl = Excel::open(path).expect("cannot open excel file");
        let vba_project = xl.vba_project().unwrap();
        let vba = vba_project.read_vba();
        let (references, modules) = vba.unwrap();
        println!("references: {:#?}", references);
        for module in &modules {
            let data = vba_project.read_module(module).unwrap();
            println!("module {}:\r\n{}", module.name, data);
        }

    }
}
<|endoftext|>


<commit_before><commit_msg>Adding alpha field to bitmask.<commit_after><|endoftext|>


<commit_before><commit_msg>add test for hashing trait impls<commit_after>// Copyright 2016 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.

// This test case tests the incremental compilation hash (ICH) implementation
// for let expressions.

// The general pattern followed here is: Change one thing between rev1 and rev2
// and make sure that the hash has changed, then change nothing between rev2 and
// rev3 and make sure that the hash has not changed.

// must-compile-successfully
// revisions: cfail1 cfail2 cfail3
// compile-flags: -Z query-dep-graph

#![allow(warnings)]
#![feature(rustc_attrs)]
#![feature(specialization)]
#![crate_type="rlib"]

struct Foo;

// Change Method Name -----------------------------------------------------------

#[cfg(cfail1)]
pub trait ChangeMethodNameTrait {
    fn method_name();
}

#[cfg(cfail1)]
impl ChangeMethodNameTrait for Foo {
    fn method_name() { }
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub trait ChangeMethodNameTrait {
    #[rustc_dirty(label="Hir", cfg="cfail2")]
    #[rustc_clean(label="Hir", cfg="cfail3")]
    #[rustc_metadata_dirty(cfg="cfail2")]
    #[rustc_metadata_clean(cfg="cfail3")]
    fn method_name2();
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl ChangeMethodNameTrait for Foo {
    #[rustc_dirty(label="Hir", cfg="cfail2")]
    #[rustc_clean(label="Hir", cfg="cfail3")]
    #[rustc_metadata_dirty(cfg="cfail2")]
    #[rustc_metadata_clean(cfg="cfail3")]
    fn method_name2() { }
}

// Change Method Body -----------------------------------------------------------
//
// This should affect the method itself, but not the trait.

pub trait ChangeMethodBodyTrait {
    fn method_name();
}

#[cfg(cfail1)]
impl ChangeMethodBodyTrait for Foo {
    fn method_name() { }
}

#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_clean(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl ChangeMethodBodyTrait for Foo {
    #[rustc_dirty(label="Hir", cfg="cfail2")]
    #[rustc_clean(label="Hir", cfg="cfail3")]
    #[rustc_metadata_dirty(cfg="cfail2")]
    #[rustc_metadata_clean(cfg="cfail3")]
    fn method_name() {
        ()
    }
}

// Change Method Selfness -----------------------------------------------------------

#[cfg(cfail1)]
pub trait ChangeMethodSelfnessTrait {
    fn method_name();
}

#[cfg(cfail1)]
impl ChangeMethodSelfnessTrait for Foo {
    fn method_name() { }
}

#[cfg(not(cfail1))]
pub trait ChangeMethodSelfnessTrait {
    fn method_name(&self);
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl ChangeMethodSelfnessTrait for Foo {
    #[rustc_dirty(label="Hir", cfg="cfail2")]
    #[rustc_clean(label="Hir", cfg="cfail3")]
    #[rustc_metadata_dirty(cfg="cfail2")]
    #[rustc_metadata_clean(cfg="cfail3")]
    fn method_name(&self) {
        ()
    }
}

// Change Method Selfness -----------------------------------------------------------

#[cfg(cfail1)]
pub trait RemoveMethodSelfnessTrait {
    fn method_name(&self);
}

#[cfg(cfail1)]
impl RemoveMethodSelfnessTrait for Foo {
    fn method_name(&self) { }
}

#[cfg(not(cfail1))]
pub trait RemoveMethodSelfnessTrait {
    fn method_name();
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl RemoveMethodSelfnessTrait for Foo {
    #[rustc_dirty(label="Hir", cfg="cfail2")]
    #[rustc_clean(label="Hir", cfg="cfail3")]
    #[rustc_metadata_dirty(cfg="cfail2")]
    #[rustc_metadata_clean(cfg="cfail3")]
    fn method_name() {
        ()
    }
}

// Change Method Selfmutness -----------------------------------------------------------

#[cfg(cfail1)]
pub trait ChangeMethodSelfmutnessTrait {
    fn method_name(&self);
}

#[cfg(cfail1)]
impl ChangeMethodSelfmutnessTrait for Foo {
    fn method_name(&self) { }
}

#[cfg(not(cfail1))]
pub trait ChangeMethodSelfmutnessTrait {
    fn method_name(&mut self);
}

#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl ChangeMethodSelfmutnessTrait for Foo {
    #[rustc_dirty(label="Hir", cfg="cfail2")]
    #[rustc_clean(label="Hir", cfg="cfail3")]
    #[rustc_metadata_dirty(cfg="cfail2")]
    #[rustc_metadata_clean(cfg="cfail3")]
    fn method_name(&mut self) {
        ()
    }
}

// Change item kind -----------------------------------------------------------

#[cfg(cfail1)]
pub trait ChangeItemKindTrait {
    fn name();
}

#[cfg(cfail1)]
impl ChangeItemKindTrait for Foo {
    fn name() { }
}

#[cfg(not(cfail1))]
pub trait ChangeItemKindTrait {
    type name;
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl ChangeItemKindTrait for Foo {
    type name = ();
}

// Remove item -----------------------------------------------------------

#[cfg(cfail1)]
pub trait RemoveItemTrait {
    type TypeName;
    fn method_name();
}

#[cfg(cfail1)]
impl RemoveItemTrait for Foo {
    type TypeName = ();
    fn method_name() { }
}

#[cfg(not(cfail1))]
pub trait RemoveItemTrait {
    type TypeName;
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl RemoveItemTrait for Foo {
    type TypeName = ();
}

// Add item -----------------------------------------------------------

#[cfg(cfail1)]
pub trait AddItemTrait {
    type TypeName;
}

#[cfg(cfail1)]
impl AddItemTrait for Foo {
    type TypeName = ();
}

#[cfg(not(cfail1))]
pub trait AddItemTrait {
    type TypeName;
    fn method_name();
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl AddItemTrait for Foo {
    type TypeName = ();
    fn method_name() { }
}

// Change has-value -----------------------------------------------------------

#[cfg(cfail1)]
pub trait ChangeHasValueTrait {
    fn method_name();
}

#[cfg(cfail1)]
impl ChangeHasValueTrait for Foo {
    fn method_name() { }
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
pub trait ChangeHasValueTrait {
    fn method_name() { }
}

#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl ChangeHasValueTrait for Foo {
    fn method_name() { }
}

// Add default

pub trait AddDefaultTrait {
    fn method_name();
}

#[cfg(cfail1)]
impl AddDefaultTrait for Foo {
    fn method_name() { }
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl AddDefaultTrait for Foo {
    default fn method_name() { }
}

// Remove default

pub trait RemoveDefaultTrait {
    fn method_name();
}

#[cfg(cfail1)]
impl RemoveDefaultTrait for Foo {
    default fn method_name() { }
}

#[cfg(not(cfail1))]
#[rustc_dirty(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl RemoveDefaultTrait for Foo {
    fn method_name() { }
}

// Add arguments

#[cfg(cfail1)]
pub trait AddArgumentTrait {
    fn method_name(&self);
}

#[cfg(cfail1)]
impl AddArgumentTrait for Foo {
    fn method_name(&self) { }
}

#[cfg(not(cfail1))]
pub trait AddArgumentTrait {
    fn method_name(&self, x: u32);
}

#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl AddArgumentTrait for Foo {
    #[rustc_dirty(label="Hir", cfg="cfail2")]
    #[rustc_clean(label="Hir", cfg="cfail3")]
    #[rustc_metadata_dirty(cfg="cfail2")]
    #[rustc_metadata_clean(cfg="cfail3")]
    fn method_name(&self, _x: u32) { }
}

// Change argument type

#[cfg(cfail1)]
pub trait ChangeArgumentTypeTrait {
    fn method_name(&self, x: u32);
}

#[cfg(cfail1)]
impl ChangeArgumentTypeTrait for Foo {
    fn method_name(&self, _x: u32) { }
}

#[cfg(not(cfail1))]
pub trait ChangeArgumentTypeTrait {
    fn method_name(&self, x: char);
}

#[cfg(not(cfail1))]
#[rustc_clean(label="Hir", cfg="cfail2")]
#[rustc_clean(label="Hir", cfg="cfail3")]
#[rustc_metadata_dirty(cfg="cfail2")]
#[rustc_metadata_clean(cfg="cfail3")]
impl ChangeArgumentTypeTrait for Foo {
    #[rustc_dirty(label="Hir", cfg="cfail2")]
    #[rustc_clean(label="Hir", cfg="cfail3")]
    #[rustc_metadata_dirty(cfg="cfail2")]
    #[rustc_metadata_clean(cfg="cfail3")]
    fn method_name(&self, _x: char) { }
}

<|endoftext|>


<commit_before><commit_msg>Simplify the status transfer filter in the sweeps() test<commit_after><|endoftext|>


<commit_before><commit_msg>Bugfix: made pam-sys ffi structures' fields publics<commit_after><|endoftext|>


<commit_before><commit_msg>mutable fields in cell<commit_after><|endoftext|>


<commit_before><commit_msg>Replace TcpStream with DataStream<commit_after><|endoftext|>


<commit_before>// Copyright 2015 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.

//! Build configuration for Rust's release channels.
//!
//! Implements the stable/beta/nightly channel distinctions by setting various
//! flags like the `unstable_features`, calculating variables like `release` and
//! `package_vers`, and otherwise indicating to the compiler what it should
//! print out as part of its version information.

use std::path::Path;
use std::process::Command;

use build_helper::output;

use Build;

// The version number
pub const CFG_RELEASE_NUM: &'static str = "1.20.0";

// An optional number to put after the label, e.g. '.2' -> '-beta.2'
// Be sure to make this starts with a dot to conform to semver pre-release
// versions (section 9)
pub const CFG_PRERELEASE_VERSION: &'static str = ".1";

pub struct GitInfo {
    inner: Option<Info>,
}

struct Info {
    commit_date: String,
    sha: String,
    short_sha: String,
}

impl GitInfo {
    pub fn new(dir: &Path) -> GitInfo {
        // See if this even begins to look like a git dir
        if !dir.join(".git").exists() {
            return GitInfo { inner: None }
        }

        // Make sure git commands work
        let out = Command::new("git")
                          .arg("rev-parse")
                          .current_dir(dir)
                          .output()
                          .expect("failed to spawn git");
        if !out.status.success() {
            return GitInfo { inner: None }
        }

        // Ok, let's scrape some info
        let ver_date = output(Command::new("git").current_dir(dir)
                                      .arg("log").arg("-1")
                                      .arg("--date=short")
                                      .arg("--pretty=format:%cd"));
        let ver_hash = output(Command::new("git").current_dir(dir)
                                      .arg("rev-parse").arg("HEAD"));
        let short_ver_hash = output(Command::new("git")
                                            .current_dir(dir)
                                            .arg("rev-parse")
                                            .arg("--short=9")
                                            .arg("HEAD"));
        GitInfo {
            inner: Some(Info {
                commit_date: ver_date.trim().to_string(),
                sha: ver_hash.trim().to_string(),
                short_sha: short_ver_hash.trim().to_string(),
            }),
        }
    }

    pub fn sha(&self) -> Option<&str> {
        self.inner.as_ref().map(|s| &s.sha[..])
    }

    pub fn sha_short(&self) -> Option<&str> {
        self.inner.as_ref().map(|s| &s.short_sha[..])
    }

    pub fn commit_date(&self) -> Option<&str> {
        self.inner.as_ref().map(|s| &s.commit_date[..])
    }

    pub fn version(&self, build: &Build, num: &str) -> String {
        let mut version = build.release(num);
        if let Some(ref inner) = self.inner {
            version.push_str(" (");
            version.push_str(&inner.short_sha);
            version.push_str(" ");
            version.push_str(&inner.commit_date);
            version.push_str(")");
        }
        return version
    }
}
<commit_msg>Remove 'static lifetimes from channels.<commit_after>// Copyright 2015 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.

//! Build configuration for Rust's release channels.
//!
//! Implements the stable/beta/nightly channel distinctions by setting various
//! flags like the `unstable_features`, calculating variables like `release` and
//! `package_vers`, and otherwise indicating to the compiler what it should
//! print out as part of its version information.

use std::path::Path;
use std::process::Command;

use build_helper::output;

use Build;

// The version number
pub const CFG_RELEASE_NUM: &str = "1.20.0";

// An optional number to put after the label, e.g. '.2' -> '-beta.2'
// Be sure to make this starts with a dot to conform to semver pre-release
// versions (section 9)
pub const CFG_PRERELEASE_VERSION: &str = ".1";

pub struct GitInfo {
    inner: Option<Info>,
}

struct Info {
    commit_date: String,
    sha: String,
    short_sha: String,
}

impl GitInfo {
    pub fn new(dir: &Path) -> GitInfo {
        // See if this even begins to look like a git dir
        if !dir.join(".git").exists() {
            return GitInfo { inner: None }
        }

        // Make sure git commands work
        let out = Command::new("git")
                          .arg("rev-parse")
                          .current_dir(dir)
                          .output()
                          .expect("failed to spawn git");
        if !out.status.success() {
            return GitInfo { inner: None }
        }

        // Ok, let's scrape some info
        let ver_date = output(Command::new("git").current_dir(dir)
                                      .arg("log").arg("-1")
                                      .arg("--date=short")
                                      .arg("--pretty=format:%cd"));
        let ver_hash = output(Command::new("git").current_dir(dir)
                                      .arg("rev-parse").arg("HEAD"));
        let short_ver_hash = output(Command::new("git")
                                            .current_dir(dir)
                                            .arg("rev-parse")
                                            .arg("--short=9")
                                            .arg("HEAD"));
        GitInfo {
            inner: Some(Info {
                commit_date: ver_date.trim().to_string(),
                sha: ver_hash.trim().to_string(),
                short_sha: short_ver_hash.trim().to_string(),
            }),
        }
    }

    pub fn sha(&self) -> Option<&str> {
        self.inner.as_ref().map(|s| &s.sha[..])
    }

    pub fn sha_short(&self) -> Option<&str> {
        self.inner.as_ref().map(|s| &s.short_sha[..])
    }

    pub fn commit_date(&self) -> Option<&str> {
        self.inner.as_ref().map(|s| &s.commit_date[..])
    }

    pub fn version(&self, build: &Build, num: &str) -> String {
        let mut version = build.release(num);
        if let Some(ref inner) = self.inner {
            version.push_str(" (");
            version.push_str(&inner.short_sha);
            version.push_str(" ");
            version.push_str(&inner.commit_date);
            version.push_str(")");
        }
        return version
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix early return when generating match arms<commit_after><|endoftext|>


<commit_before><commit_msg>Implement cursor's first method<commit_after><|endoftext|>


<commit_before><commit_msg>v8 rub work<commit_after><|endoftext|>


<commit_before><commit_msg>Add no_run To Documentation Code<commit_after><|endoftext|>


<commit_before><commit_msg>WIP serialization framework<commit_after>
use std::collections::HashMap;
use std::collections::hash_map::Entry::{Vacant, Occupied};

#[derive(Clone, Copy, Eq, PartialEq, Hash)]
struct ObjectUid(u64);
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
struct ObjectTableIndex(u32);

pub trait Encodable<ECX> {

    fn encode<'token, 'encodable, 'sess>(&'encodable self,
                                         session: &mut EncodingSession<'sess, ECX>)
        where 'encodable: 'sess;
}

pub trait EncodableObject<ECX> : Encodable<ECX> {
    fn object_uid(&self) -> ObjectUid;
    fn encode_contents<'encodable, 'sess>(&'encodable self,
                                          session: &mut EncodingSession<'sess, ECX>)
        where 'encodable: 'sess;
}

pub trait Encoder {
    fn emit_u32(&mut self, x: u32);
    fn position(&self) -> u64;
    fn finalize(self: Box<Self>, four_cc: [u8; 4], object_table_address: u64);
}

pub struct EncodingSession<'sess, ECX: 'sess> {
    encoder: Box<Encoder>,
    object_table_indices: HashMap<ObjectUid, ObjectTableIndex>,
    object_table: Vec<u64>,
    queued_objects: Vec<(&'sess EncodableObject<ECX>, ObjectTableIndex)>,
    pub context: ECX
}

impl<'sess, ECX: 'sess> EncodingSession<'sess, ECX> {

    pub fn encoder(&mut self) -> &mut Encoder {
        &mut *self.encoder
    }

    pub fn encode_object<'object, O>(&mut self, object: &'object O)
        where O: EncodableObject<ECX>,
              'object: 'sess
    {
        let object_uid = EncodableObject::object_uid(object);
        let (object_table_index, is_new) = self.get_object_table_index(object_uid);

        self.encoder().emit_u32(object_table_index.0);

        if is_new {
            self.enqueue_object_encoding(object_table_index,
                                         object as &'sess EncodableObject<ECX>);
        }
    }

    pub fn finalize(self, four_cc: [u8; 4]) {
        let object_table_address = self.encoder.position();

        // TODO: write object table

        self.encoder.finalize(four_cc, object_table_address);
    }

    fn get_object_table_index(&mut self, object_uid: ObjectUid) -> (ObjectTableIndex, bool) {
        match self.object_table_indices.entry(object_uid) {
            Occupied(occupied) => (*occupied.get(), false),
            Vacant(vacant) => {
                // TODO: make this a safe conversion
                let index = self.object_table.len() as u32;
                self.object_table.push(u64::max_value());
                (ObjectTableIndex(index), true)
            }
        }
    }

    fn write_enqueued_objects(&mut self) {
        loop {
            // encoding objects might add more to this queue, so we can't do
            // this in a for loop
            let item = self.queued_objects.pop();

            match item {
                Some((object, object_table_index)) => {
                    let position = self.encoder.position();
                    let queue_index = self.queued_objects.len();
                    object.encode_contents(self);
                    // Now that we know the address, write it to the table
                    self.object_table[object_table_index.0 as usize] = position;
                },
                None => break,
            }
        }
    }

    fn enqueue_object_encoding(&mut self,
                               object_table_index: ObjectTableIndex,
                               encodable: &'sess EncodableObject<ECX>) {
        self.queued_objects.push((encodable, object_table_index));
    }
}

pub struct EncodingSessionRef<'sess, ECX: 'sess> {
    session: EncodingSession<'sess, ECX>
}

impl<'sess, ECX: 'sess> EncodingSessionRef<'sess, ECX> {

    pub fn new<E: Encoder+'static>(encoder: E, ecx: ECX) -> EncodingSessionRef<'sess, ECX> {
        EncodingSessionRef {
            session: EncodingSession {
                encoder: Box::new(encoder),
                object_table_indices: HashMap::new(),
                object_table: Vec::new(),
                queued_objects: Vec::new(),
                context: ecx
            }
        }
    }

    pub fn encode<'encodable: 'sess, T: Encodable<ECX>>(&mut self,
                                                        encodable: &'encodable T) {
        encodable.encode(&mut self.session);
        self.session.write_enqueued_objects();
    }
}
<|endoftext|>


<commit_before><commit_msg>update to fix latest bincode<commit_after><|endoftext|>


<commit_before><commit_msg>Add corresponding decrypt() method.<commit_after><|endoftext|>


<commit_before><commit_msg>Left a note about future plans in lib.rs<commit_after><|endoftext|>


<commit_before>//! Crate **ruma_identifiers** contains types for [Matrix](https://matrix.org/) identifiers
//! for events, rooms, room aliases, room versions, and users.

#![warn(rust_2018_idioms)]
#![deny(
    missing_copy_implementations,
    missing_debug_implementations,
    missing_docs
)]
// Since we support Rust 1.36.0, we can't apply this suggestion yet
#![allow(clippy::use_self)]

#[cfg(feature = "diesel")]
#[cfg_attr(feature = "diesel", macro_use)]
extern crate diesel;

use std::{
    convert::TryFrom,
    fmt::{Formatter, Result as FmtResult},
};

use rand::{distributions::Alphanumeric, thread_rng, Rng};
use serde::de::{self, Deserialize as _, Deserializer, Unexpected};
use url::Url;

pub use url::Host;

#[doc(inline)]
pub use crate::device_id::DeviceId;
pub use crate::{
    error::Error, event_id::EventId, room_alias_id::RoomAliasId, room_id::RoomId,
    room_id_or_room_alias_id::RoomIdOrAliasId, room_version_id::RoomVersionId, user_id::UserId,
};

pub mod device_id;
#[cfg(feature = "diesel")]
mod diesel_integration;
mod error;
mod event_id;
mod room_alias_id;
mod room_id;
mod room_id_or_room_alias_id;
mod room_version_id;
mod user_id;

/// All identifiers must be 255 bytes or less.
const MAX_BYTES: usize = 255;
/// The minimum number of characters an ID can be.
///
/// This is an optimization and not required by the spec. The shortest possible valid ID is a sigil
/// + a single character local ID + a colon + a single character hostname.
const MIN_CHARS: usize = 4;
/// The number of bytes in a valid sigil.
const SIGIL_BYTES: usize = 1;

/// `Display` implementation shared by identifier types.
fn display(
    f: &mut Formatter<'_>,
    sigil: char,
    localpart: &str,
    hostname: &Host,
    port: u16,
) -> FmtResult {
    if port == 443 {
        write!(f, "{}{}:{}", sigil, localpart, hostname)
    } else {
        write!(f, "{}{}:{}:{}", sigil, localpart, hostname, port)
    }
}

/// Generates a random identifier localpart.
fn generate_localpart(length: usize) -> String {
    thread_rng()
        .sample_iter(&Alphanumeric)
        .take(length)
        .collect()
}

/// Checks if an identifier is within the acceptable byte lengths.
fn validate_id(id: &str) -> Result<(), Error> {
    if id.len() > MAX_BYTES {
        return Err(Error::MaximumLengthExceeded);
    }

    if id.len() < MIN_CHARS {
        return Err(Error::MinimumLengthNotSatisfied);
    }

    Ok(())
}

/// Parses the localpart, host, and port from a string identifier.
fn parse_id(required_sigil: char, id: &str) -> Result<(&str, Host, u16), Error> {
    validate_id(id)?;

    if !id.starts_with(required_sigil) {
        return Err(Error::MissingSigil);
    }

    let delimiter_index = match id.find(':') {
        Some(index) => index,
        None => return Err(Error::MissingDelimiter),
    };

    let localpart = &id[1..delimiter_index];
    let raw_host = &id[delimiter_index + SIGIL_BYTES..];
    let url_string = format!("https://{}", raw_host);
    let url = Url::parse(&url_string)?;

    let host = match url.host() {
        Some(host) => host.to_owned(),
        None => return Err(Error::InvalidHost),
    };

    let port = url.port().unwrap_or(443);

    Ok((localpart, host, port))
}

/// Deserializes any type of id using the provided TryFrom implementation.
///
/// This is a helper function to reduce the boilerplate of the Deserialize implementations.
fn deserialize_id<'de, D, T>(deserializer: D, expected_str: &str) -> Result<T, D::Error>
where
    D: Deserializer<'de>,
    T: for<'a> TryFrom<&'a str>,
{
    String::deserialize(deserializer).and_then(|v| {
        T::try_from(&v).map_err(|_| de::Error::invalid_value(Unexpected::Str(&v), &expected_str))
    })
}
<commit_msg>ID deserialization: Borrow from the deserializer if possible<commit_after>//! Crate **ruma_identifiers** contains types for [Matrix](https://matrix.org/) identifiers
//! for events, rooms, room aliases, room versions, and users.

#![warn(rust_2018_idioms)]
#![deny(
    missing_copy_implementations,
    missing_debug_implementations,
    missing_docs
)]
// Since we support Rust 1.36.0, we can't apply this suggestion yet
#![allow(clippy::use_self)]

#[cfg(feature = "diesel")]
#[cfg_attr(feature = "diesel", macro_use)]
extern crate diesel;

use std::{
    borrow::Cow,
    convert::TryFrom,
    fmt::{Formatter, Result as FmtResult},
};

use rand::{distributions::Alphanumeric, thread_rng, Rng};
use serde::de::{self, Deserialize as _, Deserializer, Unexpected};
use url::Url;

pub use url::Host;

#[doc(inline)]
pub use crate::device_id::DeviceId;
pub use crate::{
    error::Error, event_id::EventId, room_alias_id::RoomAliasId, room_id::RoomId,
    room_id_or_room_alias_id::RoomIdOrAliasId, room_version_id::RoomVersionId, user_id::UserId,
};

pub mod device_id;
#[cfg(feature = "diesel")]
mod diesel_integration;
mod error;
mod event_id;
mod room_alias_id;
mod room_id;
mod room_id_or_room_alias_id;
mod room_version_id;
mod user_id;

/// All identifiers must be 255 bytes or less.
const MAX_BYTES: usize = 255;
/// The minimum number of characters an ID can be.
///
/// This is an optimization and not required by the spec. The shortest possible valid ID is a sigil
/// + a single character local ID + a colon + a single character hostname.
const MIN_CHARS: usize = 4;
/// The number of bytes in a valid sigil.
const SIGIL_BYTES: usize = 1;

/// `Display` implementation shared by identifier types.
fn display(
    f: &mut Formatter<'_>,
    sigil: char,
    localpart: &str,
    hostname: &Host,
    port: u16,
) -> FmtResult {
    if port == 443 {
        write!(f, "{}{}:{}", sigil, localpart, hostname)
    } else {
        write!(f, "{}{}:{}:{}", sigil, localpart, hostname, port)
    }
}

/// Generates a random identifier localpart.
fn generate_localpart(length: usize) -> String {
    thread_rng()
        .sample_iter(&Alphanumeric)
        .take(length)
        .collect()
}

/// Checks if an identifier is within the acceptable byte lengths.
fn validate_id(id: &str) -> Result<(), Error> {
    if id.len() > MAX_BYTES {
        return Err(Error::MaximumLengthExceeded);
    }

    if id.len() < MIN_CHARS {
        return Err(Error::MinimumLengthNotSatisfied);
    }

    Ok(())
}

/// Parses the localpart, host, and port from a string identifier.
fn parse_id(required_sigil: char, id: &str) -> Result<(&str, Host, u16), Error> {
    validate_id(id)?;

    if !id.starts_with(required_sigil) {
        return Err(Error::MissingSigil);
    }

    let delimiter_index = match id.find(':') {
        Some(index) => index,
        None => return Err(Error::MissingDelimiter),
    };

    let localpart = &id[1..delimiter_index];
    let raw_host = &id[delimiter_index + SIGIL_BYTES..];
    let url_string = format!("https://{}", raw_host);
    let url = Url::parse(&url_string)?;

    let host = match url.host() {
        Some(host) => host.to_owned(),
        None => return Err(Error::InvalidHost),
    };

    let port = url.port().unwrap_or(443);

    Ok((localpart, host, port))
}

/// Deserializes any type of id using the provided TryFrom implementation.
///
/// This is a helper function to reduce the boilerplate of the Deserialize implementations.
fn deserialize_id<'de, D, T>(deserializer: D, expected_str: &str) -> Result<T, D::Error>
where
    D: Deserializer<'de>,
    T: for<'a> TryFrom<&'a str>,
{
    Cow::<'_, str>::deserialize(deserializer).and_then(|v| {
        T::try_from(&v).map_err(|_| de::Error::invalid_value(Unexpected::Str(&v), &expected_str))
    })
}
<|endoftext|>


<commit_before>// Copyright 2015 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[deny(missing_docs)]

extern crate gfx;
extern crate gfx_device_gl;
extern crate glutin;

use gfx::tex::Size;

/// A wrapper around the window that implements `Output`.
pub struct Wrap<R: gfx::Resources> {
    /// Glutin window in the open.
    pub window: glutin::Window,
    frame: gfx::FrameBufferHandle<R>,
    mask: gfx::Mask,
    /// Gamma output mode.
    pub gamma: gfx::Gamma,
}

impl<R: gfx::Resources> gfx::Output<R> for Wrap<R> {
    fn get_handle(&self) -> Option<&gfx::FrameBufferHandle<R>> {
        Some(&self.frame)
    }

    fn get_size(&self) -> (Size, Size) {
        let factor = self.window.hidpi_factor();
        let (w, h) = self.window.get_inner_size().unwrap_or((0, 0));
        ((w as f32 * factor) as Size, (h as f32 * factor) as Size)
    }

    fn get_mask(&self) -> gfx::Mask {
        self.mask
    }

    fn get_gamma(&self) -> gfx::Gamma {
        self.gamma
    }
}

impl<R: gfx::Resources> gfx::Window<R> for Wrap<R> {
    fn swap_buffers(&mut self) {
        self.window.swap_buffers();
    }
}

/// Result of successful context initialization.
pub type Success = (
    Wrap<gfx_device_gl::Resources>,
    gfx_device_gl::Device,
    gfx_device_gl::Factory,
);

/// Initialize with a window.
pub fn init(window: glutin::Window) -> Success {
    unsafe { window.make_current() };
    let (device, factory) = gfx_device_gl::create(|s| window.get_proc_address(s));
    let format = window.get_pixel_format();
    let wrap = Wrap {
        window: window,
        frame: factory.get_main_frame_buffer(),
        mask: if format.color_bits != 0 { gfx::COLOR } else { gfx::Mask::empty() } |
            if format.depth_bits != 0 { gfx::DEPTH } else  { gfx::Mask::empty() } |
            if format.stencil_bits != 0 { gfx::STENCIL } else { gfx::Mask::empty() },
        gamma: if format.srgb {
            gfx::Gamma::Convert
        } else {
            gfx::Gamma::Original
        },
    };
    (wrap, device, factory)
}
<commit_msg>Renamed Wrap to Output. Made sRGB optional<commit_after>// Copyright 2015 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[deny(missing_docs)]

extern crate gfx;
extern crate gfx_device_gl;
extern crate glutin;

use gfx::tex::Size;

/// A wrapper around the window that implements `Output`.
pub struct Output<R: gfx::Resources> {
    /// Glutin window in the open.
    pub window: glutin::Window,
    frame: gfx::FrameBufferHandle<R>,
    mask: gfx::Mask,
    supports_gamma_convertion: bool,
    gamma: gfx::Gamma,
}

impl<R: gfx::Resources> Output<R> {
    /// Try to set the gamma conversion.
    pub fn set_gamma(&mut self, gamma: gfx::Gamma) -> Result<(), ()> {
        if self.supports_gamma_convertion || gamma == gfx::Gamma::Original {
            self.gamma = gamma;
            Ok(())
        }else {
            Err(())
        }
    }
}

impl<R: gfx::Resources> gfx::Output<R> for Output<R> {
    fn get_handle(&self) -> Option<&gfx::FrameBufferHandle<R>> {
        Some(&self.frame)
    }

    fn get_size(&self) -> (Size, Size) {
        let factor = self.window.hidpi_factor();
        let (w, h) = self.window.get_inner_size().unwrap_or((0, 0));
        ((w as f32 * factor) as Size, (h as f32 * factor) as Size)
    }

    fn get_mask(&self) -> gfx::Mask {
        self.mask
    }

    fn get_gamma(&self) -> gfx::Gamma {
        self.gamma
    }
}

impl<R: gfx::Resources> gfx::Window<R> for Output<R> {
    fn swap_buffers(&mut self) {
        self.window.swap_buffers();
    }
}

/// Result of successful context initialization.
pub type Success = (
    Output<gfx_device_gl::Resources>,
    gfx_device_gl::Device,
    gfx_device_gl::Factory,
);

/// Initialize with a window.
pub fn init(window: glutin::Window) -> Success {
    unsafe { window.make_current() };
    let (device, factory) = gfx_device_gl::create(|s| window.get_proc_address(s));
    let format = window.get_pixel_format();
    let out = Output {
        window: window,
        frame: factory.get_main_frame_buffer(),
        mask: if format.color_bits != 0 { gfx::COLOR } else { gfx::Mask::empty() } |
            if format.depth_bits != 0 { gfx::DEPTH } else  { gfx::Mask::empty() } |
            if format.stencil_bits != 0 { gfx::STENCIL } else { gfx::Mask::empty() },
        supports_gamma_convertion: format.srgb,
        gamma: gfx::Gamma::Original,
    };
    (out, device, factory)
}
<|endoftext|>


<commit_before><commit_msg>Replace deprecated functioncall<commit_after><|endoftext|>


<commit_before><commit_msg>Allow clippy::wrong_self_convention here for better readable code<commit_after><|endoftext|>