<commit_before><commit_msg>Add problem 136<commit_after>//! [Problem 136](https://projecteuler.net/problem=136) solver.
//!
//! Using the same algorithm as p135.

#![warn(bad_style,
        unused, unused_extern_crates, unused_import_braces,
        unused_qualifications, unused_results, unused_typecasts)]

#![feature(phase)]

#[phase(plugin, link)] extern crate common;

use std::iter;

fn num_solutions(limit: uint) -> Vec<u32> {
    let mut cnt = Vec::from_elem(limit, 0);
    for q in range(1, limit) {
        let r = (4 - (q % 4)) % 4;
        if q * r >= limit { continue }
        for p in iter::range_step(r, q * 3, 4) {
            let n = q * p;
            if n >= limit { break }
            cnt[n] += 1;
        }
    }
    cnt
}

fn solve() -> String {
    let limit = 50000000;
    let cnt = 1;
    num_solutions(limit)
        .iter()
        .filter(|&&n| n == cnt)
        .count()
        .to_string()
}

problem!("2544559", solve);

#[cfg(test)]
mod tests {
    #[test]
    fn first_sol() {
        let pos = super::num_solutions(2000)
            .iter()
            .position(|&n| n == 10)
            .unwrap();
        assert_eq!(1155, pos);
    }
}
<|endoftext|>


<commit_before><commit_msg>Regex based url matching<commit_after><|endoftext|>


<commit_before>use std::cell::UnsafeCell;
use std::fmt;
use std::io::{self, Read};
use std::ptr;
use std::sync::Arc;

pub struct MemBuf {
    buf: Arc<UnsafeCell<Vec<u8>>>,
    start: usize,
    end: usize,
}

impl MemBuf {
    pub fn new() -> MemBuf {
        MemBuf::with_capacity(0)
    }

    pub fn with_capacity(cap: usize) -> MemBuf {
        MemBuf {
            buf: Arc::new(UnsafeCell::new(vec![0; cap])),
            start: 0,
            end: 0,
        }
    }

    pub fn bytes(&self) -> &[u8] {
        &self.buf()[self.start..self.end]
    }

    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    pub fn len(&self) -> usize {
        self.end - self.start
    }

    pub fn capacity(&self) -> usize {
        self.buf().len()
    }

    pub fn read_from<R: Read>(&mut self, io: &mut R) -> io::Result<usize> {
        let start = self.end - self.start;
        let n = try!(io.read(&mut self.buf_mut()[start..]));
        self.end += n;
        Ok(n)
    }

    pub fn slice(&mut self, len: usize) -> MemSlice {
        assert!(self.end - self.start >= len);
        let start = self.start;
        self.start += len;
        MemSlice {
            buf: self.buf.clone(),
            start: start,
            end: self.start,
        }
    }

    pub fn reserve(&mut self, needed: usize) {
        let orig_cap = self.capacity();
        let remaining = orig_cap - self.end;
        if remaining >= needed {
            // all done
            return
        }
        let is_unique = Arc::get_mut(&mut self.buf).is_some();
        trace!("MemBuf::reserve {} access", if is_unique { "unique" } else { "shared" });
        if is_unique && remaining + self.start >= needed {
            // we have unique access, we can mutate this vector
            trace!("MemBuf::reserve unique access, shifting");
            unsafe {
                let mut buf = &mut *self.buf.get();
                let len = self.len();
                ptr::copy(
                    buf.as_ptr().offset(self.start as isize),
                    buf.as_mut_ptr(),
                    len
                );
                self.start = 0;
                self.end = len;
            }
        } else if is_unique {
            // we have unique access, we can mutate this vector
            trace!("MemBuf::reserve unique access, growing");
            unsafe {
                let mut vec = &mut *self.buf.get();
                grow_zerofill(vec, needed);
            }
        } else {
            // we need to allocate more space, but dont have unique
            // access, so we need to make a new buffer
            trace!("MemBuf::reserve shared buffer, creating new");
            let mut new = MemBuf::with_capacity(needed);
            unsafe {
                ptr::copy_nonoverlapping(
                    self.bytes().as_ptr(),
                    new.buf_mut().as_mut_ptr(),
                    self.len()
                );
            }
            new.end = self.len();
            *self = new;
        }
    }

    pub fn reset(&mut self) {
        match Arc::get_mut(&mut self.buf) {
            Some(_) => {
                trace!("MemBuf::reset was unique, re-using");
                self.start = 0;
                self.end = 0;
            },
            None => {
                trace!("MemBuf::reset not unique, creating new MemBuf");
                *self = MemBuf::with_capacity(self.buf().len());
            }
        }
    }

    fn buf_mut(&mut self) -> &mut [u8] {
        // The contract here is that we NEVER have a MemSlice that exists
        // with slice.end > self.start.
        // In other words, we should *ALWAYS* be the only instance that can
        // look at the bytes on the right side of self.start.
        unsafe {
            &mut (*self.buf.get())[self.start..]
        }
    }

    fn buf(&self) -> &Vec<u8> {
        unsafe {
            &*self.buf.get()
        }
    }
}

#[inline]
unsafe fn grow_zerofill(buf: &mut Vec<u8>, additional: usize) {
    let orig_cap = buf.capacity();
    buf.reserve(additional);
    let new_cap = buf.capacity();
    let reserved = new_cap - orig_cap;
    let orig_len = buf.len();
    zero(buf, orig_len, reserved);
    buf.set_len(orig_len + reserved);

    unsafe fn zero(buf: &mut Vec<u8>, offset: usize, len: usize) {
        assert!(buf.capacity() >= len + offset,
            "offset of {} with len of {} is bigger than capacity of {}",
            offset, len, buf.capacity());
        ptr::write_bytes(buf.as_mut_ptr().offset(offset as isize), 0, len);
    }
}

#[test]
fn test_grow_zerofill() {
    for init in 0..100 {
        for reserve in (0..100).rev() {
            let mut vec = vec![0; init];
            unsafe { grow_zerofill(&mut vec, reserve) }
            assert_eq!(vec.len(), vec.capacity());
        }
    }
}

impl fmt::Debug for MemBuf {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("MemBuf")
            .field("start", &self.start)
            .field("end", &self.end)
            .field("buf", &&self.buf()[self.start..self.end])
            .finish()
    }
}

pub struct MemSlice {
    buf: Arc<UnsafeCell<Vec<u8>>>,
    start: usize,
    end: usize,
}

impl MemSlice {
    pub fn empty() -> MemSlice {
        MemSlice {
            buf: Arc::new(UnsafeCell::new(Vec::new())),
            start: 0,
            end: 0,
        }
    }
}

#[cfg(test)]
impl<T: Read> ::http::io::MemRead for ::mock::AsyncIo<T> {
    fn read_mem(&mut self, len: usize) -> io::Result<MemSlice> {
        let mut v = vec![0; len];
        let n = try!(self.read(v.as_mut_slice()));
        v.truncate(n);
        Ok(MemSlice {
            buf: Arc::new(UnsafeCell::new(v)),
            start: 0,
            end: n,
        })
    }
}

impl fmt::Debug for MemSlice {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&**self, f)
    }
}

impl ::std::ops::Deref for  MemSlice {
    type Target = [u8];
    fn deref(&self) -> &[u8] {
        unsafe {
            &(*self.buf.get())[self.start..self.end]
        }
    }
}

unsafe impl Send for MemBuf {}
unsafe impl Send for MemSlice {}

/*
#[cfg(test)]
mod tests {
    use super::{MemBuf};

    #[test]
    fn test_
}
*/
<commit_msg>refactor(http): allow MemSlice to be sliced to make copies<commit_after>use std::cell::UnsafeCell;
use std::fmt;
use std::io::{self, Read};
use std::ops::{Deref, Range, RangeFrom, RangeTo, RangeFull};
use std::ptr;
use std::sync::Arc;

pub struct MemBuf {
    buf: Arc<UnsafeCell<Vec<u8>>>,
    start: usize,
    end: usize,
}

impl MemBuf {
    pub fn new() -> MemBuf {
        MemBuf::with_capacity(0)
    }

    pub fn with_capacity(cap: usize) -> MemBuf {
        MemBuf {
            buf: Arc::new(UnsafeCell::new(vec![0; cap])),
            start: 0,
            end: 0,
        }
    }

    pub fn bytes(&self) -> &[u8] {
        &self.buf()[self.start..self.end]
    }

    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    pub fn len(&self) -> usize {
        self.end - self.start
    }

    pub fn capacity(&self) -> usize {
        self.buf().len()
    }

    pub fn read_from<R: Read>(&mut self, io: &mut R) -> io::Result<usize> {
        let start = self.end - self.start;
        let n = try!(io.read(&mut self.buf_mut()[start..]));
        self.end += n;
        Ok(n)
    }

    pub fn slice(&mut self, len: usize) -> MemSlice {
        assert!(self.end - self.start >= len);
        let start = self.start;
        self.start += len;
        MemSlice {
            buf: self.buf.clone(),
            start: start,
            end: self.start,
        }
    }

    pub fn reserve(&mut self, needed: usize) {
        let orig_cap = self.capacity();
        let remaining = orig_cap - self.end;
        if remaining >= needed {
            // all done
            return
        }
        let is_unique = Arc::get_mut(&mut self.buf).is_some();
        trace!("MemBuf::reserve {} access", if is_unique { "unique" } else { "shared" });
        if is_unique && remaining + self.start >= needed {
            // we have unique access, we can mutate this vector
            trace!("MemBuf::reserve unique access, shifting");
            unsafe {
                let mut buf = &mut *self.buf.get();
                let len = self.len();
                ptr::copy(
                    buf.as_ptr().offset(self.start as isize),
                    buf.as_mut_ptr(),
                    len
                );
                self.start = 0;
                self.end = len;
            }
        } else if is_unique {
            // we have unique access, we can mutate this vector
            trace!("MemBuf::reserve unique access, growing");
            unsafe {
                let mut vec = &mut *self.buf.get();
                grow_zerofill(vec, needed);
            }
        } else {
            // we need to allocate more space, but dont have unique
            // access, so we need to make a new buffer
            trace!("MemBuf::reserve shared buffer, creating new");
            let mut new = MemBuf::with_capacity(needed);
            unsafe {
                ptr::copy_nonoverlapping(
                    self.bytes().as_ptr(),
                    new.buf_mut().as_mut_ptr(),
                    self.len()
                );
            }
            new.end = self.len();
            *self = new;
        }
    }

    pub fn reset(&mut self) {
        match Arc::get_mut(&mut self.buf) {
            Some(_) => {
                trace!("MemBuf::reset was unique, re-using");
                self.start = 0;
                self.end = 0;
            },
            None => {
                trace!("MemBuf::reset not unique, creating new MemBuf");
                *self = MemBuf::with_capacity(self.buf().len());
            }
        }
    }

    fn buf_mut(&mut self) -> &mut [u8] {
        // The contract here is that we NEVER have a MemSlice that exists
        // with slice.end > self.start.
        // In other words, we should *ALWAYS* be the only instance that can
        // look at the bytes on the right side of self.start.
        unsafe {
            &mut (*self.buf.get())[self.start..]
        }
    }

    fn buf(&self) -> &Vec<u8> {
        unsafe {
            &*self.buf.get()
        }
    }
}

#[inline]
unsafe fn grow_zerofill(buf: &mut Vec<u8>, additional: usize) {
    let orig_cap = buf.capacity();
    buf.reserve(additional);
    let new_cap = buf.capacity();
    let reserved = new_cap - orig_cap;
    let orig_len = buf.len();
    zero(buf, orig_len, reserved);
    buf.set_len(orig_len + reserved);

    unsafe fn zero(buf: &mut Vec<u8>, offset: usize, len: usize) {
        assert!(buf.capacity() >= len + offset,
            "offset of {} with len of {} is bigger than capacity of {}",
            offset, len, buf.capacity());
        ptr::write_bytes(buf.as_mut_ptr().offset(offset as isize), 0, len);
    }
}

#[test]
fn test_grow_zerofill() {
    for init in 0..100 {
        for reserve in (0..100).rev() {
            let mut vec = vec![0; init];
            unsafe { grow_zerofill(&mut vec, reserve) }
            assert_eq!(vec.len(), vec.capacity());
        }
    }
}

impl fmt::Debug for MemBuf {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("MemBuf")
            .field("start", &self.start)
            .field("end", &self.end)
            .field("buf", &&self.buf()[self.start..self.end])
            .finish()
    }
}

pub struct MemSlice {
    buf: Arc<UnsafeCell<Vec<u8>>>,
    start: usize,
    end: usize,
}

impl MemSlice {
    pub fn empty() -> MemSlice {
        MemSlice {
            buf: Arc::new(UnsafeCell::new(Vec::new())),
            start: 0,
            end: 0,
        }
    }

    pub fn slice<S: Slice>(&self, range: S) -> MemSlice {
        range.slice(self)
    }
}

impl fmt::Debug for MemSlice {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&**self, f)
    }
}

impl Deref for  MemSlice {
    type Target = [u8];
    fn deref(&self) -> &[u8] {
        unsafe {
            &(*self.buf.get())[self.start..self.end]
        }
    }
}

pub trait Slice {
    fn slice(self, subject: &MemSlice) -> MemSlice;
}

impl Slice for Range<usize> {
    fn slice(self, subject: &MemSlice) -> MemSlice {
        assert!(subject.start + self.start <= subject.end);
        assert!(subject.start + self.end <= subject.end);
        MemSlice {
            buf: subject.buf.clone(),
            start: subject.start + self.start,
            end: subject.start + self.end,
        }
    }
}

impl Slice for RangeFrom<usize> {
    fn slice(self, subject: &MemSlice) -> MemSlice {
        assert!(subject.start + self.start <= subject.end);
        MemSlice {
            buf: subject.buf.clone(),
            start: subject.start + self.start,
            end: subject.end,
        }
    }
}

impl Slice for RangeTo<usize> {
    fn slice(self, subject: &MemSlice) -> MemSlice {
        assert!(subject.start + self.end <= subject.end);
        MemSlice {
            buf: subject.buf.clone(),
            start: subject.start,
            end: subject.start + self.end,
        }
    }
}

impl Slice for RangeFull {
    fn slice(self, subject: &MemSlice) -> MemSlice {
        MemSlice {
            buf: subject.buf.clone(),
            start: subject.start,
            end: subject.end,
        }
    }
}

unsafe impl Send for MemBuf {}
unsafe impl Send for MemSlice {}

#[cfg(test)]
impl<T: Read> ::http::io::MemRead for ::mock::AsyncIo<T> {
    fn read_mem(&mut self, len: usize) -> io::Result<MemSlice> {
        let mut v = vec![0; len];
        let n = try!(self.read(v.as_mut_slice()));
        v.truncate(n);
        Ok(MemSlice {
            buf: Arc::new(UnsafeCell::new(v)),
            start: 0,
            end: n,
        })
    }
}

#[cfg(test)]
mod tests {
    use super::{MemBuf};

    #[test]
    fn test_mem_slice_slice() {
        let mut buf = MemBuf::with_capacity(32);
        buf.read_from(&mut &b"Hello World"[..]).unwrap();

        let len = buf.len();
        let full = buf.slice(len);

        assert_eq!(&*full, b"Hello World");
        assert_eq!(&*full.slice(6..), b"World");
        assert_eq!(&*full.slice(..5), b"Hello");
        assert_eq!(&*full.slice(..), b"Hello World");
        for a in 0..len {
            for b in a..len {
                assert_eq!(&*full.slice(a..b), &b"Hello World"[a..b], "{}..{}", a, b);
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Create ppipe_example.rs<commit_after>
<|endoftext|>


<commit_before><commit_msg>fetch/artifact: fix md5 hash format<commit_after><|endoftext|>


<commit_before><commit_msg>Syncfile: move header logic into own function, create syncdir if needed<commit_after><|endoftext|>


<commit_before><commit_msg>Solved first problem for Day 1<commit_after><|endoftext|>


<commit_before><commit_msg>Moving elapsed to record time needed to read data<commit_after><|endoftext|>


<commit_before>#![feature(globs)]
#![feature(if_let)]

extern crate neovim;
extern crate rgtk;
extern crate serialize;

//use neovim::*;
use rgtk::*;
use std::collections::HashSet;

mod projects;
mod ui;
mod utils;

fn main() {
    gtk::init();

    // constants

    let width = 1242;
    let height = 768;
    let editor_height = ((height as f32) * 0.8) as i32;

    // create the window

    let mut window = gtk::Window::new(gtk::WindowType::TopLevel).unwrap();
    window.set_title("SolidOak");
    window.set_window_position(gtk::WindowPosition::Center);
    window.set_default_size(width, height);

    window.connect(gtk::signals::DeleteEvent::new(|_| {
        gtk::main_quit();
        true
    }));

    // create the panes

    let new_button = gtk::Button::new_with_label("New Project").unwrap();
    let import_button = gtk::Button::new_with_label("Import").unwrap();
    let rename_button = gtk::Button::new_with_label("Rename").unwrap();
    let remove_button = gtk::Button::new_with_label("Remove").unwrap();

    let mut proj_btns = gtk::Box::new(gtk::Orientation::Horizontal, 0).unwrap();
    proj_btns.set_size_request(-1, -1);
    proj_btns.add(&new_button);
    proj_btns.add(&import_button);
    proj_btns.add(&rename_button);
    proj_btns.add(&remove_button);

    let mut proj_tree = gtk::TreeView::new().unwrap();
    let selection = proj_tree.get_selection().unwrap();
    let column_types = [glib::ffi::g_type_string, glib::ffi::g_type_string];
    let store = gtk::TreeStore::new(&column_types).unwrap();
    let model = store.get_model().unwrap();
    proj_tree.set_model(&model);
    proj_tree.set_headers_visible(false);

    let mut scroll_pane = gtk::ScrolledWindow::new(None, None).unwrap();
    scroll_pane.add(&proj_tree);

    let column = gtk::TreeViewColumn::new().unwrap();
    let cell = gtk::CellRendererText::new().unwrap();
    column.pack_start(&cell, true);
    column.add_attribute(&cell, "text", 0);
    proj_tree.append_column(&column);

    let mut proj_pane = gtk::Box::new(gtk::Orientation::Vertical, 0).unwrap();
    proj_pane.set_size_request(-1, -1);
    proj_pane.pack_start(&proj_btns, false, true, 0);
    proj_pane.pack_start(&scroll_pane, true, true, 0);

    let editor_pane = gtk::VteTerminal::new().unwrap();
    editor_pane.set_size_request(-1, editor_height);

    let run_button = gtk::Button::new_with_label("Run").unwrap();
    let build_button = gtk::Button::new_with_label("Build").unwrap();
    let test_button = gtk::Button::new_with_label("Test").unwrap();
    let clean_button = gtk::Button::new_with_label("Clean").unwrap();
    let stop_button = gtk::Button::new_with_label("Stop").unwrap();

    let mut build_btns = gtk::Box::new(gtk::Orientation::Horizontal, 0).unwrap();
    build_btns.set_size_request(-1, -1);
    build_btns.add(&run_button);
    build_btns.add(&build_button);
    build_btns.add(&test_button);
    build_btns.add(&clean_button);
    build_btns.add(&stop_button);

    let build_term = gtk::VteTerminal::new().unwrap();

    let mut build_pane = gtk::Box::new(gtk::Orientation::Vertical, 0).unwrap();
    build_pane.pack_start(&build_btns, false, true, 0);
    build_pane.pack_start(&build_term, true, true, 0);

    let mut content = gtk::Box::new(gtk::Orientation::Vertical, 0).unwrap();
    content.pack_start(&editor_pane, false, true, 0);
    content.pack_start(&build_pane, true, true, 0);

    let mut hbox = gtk::Box::new(gtk::Orientation::Horizontal, 0).unwrap();
    hbox.pack_start(&proj_pane, false, true, 0);
    hbox.pack_start(&content, true, true, 0);
    window.add(&hbox);

    // populate the project tree

    let mut state = ::utils::State{
        projects: HashSet::new(),
        expansions: HashSet::new(),
        selection: None,
        tree_model: &model,
        tree_store: &store,
        tree_selection: &selection,
        rename_button: &rename_button,
        remove_button: &remove_button,
    };

    ::utils::create_data_dir();
    ::utils::read_prefs(&mut state);
    ::ui::update_project_tree(&mut state, &mut proj_tree);

    // connect to the signals

    new_button.connect(gtk::signals::Clicked::new(|| {
        ::projects::new_project(&mut state, &mut proj_tree);
    }));
    import_button.connect(gtk::signals::Clicked::new(|| {
        ::projects::import_project(&mut state, &mut proj_tree);
    }));
    rename_button.connect(gtk::signals::Clicked::new(|| {
        ::projects::rename_file(&mut state);
    }));
    remove_button.connect(gtk::signals::Clicked::new(|| {
        ::projects::remove_item(&mut state);
    }));
    selection.connect(gtk::signals::Changed::new(|| {
        ::projects::update_selection(&mut state);
    }));
    proj_tree.connect(gtk::signals::RowCollapsed::new(|iter_raw, _| {
        let iter = gtk::TreeIter::wrap_pointer(iter_raw);
        ::projects::remove_expansion(&mut state, &iter);
    }));
    proj_tree.connect(gtk::signals::RowExpanded::new(|iter_raw, _| {
        let iter = gtk::TreeIter::wrap_pointer(iter_raw);
        ::projects::add_expansion(&mut state, &iter);
    }));

    // show the window

    window.show_all();
    gtk::main();
}
<commit_msg>Make build pane larger<commit_after>#![feature(globs)]
#![feature(if_let)]

extern crate neovim;
extern crate rgtk;
extern crate serialize;

//use neovim::*;
use rgtk::*;
use std::collections::HashSet;

mod projects;
mod ui;
mod utils;

fn main() {
    gtk::init();

    // constants

    let width = 1242;
    let height = 768;
    let editor_height = ((height as f32) * 0.75) as i32;

    // create the window

    let mut window = gtk::Window::new(gtk::WindowType::TopLevel).unwrap();
    window.set_title("SolidOak");
    window.set_window_position(gtk::WindowPosition::Center);
    window.set_default_size(width, height);

    window.connect(gtk::signals::DeleteEvent::new(|_| {
        gtk::main_quit();
        true
    }));

    // create the panes

    let new_button = gtk::Button::new_with_label("New Project").unwrap();
    let import_button = gtk::Button::new_with_label("Import").unwrap();
    let rename_button = gtk::Button::new_with_label("Rename").unwrap();
    let remove_button = gtk::Button::new_with_label("Remove").unwrap();

    let mut proj_btns = gtk::Box::new(gtk::Orientation::Horizontal, 0).unwrap();
    proj_btns.set_size_request(-1, -1);
    proj_btns.add(&new_button);
    proj_btns.add(&import_button);
    proj_btns.add(&rename_button);
    proj_btns.add(&remove_button);

    let mut proj_tree = gtk::TreeView::new().unwrap();
    let selection = proj_tree.get_selection().unwrap();
    let column_types = [glib::ffi::g_type_string, glib::ffi::g_type_string];
    let store = gtk::TreeStore::new(&column_types).unwrap();
    let model = store.get_model().unwrap();
    proj_tree.set_model(&model);
    proj_tree.set_headers_visible(false);

    let mut scroll_pane = gtk::ScrolledWindow::new(None, None).unwrap();
    scroll_pane.add(&proj_tree);

    let column = gtk::TreeViewColumn::new().unwrap();
    let cell = gtk::CellRendererText::new().unwrap();
    column.pack_start(&cell, true);
    column.add_attribute(&cell, "text", 0);
    proj_tree.append_column(&column);

    let mut proj_pane = gtk::Box::new(gtk::Orientation::Vertical, 0).unwrap();
    proj_pane.set_size_request(-1, -1);
    proj_pane.pack_start(&proj_btns, false, true, 0);
    proj_pane.pack_start(&scroll_pane, true, true, 0);

    let editor_pane = gtk::VteTerminal::new().unwrap();
    editor_pane.set_size_request(-1, editor_height);

    let run_button = gtk::Button::new_with_label("Run").unwrap();
    let build_button = gtk::Button::new_with_label("Build").unwrap();
    let test_button = gtk::Button::new_with_label("Test").unwrap();
    let clean_button = gtk::Button::new_with_label("Clean").unwrap();
    let stop_button = gtk::Button::new_with_label("Stop").unwrap();

    let mut build_btns = gtk::Box::new(gtk::Orientation::Horizontal, 0).unwrap();
    build_btns.set_size_request(-1, -1);
    build_btns.add(&run_button);
    build_btns.add(&build_button);
    build_btns.add(&test_button);
    build_btns.add(&clean_button);
    build_btns.add(&stop_button);

    let build_term = gtk::VteTerminal::new().unwrap();

    let mut build_pane = gtk::Box::new(gtk::Orientation::Vertical, 0).unwrap();
    build_pane.pack_start(&build_btns, false, true, 0);
    build_pane.pack_start(&build_term, true, true, 0);

    let mut content = gtk::Box::new(gtk::Orientation::Vertical, 0).unwrap();
    content.pack_start(&editor_pane, false, true, 0);
    content.pack_start(&build_pane, true, true, 0);

    let mut hbox = gtk::Box::new(gtk::Orientation::Horizontal, 0).unwrap();
    hbox.pack_start(&proj_pane, false, true, 0);
    hbox.pack_start(&content, true, true, 0);
    window.add(&hbox);

    // populate the project tree

    let mut state = ::utils::State{
        projects: HashSet::new(),
        expansions: HashSet::new(),
        selection: None,
        tree_model: &model,
        tree_store: &store,
        tree_selection: &selection,
        rename_button: &rename_button,
        remove_button: &remove_button,
    };

    ::utils::create_data_dir();
    ::utils::read_prefs(&mut state);
    ::ui::update_project_tree(&mut state, &mut proj_tree);

    // connect to the signals

    new_button.connect(gtk::signals::Clicked::new(|| {
        ::projects::new_project(&mut state, &mut proj_tree);
    }));
    import_button.connect(gtk::signals::Clicked::new(|| {
        ::projects::import_project(&mut state, &mut proj_tree);
    }));
    rename_button.connect(gtk::signals::Clicked::new(|| {
        ::projects::rename_file(&mut state);
    }));
    remove_button.connect(gtk::signals::Clicked::new(|| {
        ::projects::remove_item(&mut state);
    }));
    selection.connect(gtk::signals::Changed::new(|| {
        ::projects::update_selection(&mut state);
    }));
    proj_tree.connect(gtk::signals::RowCollapsed::new(|iter_raw, _| {
        let iter = gtk::TreeIter::wrap_pointer(iter_raw);
        ::projects::remove_expansion(&mut state, &iter);
    }));
    proj_tree.connect(gtk::signals::RowExpanded::new(|iter_raw, _| {
        let iter = gtk::TreeIter::wrap_pointer(iter_raw);
        ::projects::add_expansion(&mut state, &iter);
    }));

    // show the window

    window.show_all();
    gtk::main();
}
<|endoftext|>


<commit_before>// This file is part of rgtk.
//
// rgtk is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// rgtk is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with rgtk.  If not, see <http://www.gnu.org/licenses/>.

/*!

Bindings and wrappers for __GTK+__, __GLib__ and __Cairo__.

The various parts of __rgtk__ can be found in the submodules __gtk__, __gdk__, __glib__ and __cairo__.

Trait reexports
===============

For you're conveniance the various traits of `rgtk` are reexported in the `rgtk::*`
namespace as `{Gtk/Gdk/Glib/Cairo}{trait_name}Trait` so you can just use...

```Rust
extern mod rgtk;
use rgtk::*;
```

...to easily access all the traits methods:

```Rust
let button = gtk::Button:new(); // trait gtk::traits::Button reexported as GtkButtonTrait,
                                // it's trait methods can be accessed here.
```
*/

#![crate_name = "rgtk"]
#![crate_type = "lib"]
#![crate_type = "rlib"]
#![feature(macro_rules)]
#![allow(dead_code)] // TODO: drop this
#![feature(unsafe_destructor)]

extern crate libc;

pub use gtk::traits::Widget           as GtkWidgetTrait;
pub use gtk::traits::Container        as GtkContainerTrait;
pub use gtk::traits::Window           as GtkWindowTrait;
pub use gtk::traits::Misc             as GtkMiscTrait;
pub use gtk::traits::Button           as GtkButtonTrait;
pub use gtk::traits::Label            as GtkLabelTrait;
pub use gtk::traits::Box              as GtkBoxTrait;
pub use gtk::traits::Orientable       as GtkOrientableTrait;
pub use gtk::traits::Frame            as GtkFrameTrait;
pub use gtk::traits::ToggleButton     as GtkToggleButtonTrait;
pub use gtk::traits::ScaleButton      as GtkScaleButtonTrait;
pub use gtk::traits::Entry            as GtkEntryTrait;
pub use gtk::traits::Bin              as GtkBinTrait;
pub use gtk::traits::ToolShell        as GtkToolShellTrait;
pub use gtk::traits::ToolItem         as GtkToolItemTrait;
pub use gtk::traits::ToolButton       as GtkToolButtonTrait;
pub use gtk::traits::ToggleToolButton as GtkToggleToolButtonTrait;
pub use gtk::traits::Dialog           as GtkDialogTrait;
pub use gtk::traits::ColorChooser     as GtkColorChooserTrait;
pub use gtk::traits::Scrollable       as GtkScrollableTrait;
pub use gtk::traits::FileChooser      as GtkFileChooserTrait;
pub use gtk::traits::FontChooser      as GtkFontChooserTrait;
pub use gtk::traits::AppChooser       as GtkAppChooserTrait;
pub use gtk::traits::Range            as GtkRangeTrait;
pub use gtk::traits::Editable         as GtkEditableTrait;
pub use gtk::traits::MenuShell        as GtkMenuShellTrait;
pub use gtk::traits::MenuItem         as GtkMenuItemTrait;
pub use gtk::traits::CheckMenuItem    as GtkCheckMenuItemTrait;
pub use gtk::traits::CellEditable     as GtkCellEditable;

#[doc(hidden)]
#[cfg(target_os="macos")]
mod platform {
    #[link(name = "glib-2.0")]
    #[link(name = "gtk-3.0")]
    #[link(name = "gio-2.0")]
    #[link(name = "gobject-2.0")]
    #[link(name = "gdk-3.0")]
    #[link(name = "rgtk_glue", kind = "static")]
    extern{}
}

#[doc(hidden)]
#[cfg(target_os="linux")]
mod platform {
    #[link(name = "glib-2.0")]
    #[link(name = "gtk-3")]
    #[link(name = "gio-2.0")]
    #[link(name = "gobject-2.0")]
    #[link(name = "gdk-3")]
    #[link(name = "rgtk_glue", kind = "static")]
    extern{}
}

#[doc(hidden)]
#[cfg(target_os="windows")]
mod platform {
    #[link(name = "glib-2.0")]
    #[link(name = "gtk-3")]
    #[link(name = "gio-2.0")]
    #[link(name = "gobject-2.0")]
    #[link(name = "gdk-3")]
    #[link(name = "rgtk_glue", kind = "static")]
    extern{}
}

pub mod gtk;
pub mod cairo;
pub mod gdk;
pub mod glib;
<commit_msg>Reexport CellRenderer trait<commit_after>// This file is part of rgtk.
//
// rgtk is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// rgtk is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with rgtk.  If not, see <http://www.gnu.org/licenses/>.

/*!

Bindings and wrappers for __GTK+__, __GLib__ and __Cairo__.

The various parts of __rgtk__ can be found in the submodules __gtk__, __gdk__, __glib__ and __cairo__.

Trait reexports
===============

For you're conveniance the various traits of `rgtk` are reexported in the `rgtk::*`
namespace as `{Gtk/Gdk/Glib/Cairo}{trait_name}Trait` so you can just use...

```Rust
extern mod rgtk;
use rgtk::*;
```

...to easily access all the traits methods:

```Rust
let button = gtk::Button:new(); // trait gtk::traits::Button reexported as GtkButtonTrait,
                                // it's trait methods can be accessed here.
```
*/

#![crate_name = "rgtk"]
#![crate_type = "lib"]
#![crate_type = "rlib"]
#![feature(macro_rules)]
#![allow(dead_code)] // TODO: drop this
#![feature(unsafe_destructor)]

extern crate libc;

pub use gtk::traits::Widget           as GtkWidgetTrait;
pub use gtk::traits::Container        as GtkContainerTrait;
pub use gtk::traits::Window           as GtkWindowTrait;
pub use gtk::traits::Misc             as GtkMiscTrait;
pub use gtk::traits::Button           as GtkButtonTrait;
pub use gtk::traits::Label            as GtkLabelTrait;
pub use gtk::traits::Box              as GtkBoxTrait;
pub use gtk::traits::Orientable       as GtkOrientableTrait;
pub use gtk::traits::Frame            as GtkFrameTrait;
pub use gtk::traits::ToggleButton     as GtkToggleButtonTrait;
pub use gtk::traits::ScaleButton      as GtkScaleButtonTrait;
pub use gtk::traits::Entry            as GtkEntryTrait;
pub use gtk::traits::Bin              as GtkBinTrait;
pub use gtk::traits::ToolShell        as GtkToolShellTrait;
pub use gtk::traits::ToolItem         as GtkToolItemTrait;
pub use gtk::traits::ToolButton       as GtkToolButtonTrait;
pub use gtk::traits::ToggleToolButton as GtkToggleToolButtonTrait;
pub use gtk::traits::Dialog           as GtkDialogTrait;
pub use gtk::traits::ColorChooser     as GtkColorChooserTrait;
pub use gtk::traits::Scrollable       as GtkScrollableTrait;
pub use gtk::traits::FileChooser      as GtkFileChooserTrait;
pub use gtk::traits::FontChooser      as GtkFontChooserTrait;
pub use gtk::traits::AppChooser       as GtkAppChooserTrait;
pub use gtk::traits::Range            as GtkRangeTrait;
pub use gtk::traits::Editable         as GtkEditableTrait;
pub use gtk::traits::MenuShell        as GtkMenuShellTrait;
pub use gtk::traits::MenuItem         as GtkMenuItemTrait;
pub use gtk::traits::CheckMenuItem    as GtkCheckMenuItemTrait;
pub use gtk::traits::CellEditable     as GtkCellEditable;
pub use gtk::traits::CellRenderer     as GtkCellRenderer;

#[doc(hidden)]
#[cfg(target_os="macos")]
mod platform {
    #[link(name = "glib-2.0")]
    #[link(name = "gtk-3.0")]
    #[link(name = "gio-2.0")]
    #[link(name = "gobject-2.0")]
    #[link(name = "gdk-3.0")]
    #[link(name = "rgtk_glue", kind = "static")]
    extern{}
}

#[doc(hidden)]
#[cfg(target_os="linux")]
mod platform {
    #[link(name = "glib-2.0")]
    #[link(name = "gtk-3")]
    #[link(name = "gio-2.0")]
    #[link(name = "gobject-2.0")]
    #[link(name = "gdk-3")]
    #[link(name = "rgtk_glue", kind = "static")]
    extern{}
}

#[doc(hidden)]
#[cfg(target_os="windows")]
mod platform {
    #[link(name = "glib-2.0")]
    #[link(name = "gtk-3")]
    #[link(name = "gio-2.0")]
    #[link(name = "gobject-2.0")]
    #[link(name = "gdk-3")]
    #[link(name = "rgtk_glue", kind = "static")]
    extern{}
}

pub mod gtk;
pub mod cairo;
pub mod gdk;
pub mod glib;
<|endoftext|>


<commit_before><commit_msg>Spiff up status message on send.<commit_after><|endoftext|>


<commit_before><commit_msg>Add mutable access to cells in canvas<commit_after><|endoftext|>


<commit_before>use std::iter::repeat;

use ansi_term::Style;

use options::{SizeFormat, TimeType};

#[derive(PartialEq, Debug, Copy)]
pub enum Column {
    Permissions,
    FileSize(SizeFormat),
    Timestamp(TimeType, i64),
    Blocks,
    User,
    Group,
    HardLinks,
    Inode,

    GitStatus,
}

/// Each column can pick its own **Alignment**. Usually, numbers are
/// right-aligned, and text is left-aligned.
#[derive(Copy)]
pub enum Alignment {
    Left, Right,
}

impl Column {

    /// Get the alignment this column should use.
    pub fn alignment(&self) -> Alignment {
        match *self {
            Column::FileSize(_) => Alignment::Right,
            Column::HardLinks   => Alignment::Right,
            Column::Inode       => Alignment::Right,
            Column::Blocks      => Alignment::Right,
            Column::GitStatus   => Alignment::Right,
            _                   => Alignment::Left,
        }
    }

    /// Get the text that should be printed at the top, when the user elects
    /// to have a header row printed.
    pub fn header(&self) -> &'static str {
        match *self {
            Column::Permissions     => "Permissions",
            Column::FileSize(_)     => "Size",
            Column::Timestamp(t, _) => t.header(),
            Column::Blocks          => "Blocks",
            Column::User            => "User",
            Column::Group           => "Group",
            Column::HardLinks       => "Links",
            Column::Inode           => "inode",
            Column::GitStatus       => "Git",
        }
    }
}

/// Pad a string with the given number of spaces.
fn spaces(length: usize) -> String {
    repeat(" ").take(length).collect()
}

impl Alignment {
    /// Pad a string with the given alignment and number of spaces.
    ///
    /// This doesn't take the width the string *should* be, rather the number
    /// of spaces to add: this is because the strings are usually full of
    /// invisible control characters, so getting the displayed width of the
    /// string is not as simple as just getting its length.
    pub fn pad_string(&self, string: &String, padding: usize) -> String {
        match *self {
            Alignment::Left  => format!("{}{}", string, spaces(padding).as_slice()),
            Alignment::Right => format!("{}{}", spaces(padding), string.as_slice()),
        }
    }
}

#[derive(PartialEq, Debug)]
pub struct Cell {
    pub length: usize,
    pub text: String,
}

impl Cell {
    pub fn paint(style: Style, string: &str) -> Cell {
        Cell {
            text: style.paint(string).to_string(),
            length: string.len(),
        }
    }
}
<commit_msg>Replace &String with &str<commit_after>use std::iter::repeat;

use ansi_term::Style;

use options::{SizeFormat, TimeType};

#[derive(PartialEq, Debug, Copy)]
pub enum Column {
    Permissions,
    FileSize(SizeFormat),
    Timestamp(TimeType, i64),
    Blocks,
    User,
    Group,
    HardLinks,
    Inode,

    GitStatus,
}

/// Each column can pick its own **Alignment**. Usually, numbers are
/// right-aligned, and text is left-aligned.
#[derive(Copy)]
pub enum Alignment {
    Left, Right,
}

impl Column {

    /// Get the alignment this column should use.
    pub fn alignment(&self) -> Alignment {
        match *self {
            Column::FileSize(_) => Alignment::Right,
            Column::HardLinks   => Alignment::Right,
            Column::Inode       => Alignment::Right,
            Column::Blocks      => Alignment::Right,
            Column::GitStatus   => Alignment::Right,
            _                   => Alignment::Left,
        }
    }

    /// Get the text that should be printed at the top, when the user elects
    /// to have a header row printed.
    pub fn header(&self) -> &'static str {
        match *self {
            Column::Permissions     => "Permissions",
            Column::FileSize(_)     => "Size",
            Column::Timestamp(t, _) => t.header(),
            Column::Blocks          => "Blocks",
            Column::User            => "User",
            Column::Group           => "Group",
            Column::HardLinks       => "Links",
            Column::Inode           => "inode",
            Column::GitStatus       => "Git",
        }
    }
}

/// Pad a string with the given number of spaces.
fn spaces(length: usize) -> String {
    repeat(" ").take(length).collect()
}

impl Alignment {
    /// Pad a string with the given alignment and number of spaces.
    ///
    /// This doesn't take the width the string *should* be, rather the number
    /// of spaces to add: this is because the strings are usually full of
    /// invisible control characters, so getting the displayed width of the
    /// string is not as simple as just getting its length.
    pub fn pad_string(&self, string: &str, padding: usize) -> String {
        match *self {
            Alignment::Left  => format!("{}{}", string, spaces(padding).as_slice()),
            Alignment::Right => format!("{}{}", spaces(padding), string.as_slice()),
        }
    }
}

#[derive(PartialEq, Debug)]
pub struct Cell {
    pub length: usize,
    pub text: String,
}

impl Cell {
    pub fn paint(style: Style, string: &str) -> Cell {
        Cell {
            text: style.paint(string).to_string(),
            length: string.len(),
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Generate `AmbigGt` only when '>' followed by '>' or '='. Fix.<commit_after><|endoftext|>


<commit_before><commit_msg>Iterator::to_owned_vec is no more.<commit_after><|endoftext|>


<commit_before><commit_msg>Updated documentation<commit_after><|endoftext|>


<commit_before><commit_msg>Make search_dbpage's argument to be SearchCond enum, dispatch to different subroutines based on it's a key or command<commit_after><|endoftext|>


<commit_before><commit_msg>Add more tests and fix a bug in from_code.<commit_after><|endoftext|>


<commit_before><commit_msg>Switch from compare to is_less<commit_after><|endoftext|>


<commit_before><commit_msg>Allow using VAR= and setting the value to empty string<commit_after><|endoftext|>


<commit_before><commit_msg>Add missing details; print code along with result<commit_after><|endoftext|>


<commit_before><commit_msg>Remove Singleton<commit_after><|endoftext|>


<commit_before><commit_msg>rub updates<commit_after><|endoftext|>


<commit_before><commit_msg>Don't fail horribly on empty strings and newlines<commit_after><|endoftext|>


<commit_before><commit_msg>Add re-exporting library part to ilc, for easier reuse<commit_after>extern crate ilc_base;
extern crate ilc_ops;
extern crate ilc_cli;

extern crate ilc_format_weechat;
extern crate ilc_format_energymech;

pub use ilc_base::{Context, Decode, Encode, Event, context, dummy, error, event, format};
pub use ilc_ops::{convert, dedup, freq, parse, seen, sort};

pub use ilc_cli::{decoder, encoder, force_decoder, force_encoder, open_files};

pub use convert::convert;
pub use dedup::dedup;
pub use freq::freq;
pub use parse::parse;
pub use seen::seen;
pub use sort::sort;
<|endoftext|>


<commit_before><commit_msg>Feature add serde_yaml output framework<commit_after>use std::collections::BTreeMap;
use rusqlite::Connection;
use dbVariableName;
use dbJob;
use dbFsFile;
use serde_yaml;
use std::collections::HashSet;

fn job_provide_list_by_job(conn: &Connection) -> Vec<dbVariableName::VariableName> {
    let mut items = Vec::<dbVariableName::VariableName>::new();
    let provide_list_prep_rc = conn.prepare(
        "SELECT DISTINCT
            VARIABLE_NAME.id,
            VARIABLE_NAME.name
            FROM JOBPROVIDE , VARIABLE_NAME
        WHERE
            VARIABLE_NAME.id = JOBPROVIDE.fk_variable
            order by VARIABLE_NAME.name",
    );
    if provide_list_prep_rc.is_err() {
        error!("SQL issue in job_provide_list");
        return items;
    }
    let mut provide_list_prep = provide_list_prep_rc.unwrap();

    let result_row = provide_list_prep.query(&[]);
    let mut rox = result_row.unwrap();

    while let Some(row_query) = rox.next() {
        let row = row_query.unwrap();
        let bill = dbVariableName::VariableName {
            id: row.get(0),
            name: row.get(1),
        };
        debug!("bill:{}", bill.id);
        items.push(bill);
    }
    return items;
}

fn job_depend_list_by_job(conn: &Connection) -> Vec<dbVariableName::VariableName> {
    let mut items = Vec::<dbVariableName::VariableName>::new();
    let provide_list_prep_rc = conn.prepare(
        "SELECT DISTINCT
            VARIABLE_NAME.id,
            VARIABLE_NAME.name
            FROM JOBDEPEND , VARIABLE_NAME
        WHERE
            VARIABLE_NAME.id = JOBDEPEND.fk_variable
            order by VARIABLE_NAME.name",
    );
    if provide_list_prep_rc.is_err() {
        error!("SQL issue in job_provide_list");
        return items;
    }
    let mut provide_list_prep = provide_list_prep_rc.unwrap();

    let result_row = provide_list_prep.query(&[]);
    let mut rox = result_row.unwrap();

    while let Some(row_query) = rox.next() {
        let row = row_query.unwrap();
        let bill = dbVariableName::VariableName {
            id: row.get(0),
            name: row.get(1),
        };
        debug!("bill:{}", bill.id);
        items.push(bill);
    }
    return items;
}

fn job_targets_list_by_job(conn: &Connection) -> Vec<dbVariableName::VariableName> {
    let mut items = Vec::<dbVariableName::VariableName>::new();

    let mut hs_depend: HashSet<i32> = HashSet::new();
    let list_dep = job_depend_list_by_job(&conn);
    for item in list_dep {
        hs_depend.insert(item.id);
    }
    for item in job_provide_list_by_job(&conn) {
        let foo = hs_depend.contains(&item.id);
        if foo == false {
            items.push(item)
        }
    }
    return items;
}

fn list_job(conn: &Connection, fk_variable_name: &i32) -> Vec<dbJob::Job> {
    let mut items = Vec::<dbJob::Job>::new();
    let provide_list_prep_rc = conn.prepare(
        "SELECT DISTINCT
            JOB.id,
            JOB.name,
            JOB.fk_file
            FROM JOB, JOBPROVIDE , VARIABLE_NAME
        WHERE
            JOB.id = JOBPROVIDE.fk_job
            AND
            VARIABLE_NAME.id = JOBPROVIDE.fk_variable
            AND
            VARIABLE_NAME.id = ?1
            order by JOB.name",
    );
    if provide_list_prep_rc.is_err() {
        error!("SQL issue in job_provide_list");
        return items;
    }
    let mut provide_list_prep = provide_list_prep_rc.unwrap();

    let result_row = provide_list_prep.query(&[fk_variable_name]);
    let mut rox = result_row.unwrap();

    while let Some(row_query) = rox.next() {
        let row = row_query.unwrap();
        let bill = dbJob::Job {
            id: row.get(0),
            name: row.get(1),
            fk_file: row.get(2),
        };
        debug!("bill:{}", bill.id);
        items.push(bill);
    }
    return items;
}

fn list_file(conn: &Connection, fk_variable_name: &i32) -> Vec<dbFsFile::FsFile> {
    let mut items = Vec::<dbFsFile::FsFile>::new();
    let provide_list_prep_rc = conn.prepare(
        "SELECT DISTINCT
            FS_FILE.id,
            FS_FILE.fk_fs_dir,
            FS_FILE.name
        FROM
            FS_FILE
        WHERE
            FS_FILE.id = ?1
            order by FS_FILE.name",
    );
    if provide_list_prep_rc.is_err() {
        error!("SQL issue in job_provide_list");
        return items;
    }
    let mut provide_list_prep = provide_list_prep_rc.unwrap();

    let result_row = provide_list_prep.query(&[fk_variable_name]);
    let mut rox = result_row.unwrap();

    while let Some(row_query) = rox.next() {
        let row = row_query.unwrap();
        let bill = dbFsFile::FsFile {
            id: row.get(0),
            fk_fs_dir: row.get(1),
            name: row.get(2),
        };
        debug!("bill:{}", bill.id);
        items.push(bill);
    }
    return items;
}

fn shared_foo(conn: &Connection, variables: &Vec<dbVariableName::VariableName>) -> String {
    let mut map = BTreeMap::new();
    for var_name in variables {
        let mut v_new = Vec::<BTreeMap<&str, String>>::new();
        let doop = list_job(&conn, &var_name.id);
        for item in doop {
            let mut map2 = BTreeMap::new();
            map2.insert("name", item.name.to_string());
            let woop = list_file(&conn, &item.fk_file);
            for op in woop {
                map2.insert("file_name", op.name.to_string());
            }
            v_new.push(map2);
        }
        map.insert(var_name.name.to_string(), v_new);
    }
    return serde_yaml::to_string(&map).unwrap();
}

pub fn process_list_provides(conn: &Connection) {
    let henry = job_provide_list_by_job(&conn);
    println!("{}", shared_foo(&conn, &henry));
}

pub fn process_list_targets(conn: &Connection) {
    let henry = job_targets_list_by_job(&conn);
    println!("{}", shared_foo(&conn, &henry));
}
<|endoftext|>


<commit_before><commit_msg>Add accepts function.<commit_after><|endoftext|>


<commit_before><commit_msg>Auto merge of #270 - frewsxcv:doc-examples, r=Hoverbear<commit_after><|endoftext|>


<commit_before><commit_msg>fix warnings<commit_after><|endoftext|>


<commit_before><commit_msg>Add an IO variant to LibError that encompasses std::io::Error<commit_after><|endoftext|>


<commit_before>//! A collection of traits abstracting over Listeners and Streams.
use std::any::{Any, TypeId};
use std::fmt;
use std::old_io::{IoResult, IoError, ConnectionAborted, InvalidInput, OtherIoError,
              Stream, Listener, Acceptor};
use std::old_io::net::ip::{SocketAddr, ToSocketAddr, Port};
use std::old_io::net::tcp::{TcpStream, TcpListener, TcpAcceptor};
use std::mem;
use std::raw::{self, TraitObject};
use std::sync::Arc;

use uany::UnsafeAnyExt;
use openssl::ssl::{Ssl, SslStream, SslContext};
use openssl::ssl::SslVerifyMode::SslVerifyNone;
use openssl::ssl::SslMethod::Sslv23;
use openssl::ssl::error::{SslError, StreamError, OpenSslErrors, SslSessionClosed};
use openssl::x509::X509FileType;

macro_rules! try_some {
    ($expr:expr) => (match $expr {
        Some(val) => { return Err(val); },
        _ => {}
    })
}

/// The write-status indicating headers have not been written.
#[allow(missing_copy_implementations)]
pub struct Fresh;

/// The write-status indicating headers have been written.
#[allow(missing_copy_implementations)]
pub struct Streaming;

/// An abstraction to listen for connections on a certain port.
pub trait NetworkListener {
    type Acceptor: NetworkAcceptor;
    /// Listens on a socket.
    fn listen<To: ToSocketAddr>(&mut self, addr: To) -> IoResult<Self::Acceptor>;
}

/// An abstraction to receive `NetworkStream`s.
pub trait NetworkAcceptor: Clone + Send {
    type Stream: NetworkStream + Send + Clone;

    /// Returns an iterator of streams.
    fn accept(&mut self) -> IoResult<Self::Stream>;

    /// Get the address this Listener ended up listening on.
    fn socket_name(&self) -> IoResult<SocketAddr>;

    /// Closes the Acceptor, so no more incoming connections will be handled.
    fn close(&mut self) -> IoResult<()>;

    /// Returns an iterator over incoming connections.
    fn incoming(&mut self) -> NetworkConnections<Self> {
        NetworkConnections(self)
    }
}

/// An iterator wrapper over a NetworkAcceptor.
pub struct NetworkConnections<'a, N: NetworkAcceptor>(&'a mut N);

impl<'a, N: NetworkAcceptor> Iterator for NetworkConnections<'a, N> {
    type Item = IoResult<N::Stream>;
    fn next(&mut self) -> Option<IoResult<N::Stream>> {
        Some(self.0.accept())
    }
}

/// An abstraction over streams that a Server can utilize.
pub trait NetworkStream: Stream + Any + StreamClone + Send {
    /// Get the remote address of the underlying connection.
    fn peer_name(&mut self) -> IoResult<SocketAddr>;
}

#[doc(hidden)]
pub trait StreamClone {
    fn clone_box(&self) -> Box<NetworkStream + Send>;
}

impl<T: NetworkStream + Send + Clone> StreamClone for T {
    #[inline]
    fn clone_box(&self) -> Box<NetworkStream + Send> {
        Box::new(self.clone())
    }
}

/// A connector creates a NetworkStream.
pub trait NetworkConnector {
    type Stream: NetworkStream + Send;
    /// Connect to a remote address.
    fn connect(&mut self, host: &str, port: Port, scheme: &str) -> IoResult<Self::Stream>;
}

impl fmt::Debug for Box<NetworkStream + Send> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.pad("Box<NetworkStream>")
    }
}

impl Clone for Box<NetworkStream + Send> {
    #[inline]
    fn clone(&self) -> Box<NetworkStream + Send> { self.clone_box() }
}

impl Reader for Box<NetworkStream + Send> {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> { (**self).read(buf) }
}

impl Writer for Box<NetworkStream + Send> {
    #[inline]
    fn write_all(&mut self, msg: &[u8]) -> IoResult<()> { (**self).write_all(msg) }

    #[inline]
    fn flush(&mut self) -> IoResult<()> { (**self).flush() }
}

impl<'a> Reader for &'a mut NetworkStream {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> { (**self).read(buf) }
}

impl<'a> Writer for &'a mut NetworkStream {
    #[inline]
    fn write_all(&mut self, msg: &[u8]) -> IoResult<()> { (**self).write_all(msg) }

    #[inline]
    fn flush(&mut self) -> IoResult<()> { (**self).flush() }
}

impl UnsafeAnyExt for NetworkStream {
    unsafe fn downcast_ref_unchecked<T: 'static>(&self) -> &T {
        mem::transmute(mem::transmute::<&NetworkStream,
                                        raw::TraitObject>(self).data)
    }

    unsafe fn downcast_mut_unchecked<T: 'static>(&mut self) -> &mut T {
        mem::transmute(mem::transmute::<&mut NetworkStream,
                                        raw::TraitObject>(self).data)
    }

    unsafe fn downcast_unchecked<T: 'static>(self: Box<NetworkStream>) -> Box<T>  {
        mem::transmute(mem::transmute::<Box<NetworkStream>,
                                        raw::TraitObject>(self).data)
    }
}

impl NetworkStream {
    /// Is the underlying type in this trait object a T?
    #[inline]
    pub fn is<T: 'static>(&self) -> bool {
        self.get_type_id() == TypeId::of::<T>()
    }

    /// If the underlying type is T, get a reference to the contained data.
    #[inline]
    pub fn downcast_ref<T: 'static>(&self) -> Option<&T> {
        if self.is::<T>() {
            Some(unsafe { self.downcast_ref_unchecked() })
        } else {
            None
        }
    }

    /// If the underlying type is T, get a mutable reference to the contained
    /// data.
    #[inline]
    pub fn downcast_mut<T: 'static>(&mut self) -> Option<&mut T> {
        if self.is::<T>() {
            Some(unsafe { self.downcast_mut_unchecked() })
        } else {
            None
        }
    }

    /// If the underlying type is T, extract it.
    pub fn downcast<T: 'static>(self: Box<NetworkStream>)
            -> Result<Box<T>, Box<NetworkStream>> {
        if self.is::<T>() {
            Ok(unsafe { self.downcast_unchecked() })
        } else {
            Err(self)
        }
    }
}

/// A `NetworkListener` for `HttpStream`s.
#[allow(missing_copy_implementations)]
pub enum HttpListener {
    /// Http variant.
    Http,
    /// Https variant. The two paths point to the certificate and key PEM files, in that order.
    Https(Path, Path),
}

impl NetworkListener for HttpListener {
    type Acceptor = HttpAcceptor;

    #[inline]
    fn listen<To: ToSocketAddr>(&mut self, addr: To) -> IoResult<HttpAcceptor> {
        let mut tcp = try!(TcpListener::bind(addr));
        let addr = try!(tcp.socket_name());
        Ok(match *self {
            HttpListener::Http => HttpAcceptor::Http(try!(tcp.listen()), addr),
            HttpListener::Https(ref cert, ref key) => {
                let mut ssl_context = try!(SslContext::new(Sslv23).map_err(lift_ssl_error));
                try_some!(ssl_context.set_cipher_list("DEFAULT").map(lift_ssl_error));
                try_some!(ssl_context.set_certificate_file(
                        cert, X509FileType::PEM).map(lift_ssl_error));
                try_some!(ssl_context.set_private_key_file(
                        key, X509FileType::PEM).map(lift_ssl_error));
                ssl_context.set_verify(SslVerifyNone, None);
                HttpAcceptor::Https(try!(tcp.listen()), addr, Arc::new(ssl_context))
            }
        })
    }
}

/// A `NetworkAcceptor` for `HttpStream`s.
#[derive(Clone)]
pub enum HttpAcceptor {
    /// Http variant.
    Http(TcpAcceptor, SocketAddr),
    /// Https variant.
    Https(TcpAcceptor, SocketAddr, Arc<SslContext>),
}

impl NetworkAcceptor for HttpAcceptor {
    type Stream = HttpStream;

    #[inline]
    fn accept(&mut self) -> IoResult<HttpStream> {
        Ok(match *self {
            HttpAcceptor::Http(ref mut tcp, _) => HttpStream::Http(try!(tcp.accept())),
            HttpAcceptor::Https(ref mut tcp, _, ref ssl_context) => {
                let stream = try!(tcp.accept());
                let ssl_stream = try!(SslStream::<TcpStream>::new_server(&**ssl_context, stream).
                                     map_err(lift_ssl_error));
                HttpStream::Https(ssl_stream)
            }
        })
    }

    #[inline]
    fn close(&mut self) -> IoResult<()> {
        match *self {
            HttpAcceptor::Http(ref mut tcp, _) => tcp.close_accept(),
            HttpAcceptor::Https(ref mut tcp, _, _) => tcp.close_accept(),
        }
    }

    #[inline]
    fn socket_name(&self) -> IoResult<SocketAddr> {
        match *self {
            HttpAcceptor::Http(_, addr) => Ok(addr),
            HttpAcceptor::Https(_, addr, _) => Ok(addr),
        }
    }
}

/// A wrapper around a TcpStream.
#[derive(Clone)]
pub enum HttpStream {
    /// A stream over the HTTP protocol.
    Http(TcpStream),
    /// A stream over the HTTP protocol, protected by SSL.
    Https(SslStream<TcpStream>),
}

impl Reader for HttpStream {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
        match *self {
            HttpStream::Http(ref mut inner) => inner.read(buf),
            HttpStream::Https(ref mut inner) => inner.read(buf)
        }
    }
}

impl Writer for HttpStream {
    #[inline]
    fn write_all(&mut self, msg: &[u8]) -> IoResult<()> {
        match *self {
            HttpStream::Http(ref mut inner) => inner.write_all(msg),
            HttpStream::Https(ref mut inner) => inner.write_all(msg)
        }
    }
    #[inline]
    fn flush(&mut self) -> IoResult<()> {
        match *self {
            HttpStream::Http(ref mut inner) => inner.flush(),
            HttpStream::Https(ref mut inner) => inner.flush(),
        }
    }
}

impl NetworkStream for HttpStream {
    fn peer_name(&mut self) -> IoResult<SocketAddr> {
        match *self {
            HttpStream::Http(ref mut inner) => inner.peer_name(),
            HttpStream::Https(ref mut inner) => inner.get_mut().peer_name()
        }
    }
}

/// A connector that will produce HttpStreams.
#[allow(missing_copy_implementations)]
pub struct HttpConnector<'v>(pub Option<ContextVerifier<'v>>);

/// A method that can set verification methods on an SSL context
pub type ContextVerifier<'v> = Box<FnMut(&mut SslContext) -> ()+'v>;

impl<'v> NetworkConnector for HttpConnector<'v> {
    type Stream = HttpStream;

    fn connect(&mut self, host: &str, port: Port, scheme: &str) -> IoResult<HttpStream> {
        let addr = (host, port);
        match scheme {
            "http" => {
                debug!("http scheme");
                Ok(HttpStream::Http(try!(TcpStream::connect(addr))))
            },
            "https" => {
                debug!("https scheme");
                let stream = try!(TcpStream::connect(addr));
                let mut context = try!(SslContext::new(Sslv23).map_err(lift_ssl_error));
                if let Some(ref mut verifier) = self.0 {
                    verifier(&mut context);
                }
                let ssl = try!(Ssl::new(&context).map_err(lift_ssl_error));
                try!(ssl.set_hostname(host).map_err(lift_ssl_error));
                let stream = try!(SslStream::new(&context, stream).map_err(lift_ssl_error));
                Ok(HttpStream::Https(stream))
            },
            _ => {
                Err(IoError {
                    kind: InvalidInput,
                    desc: "Invalid scheme for Http",
                    detail: None
                })
            }
        }
    }
}

fn lift_ssl_error(ssl: SslError) -> IoError {
    debug!("lift_ssl_error: {:?}", ssl);
    match ssl {
        StreamError(err) => err,
        SslSessionClosed => IoError {
            kind: ConnectionAborted,
            desc: "SSL Connection Closed",
            detail: None
        },
        // Unfortunately throw this away. No way to support this
        // detail without a better Error abstraction.
        OpenSslErrors(errs) => IoError {
            kind: OtherIoError,
            desc: "Error in OpenSSL",
            detail: Some(format!("{:?}", errs))
        }
    }
}

#[cfg(test)]
mod tests {
    use uany::UnsafeAnyExt;

    use mock::MockStream;
    use super::NetworkStream;

    #[test]
    fn test_downcast_box_stream() {
        let stream = box MockStream::new() as Box<NetworkStream + Send>;

        let mock = stream.downcast::<MockStream>().ok().unwrap();
        assert_eq!(mock, box MockStream::new());

    }

    #[test]
    fn test_downcast_unchecked_box_stream() {
        let stream = box MockStream::new() as Box<NetworkStream + Send>;

        let mock = unsafe { stream.downcast_unchecked::<MockStream>() };
        assert_eq!(mock, box MockStream::new());

    }

}
<commit_msg>fix(net): don't stop the server when an SSL handshake fails with EOF<commit_after>//! A collection of traits abstracting over Listeners and Streams.
use std::any::{Any, TypeId};
use std::fmt;
use std::old_io::{IoResult, IoError, ConnectionAborted, InvalidInput, OtherIoError,
              Stream, Listener, Acceptor};
use std::old_io::net::ip::{SocketAddr, ToSocketAddr, Port};
use std::old_io::net::tcp::{TcpStream, TcpListener, TcpAcceptor};
use std::mem;
use std::raw::{self, TraitObject};
use std::sync::Arc;

use uany::UnsafeAnyExt;
use openssl::ssl::{Ssl, SslStream, SslContext};
use openssl::ssl::SslVerifyMode::SslVerifyNone;
use openssl::ssl::SslMethod::Sslv23;
use openssl::ssl::error::{SslError, StreamError, OpenSslErrors, SslSessionClosed};
use openssl::x509::X509FileType;

macro_rules! try_some {
    ($expr:expr) => (match $expr {
        Some(val) => { return Err(val); },
        _ => {}
    })
}

/// The write-status indicating headers have not been written.
#[allow(missing_copy_implementations)]
pub struct Fresh;

/// The write-status indicating headers have been written.
#[allow(missing_copy_implementations)]
pub struct Streaming;

/// An abstraction to listen for connections on a certain port.
pub trait NetworkListener {
    type Acceptor: NetworkAcceptor;
    /// Listens on a socket.
    fn listen<To: ToSocketAddr>(&mut self, addr: To) -> IoResult<Self::Acceptor>;
}

/// An abstraction to receive `NetworkStream`s.
pub trait NetworkAcceptor: Clone + Send {
    type Stream: NetworkStream + Send + Clone;

    /// Returns an iterator of streams.
    fn accept(&mut self) -> IoResult<Self::Stream>;

    /// Get the address this Listener ended up listening on.
    fn socket_name(&self) -> IoResult<SocketAddr>;

    /// Closes the Acceptor, so no more incoming connections will be handled.
    fn close(&mut self) -> IoResult<()>;

    /// Returns an iterator over incoming connections.
    fn incoming(&mut self) -> NetworkConnections<Self> {
        NetworkConnections(self)
    }
}

/// An iterator wrapper over a NetworkAcceptor.
pub struct NetworkConnections<'a, N: NetworkAcceptor>(&'a mut N);

impl<'a, N: NetworkAcceptor> Iterator for NetworkConnections<'a, N> {
    type Item = IoResult<N::Stream>;
    fn next(&mut self) -> Option<IoResult<N::Stream>> {
        Some(self.0.accept())
    }
}

/// An abstraction over streams that a Server can utilize.
pub trait NetworkStream: Stream + Any + StreamClone + Send {
    /// Get the remote address of the underlying connection.
    fn peer_name(&mut self) -> IoResult<SocketAddr>;
}

#[doc(hidden)]
pub trait StreamClone {
    fn clone_box(&self) -> Box<NetworkStream + Send>;
}

impl<T: NetworkStream + Send + Clone> StreamClone for T {
    #[inline]
    fn clone_box(&self) -> Box<NetworkStream + Send> {
        Box::new(self.clone())
    }
}

/// A connector creates a NetworkStream.
pub trait NetworkConnector {
    type Stream: NetworkStream + Send;
    /// Connect to a remote address.
    fn connect(&mut self, host: &str, port: Port, scheme: &str) -> IoResult<Self::Stream>;
}

impl fmt::Debug for Box<NetworkStream + Send> {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.pad("Box<NetworkStream>")
    }
}

impl Clone for Box<NetworkStream + Send> {
    #[inline]
    fn clone(&self) -> Box<NetworkStream + Send> { self.clone_box() }
}

impl Reader for Box<NetworkStream + Send> {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> { (**self).read(buf) }
}

impl Writer for Box<NetworkStream + Send> {
    #[inline]
    fn write_all(&mut self, msg: &[u8]) -> IoResult<()> { (**self).write_all(msg) }

    #[inline]
    fn flush(&mut self) -> IoResult<()> { (**self).flush() }
}

impl<'a> Reader for &'a mut NetworkStream {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> { (**self).read(buf) }
}

impl<'a> Writer for &'a mut NetworkStream {
    #[inline]
    fn write_all(&mut self, msg: &[u8]) -> IoResult<()> { (**self).write_all(msg) }

    #[inline]
    fn flush(&mut self) -> IoResult<()> { (**self).flush() }
}

impl UnsafeAnyExt for NetworkStream {
    unsafe fn downcast_ref_unchecked<T: 'static>(&self) -> &T {
        mem::transmute(mem::transmute::<&NetworkStream,
                                        raw::TraitObject>(self).data)
    }

    unsafe fn downcast_mut_unchecked<T: 'static>(&mut self) -> &mut T {
        mem::transmute(mem::transmute::<&mut NetworkStream,
                                        raw::TraitObject>(self).data)
    }

    unsafe fn downcast_unchecked<T: 'static>(self: Box<NetworkStream>) -> Box<T>  {
        mem::transmute(mem::transmute::<Box<NetworkStream>,
                                        raw::TraitObject>(self).data)
    }
}

impl NetworkStream {
    /// Is the underlying type in this trait object a T?
    #[inline]
    pub fn is<T: 'static>(&self) -> bool {
        self.get_type_id() == TypeId::of::<T>()
    }

    /// If the underlying type is T, get a reference to the contained data.
    #[inline]
    pub fn downcast_ref<T: 'static>(&self) -> Option<&T> {
        if self.is::<T>() {
            Some(unsafe { self.downcast_ref_unchecked() })
        } else {
            None
        }
    }

    /// If the underlying type is T, get a mutable reference to the contained
    /// data.
    #[inline]
    pub fn downcast_mut<T: 'static>(&mut self) -> Option<&mut T> {
        if self.is::<T>() {
            Some(unsafe { self.downcast_mut_unchecked() })
        } else {
            None
        }
    }

    /// If the underlying type is T, extract it.
    pub fn downcast<T: 'static>(self: Box<NetworkStream>)
            -> Result<Box<T>, Box<NetworkStream>> {
        if self.is::<T>() {
            Ok(unsafe { self.downcast_unchecked() })
        } else {
            Err(self)
        }
    }
}

/// A `NetworkListener` for `HttpStream`s.
#[allow(missing_copy_implementations)]
pub enum HttpListener {
    /// Http variant.
    Http,
    /// Https variant. The two paths point to the certificate and key PEM files, in that order.
    Https(Path, Path),
}

impl NetworkListener for HttpListener {
    type Acceptor = HttpAcceptor;

    #[inline]
    fn listen<To: ToSocketAddr>(&mut self, addr: To) -> IoResult<HttpAcceptor> {
        let mut tcp = try!(TcpListener::bind(addr));
        let addr = try!(tcp.socket_name());
        Ok(match *self {
            HttpListener::Http => HttpAcceptor::Http(try!(tcp.listen()), addr),
            HttpListener::Https(ref cert, ref key) => {
                let mut ssl_context = try!(SslContext::new(Sslv23).map_err(lift_ssl_error));
                try_some!(ssl_context.set_cipher_list("DEFAULT").map(lift_ssl_error));
                try_some!(ssl_context.set_certificate_file(
                        cert, X509FileType::PEM).map(lift_ssl_error));
                try_some!(ssl_context.set_private_key_file(
                        key, X509FileType::PEM).map(lift_ssl_error));
                ssl_context.set_verify(SslVerifyNone, None);
                HttpAcceptor::Https(try!(tcp.listen()), addr, Arc::new(ssl_context))
            }
        })
    }
}

/// A `NetworkAcceptor` for `HttpStream`s.
#[derive(Clone)]
pub enum HttpAcceptor {
    /// Http variant.
    Http(TcpAcceptor, SocketAddr),
    /// Https variant.
    Https(TcpAcceptor, SocketAddr, Arc<SslContext>),
}

impl NetworkAcceptor for HttpAcceptor {
    type Stream = HttpStream;

    #[inline]
    fn accept(&mut self) -> IoResult<HttpStream> {
        Ok(match *self {
            HttpAcceptor::Http(ref mut tcp, _) => HttpStream::Http(try!(tcp.accept())),
            HttpAcceptor::Https(ref mut tcp, _, ref ssl_context) => {
                let stream = try!(tcp.accept());
                match SslStream::<TcpStream>::new_server(&**ssl_context, stream) {
                    Ok(ssl_stream) => HttpStream::Https(ssl_stream),
                    Err(StreamError(ref e)) => {
                        return Err(IoError {
                            kind: ConnectionAborted,
                            desc: "SSL Handshake Interrupted",
                            detail: Some(e.desc.to_string())
                        });
                    },
                    Err(e) => return Err(lift_ssl_error(e))
                }
            }
        })
    }

    #[inline]
    fn close(&mut self) -> IoResult<()> {
        match *self {
            HttpAcceptor::Http(ref mut tcp, _) => tcp.close_accept(),
            HttpAcceptor::Https(ref mut tcp, _, _) => tcp.close_accept(),
        }
    }

    #[inline]
    fn socket_name(&self) -> IoResult<SocketAddr> {
        match *self {
            HttpAcceptor::Http(_, addr) => Ok(addr),
            HttpAcceptor::Https(_, addr, _) => Ok(addr),
        }
    }
}

/// A wrapper around a TcpStream.
#[derive(Clone)]
pub enum HttpStream {
    /// A stream over the HTTP protocol.
    Http(TcpStream),
    /// A stream over the HTTP protocol, protected by SSL.
    Https(SslStream<TcpStream>),
}

impl Reader for HttpStream {
    #[inline]
    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
        match *self {
            HttpStream::Http(ref mut inner) => inner.read(buf),
            HttpStream::Https(ref mut inner) => inner.read(buf)
        }
    }
}

impl Writer for HttpStream {
    #[inline]
    fn write_all(&mut self, msg: &[u8]) -> IoResult<()> {
        match *self {
            HttpStream::Http(ref mut inner) => inner.write_all(msg),
            HttpStream::Https(ref mut inner) => inner.write_all(msg)
        }
    }
    #[inline]
    fn flush(&mut self) -> IoResult<()> {
        match *self {
            HttpStream::Http(ref mut inner) => inner.flush(),
            HttpStream::Https(ref mut inner) => inner.flush(),
        }
    }
}

impl NetworkStream for HttpStream {
    fn peer_name(&mut self) -> IoResult<SocketAddr> {
        match *self {
            HttpStream::Http(ref mut inner) => inner.peer_name(),
            HttpStream::Https(ref mut inner) => inner.get_mut().peer_name()
        }
    }
}

/// A connector that will produce HttpStreams.
#[allow(missing_copy_implementations)]
pub struct HttpConnector<'v>(pub Option<ContextVerifier<'v>>);

/// A method that can set verification methods on an SSL context
pub type ContextVerifier<'v> = Box<FnMut(&mut SslContext) -> ()+'v>;

impl<'v> NetworkConnector for HttpConnector<'v> {
    type Stream = HttpStream;

    fn connect(&mut self, host: &str, port: Port, scheme: &str) -> IoResult<HttpStream> {
        let addr = (host, port);
        match scheme {
            "http" => {
                debug!("http scheme");
                Ok(HttpStream::Http(try!(TcpStream::connect(addr))))
            },
            "https" => {
                debug!("https scheme");
                let stream = try!(TcpStream::connect(addr));
                let mut context = try!(SslContext::new(Sslv23).map_err(lift_ssl_error));
                if let Some(ref mut verifier) = self.0 {
                    verifier(&mut context);
                }
                let ssl = try!(Ssl::new(&context).map_err(lift_ssl_error));
                try!(ssl.set_hostname(host).map_err(lift_ssl_error));
                let stream = try!(SslStream::new(&context, stream).map_err(lift_ssl_error));
                Ok(HttpStream::Https(stream))
            },
            _ => {
                Err(IoError {
                    kind: InvalidInput,
                    desc: "Invalid scheme for Http",
                    detail: None
                })
            }
        }
    }
}

fn lift_ssl_error(ssl: SslError) -> IoError {
    debug!("lift_ssl_error: {:?}", ssl);
    match ssl {
        StreamError(err) => err,
        SslSessionClosed => IoError {
            kind: ConnectionAborted,
            desc: "SSL Connection Closed",
            detail: None
        },
        // Unfortunately throw this away. No way to support this
        // detail without a better Error abstraction.
        OpenSslErrors(errs) => IoError {
            kind: OtherIoError,
            desc: "Error in OpenSSL",
            detail: Some(format!("{:?}", errs))
        }
    }
}

#[cfg(test)]
mod tests {
    use uany::UnsafeAnyExt;

    use mock::MockStream;
    use super::NetworkStream;

    #[test]
    fn test_downcast_box_stream() {
        let stream = box MockStream::new() as Box<NetworkStream + Send>;

        let mock = stream.downcast::<MockStream>().ok().unwrap();
        assert_eq!(mock, box MockStream::new());

    }

    #[test]
    fn test_downcast_unchecked_box_stream() {
        let stream = box MockStream::new() as Box<NetworkStream + Send>;

        let mock = unsafe { stream.downcast_unchecked::<MockStream>() };
        assert_eq!(mock, box MockStream::new());

    }

}
<|endoftext|>


<commit_before><commit_msg>Make percent-{en,de}coding public.<commit_after><|endoftext|>


<commit_before>// Copyright 2019 Twitter, Inc.
// Licensed under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0

use logger::*;

use core::fmt::Debug;
use std::collections::{HashMap, HashSet};
use std::hash::Hash;

pub struct Wheel<T> {
    tick: usize,
    buckets: Vec<Bucket<T>>,
    timers: HashMap<T, Timer<T>>,
}

impl<T> Wheel<T>
where
    T: Copy + Clone + Eq + Hash + Debug,
{
    pub fn new(buckets: usize) -> Self {
        let mut wheel = Self {
            tick: 0,
            buckets: Vec::with_capacity(buckets),
            timers: HashMap::new(),
        };
        for _ in 0..buckets {
            wheel.buckets.push(Bucket::new());
        }
        wheel
    }

    pub fn tick(&mut self, ticks: usize) -> Vec<T> {
        let mut timers = Vec::new();
        for _ in 0..ticks {
            timers.extend(self.do_tick());
        }
        if !timers.is_empty() {
            debug!("timeouts: {}", timers.len());
        }
        timers
    }

    pub fn do_tick(&mut self) -> Vec<T> {
        let mut expired = Vec::with_capacity(self.buckets[self.tick].timers.len());
        let mut remaining = HashSet::new();
        for token in &self.buckets[self.tick].timers {
            if self.timers[&token].remaining == 0 {
                expired.push(*token);
                self.timers.remove(&token);
            } else {
                remaining.insert(*token);
                self.timers.get_mut(token).unwrap().remaining -= 1;
            }
        }
        self.buckets[self.tick].timers = remaining;
        if self.tick == (self.buckets.len() - 1) {
            self.tick = 0;
        } else {
            self.tick += 1;
        }
        expired
    }

    pub fn add(&mut self, token: T, ticks: usize) {
        trace!("Add timer for {:?} in {} ticks", token, ticks);
        if self.timers.contains_key(&token) {
            self.cancel(token);
        }
        let bucket = (ticks + self.tick) % self.buckets.len();
        let remaining = ticks / self.buckets.len();
        let timer = Timer {
            token,
            remaining,
            bucket,
        };
        self.timers.insert(token, timer);
        self.buckets[bucket].timers.insert(token);
    }

    pub fn pending(&self) -> usize {
        self.timers.len()
    }

    pub fn cancel(&mut self, token: T) {
        if let Some(timer) = self.timers.remove(&token) {
            self.buckets[timer.bucket].timers.remove(&token);
        }
        self.timers.shrink_to_fit();
    }

    pub fn next_timeout(&self) -> Option<usize> {
        if self.timers.is_empty() {
            None
        } else {
            let mut remaining = 0;
            loop {
                for offset in 0..self.buckets.len() {
                    let mut tick = self.tick + offset;
                    if tick >= self.buckets.len() {
                        tick -= self.buckets.len();
                    }
                    for timer in &self.buckets[tick].timers {
                        if self.timers[&timer].remaining == remaining {
                            return Some(offset + remaining * self.buckets.len());
                        }
                    }
                }
                remaining += 1;
            }
        }
    }
}

pub struct Bucket<T> {
    timers: HashSet<T>,
}

impl<T> Bucket<T>
where
    T: Copy + Clone + Eq + Hash + Debug,
{
    pub fn new() -> Self {
        Self {
            timers: HashSet::new(),
        }
    }
}

impl<T> Default for Bucket<T>
where
    T: Copy + Clone + Eq + Hash + Debug,
{
    fn default() -> Bucket<T> {
        Bucket::new()
    }
}

#[derive(Clone, Copy, Eq, PartialEq, Hash)]
pub struct Timer<T> {
    bucket: usize,
    remaining: usize,
    token: T,
}

impl<T> Timer<T>
where
    T: Copy + Clone + Eq + Hash + Debug,
{
    pub fn token(&self) -> T {
        self.token
    }
}

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

    #[test]
    fn new() {
        let mut wheel = Wheel::<usize>::new(1000);
        assert!(wheel.tick(1000).is_empty());
        assert_eq!(wheel.next_timeout(), None);
    }

    #[test]
    fn add() {
        let mut wheel = Wheel::new(1000);
        let _id = wheel.add(0, 0);
        assert_eq!(wheel.pending(), 1);
        assert_eq!(wheel.next_timeout(), Some(0));
        let timers = wheel.tick(1);
        assert_eq!(timers.len(), 1);
        assert_eq!(wheel.pending(), 0);
        assert_eq!(wheel.next_timeout(), None);
    }

    #[test]
    fn cancel() {
        let mut wheel = Wheel::new(1000);
        wheel.add(0, 0);
        assert_eq!(wheel.pending(), 1);
        assert_eq!(wheel.next_timeout(), Some(0));
        wheel.cancel(0);
        assert_eq!(wheel.pending(), 0);
        assert_eq!(wheel.next_timeout(), None);
    }

    #[test]
    fn tick() {
        let mut wheel = Wheel::new(1000);
        for i in 0..1000 {
            wheel.add(i, i);
        }
        assert_eq!(wheel.pending(), 1000);
        for i in 0..1000 {
            assert_eq!(wheel.next_timeout(), Some(0));
            let timers = wheel.tick(1);
            assert_eq!(timers.len(), 1);
            assert_eq!(timers[0], i);
        }
        assert_eq!(wheel.pending(), 0);
        assert_eq!(wheel.next_timeout(), None);
    }

    #[test]
    fn wrap() {
        let mut wheel = Wheel::new(1000);
        for i in 0..2000 {
            wheel.add(i, i);
        }
        assert_eq!(wheel.pending(), 2000);
        for _ in 0..1000 {
            let timers = wheel.tick(1);
            assert_eq!(timers.len(), 1);
        }
        assert_eq!(wheel.pending(), 1000);
        for _ in 0..1000 {
            let timers = wheel.tick(1);
            assert_eq!(timers.len(), 1);
        }
        assert_eq!(wheel.pending(), 0);
    }

    #[test]
    fn next_timeout() {
        let mut wheel = Wheel::new(1000);
        wheel.add(1, 5000);
        assert_eq!(wheel.next_timeout(), Some(5000));
        wheel.add(2, 1000);
        assert_eq!(wheel.next_timeout(), Some(1000));
        wheel.add(3, 1);
        assert_eq!(wheel.next_timeout(), Some(1));
    }
}
<commit_msg>timer: add rustdoc<commit_after>// Copyright 2019 Twitter, Inc.
// Licensed under the Apache License, Version 2.0
// http://www.apache.org/licenses/LICENSE-2.0

//! A basic implementation of a hashed wheel timer

use logger::*;

use core::fmt::Debug;
use std::collections::{HashMap, HashSet};
use std::hash::Hash;

pub struct Wheel<T> {
    tick: usize,
    buckets: Vec<Bucket<T>>,
    timers: HashMap<T, Timer<T>>,
}

impl<T> Wheel<T>
where
    T: Copy + Clone + Eq + Hash + Debug,
{
    /// Create a new timer `Wheel` with a given number of `buckets`. Higher
    /// bucket count reduces collisions and results in more efficient
    /// bookkeeping at the expense of additional memory.
    ///
    /// # Example
    ///
    /// ```
    /// use timer::*;
    ///
    /// let timer = Wheel::<usize>::new(1000);
    /// ```
    pub fn new(buckets: usize) -> Self {
        let mut wheel = Self {
            tick: 0,
            buckets: Vec::with_capacity(buckets),
            timers: HashMap::new(),
        };
        for _ in 0..buckets {
            wheel.buckets.push(Bucket::new());
        }
        wheel
    }

    /// Moves the timer forward by a set number of ticks. Any timers that expire
    /// within the provided number of ticks will be returned in a `Vec<T>`
    ///
    /// # Example
    ///
    /// ```
    /// use timer::*;
    /// use std::time::{Duration, Instant};
    ///
    /// let mut timer = Wheel::new(1000);
    /// timer.add(1, 100);
    ///
    /// let mut last_tick = Instant::now();
    ///
    /// loop {
    ///     // do something here
    ///     let elapsed = Instant::now() - last_tick;
    ///     let ticks = elapsed.subsec_millis();
    ///     let expired = timer.tick(ticks as usize);
    ///     if expired.len() > 0 {
    ///         break;
    ///     }
    /// }
    /// ```
    pub fn tick(&mut self, ticks: usize) -> Vec<T> {
        let mut timers = Vec::new();
        for _ in 0..ticks {
            timers.extend(self.do_tick());
        }
        if !timers.is_empty() {
            debug!("timeouts: {}", timers.len());
        }
        timers
    }

    // internal function to advance by a single tick
    fn do_tick(&mut self) -> Vec<T> {
        let mut expired = Vec::with_capacity(self.buckets[self.tick].timers.len());
        let mut remaining = HashSet::new();
        for token in &self.buckets[self.tick].timers {
            if self.timers[&token].remaining == 0 {
                expired.push(*token);
                self.timers.remove(&token);
            } else {
                remaining.insert(*token);
                self.timers.get_mut(token).unwrap().remaining -= 1;
            }
        }
        self.buckets[self.tick].timers = remaining;
        if self.tick == (self.buckets.len() - 1) {
            self.tick = 0;
        } else {
            self.tick += 1;
        }
        expired
    }

    /// Adds a new timer for the given token for a number of ticks in the future
    ///
    /// # Examples
    ///
    /// ```
    /// use timer::*;
    ///
    /// let mut timer = Wheel::new(1000);
    ///
    /// timer.add(1, 0); // will expire on next tick
    /// let expired = timer.tick(1);
    /// assert_eq!(expired.len(), 1);
    /// ```
    pub fn add(&mut self, token: T, ticks: usize) {
        trace!("Add timer for {:?} in {} ticks", token, ticks);
        if self.timers.contains_key(&token) {
            self.cancel(token);
        }
        let bucket = (ticks + self.tick) % self.buckets.len();
        let remaining = ticks / self.buckets.len();
        let timer = Timer {
            token,
            remaining,
            bucket,
        };
        self.timers.insert(token, timer);
        self.buckets[bucket].timers.insert(token);
    }

    /// Return the number of timers registered
    ///
    /// # Examples
    ///
    /// ```
    /// use timer::*;
    ///
    /// let mut timer = Wheel::new(1000);
    ///
    /// assert_eq!(timer.pending(), 0);
    ///
    /// timer.add(1, 1);
    /// assert_eq!(timer.pending(), 1);
    /// ```
    pub fn pending(&self) -> usize {
        self.timers.len()
    }

    /// Cancel a pending timer
    ///
    /// # Examples
    ///
    /// ```
    /// use timer::*;
    ///
    /// let mut timer = Wheel::new(1000);
    ///
    /// timer.add(1, 1);
    /// assert_eq!(timer.pending(), 1);
    ///
    /// timer.cancel(1);
    /// assert_eq!(timer.pending(), 0);
    /// ```
    pub fn cancel(&mut self, token: T) {
        if let Some(timer) = self.timers.remove(&token) {
            self.buckets[timer.bucket].timers.remove(&token);
        }
        self.timers.shrink_to_fit();
    }

    /// Return the number of ticks until the next timeout would occur
    ///
    /// # Examples
    ///
    /// ```
    /// use timer::*;
    ///
    /// let mut timer = Wheel::new(1000);
    ///
    /// timer.add(1, 100);
    /// assert_eq!(timer.next_timeout(), Some(100));
    /// ```
    pub fn next_timeout(&self) -> Option<usize> {
        if self.timers.is_empty() {
            None
        } else {
            let mut remaining = 0;
            loop {
                for offset in 0..self.buckets.len() {
                    let mut tick = self.tick + offset;
                    if tick >= self.buckets.len() {
                        tick -= self.buckets.len();
                    }
                    for timer in &self.buckets[tick].timers {
                        if self.timers[&timer].remaining == remaining {
                            return Some(offset + remaining * self.buckets.len());
                        }
                    }
                }
                remaining += 1;
            }
        }
    }
}

pub struct Bucket<T> {
    timers: HashSet<T>,
}

impl<T> Bucket<T>
where
    T: Copy + Clone + Eq + Hash + Debug,
{
    pub fn new() -> Self {
        Self {
            timers: HashSet::new(),
        }
    }
}

impl<T> Default for Bucket<T>
where
    T: Copy + Clone + Eq + Hash + Debug,
{
    fn default() -> Bucket<T> {
        Bucket::new()
    }
}

#[derive(Clone, Copy, Eq, PartialEq, Hash)]
pub struct Timer<T> {
    bucket: usize,
    remaining: usize,
    token: T,
}

impl<T> Timer<T>
where
    T: Copy + Clone + Eq + Hash + Debug,
{
    pub fn token(&self) -> T {
        self.token
    }
}

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

    #[test]
    fn new() {
        let mut wheel = Wheel::<usize>::new(1000);
        assert!(wheel.tick(1000).is_empty());
        assert_eq!(wheel.next_timeout(), None);
    }

    #[test]
    fn add() {
        let mut wheel = Wheel::new(1000);
        let _id = wheel.add(0, 0);
        assert_eq!(wheel.pending(), 1);
        assert_eq!(wheel.next_timeout(), Some(0));
        let timers = wheel.tick(1);
        assert_eq!(timers.len(), 1);
        assert_eq!(wheel.pending(), 0);
        assert_eq!(wheel.next_timeout(), None);
    }

    #[test]
    fn cancel() {
        let mut wheel = Wheel::new(1000);
        wheel.add(0, 0);
        assert_eq!(wheel.pending(), 1);
        assert_eq!(wheel.next_timeout(), Some(0));
        wheel.cancel(0);
        assert_eq!(wheel.pending(), 0);
        assert_eq!(wheel.next_timeout(), None);
    }

    #[test]
    fn tick() {
        let mut wheel = Wheel::new(1000);
        for i in 0..1000 {
            wheel.add(i, i);
        }
        assert_eq!(wheel.pending(), 1000);
        for i in 0..1000 {
            assert_eq!(wheel.next_timeout(), Some(0));
            let timers = wheel.tick(1);
            assert_eq!(timers.len(), 1);
            assert_eq!(timers[0], i);
        }
        assert_eq!(wheel.pending(), 0);
        assert_eq!(wheel.next_timeout(), None);
    }

    #[test]
    fn wrap() {
        let mut wheel = Wheel::new(1000);
        for i in 0..2000 {
            wheel.add(i, i);
        }
        assert_eq!(wheel.pending(), 2000);
        for _ in 0..1000 {
            let timers = wheel.tick(1);
            assert_eq!(timers.len(), 1);
        }
        assert_eq!(wheel.pending(), 1000);
        for _ in 0..1000 {
            let timers = wheel.tick(1);
            assert_eq!(timers.len(), 1);
        }
        assert_eq!(wheel.pending(), 0);
    }

    #[test]
    fn next_timeout() {
        let mut wheel = Wheel::new(1000);
        wheel.add(1, 5000);
        assert_eq!(wheel.next_timeout(), Some(5000));
        wheel.add(2, 1000);
        assert_eq!(wheel.next_timeout(), Some(1000));
        wheel.add(3, 1);
        assert_eq!(wheel.next_timeout(), Some(1));
    }
}
<|endoftext|>


<commit_before>#![crate_id(name="sum", vers="1.0.0", author="T. Jameson Little")]
#![feature(macro_rules)]

/*
* This file is part of the uutils coreutils package.
*
* (c) T. Jameson Little <t.jameson.little@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

extern crate getopts;
extern crate libc;

use std::os;
use std::io::{File, IoResult, print};
use std::io::stdio::{stdin_raw};

#[path="../common/util.rs"]
mod util;

static VERSION: &'static str = "1.0.0";
static NAME: &'static str = "sum";

fn bsd_sum(mut reader: Box<Reader>) -> (uint, u16) {
    let mut buf = [0, .. 1024];
    let mut blocks_read = 0;
    let mut checksum: u16 = 0;
    loop {
        match reader.read(buf) {
            Ok(n) if n != 0 => {
                blocks_read += 1;
                for &byte in buf.slice_to(n).iter() {
                    checksum = (checksum >> 1) + ((checksum & 1) << 15);
                    checksum += byte as u16;
                }
            },
            _ => break,
        }
    }

    (blocks_read, checksum)
}

fn sysv_sum(mut reader: Box<Reader>) -> (uint, u16) {
    let mut buf = [0, .. 512];
    let mut blocks_read = 0;
    let mut ret = 0;

    loop {
        match reader.read(buf) {
            Ok(n) if n != 0 => {
                blocks_read += 1;
                for &byte in buf.slice_to(n).iter() {
                    ret += byte as u32;
                }
            },
            _ => break,
        }
    }

    ret = (ret & 0xffff) + (ret >> 16);
    ret = (ret & 0xffff) + (ret >> 16);

    (blocks_read, ret as u16)
}

fn open(name: &str) -> IoResult<Box<Reader>> {
	match name {
		"-" => Ok(box stdin_raw() as Box<Reader>),
		_ => {
			let f = try!(File::open(&Path::new(name)));
			Ok(box f as Box<Reader>)
		}
	}
}

#[allow(dead_code)]
fn main() { os::set_exit_status(uumain(os::args())); }

pub fn uumain(args: Vec<String>) -> int {
    let program = args.get(0).as_slice();
    let opts = [
        getopts::optflag("r", "", "use the BSD compatible algorithm (default)"),
        getopts::optflag("s", "sysv", "use System V compatible algorithm"),
        getopts::optflag("h", "help", "show this help message"),
        getopts::optflag("v", "version", "print the version and exit"),
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => m,
        Err(f) => crash!(1, "Invalid options\n{}", f)
    };

    if matches.opt_present("help") {
        println!("{} {}", program, VERSION);
        println!("");
        println!("Usage:");
        println!("  {0:s} [OPTION]... [FILE]...", program);
        println!("");
        print(getopts::usage("checksum and count the blocks in a file", opts).as_slice());
        println!("");
        println!("With no FILE, or when  FILE is -, read standard input.");
        return 0;
    }
    if matches.opt_present("version") {
        println!("{} {}", program, VERSION);
        return 0;
    }

    let sysv = matches.opt_present("sysv");

    let file = if matches.free.is_empty() {
        "-"
    } else {
        matches.free.get(0).as_slice()
    };

    let reader = match open(file) {
        Ok(f) => f,
        _ => crash!(1, "unable to open file")
    };
    let (blocks, sum) = if sysv {
        sysv_sum(reader)
    } else {
        bsd_sum(reader)
    };

    println!("{} {}", sum, blocks);

    0
}
<commit_msg>sum: handle multiple file args<commit_after>#![crate_id(name="sum", vers="1.0.0", author="T. Jameson Little")]
#![feature(macro_rules)]

/*
* This file is part of the uutils coreutils package.
*
* (c) T. Jameson Little <t.jameson.little@gmail.com>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

extern crate getopts;
extern crate libc;

use std::os;
use std::io::{File, IoResult, print};
use std::io::stdio::{stdin_raw};

#[path="../common/util.rs"]
mod util;

static VERSION: &'static str = "1.0.0";
static NAME: &'static str = "sum";

fn bsd_sum(mut reader: Box<Reader>) -> (uint, u16) {
    let mut buf = [0, .. 1024];
    let mut blocks_read = 0;
    let mut checksum: u16 = 0;
    loop {
        match reader.read(buf) {
            Ok(n) if n != 0 => {
                blocks_read += 1;
                for &byte in buf.slice_to(n).iter() {
                    checksum = (checksum >> 1) + ((checksum & 1) << 15);
                    checksum += byte as u16;
                }
            },
            _ => break,
        }
    }

    (blocks_read, checksum)
}

fn sysv_sum(mut reader: Box<Reader>) -> (uint, u16) {
    let mut buf = [0, .. 512];
    let mut blocks_read = 0;
    let mut ret = 0;

    loop {
        match reader.read(buf) {
            Ok(n) if n != 0 => {
                blocks_read += 1;
                for &byte in buf.slice_to(n).iter() {
                    ret += byte as u32;
                }
            },
            _ => break,
        }
    }

    ret = (ret & 0xffff) + (ret >> 16);
    ret = (ret & 0xffff) + (ret >> 16);

    (blocks_read, ret as u16)
}

fn open(name: &str) -> IoResult<Box<Reader>> {
	match name {
		"-" => Ok(box stdin_raw() as Box<Reader>),
		_ => {
			let f = try!(File::open(&Path::new(name)));
			Ok(box f as Box<Reader>)
		}
	}
}

#[allow(dead_code)]
fn main() { os::set_exit_status(uumain(os::args())); }

pub fn uumain(args: Vec<String>) -> int {
    let program = args.get(0).as_slice();
    let opts = [
        getopts::optflag("r", "", "use the BSD compatible algorithm (default)"),
        getopts::optflag("s", "sysv", "use System V compatible algorithm"),
        getopts::optflag("h", "help", "show this help message"),
        getopts::optflag("v", "version", "print the version and exit"),
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => m,
        Err(f) => crash!(1, "Invalid options\n{}", f)
    };

    if matches.opt_present("help") {
        println!("{} {}", program, VERSION);
        println!("");
        println!("Usage:");
        println!("  {0:s} [OPTION]... [FILE]...", program);
        println!("");
        print(getopts::usage("checksum and count the blocks in a file", opts).as_slice());
        println!("");
        println!("With no FILE, or when  FILE is -, read standard input.");
        return 0;
    }
    if matches.opt_present("version") {
        println!("{} {}", program, VERSION);
        return 0;
    }

    let sysv = matches.opt_present("sysv");

    let files = if matches.free.is_empty() {
        Vec::from_elem(1, "-".to_string())
    } else {
        matches.free
    };

    for file in files.iter() {
        let reader = match open(file.as_slice()) {
            Ok(f) => f,
            _ => crash!(1, "unable to open file")
        };
        let (blocks, sum) = if sysv {
            sysv_sum(reader)
        } else {
            bsd_sum(reader)
        };

        println!("{} {}", sum, blocks);
    }

    0
}
<|endoftext|>