<commit_before>use imgui::{Ui,ImStr,ImString};
use lichen::parse::{StreamParser,Env};

use std::fs;
use std::path::Path;

use app::AppState;

use std::io::{BufReader};
use std::fs::File;

pub struct FileState {
    /// MAX_PATH set to 260 chars
    cd: ImString,
    idx: i32,
    files: Vec<String>,
    selected: Option<String>,
    stream: Option<StreamParser<BufReader<File>>>,
    failed: String,
}

impl Default for FileState {
    fn default() -> Self {
        let mut cd = ImString::from(im_str!("./"));
        cd.reserve(261); //arbitrary max path size

        FileState {
            cd: cd,
            idx: 1,
            files: vec![],
            selected: None,
            stream: None,
            failed: "".to_owned(),
        }
    }
}

impl FileState {
    fn update(&mut self) -> Option<Env> {
        if self.idx > 1 { // chose a file?
            self.failed.clear();

            if let Some(file) = self.files.get(self.idx as usize) {
                self.cd.clear();
                self.cd.push_str(file);
                self.idx = 1;
            }
        }
        else if self.idx < 1 { // up a directory?
            self.failed.clear();
            self.to_parent();
        }

        let cd = self.cd.to_string();
        if Path::new(&cd).is_dir() {
            if let Ok(paths) = fs::read_dir(&cd) {
                self.files = paths
                    .filter(|p| p.is_ok())
                    .map(|p| {
                        p.unwrap().path().as_path().to_str().unwrap().to_owned()
                    })
                    .collect();

                self.files.insert(0,"./".to_owned());
                self.files.insert(0,"..".to_owned());
            }
            // NOTE: we should throw a warning here if directory cannot be traversed
        }
        else {
            if !cd.is_empty() {
                self.selected = Some(cd);
            }
        }

        if self.stream.is_some() {
            let r = self.step_stream();
            if !self.failed.is_empty() {
                self.stream = None;
            }
            r
        }
        else { None }
    }

    /// Steps through the stream chunks, finally returns parsed lichen environment
    fn step_stream (&mut self) -> Option<Env> {
        let r = {
            if let Some(ref mut stream) = self.stream {
                stream.next()
            }
            else { None }
        };

        if r.is_none() { // close stream, we're probably done
            let mut env = Env::empty();
            if let Some(ref mut stream) = self.stream {
                if let Err(e) = stream.sink(&mut env) {
                    self.failed = e.to_owned();
                    return None;
                }
            }

            self.stream = None;
            self.to_parent();

            return Some(env);
        }

        None
    }

    fn to_parent(&mut self) {
        self.selected = None;
        if let Some(path) = Path::new(&self.cd.to_string()).parent() {
            self.cd.clear();
            self.cd.push_str(path.to_str().expect("ERROR: Cannot parse path into string"));
            self.idx = 1;
        }
        // NOTE: this fails if we're at the top of a relative directory listing,
        // or the root of the drive/share
    }

    pub fn render (&mut self, ui: &Ui, state: &mut AppState) {
        if !state.open_file { return }
        state.env = self.update(); // NOTE: we should check if the environment is empty
        state.open_file = !state.env.is_some(); // close file if done

        ui.window(im_str!("Select source"))
            .always_auto_resize(true)
            .movable(true)
            .show_borders(true)
            .opened(&mut state.open_file)
            .build(||{
                ui.text(im_str!("Select a source file to be parsed and evaluated.\nSource files must be parsable through the lichen crate."));
                ui.separator();
                ui.input_text(im_str!("Current Directory"), &mut self.cd)
                    .enter_returns_true(true)
                    .build();
                ui.separator();

                // NOTE: to appease the borrow checker and have the proper argument for list_box
                // we must build the list in two steps
                let paths: Vec<ImString> = self.files.iter().map(|p| {
                    im_str!("{:}", p).to_owned()
                }).collect();

                let paths: Vec<&ImStr> = paths.iter().map(|p|p.as_ref()).collect();

                ui.list_box(im_str!("Files"),
                            &mut self.idx,
                            &paths[..],
                            paths.len() as i32);

                if let Some(ref file) = self.selected {
                    ui.text(im_str!("Select File {:}?",file));

                    if ui.small_button(im_str!("open")) {
                        if let Ok(f) = File::open(file) {
                            let f = BufReader::new(f);
                            let s = StreamParser::new(f,None);
                            self.stream = Some(s);
                        }
                    }
                }

                if !self.failed.is_empty() {
                    ui.text(im_str!("Failed to parse file {:}\nParse Error at: {:}",
                                    &self.cd.to_str(), &self.failed));
                }
            })
    }

}

<commit_msg>remove cd in listing<commit_after>use imgui::{Ui,ImStr,ImString};
use lichen::parse::{StreamParser,Env};

use std::fs;
use std::path::Path;

use app::AppState;

use std::io::{BufReader};
use std::fs::File;

pub struct FileState {
    /// MAX_PATH set to 260 chars
    cd: ImString,
    idx: i32,
    files: Vec<String>,
    selected: Option<String>,
    stream: Option<StreamParser<BufReader<File>>>,
    failed: String,
}

impl Default for FileState {
    fn default() -> Self {
        let mut cd = ImString::from(im_str!("./"));
        cd.reserve(261); //arbitrary max path size

        FileState {
            cd: cd,
            idx: 1,
            files: vec![],
            selected: None,
            stream: None,
            failed: "".to_owned(),
        }
    }
}

impl FileState {
    fn update(&mut self) -> Option<Env> {
        if self.idx > 0 { // chose a file?
            self.failed.clear();

            if let Some(file) = self.files.get(self.idx as usize) {
                self.cd.clear();
                self.cd.push_str(file);
                self.idx = -1;
            }
        }
        else if self.idx == 0 { // up a directory?
            self.failed.clear();
            self.to_parent();
        }

        let cd = self.cd.to_string();
        if Path::new(&cd).is_dir() {
            if let Ok(paths) = fs::read_dir(&cd) {
                self.files = paths
                    .filter(|p| p.is_ok())
                    .map(|p| {
                        p.unwrap().path().as_path().to_str().unwrap().to_owned()
                    })
                    .collect();

                //self.files.insert(0,"./".to_owned());
                self.files.insert(0,"..".to_owned());
            }
            // NOTE: we should throw a warning here if directory cannot be traversed
        }
        else {
            if !cd.is_empty() {
                self.selected = Some(cd);
            }
        }

        if self.stream.is_some() {
            let r = self.step_stream();
            if !self.failed.is_empty() {
                self.stream = None;
            }
            r
        }
        else { None }
    }

    /// Steps through the stream chunks, finally returns parsed lichen environment
    fn step_stream (&mut self) -> Option<Env> {
        let r = {
            if let Some(ref mut stream) = self.stream {
                stream.next()
            }
            else { None }
        };

        if r.is_none() { // close stream, we're probably done
            let mut env = Env::empty();
            if let Some(ref mut stream) = self.stream {
                if let Err(e) = stream.sink(&mut env) {
                    self.failed = e.to_owned();
                    return None;
                }
            }

            self.stream = None;
            self.to_parent();

            return Some(env);
        }

        None
    }

    fn to_parent(&mut self) {
        self.selected = None;
        if let Some(path) = Path::new(&self.cd.to_string()).parent() {
            self.cd.clear();
            self.cd.push_str(path.to_str().expect("ERROR: Cannot parse path into string"));
            self.idx = -1;
        }
        // NOTE: this fails if we're at the top of a relative directory listing,
        // or the root of the drive/share
    }

    pub fn render (&mut self, ui: &Ui, state: &mut AppState) {
        if !state.open_file { return }
        state.env = self.update(); // NOTE: we should check if the environment is empty
        state.open_file = !state.env.is_some(); // close file if done

        ui.window(im_str!("Select source"))
            .always_auto_resize(true)
            .movable(true)
            .show_borders(true)
            .opened(&mut state.open_file)
            .build(||{
                ui.text(im_str!("Select a source file to be parsed and evaluated.\nSource files must be parsable through the lichen crate."));
                ui.separator();
                ui.input_text(im_str!("Current Directory"), &mut self.cd)
                    .enter_returns_true(true)
                    .build();
                ui.separator();

                // NOTE: to appease the borrow checker and have the proper argument for list_box
                // we must build the list in two steps
                let paths: Vec<ImString> = self.files.iter().map(|p| {
                    im_str!("{:}", p).to_owned()
                }).collect();

                let paths: Vec<&ImStr> = paths.iter().map(|p|p.as_ref()).collect();

                ui.list_box(im_str!("Files"),
                            &mut self.idx,
                            &paths[..],
                            paths.len() as i32);

                if let Some(ref file) = self.selected {
                    ui.text(im_str!("Select File {:}?",file));

                    if ui.small_button(im_str!("open")) {
                        if let Ok(f) = File::open(file) {
                            let f = BufReader::new(f);
                            let s = StreamParser::new(f,None);
                            self.stream = Some(s);
                        }
                    }
                }

                if !self.failed.is_empty() {
                    ui.text(im_str!("Failed to parse file {:}\nParse Error at: {:}",
                                    &self.cd.to_str(), &self.failed));
                }
            })
    }

}

<|endoftext|>


<commit_before>//! Free functions that create iterator adaptors or call iterator methods.
//!
//! The benefit of free functions is that they accept any `IntoIterator` as
//! argument, so the resulting code may be easier to read.

use std::fmt::Display;
use std::iter::{self, Zip};
use {
    Interleave,
    Itertools,
    KMerge,
    Merge,
    ZipEq,
};

/// Iterate `iterable` with a running index.
///
/// `IntoIterator` enabled version of `.enumerate()`.
///
/// ```
/// use itertools::enumerate;
///
/// for (i, elt) in enumerate(&[1, 2, 3]) {
///     /* loop body */
/// }
/// ```
pub fn enumerate<I>(iterable: I) -> iter::Enumerate<I::IntoIter>
    where I: IntoIterator
{
    iterable.into_iter().enumerate()
}

/// Iterate `iterable` in reverse.
///
/// `IntoIterator` enabled version of `.rev()`.
///
/// ```
/// use itertools::rev;
///
/// for elt in rev(&[1, 2, 3]) {
///     /* loop body */
/// }
/// ```
pub fn rev<I>(iterable: I) -> iter::Rev<I::IntoIter>
    where I: IntoIterator,
          I::IntoIter: DoubleEndedIterator
{
    iterable.into_iter().rev()
}

/// Iterate `i` and `j` in lock step.
///
/// `IntoIterator` enabled version of `i.zip(j)`.
///
/// ```
/// use itertools::free::zip;
///
/// let data = [1, 2, 3, 4, 5];
/// for (a, b) in zip(&data, &data[1..]) {
///     /* loop body */
/// }
/// ```
pub fn zip<I, J>(i: I, j: J) -> Zip<I::IntoIter, J::IntoIter>
    where I: IntoIterator,
          J: IntoIterator
{
    i.into_iter().zip(j)
}

/// Iterate `i` and `j` in lock step.
///
/// **Panics** if the iterators are not of the same length.
///
/// `IntoIterator` enabled version of `i.zip_eq(j)`.
///
/// ```
/// use itertools::free::zip_eq;
///
/// let data = [1, 2, 3, 4, 5];
/// for (a, b) in zip_eq(&data[..data.len() - 1], &data[1..]) {
///     /* loop body */
/// }
/// ```
pub fn zip_eq<I, J>(i: I, j: J) -> ZipEq<I::IntoIter, J::IntoIter>
    where I: IntoIterator,
          J: IntoIterator
{
    i.into_iter().zip_eq(j)
}

/// Create an iterator that first iterates `i` and then `j`.
///
/// `IntoIterator` enabled version of `i.chain(j)`.
///
/// ```
/// use itertools::free::chain;
///
/// for elt in chain(&[1, 2, 3], &[4]) {
///     /* loop body */
/// }
/// ```
pub fn chain<I, J>(i: I, j: J) -> iter::Chain<<I as IntoIterator>::IntoIter, <J as IntoIterator>::IntoIter>
    where I: IntoIterator,
          J: IntoIterator<Item = I::Item>
{
    i.into_iter().chain(j)
}

/// Perform a fold operation over the iterable.
///
/// `IntoIterator` enabled version of `i.fold(init, f)`
///
/// ```
/// use itertools::free::fold;
///
/// assert_eq!(fold(&[1., 2., 3.], 0., |a, &b| f32::max(a, b)), 3.);
/// ```
pub fn fold<I, B, F>(iterable: I, init: B, f: F) -> B
    where I: IntoIterator,
          F: FnMut(B, I::Item) -> B
{
    iterable.into_iter().fold(init, f)
}

/// Test whether the predicate holds for all elements in the iterable.
///
/// `IntoIterator` enabled version of `i.all(f)`
///
/// ```
/// use itertools::free::all;
///
/// assert!(all(&[1, 2, 3], |elt| *elt > 0));
/// ```
pub fn all<I, F>(iterable: I, f: F) -> bool
    where I: IntoIterator,
          F: FnMut(I::Item) -> bool
{
    iterable.into_iter().all(f)
}

/// Test whether the predicate holds for any elements in the iterable.
///
/// `IntoIterator` enabled version of `i.any(f)`
///
/// ```
/// use itertools::free::any;
///
/// assert!(any(&[0, -1, 2], |elt| *elt > 0));
/// ```
pub fn any<I, F>(iterable: I, f: F) -> bool
    where I: IntoIterator,
          F: FnMut(I::Item) -> bool
{
    iterable.into_iter().any(f)
}

/// Return the maximum value of the iterable.
///
/// `IntoIterator` enabled version of `i.max()`.
///
/// ```
/// use itertools::free::max;
///
/// assert_eq!(max(0..10), Some(9));
/// ```
pub fn max<I>(iterable: I) -> Option<I::Item>
    where I: IntoIterator,
          I::Item: Ord
{
    iterable.into_iter().max()
}

/// Return the minimum value of the iterable.
///
/// `IntoIterator` enabled version of `i.min()`.
///
/// ```
/// use itertools::free::min;
///
/// assert_eq!(min(0..10), Some(0));
/// ```
pub fn min<I>(iterable: I) -> Option<I::Item>
    where I: IntoIterator,
          I::Item: Ord
{
    iterable.into_iter().min()
}

/// Create an iterator that interleaves elements in `i` and `j`.
///
/// `IntoIterator` enabled version of `i.interleave(j)`.
///
/// ```
/// use itertools::free::interleave;
///
/// for elt in interleave(&[1, 2, 3], &[2, 3, 4]) {
///     /* loop body */
/// }
/// ```
pub fn interleave<I, J>(i: I, j: J) -> Interleave<<I as IntoIterator>::IntoIter, <J as IntoIterator>::IntoIter>
    where I: IntoIterator,
          J: IntoIterator<Item = I::Item>
{
    i.into_iter().interleave(j)
}

/// Create an iterator that merges elements in `i` and `j`.
///
/// `IntoIterator` enabled version of `i.merge(j)`.
///
/// ```
/// use itertools::free::merge;
///
/// for elt in merge(&[1, 2, 3], &[2, 3, 4]) {
///     /* loop body */
/// }
/// ```
pub fn merge<I, J>(i: I, j: J) -> Merge<<I as IntoIterator>::IntoIter, <J as IntoIterator>::IntoIter>
    where I: IntoIterator,
          J: IntoIterator<Item = I::Item>,
          I::Item: PartialOrd
{
    i.into_iter().merge(j)
}

/// Create an iterator that merges elements of the contained iterators.
///
/// Equivalent to `i.into_iter().kmerge()`.
///
/// ```
/// use itertools::free::kmerge;
///
/// for elt in kmerge(vec![vec![0, 2, 4], vec![1, 3, 5], vec![6, 7]]) {
///     /* loop body */
/// }
/// ```
pub fn kmerge<I>(i: I) -> KMerge<<<I as IntoIterator>::Item as IntoIterator>::IntoIter>
    where I: IntoIterator,
          I::Item: IntoIterator,
          <<I as IntoIterator>::Item as IntoIterator>::Item: Ord,
{
    i.into_iter().kmerge()
}

/// Combine all iterator elements into one String, seperated by `sep`.
///
/// `IntoIterator` enabled version of `iterable.join(sep)`.
///
/// ```
/// use itertools::free::join;
///
/// assert_eq!(join(&[1, 2, 3], ", "), "1, 2, 3");
/// ```
pub fn join<I>(iterable: I, sep: &str) -> String
    where I: IntoIterator,
          I::Item: Display
{
    iterable.into_iter().join(sep)
}

/// Collect all the iterable's elements into a sorted vector in ascending order.
///
/// `IntoIterator` enabled version of `iterable.sorted()`.
///
/// ```
/// use itertools::free::sorted;
/// use itertools::assert_equal;
///
/// assert_equal(sorted("rust".chars()), "rstu".chars());
/// ```
pub fn sorted<I>(iterable: I) -> Vec<I::Item>
    where I: IntoIterator,
          I::Item: Ord
{
    iterable.into_iter().sorted()
}
<commit_msg>Add fn cloned to itertools::free<commit_after>//! Free functions that create iterator adaptors or call iterator methods.
//!
//! The benefit of free functions is that they accept any `IntoIterator` as
//! argument, so the resulting code may be easier to read.

use std::fmt::Display;
use std::iter::{self, Zip};
use {
    Interleave,
    Itertools,
    KMerge,
    Merge,
    ZipEq,
};

/// Iterate `iterable` with a running index.
///
/// `IntoIterator` enabled version of `.enumerate()`.
///
/// ```
/// use itertools::enumerate;
///
/// for (i, elt) in enumerate(&[1, 2, 3]) {
///     /* loop body */
/// }
/// ```
pub fn enumerate<I>(iterable: I) -> iter::Enumerate<I::IntoIter>
    where I: IntoIterator
{
    iterable.into_iter().enumerate()
}

/// Iterate `iterable` in reverse.
///
/// `IntoIterator` enabled version of `.rev()`.
///
/// ```
/// use itertools::rev;
///
/// for elt in rev(&[1, 2, 3]) {
///     /* loop body */
/// }
/// ```
pub fn rev<I>(iterable: I) -> iter::Rev<I::IntoIter>
    where I: IntoIterator,
          I::IntoIter: DoubleEndedIterator
{
    iterable.into_iter().rev()
}

/// Iterate `i` and `j` in lock step.
///
/// `IntoIterator` enabled version of `i.zip(j)`.
///
/// ```
/// use itertools::free::zip;
///
/// let data = [1, 2, 3, 4, 5];
/// for (a, b) in zip(&data, &data[1..]) {
///     /* loop body */
/// }
/// ```
pub fn zip<I, J>(i: I, j: J) -> Zip<I::IntoIter, J::IntoIter>
    where I: IntoIterator,
          J: IntoIterator
{
    i.into_iter().zip(j)
}

/// Iterate `i` and `j` in lock step.
///
/// **Panics** if the iterators are not of the same length.
///
/// `IntoIterator` enabled version of `i.zip_eq(j)`.
///
/// ```
/// use itertools::free::zip_eq;
///
/// let data = [1, 2, 3, 4, 5];
/// for (a, b) in zip_eq(&data[..data.len() - 1], &data[1..]) {
///     /* loop body */
/// }
/// ```
pub fn zip_eq<I, J>(i: I, j: J) -> ZipEq<I::IntoIter, J::IntoIter>
    where I: IntoIterator,
          J: IntoIterator
{
    i.into_iter().zip_eq(j)
}

/// Create an iterator that first iterates `i` and then `j`.
///
/// `IntoIterator` enabled version of `i.chain(j)`.
///
/// ```
/// use itertools::free::chain;
///
/// for elt in chain(&[1, 2, 3], &[4]) {
///     /* loop body */
/// }
/// ```
pub fn chain<I, J>(i: I, j: J) -> iter::Chain<<I as IntoIterator>::IntoIter, <J as IntoIterator>::IntoIter>
    where I: IntoIterator,
          J: IntoIterator<Item = I::Item>
{
    i.into_iter().chain(j)
}

/// Create an iterator that clones each element from &T to T
///
/// `IntoIterator` enabled version of `i.cloned()`.
///
/// ```
/// use itertools::free::cloned;
///
/// assert_eq!(cloned(b"abc").next(), Some(b'a'));
/// ```
pub fn cloned<'a, I, T: 'a>(iterable: I) -> iter::Cloned<I::IntoIter>
    where I: IntoIterator<Item=&'a T>,
          T: Clone,
{
    iterable.into_iter().cloned()
}

/// Perform a fold operation over the iterable.
///
/// `IntoIterator` enabled version of `i.fold(init, f)`
///
/// ```
/// use itertools::free::fold;
///
/// assert_eq!(fold(&[1., 2., 3.], 0., |a, &b| f32::max(a, b)), 3.);
/// ```
pub fn fold<I, B, F>(iterable: I, init: B, f: F) -> B
    where I: IntoIterator,
          F: FnMut(B, I::Item) -> B
{
    iterable.into_iter().fold(init, f)
}

/// Test whether the predicate holds for all elements in the iterable.
///
/// `IntoIterator` enabled version of `i.all(f)`
///
/// ```
/// use itertools::free::all;
///
/// assert!(all(&[1, 2, 3], |elt| *elt > 0));
/// ```
pub fn all<I, F>(iterable: I, f: F) -> bool
    where I: IntoIterator,
          F: FnMut(I::Item) -> bool
{
    iterable.into_iter().all(f)
}

/// Test whether the predicate holds for any elements in the iterable.
///
/// `IntoIterator` enabled version of `i.any(f)`
///
/// ```
/// use itertools::free::any;
///
/// assert!(any(&[0, -1, 2], |elt| *elt > 0));
/// ```
pub fn any<I, F>(iterable: I, f: F) -> bool
    where I: IntoIterator,
          F: FnMut(I::Item) -> bool
{
    iterable.into_iter().any(f)
}

/// Return the maximum value of the iterable.
///
/// `IntoIterator` enabled version of `i.max()`.
///
/// ```
/// use itertools::free::max;
///
/// assert_eq!(max(0..10), Some(9));
/// ```
pub fn max<I>(iterable: I) -> Option<I::Item>
    where I: IntoIterator,
          I::Item: Ord
{
    iterable.into_iter().max()
}

/// Return the minimum value of the iterable.
///
/// `IntoIterator` enabled version of `i.min()`.
///
/// ```
/// use itertools::free::min;
///
/// assert_eq!(min(0..10), Some(0));
/// ```
pub fn min<I>(iterable: I) -> Option<I::Item>
    where I: IntoIterator,
          I::Item: Ord
{
    iterable.into_iter().min()
}

/// Create an iterator that interleaves elements in `i` and `j`.
///
/// `IntoIterator` enabled version of `i.interleave(j)`.
///
/// ```
/// use itertools::free::interleave;
///
/// for elt in interleave(&[1, 2, 3], &[2, 3, 4]) {
///     /* loop body */
/// }
/// ```
pub fn interleave<I, J>(i: I, j: J) -> Interleave<<I as IntoIterator>::IntoIter, <J as IntoIterator>::IntoIter>
    where I: IntoIterator,
          J: IntoIterator<Item = I::Item>
{
    i.into_iter().interleave(j)
}

/// Create an iterator that merges elements in `i` and `j`.
///
/// `IntoIterator` enabled version of `i.merge(j)`.
///
/// ```
/// use itertools::free::merge;
///
/// for elt in merge(&[1, 2, 3], &[2, 3, 4]) {
///     /* loop body */
/// }
/// ```
pub fn merge<I, J>(i: I, j: J) -> Merge<<I as IntoIterator>::IntoIter, <J as IntoIterator>::IntoIter>
    where I: IntoIterator,
          J: IntoIterator<Item = I::Item>,
          I::Item: PartialOrd
{
    i.into_iter().merge(j)
}

/// Create an iterator that merges elements of the contained iterators.
///
/// Equivalent to `i.into_iter().kmerge()`.
///
/// ```
/// use itertools::free::kmerge;
///
/// for elt in kmerge(vec![vec![0, 2, 4], vec![1, 3, 5], vec![6, 7]]) {
///     /* loop body */
/// }
/// ```
pub fn kmerge<I>(i: I) -> KMerge<<<I as IntoIterator>::Item as IntoIterator>::IntoIter>
    where I: IntoIterator,
          I::Item: IntoIterator,
          <<I as IntoIterator>::Item as IntoIterator>::Item: Ord,
{
    i.into_iter().kmerge()
}

/// Combine all iterator elements into one String, seperated by `sep`.
///
/// `IntoIterator` enabled version of `iterable.join(sep)`.
///
/// ```
/// use itertools::free::join;
///
/// assert_eq!(join(&[1, 2, 3], ", "), "1, 2, 3");
/// ```
pub fn join<I>(iterable: I, sep: &str) -> String
    where I: IntoIterator,
          I::Item: Display
{
    iterable.into_iter().join(sep)
}

/// Collect all the iterable's elements into a sorted vector in ascending order.
///
/// `IntoIterator` enabled version of `iterable.sorted()`.
///
/// ```
/// use itertools::free::sorted;
/// use itertools::assert_equal;
///
/// assert_equal(sorted("rust".chars()), "rstu".chars());
/// ```
pub fn sorted<I>(iterable: I) -> Vec<I::Item>
    where I: IntoIterator,
          I::Item: Ord
{
    iterable.into_iter().sorted()
}
<|endoftext|>


<commit_before>extern crate ws;

use ws::{Factory, Sender, Handler, Message, Result};

use player::Player;

// We should probably use RefCells so we can borrow the struct and mutate it across threads
pub struct Game<S: Handler> {
    state: S
}

impl<S: Handler> Factory for Game<S> {
    type Handler = S;

    fn connection_made(&mut self, _: Sender) -> Self::Handler {
        self.state
    }

    fn client_connected(&mut self, ws: Sender) -> Self::Handler {
        self.connection_made(ws)
    }
}

struct Inactive<'a> {
    players: &'a mut Vec<Player>,
}

impl<'a> Handler for Inactive<'a> {
    fn on_message(&mut self, msg: Message) -> Result<()> {
        if let Ok(text) = msg.as_text() {
            match text {
                _ => println!("{}", text)
            }
        }

        let new_state: Nominating = Nominating::from(*self);

        Ok(())
    }
}

struct Nominating<'a> {
    players: &'a mut Vec<Player>,
}

impl<'a> Handler for Nominating<'a> {
    fn on_message(&mut self, msg: Message) -> Result<()> {
        Ok(())
    }
}

struct RoundStart<'a> {
    players: &'a mut Vec<Player>,
}

impl<'a> Handler for RoundStart<'a> {
    fn on_message(&mut self, msg: Message) -> Result<()> {
        Ok(())
    }
}

struct RoundEnd<'a> {
    players: &'a mut Vec<Player>,
}

impl<'a> Handler for RoundEnd<'a> {
    fn on_message(&mut self, msg: Message) -> Result<()> {
        Ok(())
    }
}

struct Paused<'a> {
    players: &'a mut Vec<Player>,
}

impl<'a> Handler for Paused<'a> {
    fn on_message(&mut self, msg: Message) -> Result<()> {
        Ok(())
    }
}

// Games start off in the inactive state
impl<'a> Game<Inactive<'a>> {
    pub fn new(players: &'a mut Vec<Player>) -> Self {
        let game = Game {
            state: Inactive {
                players: players,
            }
        };

        game
    }
}

// Transitions

// Transition for when player quota is not met while nominating
impl<'a> From<Nominating<'a>> for Inactive<'a> {
    fn from(prev: Nominating<'a>) -> Inactive<'a> {
        Inactive {
            players: prev.players,
        }
    }
}

// Transition on player join
impl<'a> From<Inactive<'a>> for Nominating<'a> {
    fn from(prev: Inactive<'a>) -> Nominating<'a> {
        Nominating {
            players: prev.players,
        }
    }
}

// Transition when player quota is not met while round is starting
impl<'a> From<RoundStart<'a>> for Nominating<'a> {
    fn from(prev: RoundStart<'a>) -> Nominating<'a> {
        Nominating {
            players: prev.players,
        }
    }
}

// Transition when player quota is met while nominating
impl<'a> From<Nominating<'a>> for RoundStart<'a> {
    fn from(prev: Nominating<'a>) -> RoundStart<'a> {
        RoundStart {
            players: prev.players,
        }
    }
}

// Transition for a completed round
impl<'a> From<RoundEnd<'a>> for RoundStart<'a> {
    fn from(prev: RoundEnd<'a>) -> RoundStart<'a> {
        RoundStart {
            players: prev.players,
        }
    }
}

// Transition when judge chooses or times out
impl<'a> From<RoundStart<'a>> for RoundEnd<'a> {
    fn from(prev: RoundStart<'a>) -> RoundEnd<'a> {
        RoundEnd {
            players: prev.players,
        }
    }
}<commit_msg>Return game object directly<commit_after>extern crate ws;

use ws::{Factory, Sender, Handler, Message, Result};

use player::Player;

// We should probably use RefCells so we can borrow the struct and mutate it across threads
pub struct Game<S: Handler> {
    state: S
}

impl<S: Handler> Factory for Game<S> {
    type Handler = S;

    fn connection_made(&mut self, _: Sender) -> Self::Handler {
        self.state
    }

    fn client_connected(&mut self, ws: Sender) -> Self::Handler {
        self.connection_made(ws)
    }
}

struct Inactive<'a> {
    players: &'a mut Vec<Player>,
}

impl<'a> Handler for Inactive<'a> {
    fn on_message(&mut self, msg: Message) -> Result<()> {
        if let Ok(text) = msg.as_text() {
            match text {
                _ => println!("{}", text)
            }
        }

        let new_state: Nominating = Nominating::from(*self);

        Ok(())
    }
}

struct Nominating<'a> {
    players: &'a mut Vec<Player>,
}

impl<'a> Handler for Nominating<'a> {
    fn on_message(&mut self, msg: Message) -> Result<()> {
        Ok(())
    }
}

struct RoundStart<'a> {
    players: &'a mut Vec<Player>,
}

impl<'a> Handler for RoundStart<'a> {
    fn on_message(&mut self, msg: Message) -> Result<()> {
        Ok(())
    }
}

struct RoundEnd<'a> {
    players: &'a mut Vec<Player>,
}

impl<'a> Handler for RoundEnd<'a> {
    fn on_message(&mut self, msg: Message) -> Result<()> {
        Ok(())
    }
}

struct Paused<'a> {
    players: &'a mut Vec<Player>,
}

impl<'a> Handler for Paused<'a> {
    fn on_message(&mut self, msg: Message) -> Result<()> {
        Ok(())
    }
}

// Games start off in the inactive state
impl<'a> Game<Inactive<'a>> {
    pub fn new(players: &'a mut Vec<Player>) -> Self {
        Game {
            state: Inactive {
                players: players,
            }
        }
    }
}

// Transitions

// Transition for when player quota is not met while nominating
impl<'a> From<Nominating<'a>> for Inactive<'a> {
    fn from(prev: Nominating<'a>) -> Inactive<'a> {
        Inactive {
            players: prev.players,
        }
    }
}

// Transition on player join
impl<'a> From<Inactive<'a>> for Nominating<'a> {
    fn from(prev: Inactive<'a>) -> Nominating<'a> {
        Nominating {
            players: prev.players,
        }
    }
}

// Transition when player quota is not met while round is starting
impl<'a> From<RoundStart<'a>> for Nominating<'a> {
    fn from(prev: RoundStart<'a>) -> Nominating<'a> {
        Nominating {
            players: prev.players,
        }
    }
}

// Transition when player quota is met while nominating
impl<'a> From<Nominating<'a>> for RoundStart<'a> {
    fn from(prev: Nominating<'a>) -> RoundStart<'a> {
        RoundStart {
            players: prev.players,
        }
    }
}

// Transition for a completed round
impl<'a> From<RoundEnd<'a>> for RoundStart<'a> {
    fn from(prev: RoundEnd<'a>) -> RoundStart<'a> {
        RoundStart {
            players: prev.players,
        }
    }
}

// Transition when judge chooses or times out
impl<'a> From<RoundStart<'a>> for RoundEnd<'a> {
    fn from(prev: RoundStart<'a>) -> RoundEnd<'a> {
        RoundEnd {
            players: prev.players,
        }
    }
}<|endoftext|>


<commit_before>pub use imp::{gzip, identity, MaybeGzip};

#[cfg(feature = "gzip")]
mod imp {
    use std::io;
    use std::pin::Pin;
    use std::task::{Context, Poll};

    use async_compression::tokio::bufread::GzipDecoder;
    use bytes::{Buf, Bytes};
    use futures_core::{Stream, TryStream};
    use futures_util::future::Either;
    use futures_util::ready;
    use pin_project_lite::pin_project;
    use tokio_util::codec::{BytesCodec, FramedRead};
    use tokio_util::io::StreamReader;

    use crate::error::Error;

    pub type MaybeGzip<S> = Either<Gzip<S>, S>;

    type DecoderStream<S> =
        FramedRead<GzipDecoder<StreamReader<S, <S as TryStream>::Ok>>, BytesCodec>;

    pin_project! {
        pub struct Gzip<S: TryStream> {
            #[pin]
            inner: DecoderStream<Adapter<S>>,
        }
    }

    pin_project! {
        struct Adapter<S>
        where
            S: TryStream,
        {
            #[pin]
            inner: S,
            error: Option<S::Error>,
        }
    }

    impl<S: TryStream> Gzip<S>
    where
        S::Ok: Buf,
    {
        fn new(s: S) -> Self {
            let inner = FramedRead::new(
                GzipDecoder::new(StreamReader::new(Adapter {
                    inner: s,
                    error: None,
                })),
                BytesCodec::new(),
            );
            Gzip { inner }
        }
    }

    impl<S: TryStream<Error = Error<E>>, E> Stream for Gzip<S>
    where
        S::Ok: Buf,
    {
        type Item = Result<Bytes, Error<E>>;

        fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
            let mut inner = self.project().inner;
            // This cannot be `Pin::new(&mut inner.map_err(..)).poll_next(cx)`
            // because `inner` is borrowed inside `map_err`.
            inner.as_mut().poll_next(cx).map(|option| {
                option.map(|result| {
                    result.map(Into::into).map_err(|e| {
                        inner
                            .get_pin_mut()
                            .get_pin_mut()
                            .get_pin_mut()
                            .project()
                            .error
                            .take()
                            .unwrap_or(Error::Gzip(e))
                    })
                })
            })
        }
    }

    impl<S: TryStream> Stream for Adapter<S> {
        type Item = io::Result<S::Ok>;

        fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
            let mut this = self.project();
            match ready!(this.inner.as_mut().try_poll_next(cx)) {
                Some(result) => Poll::Ready(Some(result.map_err(|e| {
                    *this.error = Some(e);
                    io::Error::from_raw_os_error(0)
                }))),
                None => Poll::Ready(None),
            }
        }
    }

    pub fn gzip<S: TryStream>(s: S) -> MaybeGzip<S>
    where
        S::Ok: Buf,
    {
        Either::Left(Gzip::new(s))
    }

    pub fn identity<S: TryStream>(s: S) -> MaybeGzip<S> {
        Either::Right(s)
    }
}

#[cfg(not(feature = "gzip"))]
mod imp {
    use bytes::Bytes;
    use futures_core::TryStream;

    pub type MaybeGzip<S> = S;

    pub fn gzip<S: TryStream<Ok = Bytes>>(s: S) -> MaybeGzip<S> {
        s
    }

    pub fn identity<S: TryStream<Ok = Bytes>>(s: S) -> MaybeGzip<S> {
        s
    }
}
<commit_msg>Replace nested combinator calls with a single `match`<commit_after>pub use imp::{gzip, identity, MaybeGzip};

#[cfg(feature = "gzip")]
mod imp {
    use std::io;
    use std::pin::Pin;
    use std::task::{Context, Poll};

    use async_compression::tokio::bufread::GzipDecoder;
    use bytes::{Buf, Bytes};
    use futures_core::{Stream, TryStream};
    use futures_util::future::Either;
    use futures_util::ready;
    use pin_project_lite::pin_project;
    use tokio_util::codec::{BytesCodec, FramedRead};
    use tokio_util::io::StreamReader;

    use crate::error::Error;

    pub type MaybeGzip<S> = Either<Gzip<S>, S>;

    type DecoderStream<S> =
        FramedRead<GzipDecoder<StreamReader<S, <S as TryStream>::Ok>>, BytesCodec>;

    pin_project! {
        pub struct Gzip<S: TryStream> {
            #[pin]
            inner: DecoderStream<Adapter<S>>,
        }
    }

    pin_project! {
        struct Adapter<S>
        where
            S: TryStream,
        {
            #[pin]
            inner: S,
            error: Option<S::Error>,
        }
    }

    impl<S: TryStream> Gzip<S>
    where
        S::Ok: Buf,
    {
        fn new(s: S) -> Self {
            let inner = FramedRead::new(
                GzipDecoder::new(StreamReader::new(Adapter {
                    inner: s,
                    error: None,
                })),
                BytesCodec::new(),
            );
            Gzip { inner }
        }
    }

    impl<S: TryStream<Error = Error<E>>, E> Stream for Gzip<S>
    where
        S::Ok: Buf,
    {
        type Item = Result<Bytes, Error<E>>;

        fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
            let mut inner = self.project().inner;
            match ready!(inner.as_mut().poll_next(cx)) {
                Some(Ok(buf)) => Poll::Ready(Some(Ok(buf.freeze()))),
                Some(Err(e)) => Poll::Ready(Some(Err(inner
                    .get_pin_mut()
                    .get_pin_mut()
                    .get_pin_mut()
                    .project()
                    .error
                    .take()
                    .unwrap_or(Error::Gzip(e))))),
                None => Poll::Ready(None),
            }
        }
    }

    impl<S: TryStream> Stream for Adapter<S> {
        type Item = io::Result<S::Ok>;

        fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
            let mut this = self.project();
            match ready!(this.inner.as_mut().try_poll_next(cx)) {
                Some(result) => Poll::Ready(Some(result.map_err(|e| {
                    *this.error = Some(e);
                    io::Error::from_raw_os_error(0)
                }))),
                None => Poll::Ready(None),
            }
        }
    }

    pub fn gzip<S: TryStream>(s: S) -> MaybeGzip<S>
    where
        S::Ok: Buf,
    {
        Either::Left(Gzip::new(s))
    }

    pub fn identity<S: TryStream>(s: S) -> MaybeGzip<S> {
        Either::Right(s)
    }
}

#[cfg(not(feature = "gzip"))]
mod imp {
    use bytes::Bytes;
    use futures_core::TryStream;

    pub type MaybeGzip<S> = S;

    pub fn gzip<S: TryStream<Ok = Bytes>>(s: S) -> MaybeGzip<S> {
        s
    }

    pub fn identity<S: TryStream<Ok = Bytes>>(s: S) -> MaybeGzip<S> {
        s
    }
}
<|endoftext|>


<commit_before>use error;

#[allow(non_camel_case_types)]
#[repr(C)]
#[warn(improper_ctypes)]
struct virConnect;

#[link(name = "virt")]
extern {
    fn virConnectOpen(name: *const u8) -> *mut virConnect;
    fn virConnectClose(conn: *const virConnect) -> *const u8;
}

pub struct Host {
    conn: *mut virConnect
}

impl Host {
    /// This function should be called first to get a connection to
    /// the Hypervisor and xen store.
    ///
    /// If @name is NULL, if the LIBVIRT_DEFAULT_URI environment
    /// variable is set, then it will be used. Otherwise if the client
    /// configuration file has the "uri_default" parameter set, then
    /// it will be used. Finally probing will be done to determine a
    /// suitable default driver to activate. This involves trying each
    /// hypervisor in turn until one successfully opens.
    ///
    /// If connecting to an unprivileged hypervisor driver which
    /// requires the libvirtd daemon to be active, it will
    /// automatically be launched if not already running. This can be
    /// prevented by setting the environment variable
    /// LIBVIRT_AUTOSTART=0
    ///
    /// URIs are documented at http://libvirt.org/uri.html
    ///
    /// Host.close should be used to release the resources after the
    /// connection is no longer needed.
    ///
    /// # Examples
    ///
    /// ```
    /// use virt::host::Host;
    ///
    /// match Host:: open("test:///default") {
    ///   Ok(h) => {
    ///     println!("Hello libvirt!");
    ///     h.close()
    ///   }
    ///   Err(e) => println!(
    ///     "failed with code {}, message: {}", e.code, e.message)
    /// }
    /// ```
    pub fn open(uri: &str) -> Result<Host, error::VirtError> {
        unsafe {
            let conn = virConnectOpen(uri.as_ptr());
            if conn.is_null() {
                return Err(error::VirtError::get_last_error());
            }
            Ok(Host{conn: conn})
        }
    }

    pub fn close(&self) {
        unsafe {
            virConnectClose(self.conn);
        }
    }
}

#[test]
fn it_works() {
}
<commit_msg>no need of that file anymore<commit_after><|endoftext|>


<commit_before>//! Utilities for lifting functions into signals.

/// Maps a function over the value of signals.
///
/// This converts a function `Fn(A, B, ...) -> R` and the signals `Signal<A>, Signal<B>, ...`
/// into a `Signal<R>` that computes it's value by sampling the input signals and then
/// calling the supplied function.
#[macro_export]
macro_rules! signal_lift {
    ($($sig:expr),+ => | $($arg:ident),+ | $body:expr) => {
        $crate::signal_lift!(@closure $($sig),+ ; $($arg)+ ; $body)
    };

    ($($sig:expr),+ => $f:expr) => {
        $crate::signal_lift!(@expr $f; $($sig),+ ;)
    };

    (@expr $f:expr ; ; $($arg:ident)*) => {
        $f($($arg),*)
    };

    (@expr $f:expr ; $sig:expr $(,$tail:expr)* ; $($arg:ident)*) => {
        $sig.map(move |arg| $crate::signal_lift!(@expr $f ; $($tail),* ; $($arg)* arg))
    };

    (@closure ; ; $body:expr) => ($body);

    (@closure $sig:expr $(,$stail:expr)* ; $arg:ident $($atail:ident)* ; $body:expr) => {
        $sig.map(move |$arg| $crate::signal_lift!(@closure $($stail),* ; $($atail)* ; $body))
    }
}

#[cfg(test)]
mod tests {
    use crate::stream::Sink;

    fn incr(a: i32) -> i32 {
        a + 1
    }

    fn append(a: i32, b: &str) -> String {
        a.to_string() + b
    }

    #[test]
    fn signal_lift1() {
        let sink = Sink::new();
        let sig = sink.stream().hold(0);
        let res_e = signal_lift!(sig => incr);
        let res_c = signal_lift!(sig => |a| a + 1);

        assert_eq!(res_e.sample(), 1);
        assert_eq!(res_c.sample(), 1);
        sink.send(12);
        assert_eq!(res_e.sample(), 13);
        assert_eq!(res_c.sample(), 13);
    }

    #[test]
    fn signal_lift2() {
        let sink1 = Sink::new();
        let sink2 = Sink::new();
        let sig1 = sink1.stream().hold(0);
        let sig2 = sink2.stream().hold("a");
        let sig2_ = sig2.clone();
        let lifted_e = signal_lift!(sig1, sig2 => append);
        let lifted_c = signal_lift!(sig1, sig2_ => |a, b| a.to_string() + b);
        let res_e = lifted_e.map(|s| format!("({})", s));
        let res_c = lifted_c.map(|s| format!("({})", s));

        assert_eq!(res_e.sample(), "(0a)");
        assert_eq!(res_c.sample(), "(0a)");
        sink1.send(42);
        assert_eq!(res_e.sample(), "(42a)");
        assert_eq!(res_c.sample(), "(42a)");
        sink2.send("xyz");
        assert_eq!(res_e.sample(), "(42xyz)");
        assert_eq!(res_c.sample(), "(42xyz)");
    }
}
<commit_msg>actually correct implementation of signal_lift<commit_after>//! Utilities for lifting functions into signals.

/// Maps a function over the value of signals.
///
/// This converts a function `Fn(A, B, ...) -> R` and the signals `Signal<A>, Signal<B>, ...`
/// into a `Signal<R>` that computes it's value by sampling the input signals and then
/// calling the supplied function.
#[macro_export]
macro_rules! signal_lift {
    ($sig:expr => $f:expr) => {
        $crate::Signal::map(&$sig, $f)
    };

    ($($sig:expr),+ => $f:expr) => {
        $crate::Signal::from_fn(move || $f($($crate::Signal::sample(&$sig)),+))
    };
}

#[cfg(test)]
mod tests {
    use crate::{Signal, Sink};

    #[test]
    fn signal_lift1() {
        let sink = Sink::new();
        let sig = sink.stream().hold(0);
        let res: Signal<i32> = signal_lift!(sig => |a| a + 1);

        assert_eq!(res.sample(), 1);
        sink.send(12);
        assert_eq!(res.sample(), 13);
    }

    #[test]
    fn signal_lift2() {
        let sink1 = Sink::new();
        let sink2 = Sink::new();
        let sig1 = sink1.stream().hold(0);
        let sig2 = sink2.stream().hold(1);
        let res: Signal<i32> = signal_lift!(sig1, sig2 => |a, b| a + b);

        assert_eq!(res.sample(), 1);
        sink1.send(42);
        assert_eq!(res.sample(), 43);
        sink2.send(100);
        assert_eq!(res.sample(), 142);
    }
}
<|endoftext|>


<commit_before>//! Draw Line

use crate::{
    math::{Matrix2d, Scalar},
    triangulation, types,
    types::{Color, Radius},
    DrawState, Graphics,
};

/// The shape of the line
#[derive(Copy, Clone)]
pub enum Shape {
    /// Square edges
    Square,
    /// Round edges
    Round,
    /// Round edges with specified resolution.
    RoundWithResolution(u32),
    /// Bevel edges
    Bevel,
}

impl Shape {
    /// Gets the round resolution of the shape.
    fn resolution(&self) -> u32 {
        use Shape::*;

        match self {
            Square => 2,
            Bevel => 3,
            Round => 64,
            RoundWithResolution(n) => *n,
        }
    }
}

/// A colored line with a default border radius
#[derive(Copy, Clone)]
pub struct Line {
    /// The line color
    pub color: Color,
    /// The line radius
    pub radius: Radius,
    /// The line shape
    pub shape: Shape,
}

impl Line {
    /// Creates a new line
    pub fn new(color: Color, radius: Radius) -> Line {
        Line {
            color,
            radius,
            shape: Shape::Square,
        }
    }

    /// Creates a new line
    pub fn new_round(color: Color, radius: Radius) -> Line {
        Line {
            color,
            radius,
            shape: Shape::Round,
        }
    }

    /// Sets color.
    pub fn color(mut self, value: Color) -> Self {
        self.color = value;
        self
    }

    /// Sets radius.
    pub fn radius(mut self, value: Radius) -> Self {
        self.radius = value;
        self
    }

    /// Sets width.
    pub fn width(mut self, value: types::Width) -> Self {
        self.radius = 0.5 * value;
        self
    }

    /// Sets shape.
    pub fn shape(mut self, value: Shape) -> Self {
        self.shape = value;
        self
    }

    /// Draws line using default method between points.
    #[inline(always)]
    pub fn draw_from_to<P: Into<types::Vec2d>, G>(
        &self,
        from: P,
        to: P,
        draw_state: &DrawState,
        transform: Matrix2d,
        g: &mut G,
    ) where
        G: Graphics,
    {
        let from: types::Vec2d = from.into();
        let to: types::Vec2d = to.into();
        g.line(
            self,
            [from[0], from[1], to[0], to[1]],
            draw_state,
            transform,
        );
    }

    /// Draws line using default method.
    #[inline(always)]
    pub fn draw<L: Into<types::Line>, G>(
        &self,
        line: L,
        draw_state: &DrawState,
        transform: Matrix2d,
        g: &mut G,
    ) where
        G: Graphics,
    {
        g.line(self, line, draw_state, transform);
    }

    /// Draws line using triangulation.
    pub fn draw_tri<L: Into<types::Line>, G>(
        &self,
        line: L,
        draw_state: &DrawState,
        transform: Matrix2d,
        g: &mut G,
    ) where
        G: Graphics,
    {
        let line = line.into();
        g.tri_list(draw_state, &self.color, |f| {
            triangulation::with_round_border_line_tri_list(
                self.shape.resolution(),
                transform,
                line,
                self.radius,
                |vertices| f(vertices),
            )
        });
    }

    /// Draws an arrow
    ///
    /// Head size is the sides of the triangle
    /// between the arrow hooks and the line
    pub fn draw_arrow<L: Into<types::Line>, G>(
        &self,
        line: L,
        head_size: Scalar,
        draw_state: &DrawState,
        transform: Matrix2d,
        g: &mut G,
    ) where
        G: Graphics,
    {
        use crate::Transformed;

        let line = line.into();
        self.draw(line, draw_state, transform, g);
        let diff = [line[2] - line[0], line[3] - line[1]];
        let arrow_head = transform.trans(line[2], line[3]).orient(diff[0], diff[1]);
        self.draw([-head_size, head_size, 0.0, 0.0], draw_state, arrow_head, g);
        self.draw(
            [-head_size, -head_size, 0.0, 0.0],
            draw_state,
            arrow_head,
            g,
        );
    }
}

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

    #[test]
    fn test_line() {
        use crate::Colored;

        let _line = Line::new([0.0; 4], 3.0)
            .color([1.0; 4])
            .radius(3.0)
            .shape(Shape::Round)
            .hue_deg(1.0);
    }
}
<commit_msg>Use `types::Resolution`<commit_after>//! Draw Line

use crate::{
    math::{Matrix2d, Scalar},
    triangulation, types,
    types::{Color, Radius, Resolution},
    DrawState, Graphics,
};

/// The shape of the line
#[derive(Copy, Clone)]
pub enum Shape {
    /// Square edges
    Square,
    /// Round edges
    Round,
    /// Round edges with specified resolution
    RoundWithResolution(Resolution),
    /// Bevel edges
    Bevel,
}

impl Shape {
    /// Gets the round resolution of the shape.
    fn resolution(&self) -> u32 {
        use Shape::*;

        match self {
            Square => 2,
            Bevel => 3,
            Round => 64,
            RoundWithResolution(n) => *n,
        }
    }
}

/// A colored line with a default border radius
#[derive(Copy, Clone)]
pub struct Line {
    /// The line color
    pub color: Color,
    /// The line radius
    pub radius: Radius,
    /// The line shape
    pub shape: Shape,
}

impl Line {
    /// Creates a new line
    pub fn new(color: Color, radius: Radius) -> Line {
        Line {
            color,
            radius,
            shape: Shape::Square,
        }
    }

    /// Creates a new line
    pub fn new_round(color: Color, radius: Radius) -> Line {
        Line {
            color,
            radius,
            shape: Shape::Round,
        }
    }

    /// Sets color.
    pub fn color(mut self, value: Color) -> Self {
        self.color = value;
        self
    }

    /// Sets radius.
    pub fn radius(mut self, value: Radius) -> Self {
        self.radius = value;
        self
    }

    /// Sets width.
    pub fn width(mut self, value: types::Width) -> Self {
        self.radius = 0.5 * value;
        self
    }

    /// Sets shape.
    pub fn shape(mut self, value: Shape) -> Self {
        self.shape = value;
        self
    }

    /// Draws line using default method between points.
    #[inline(always)]
    pub fn draw_from_to<P: Into<types::Vec2d>, G>(
        &self,
        from: P,
        to: P,
        draw_state: &DrawState,
        transform: Matrix2d,
        g: &mut G,
    ) where
        G: Graphics,
    {
        let from: types::Vec2d = from.into();
        let to: types::Vec2d = to.into();
        g.line(
            self,
            [from[0], from[1], to[0], to[1]],
            draw_state,
            transform,
        );
    }

    /// Draws line using default method.
    #[inline(always)]
    pub fn draw<L: Into<types::Line>, G>(
        &self,
        line: L,
        draw_state: &DrawState,
        transform: Matrix2d,
        g: &mut G,
    ) where
        G: Graphics,
    {
        g.line(self, line, draw_state, transform);
    }

    /// Draws line using triangulation.
    pub fn draw_tri<L: Into<types::Line>, G>(
        &self,
        line: L,
        draw_state: &DrawState,
        transform: Matrix2d,
        g: &mut G,
    ) where
        G: Graphics,
    {
        let line = line.into();
        g.tri_list(draw_state, &self.color, |f| {
            triangulation::with_round_border_line_tri_list(
                self.shape.resolution(),
                transform,
                line,
                self.radius,
                |vertices| f(vertices),
            )
        });
    }

    /// Draws an arrow
    ///
    /// Head size is the sides of the triangle
    /// between the arrow hooks and the line
    pub fn draw_arrow<L: Into<types::Line>, G>(
        &self,
        line: L,
        head_size: Scalar,
        draw_state: &DrawState,
        transform: Matrix2d,
        g: &mut G,
    ) where
        G: Graphics,
    {
        use crate::Transformed;

        let line = line.into();
        self.draw(line, draw_state, transform, g);
        let diff = [line[2] - line[0], line[3] - line[1]];
        let arrow_head = transform.trans(line[2], line[3]).orient(diff[0], diff[1]);
        self.draw([-head_size, head_size, 0.0, 0.0], draw_state, arrow_head, g);
        self.draw(
            [-head_size, -head_size, 0.0, 0.0],
            draw_state,
            arrow_head,
            g,
        );
    }
}

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

    #[test]
    fn test_line() {
        use crate::Colored;

        let _line = Line::new([0.0; 4], 3.0)
            .color([1.0; 4])
            .radius(3.0)
            .shape(Shape::Round)
            .hue_deg(1.0);
    }
}
<|endoftext|>


<commit_before>use {
    AddColor,
    Borrowed,
    Field,
    BevelRectangleColorContext,
    Value,
};
use internal::{
    CanRectangle,
    CanTransform,
    CanViewTransform,
    ColorComponent,
    HasRectangle,
    HasTransform,
    HasViewTransform,
    Matrix2d,
    Radius,
    Rectangle,
};

/// A bevel rectangle context.
pub struct BevelRectangleContext<'a> {
    /// View transform.
    pub view: Field<'a, Matrix2d>,
    /// Current transform.
    pub transform: Field<'a, Matrix2d>,
    /// Current rectangle.
    pub rect: Field<'a, Rectangle>,
    /// Current bevel radius.
    pub bevel_radius: Field<'a, Radius>,
}

impl<'a> Clone for BevelRectangleContext<'a> {
    #[inline(always)]
    fn clone(&self) -> BevelRectangleContext<'static> {
        BevelRectangleContext {
            view: Value(*self.view.get()),
            transform: Value(*self.transform.get()),
            rect: Value(*self.rect.get()),
            bevel_radius: Value(*self.bevel_radius.get()),
        }
    }
}

impl<'a> HasTransform<'a, Matrix2d> for BevelRectangleContext<'a> {
    #[inline(always)]
    fn get_transform(&'a self) -> &'a Matrix2d {
        self.transform.get()
    }
}

impl<'a> CanTransform<'a, BevelRectangleContext<'a>, Matrix2d> for BevelRectangleContext<'a> {
    #[inline(always)]
    fn transform(&'a self, value: Matrix2d) -> BevelRectangleContext<'a> {
        BevelRectangleContext {
            view: Borrowed(self.view.get()),
            transform: Value(value),
            rect: Borrowed(self.rect.get()),
            bevel_radius: Borrowed(self.bevel_radius.get()),
        }
    }
}

impl<'a> HasViewTransform<'a, Matrix2d> for BevelRectangleContext<'a> {
    #[inline(always)]
    fn get_view_transform(&'a self) -> &'a Matrix2d {
        self.view.get()
    }
}

impl<'a> CanViewTransform<'a, BevelRectangleContext<'a>, Matrix2d> for BevelRectangleContext<'a> {
    #[inline(always)]
    fn view_transform(&'a self, value: Matrix2d) -> BevelRectangleContext<'a> {
        BevelRectangleContext {
            view: Value(value),
            transform: Borrowed(self.transform.get()),
            rect: Borrowed(self.rect.get()),
            bevel_radius: Borrowed(self.bevel_radius.get()),
        }
    }
}

impl<'a> HasRectangle<'a, Rectangle> for BevelRectangleContext<'a> {
    #[inline(always)]
    fn get_rectangle(&'a self) -> &'a Rectangle {
        self.rect.get()
    }
}

impl<'a> CanRectangle<'a, BevelRectangleContext<'a>, Rectangle> for BevelRectangleContext<'a> {
    #[inline(always)]
    fn rectangle(&'a self, rect: Rectangle) -> BevelRectangleContext<'a> {
        BevelRectangleContext {
            view: Borrowed(self.view.get()),
            transform: Borrowed(self.transform.get()),
            rect: Value(rect),
            bevel_radius: Borrowed(self.bevel_radius.get()),
        }
    }
}

impl<'a> AddColor<'a, BevelRectangleColorContext<'a>> for BevelRectangleContext<'a> {
    /// Creates a RectangleColorContext.
    #[inline(always)]
    fn rgba(
        &'a self,
        r: ColorComponent,
        g: ColorComponent,
        b: ColorComponent,
        a: ColorComponent
    ) -> BevelRectangleColorContext<'a> {
        BevelRectangleColorContext {
            view: Borrowed(self.view.get()),
            transform: Borrowed(self.transform.get()),
            color: Value([r, g, b, a]),
            rect: Borrowed(self.rect.get()),
            bevel_radius: Borrowed(self.bevel_radius.get()),
        }
    }
}

<commit_msg>Implemented `AddBorder` for `BevelRectangleContext`<commit_after>use {
    AddBorder,
    AddColor,
    Borrowed,
    Field,
    BevelRectangleBorderContext,
    BevelRectangleColorContext,
    Value,
};
use internal::{
    CanRectangle,
    CanTransform,
    CanViewTransform,
    ColorComponent,
    HasRectangle,
    HasTransform,
    HasViewTransform,
    Matrix2d,
    Radius,
    Rectangle,
};

/// A bevel rectangle context.
pub struct BevelRectangleContext<'a> {
    /// View transform.
    pub view: Field<'a, Matrix2d>,
    /// Current transform.
    pub transform: Field<'a, Matrix2d>,
    /// Current rectangle.
    pub rect: Field<'a, Rectangle>,
    /// Current bevel radius.
    pub bevel_radius: Field<'a, Radius>,
}

impl<'a> Clone for BevelRectangleContext<'a> {
    #[inline(always)]
    fn clone(&self) -> BevelRectangleContext<'static> {
        BevelRectangleContext {
            view: Value(*self.view.get()),
            transform: Value(*self.transform.get()),
            rect: Value(*self.rect.get()),
            bevel_radius: Value(*self.bevel_radius.get()),
        }
    }
}

impl<'a> HasTransform<'a, Matrix2d> for BevelRectangleContext<'a> {
    #[inline(always)]
    fn get_transform(&'a self) -> &'a Matrix2d {
        self.transform.get()
    }
}

impl<'a> CanTransform<'a, BevelRectangleContext<'a>, Matrix2d> for BevelRectangleContext<'a> {
    #[inline(always)]
    fn transform(&'a self, value: Matrix2d) -> BevelRectangleContext<'a> {
        BevelRectangleContext {
            view: Borrowed(self.view.get()),
            transform: Value(value),
            rect: Borrowed(self.rect.get()),
            bevel_radius: Borrowed(self.bevel_radius.get()),
        }
    }
}

impl<'a> HasViewTransform<'a, Matrix2d> for BevelRectangleContext<'a> {
    #[inline(always)]
    fn get_view_transform(&'a self) -> &'a Matrix2d {
        self.view.get()
    }
}

impl<'a> CanViewTransform<'a, BevelRectangleContext<'a>, Matrix2d> for BevelRectangleContext<'a> {
    #[inline(always)]
    fn view_transform(&'a self, value: Matrix2d) -> BevelRectangleContext<'a> {
        BevelRectangleContext {
            view: Value(value),
            transform: Borrowed(self.transform.get()),
            rect: Borrowed(self.rect.get()),
            bevel_radius: Borrowed(self.bevel_radius.get()),
        }
    }
}

impl<'a> HasRectangle<'a, Rectangle> for BevelRectangleContext<'a> {
    #[inline(always)]
    fn get_rectangle(&'a self) -> &'a Rectangle {
        self.rect.get()
    }
}

impl<'a> CanRectangle<'a, BevelRectangleContext<'a>, Rectangle> for BevelRectangleContext<'a> {
    #[inline(always)]
    fn rectangle(&'a self, rect: Rectangle) -> BevelRectangleContext<'a> {
        BevelRectangleContext {
            view: Borrowed(self.view.get()),
            transform: Borrowed(self.transform.get()),
            rect: Value(rect),
            bevel_radius: Borrowed(self.bevel_radius.get()),
        }
    }
}

impl<'a> AddColor<'a, BevelRectangleColorContext<'a>> for BevelRectangleContext<'a> {
    /// Creates a RectangleColorContext.
    #[inline(always)]
    fn rgba(
        &'a self,
        r: ColorComponent,
        g: ColorComponent,
        b: ColorComponent,
        a: ColorComponent
    ) -> BevelRectangleColorContext<'a> {
        BevelRectangleColorContext {
            view: Borrowed(self.view.get()),
            transform: Borrowed(self.transform.get()),
            color: Value([r, g, b, a]),
            rect: Borrowed(self.rect.get()),
            bevel_radius: Borrowed(self.bevel_radius.get()),
        }
    }
}

impl<'a> AddBorder<'a, BevelRectangleBorderContext<'a>>
for BevelRectangleContext<'a> {
    #[inline(always)]
    fn border_radius(&'a self, radius: f64) -> BevelRectangleBorderContext<'a> {
        BevelRectangleBorderContext {
            view: Borrowed(self.view.get()),
            transform: Borrowed(self.transform.get()),
            rect: Borrowed(self.rect.get()),
            bevel_radius: Borrowed(self.bevel_radius.get()),
            border: Value(radius),
        }
    }
}

<|endoftext|>


<commit_before>#![feature(duration_span)]

extern crate image;
extern crate rand;
extern crate docopt;
extern crate rustc_serialize;
extern crate num_cpus;
extern crate scoped_threadpool;
extern crate tray_rust;

use std::vec::Vec;
use std::iter;
use std::path::Path;
use std::time::Duration;

use rand::StdRng;
use docopt::Docopt;

use tray_rust::film::{self, filter, ImageSample};
use tray_rust::geometry::{Geometry, Instance, Emitter};
use tray_rust::sampler::{self, Sampler};
use tray_rust::scene;
use tray_rust::integrator::Integrator;

static USAGE: &'static str = "
Usage: tray_rust <scenefile> [options]

Options:
  -o <file>     Specify the output file to save the image. Supported formats are
                PNG, JPG and PPM. Default is 'out.png'.
  -n <number>   Specify the number of threads to use for rendering. Defaults to the number of cores
                on the system.
  -h, --help    Show this message.
";

#[derive(RustcDecodable, Debug)]
struct Args {
    arg_scenefile: String,
    flag_o: Option<String>,
    flag_n: Option<u32>,
}

/// Threads are each sent a sender end of the channel that is
/// read from by the render target thread which then saves the
/// values recieved to the render target
fn thread_work(spp: usize, queue: &sampler::BlockQueue, scene: &scene::Scene,
               target: &film::RenderTarget, light_list: &Vec<&Emitter>) {
    let mut sampler = sampler::LowDiscrepancy::new(queue.block_dim(), spp);
    let mut sample_pos = Vec::with_capacity(sampler.max_spp());
    let mut time_samples: Vec<_> = iter::repeat(0.0).take(sampler.max_spp()).collect();
    let block_dim = queue.block_dim();
    let mut block_samples = Vec::with_capacity(sampler.max_spp() * (block_dim.0 * block_dim.1) as usize);
    let mut rng = match StdRng::new() {
        Ok(r) => r,
        Err(e) => { println!("Failed to get StdRng, {}", e); return }
    };
    // Grab a block from the queue and start working on it, submitting samples
    // to the render target thread after each pixel
    for b in queue.iter() {
        sampler.select_block(b);
        while sampler.has_samples() {
            // Get samples for a pixel and render them
            sampler.get_samples(&mut sample_pos, &mut rng);
            sampler.get_samples_1d(&mut time_samples[..], &mut rng);
            for (s, t) in sample_pos.iter().zip(time_samples.iter()) {
                let mut ray = scene.camera.generate_ray(s, *t);
                if let Some(hit) = scene.intersect(&mut ray) {
                    let c = scene.integrator.illumination(scene, light_list, &ray,
                                                          &hit, &mut sampler, &mut rng).clamp();
                    block_samples.push(ImageSample::new(s.0, s.1, c));
                }
            }
        }
        target.write_block(&block_samples, sampler.get_region());
        block_samples.clear();
    }
}

/// Render the scene in parallel using `n` threads and write the result to the render target
fn render_parallel(rt: &mut film::RenderTarget, scene: &scene::Scene, n: u32, spp: usize){
    let mut pool = scoped_threadpool::Pool::new(n);
    println!("Rendering using {} threads", n);
    pool.scoped(|scope| {
        let dim = rt.dimensions();
        let block_queue = sampler::BlockQueue::new((dim.0 as u32, dim.1 as u32), (8, 8));
        let light_list: Vec<_> = scene.bvh.into_iter().filter_map(|x| {
            match x {
                &Instance::Emitter(ref e) => Some(e),
                _ => None,
            }
        }).collect();
        assert!(!light_list.is_empty(), "At least one light is required");

        for _ in 0..n {
            let b = &block_queue;
            let r = &*rt;
            let l = &light_list;
            scope.execute(move || {
                thread_work(spp, b, scene, r, l);
            });
        }
    });
}

fn main() {
    let args: Args = Docopt::new(USAGE).and_then(|d| d.decode()).unwrap_or_else(|e| e.exit());

    let (mut scene, spp, image_dim) = scene::Scene::load_file(&args.arg_scenefile[..]);
    let mut rt = film::RenderTarget::new(image_dim, (4, 4),
                    Box::new(filter::MitchellNetravali::new(2.0, 2.0, 1.0 / 3.0, 1.0 / 3.0))
                    as Box<filter::Filter + Send + Sync>);
    let n = match args.flag_n {
        Some(n) => n,
        None => num_cpus::get() as u32,
    };

    // Render 5 frames. TODO: This should be read from scene file
    let scene_time = 0.0;
    let frames = 1;
    let time_step = scene_time / (frames as f32);
    for i in 0..frames {
        scene.camera.update_shutter(i as f32 * time_step, (i as f32 + 1.0) * time_step);
        let d = Duration::span(|| render_parallel(&mut rt, &scene, n, spp));
        let time = d.as_secs() as f64 + (d.subsec_nanos() as f64) / 1_000_000_000.0;
        println!("Rendering took {}s", time);

        let img = rt.get_render();
        let out_file = match &args.flag_o {
            &Some(ref f) => f.to_string(),
            &None => format!("out_frame{:03}.png", i).to_string(),
        };

        match image::save_buffer(&Path::new(&out_file), &img[..], image_dim.0 as u32, image_dim.1 as u32, image::RGB(8)) {
            Ok(_) => {},
            Err(e) => println!("Error saving image, {}", e),
        };
        rt.clear();
    }
}

<commit_msg>2x2 locking seems to give best perf vs. 1x1 and 4x4<commit_after>#![feature(duration_span)]

extern crate image;
extern crate rand;
extern crate docopt;
extern crate rustc_serialize;
extern crate num_cpus;
extern crate scoped_threadpool;
extern crate tray_rust;

use std::vec::Vec;
use std::iter;
use std::path::Path;
use std::time::Duration;

use rand::StdRng;
use docopt::Docopt;

use tray_rust::film::{self, filter, ImageSample};
use tray_rust::geometry::{Geometry, Instance, Emitter};
use tray_rust::sampler::{self, Sampler};
use tray_rust::scene;
use tray_rust::integrator::Integrator;

static USAGE: &'static str = "
Usage: tray_rust <scenefile> [options]

Options:
  -o <file>     Specify the output file to save the image. Supported formats are
                PNG, JPG and PPM. Default is 'out.png'.
  -n <number>   Specify the number of threads to use for rendering. Defaults to the number of cores
                on the system.
  -h, --help    Show this message.
";

#[derive(RustcDecodable, Debug)]
struct Args {
    arg_scenefile: String,
    flag_o: Option<String>,
    flag_n: Option<u32>,
}

/// Threads are each sent a sender end of the channel that is
/// read from by the render target thread which then saves the
/// values recieved to the render target
fn thread_work(spp: usize, queue: &sampler::BlockQueue, scene: &scene::Scene,
               target: &film::RenderTarget, light_list: &Vec<&Emitter>) {
    let mut sampler = sampler::LowDiscrepancy::new(queue.block_dim(), spp);
    let mut sample_pos = Vec::with_capacity(sampler.max_spp());
    let mut time_samples: Vec<_> = iter::repeat(0.0).take(sampler.max_spp()).collect();
    let block_dim = queue.block_dim();
    let mut block_samples = Vec::with_capacity(sampler.max_spp() * (block_dim.0 * block_dim.1) as usize);
    let mut rng = match StdRng::new() {
        Ok(r) => r,
        Err(e) => { println!("Failed to get StdRng, {}", e); return }
    };
    // Grab a block from the queue and start working on it, submitting samples
    // to the render target thread after each pixel
    for b in queue.iter() {
        sampler.select_block(b);
        while sampler.has_samples() {
            // Get samples for a pixel and render them
            sampler.get_samples(&mut sample_pos, &mut rng);
            sampler.get_samples_1d(&mut time_samples[..], &mut rng);
            for (s, t) in sample_pos.iter().zip(time_samples.iter()) {
                let mut ray = scene.camera.generate_ray(s, *t);
                if let Some(hit) = scene.intersect(&mut ray) {
                    let c = scene.integrator.illumination(scene, light_list, &ray,
                                                          &hit, &mut sampler, &mut rng).clamp();
                    block_samples.push(ImageSample::new(s.0, s.1, c));
                }
            }
        }
        target.write_block(&block_samples, sampler.get_region());
        block_samples.clear();
    }
}

/// Render the scene in parallel using `n` threads and write the result to the render target
fn render_parallel(rt: &mut film::RenderTarget, scene: &scene::Scene, n: u32, spp: usize){
    let mut pool = scoped_threadpool::Pool::new(n);
    println!("Rendering using {} threads", n);
    pool.scoped(|scope| {
        let dim = rt.dimensions();
        let block_queue = sampler::BlockQueue::new((dim.0 as u32, dim.1 as u32), (8, 8));
        let light_list: Vec<_> = scene.bvh.into_iter().filter_map(|x| {
            match x {
                &Instance::Emitter(ref e) => Some(e),
                _ => None,
            }
        }).collect();
        assert!(!light_list.is_empty(), "At least one light is required");

        for _ in 0..n {
            let b = &block_queue;
            let r = &*rt;
            let l = &light_list;
            scope.execute(move || {
                thread_work(spp, b, scene, r, l);
            });
        }
    });
}

fn main() {
    let args: Args = Docopt::new(USAGE).and_then(|d| d.decode()).unwrap_or_else(|e| e.exit());

    let (mut scene, spp, image_dim) = scene::Scene::load_file(&args.arg_scenefile[..]);
    let mut rt = film::RenderTarget::new(image_dim, (2, 2),
                    Box::new(filter::MitchellNetravali::new(2.0, 2.0, 1.0 / 3.0, 1.0 / 3.0))
                    as Box<filter::Filter + Send + Sync>);
    let n = match args.flag_n {
        Some(n) => n,
        None => num_cpus::get() as u32,
    };

    // Render 5 frames. TODO: This should be read from scene file
    let scene_time = 0.0;
    let frames = 1;
    let time_step = scene_time / (frames as f32);
    for i in 0..frames {
        scene.camera.update_shutter(i as f32 * time_step, (i as f32 + 1.0) * time_step);
        let d = Duration::span(|| render_parallel(&mut rt, &scene, n, spp));
        let time = d.as_secs() as f64 + (d.subsec_nanos() as f64) / 1_000_000_000.0;
        println!("Rendering took {}s", time);

        let img = rt.get_render();
        let out_file = match &args.flag_o {
            &Some(ref f) => f.to_string(),
            &None => format!("out_frame{:03}.png", i).to_string(),
        };

        match image::save_buffer(&Path::new(&out_file), &img[..], image_dim.0 as u32, image_dim.1 as u32, image::RGB(8)) {
            Ok(_) => {},
            Err(e) => println!("Error saving image, {}", e),
        };
        rt.clear();
    }
}

<|endoftext|>


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

extern crate getopts;
extern crate mio;
extern crate libc;

#[macro_use]
extern crate serde_derive;
extern crate bincode;

extern crate env_logger;
extern crate dns_lookup;
extern crate snap;
extern crate rand;
extern crate transient_hashmap;

#[macro_use]
extern crate log;
extern crate ring;

use std::sync::atomic::Ordering;
use ring::rand::{SystemRandom, SecureRandom};

mod device;
mod utils;
mod network;
mod packet;

fn print_usage(program: &str, opts: getopts::Options) {
    let brief = format!("Usage: {} [options]", program);
    print!("{}", opts.usage(&brief));
}

extern "C" fn handle_signal(_: libc::c_int) {
    network::INTERRUPTED.store(true, Ordering::Relaxed);
}

fn main() {
    env_logger::init().unwrap();

    if !utils::is_root() {
        panic!("Please run as root");
    }

    let mut opts = getopts::Options::new();
    opts.reqopt("m", "mode", "mode (server or client)", "[s|c]");
    opts.optopt("p", "port", "UDP port to listen/connect", "PORT");
    opts.optopt("h", "host", "remote host to connect (client mode)", "HOST");
    opts.optopt("s", "secret", "shared secret", "PASSWORD");

    let args: Vec<String> = std::env::args().collect();
    let program = args[0].clone();

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(_) => {
            print_usage(&program, opts);
            return;
        }
    };

    let mode = matches.opt_str("m").unwrap();
    let port: u16 = matches.opt_str("p").unwrap_or(String::from("8964")).parse().unwrap();
    let secret = matches.opt_str("s").unwrap();

    unsafe {
        libc::signal(libc::SIGINT, handle_signal as libc::sighandler_t);
        libc::signal(libc::SIGTERM, handle_signal as libc::sighandler_t);
    }

    match mode.as_ref() {
        "s" => network::serve(port, &secret),
        "c" => {
            let host = matches.opt_str("h").unwrap();
            network::connect(&host, port, true, &secret)
        }
        _ => unreachable!(),
    };

    println!("SIGINT/SIGTERM captured. Exit.");
}
<commit_msg>Fix compilation<commit_after>// Copyright 2016-2017 Chang Lan
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate getopts;
extern crate mio;
extern crate libc;

#[macro_use]
extern crate serde_derive;
extern crate bincode;

extern crate env_logger;
extern crate dns_lookup;
extern crate snap;
extern crate rand;
extern crate transient_hashmap;

#[macro_use]
extern crate log;
extern crate ring;

use std::sync::atomic::Ordering;

mod device;
mod utils;
mod network;
mod packet;

fn print_usage(program: &str, opts: getopts::Options) {
    let brief = format!("Usage: {} [options]", program);
    print!("{}", opts.usage(&brief));
}

extern "C" fn handle_signal(_: libc::c_int) {
    network::INTERRUPTED.store(true, Ordering::Relaxed);
}

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

    if !utils::is_root() {
        panic!("Please run as root");
    }

    let mut opts = getopts::Options::new();
    opts.reqopt("m", "mode", "mode (server or client)", "[s|c]");
    opts.optopt("p", "port", "UDP port to listen/connect", "PORT");
    opts.optopt("h", "host", "remote host to connect (client mode)", "HOST");
    opts.optopt("s", "secret", "shared secret", "PASSWORD");

    let args: Vec<String> = std::env::args().collect();
    let program = args[0].clone();

    let matches = match opts.parse(&args[1..]) {
        Ok(m) => m,
        Err(_) => {
            print_usage(&program, opts);
            return;
        }
    };

    let mode = matches.opt_str("m").unwrap();
    let port: u16 = matches.opt_str("p").unwrap_or(String::from("8964")).parse().unwrap();
    let secret = matches.opt_str("s").unwrap();

    unsafe {
        libc::signal(libc::SIGINT, handle_signal as libc::sighandler_t);
        libc::signal(libc::SIGTERM, handle_signal as libc::sighandler_t);
    }

    match mode.as_ref() {
        "s" => network::serve(port, &secret),
        "c" => {
            let host = matches.opt_str("h").unwrap();
            network::connect(&host, port, true, &secret)
        }
        _ => unreachable!(),
    };

    println!("SIGINT/SIGTERM captured. Exit.");
}
<|endoftext|>


<commit_before>#[macro_use] extern crate clap;
extern crate migrant_lib;

use std::env;
use std::path::PathBuf;
use clap::{Arg, App, SubCommand};
use migrant_lib::{Error, Config, Direction, Migrator};

fn main() {
    let matches = App::new("Migrant")
        .version(crate_version!())
        .author("James K. <james.kominick@gmail.com>")
        .about("Postgres/SQLite migration manager")
        .subcommand(SubCommand::with_name("init")
            .about("Initialize project"))
        .subcommand(SubCommand::with_name("list")
            .about("List status of applied and available migrations"))
        .subcommand(SubCommand::with_name("apply")
            .about("Moves up or down (applies up/down.sql) one migration. Default direction is up unless specified with `-d/--down`.")
            .arg(Arg::with_name("down")
                .long("down")
                .short("d")
                .help("Applies `down.sql` migrations"))
            .arg(Arg::with_name("all")
                .long("all")
                .short("a")
                .help("Applies all available migrations"))
            .arg(Arg::with_name("force")
                .long("force")
                .help("Applies the migration and treats it as if it were successful"))
            .arg(Arg::with_name("fake")
                .long("fake")
                .help("Updates the `.migrant.toml` file as if the specified migration was applied")))
        .subcommand(SubCommand::with_name("new")
            .about("Create new migration up/down files")
            .arg(Arg::with_name("TAG")
                 .required(true)
                 .help("tag to use for new migration")))
        .subcommand(SubCommand::with_name("shell")
            .about("Open a repl connection"))
        .subcommand(SubCommand::with_name("which-config")
            .about("Display the path to the configuration file being used"))
        .get_matches();

    let dir = env::current_dir().expect("Unable to retrieve current directory");

    if let Err(ref e) = run(&dir, &matches) {
        match *e {
            Error::MigrationComplete(ref s) => println!("{}", s),
            _ => {
                println!("[ERROR] {}", e);
                ::std::process::exit(1);
            }
        }
    }
}

fn run(dir: &PathBuf, matches: &clap::ArgMatches) -> Result<(), Error> {
    let config_path = migrant_lib::search_for_config(dir);

    if matches.is_present("init") || config_path.is_none() {
        let _ = Config::init(dir)?;
        return Ok(())
    }

    let config_path = config_path.unwrap();    // absolute path of `.migrant` file

    let config = Config::load(&config_path)?;

    match matches.subcommand() {
        ("list", _) => {
            migrant_lib::list(&config)?;
        }
        ("new", Some(matches)) => {
            let tag = matches.value_of("TAG").unwrap();
            migrant_lib::new(&config, tag)?;
            migrant_lib::list(&config)?;
        }
        ("apply", Some(matches)) => {
            let force = matches.is_present("force");
            let fake = matches.is_present("fake");
            let all = matches.is_present("all");
            let direction = if matches.is_present("down") { Direction::Down } else { Direction::Up };

            Migrator::with_config(&config)
                .direction(direction)
                .force(force)
                .fake(fake)
                .all(all)
                .apply()?;

            let config = config.reload()?;
            migrant_lib::list(&config)?;
        }
        ("shell", _) => {
            migrant_lib::shell(&config)?;
        }
        ("which-config", _) => {
            println!("{}", config_path.to_str().unwrap());
        }
        _ => {
            println!("migrant: see `--help`");
        }
    };
    Ok(())
}
<commit_msg>update config/setup<commit_after>#[macro_use] extern crate clap;
extern crate migrant_lib;

use std::env;
use std::path::PathBuf;
use clap::{Arg, App, SubCommand};
use migrant_lib::{Error, Config, Direction, Migrator};

fn main() {
    let matches = App::new("Migrant")
        .version(crate_version!())
        .author("James K. <james.kominick@gmail.com>")
        .about("Postgres/SQLite migration manager")
        .subcommand(SubCommand::with_name("init")
            .about("Initialize project config"))
        .subcommand(SubCommand::with_name("setup")
            .about("Setup migration table"))
        .subcommand(SubCommand::with_name("connect-string")
            .about("Print out the connection string for postgres, or file-path for sqlite"))
        .subcommand(SubCommand::with_name("list")
            .about("List status of applied and available migrations"))
        .subcommand(SubCommand::with_name("apply")
            .about("Moves up or down (applies up/down.sql) one migration. Default direction is up unless specified with `-d/--down`.")
            .arg(Arg::with_name("down")
                .long("down")
                .short("d")
                .help("Applies `down.sql` migrations"))
            .arg(Arg::with_name("all")
                .long("all")
                .short("a")
                .help("Applies all available migrations"))
            .arg(Arg::with_name("force")
                .long("force")
                .help("Applies the migration and treats it as if it were successful"))
            .arg(Arg::with_name("fake")
                .long("fake")
                .help("Updates the `.migrant.toml` file as if the specified migration was applied")))
        .subcommand(SubCommand::with_name("new")
            .about("Create new migration up/down files")
            .arg(Arg::with_name("TAG")
                 .required(true)
                 .help("tag to use for new migration")))
        .subcommand(SubCommand::with_name("shell")
            .about("Open a repl connection"))
        .subcommand(SubCommand::with_name("which-config")
            .about("Display the path to the configuration file being used"))
        .get_matches();

    let dir = env::current_dir().expect("Unable to retrieve current directory");

    if let Err(ref e) = run(&dir, &matches) {
        match *e {
            Error::MigrationComplete(ref s) => println!("{}", s),
            _ => {
                println!("[ERROR] {}", e);
                ::std::process::exit(1);
            }
        }
    }
}

fn run(dir: &PathBuf, matches: &clap::ArgMatches) -> Result<(), Error> {
    let config_path = migrant_lib::search_for_config(dir);

    if matches.is_present("init") || config_path.is_none() {
        let _ = Config::init(dir)?;
        return Ok(())
    }

    let config_path = config_path.unwrap();    // absolute path of `.migrant` file
    let config = Config::load(&config_path)?;

    if matches.is_present("setup") {
        config.setup()?;
        return Ok(())
    }

    match matches.subcommand() {
        ("connect-string", _) => {
            if config.database_type()? == "sqlite" {
                println!("{}", config.database_path()?.to_str().unwrap());
            } else {
                println!("{}", config.connect_string()?);
            }
        }
        ("list", _) => {
            migrant_lib::list(&config)?;
        }
        ("new", Some(matches)) => {
            let tag = matches.value_of("TAG").unwrap();
            migrant_lib::new(&config, tag)?;
            migrant_lib::list(&config)?;
        }
        ("apply", Some(matches)) => {
            let force = matches.is_present("force");
            let fake = matches.is_present("fake");
            let all = matches.is_present("all");
            let direction = if matches.is_present("down") { Direction::Down } else { Direction::Up };

            Migrator::with_config(&config)
                .direction(direction)
                .force(force)
                .fake(fake)
                .all(all)
                .apply()?;

            let config = config.reload()?;
            migrant_lib::list(&config)?;
        }
        ("shell", _) => {
            migrant_lib::shell(&config)?;
        }
        ("which-config", _) => {
            println!("{}", config_path.to_str().unwrap());
        }
        _ => {
            println!("migrant: see `--help`");
        }
    };
    Ok(())
}
<|endoftext|>


<commit_before>extern crate tokio_core;
extern crate tokio_io;
extern crate futures;
extern crate nix;
extern crate libc;

use std::sync::Arc;
use std::env;
use std::net::{Shutdown, SocketAddr};
use std::io::{self, Read, Write};

use futures::stream::Stream;
use futures::{Future, Poll};
use tokio_core::net::{TcpListener, TcpStream};
use tokio_core::reactor::Core;
use tokio_io::{AsyncRead, AsyncWrite};
use tokio_io::io::{copy, shutdown};

use nix::sys::socket::getsockopt;
use nix::sys::socket::{sockopt, InetAddr};
use std::os::unix::io::AsRawFd;

fn main() {
    let listen_addr = env::args().nth(1).unwrap_or("127.0.0.1:1080".to_string());
    let listen_addr = listen_addr.parse::<SocketAddr>().unwrap();

    // Create the event loop that will drive this server.
    let mut l = Core::new().unwrap();
    let handle = l.handle();

    // Create a TCP listener which will listen for incoming connections.
    let socket = TcpListener::bind(&listen_addr, &l.handle()).unwrap();
    println!("Listening on: {}", listen_addr);

    let done = socket
        .incoming()
        .for_each(move |(client, client_addr)| {
            let server_addr = getsockopt(client.as_raw_fd(), sockopt::OriginalDst).unwrap();
            let server_addr = InetAddr::V4(server_addr).to_std();
            if client.local_addr().unwrap() == server_addr {
                eprintln!("[WARM]from {} to {} error, cannot service to local network.",
                          client_addr,
                          server_addr);
                return Ok(());
            }
            let server = TcpStream::connect(&server_addr, &handle);
            client.set_nodelay(true).unwrap_or_default();
            let amounts = server.and_then(move |server| {
                server.set_nodelay(true).unwrap_or_default();
                let client_reader = TransparentTcpStream(Arc::new(client));
                let client_writer = client_reader.clone();
                let server_reader = TransparentTcpStream(Arc::new(server));
                let server_writer = server_reader.clone();
                let client_to_server =
                    copy(client_reader, server_writer)
                        .and_then(|(n, _, server_writer)| shutdown(server_writer).map(move |_| n));

                let server_to_client =
                    copy(server_reader, client_writer)
                        .and_then(|(n, _, client_writer)| shutdown(client_writer).map(move |_| n));

                client_to_server.join(server_to_client)
            });

            let msg = amounts
                .map(move |(from_client, from_server)| {
                    println!("[INFO]from {} to {} closed, wrote {} bytes and received {} bytes",
                             server_addr,
                             client_addr,
                             from_client,
                             from_server);
                })
                .map_err(|e| {
                             // Don't panic. Maybe the client just disconnected too soon.
                             println!("[WARM]error: {}", e);
                         });
            handle.spawn(msg);

            Ok(())
        });
    l.run(done).unwrap();
}

#[derive(Clone)]
struct TransparentTcpStream(Arc<TcpStream>);

impl Read for TransparentTcpStream {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        (&*self.0).read(buf)
    }
}

impl Write for TransparentTcpStream {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        (&*self.0).write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

impl AsyncRead for TransparentTcpStream {}

impl AsyncWrite for TransparentTcpStream {
    fn shutdown(&mut self) -> Poll<(), io::Error> {
        try!(self.0.shutdown(Shutdown::Write));
        Ok(().into())
    }
}
<commit_msg>Fix print wrong IP in log<commit_after>extern crate tokio_core;
extern crate tokio_io;
extern crate futures;
extern crate nix;
extern crate libc;

use std::sync::Arc;
use std::env;
use std::net::{Shutdown, SocketAddr};
use std::io::{self, Read, Write};

use futures::stream::Stream;
use futures::{Future, Poll};
use tokio_core::net::{TcpListener, TcpStream};
use tokio_core::reactor::Core;
use tokio_io::{AsyncRead, AsyncWrite};
use tokio_io::io::{copy, shutdown};

use nix::sys::socket::getsockopt;
use nix::sys::socket::{sockopt, InetAddr};
use std::os::unix::io::AsRawFd;

fn main() {
    let listen_addr = env::args().nth(1).unwrap_or("127.0.0.1:1080".to_string());
    let listen_addr = listen_addr.parse::<SocketAddr>().unwrap();

    // Create the event loop that will drive this server.
    let mut l = Core::new().unwrap();
    let handle = l.handle();

    // Create a TCP listener which will listen for incoming connections.
    let socket = TcpListener::bind(&listen_addr, &l.handle()).unwrap();
    println!("Listening on: {}", listen_addr);

    let done = socket
        .incoming()
        .for_each(move |(client, client_addr)| {
            let server_addr = getsockopt(client.as_raw_fd(), sockopt::OriginalDst).unwrap();
            let server_addr = InetAddr::V4(server_addr).to_std();
            if client.local_addr().unwrap() == server_addr {
                eprintln!("[WARM]from {} to {} error, cannot service to local network.",
                          client_addr,
                          server_addr);
                return Ok(());
            }
            let server = TcpStream::connect(&server_addr, &handle);
            client.set_nodelay(true).unwrap_or_default();
            let amounts = server.and_then(move |server| {
                server.set_nodelay(true).unwrap_or_default();
                let client_reader = TransparentTcpStream(Arc::new(client));
                let client_writer = client_reader.clone();
                let server_reader = TransparentTcpStream(Arc::new(server));
                let server_writer = server_reader.clone();
                let client_to_server =
                    copy(client_reader, server_writer)
                        .and_then(|(n, _, server_writer)| shutdown(server_writer).map(move |_| n));

                let server_to_client =
                    copy(server_reader, client_writer)
                        .and_then(|(n, _, client_writer)| shutdown(client_writer).map(move |_| n));

                client_to_server.join(server_to_client)
            });

            let msg = amounts
                .map(move |(from_client, from_server)| {
                    println!("[INFO]from {} to {} closed, wrote {} bytes and received {} bytes",
                             client_addr,
                             server_addr,
                             from_client,
                             from_server);
                })
                .map_err(|e| {
                             // Don't panic. Maybe the client just disconnected too soon.
                             println!("[WARM]error: {}", e);
                         });
            handle.spawn(msg);

            Ok(())
        });
    l.run(done).unwrap();
}

#[derive(Clone)]
struct TransparentTcpStream(Arc<TcpStream>);

impl Read for TransparentTcpStream {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        (&*self.0).read(buf)
    }
}

impl Write for TransparentTcpStream {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        (&*self.0).write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

impl AsyncRead for TransparentTcpStream {}

impl AsyncWrite for TransparentTcpStream {
    fn shutdown(&mut self) -> Poll<(), io::Error> {
        try!(self.0.shutdown(Shutdown::Write));
        Ok(().into())
    }
}
<|endoftext|>


<commit_before>extern crate clap;
extern crate codemap;
extern crate mask;

use clap::App;
use clap::Arg;
use codemap::CodeMap;
use std::fs::File;
use std::io::Write;
use std::io::prelude::*;
use std::io;
use std::path::Path;

fn print_tokens(map: &CodeMap, tokens: &Vec<codemap::Spanned<mask::lexer::Token>>) {
  let mut indent = 0;

  for token in tokens {
    match token.node {
      mask::lexer::Token::End | mask::lexer::Token::EOF => {
        println!("{:?}", token.node);
        for _ in 0..indent {
          print!(" ");
        }
      }

      mask::lexer::Token::Enter => {
        indent += 2;
        println!("{:?}", token.node);
        for _ in 0..indent {
          print!(" ");
        }
      }

      mask::lexer::Token::Exit => {
        indent -= 2;
        print!("{:?} ", token.node);
      }

      _ => {
        let span = map.look_up_span(token.span);
        print!("{:?} ", token.node);
        //print!("{}:{}:{}: {:?} ", span.file.name(), span.begin.line, span.begin.column, token.node);
        //print!("{:?}<{:?}> ", token.node, );
      }
    }
  }
}

fn main() {
  let argv = App::new("mask")
    .version("0.0.1")
    .author("John Weachock <jweachock@gmail.com>")
    .about("A programming language.")
    .arg(
      Arg::with_name("code")
        .short("c")
        .long("code")
        .value_name("CODE")
        .help("Mask code to execute. Overrides any specified module")
        .takes_value(true),
    )
    .arg(
      Arg::with_name("path")
        .takes_value(true)
        .index(1)
        .help("Mask module to execute"),
    )
    .get_matches();

  let mut map = CodeMap::new();

  if let Some(source) = argv.value_of("code") {
    let file = map.add_file(String::from("_stdin"), source.to_string());

    // FIXME this code is duplicated a lot, but that's because there's no
    // "module" component in the compiler yet
    let tokens = mask::lexer::lex(&file);
    let ast = mask::parser::parse(tokens);
    println!("AST: {:?}", ast);
  } else if let Some(filename) = argv.value_of("path") {
    let path = Path::new(&filename);
    let mut file = match File::open(path) {
      Ok(file) => file,
      Err(why) => panic!("Couldn't open {}: {}", path.display(), why),
    };

    let mut contents = String::new();
    let cm_file = match file.read_to_string(&mut contents) {
      Ok(_) => map.add_file(filename.to_string(), contents.to_string()),
      Err(why) => panic!("Couldn't read {}: {}", path.display(), why),
    };

    // see FIXME above
    let tokens = mask::lexer::lex(&cm_file);
    let ast = mask::parser::parse(tokens);
    println!("AST: {:?}", ast);
  } else {
    println!("Starting REPL");
    loop {
      let mut buffer = String::new();
      print!("> ");
      io::stdout().flush();

      match io::stdin().read_line(&mut buffer) {
        Ok(nbytes) => {
          if nbytes == 0 || buffer == "quit\n" {
            println!("");
            break;
          }

          let file = map.add_file(String::from("_stdin"), buffer);

          // see FIXME above
          let tokens = mask::lexer::lex(&file);
          let ast = mask::parser::parse(tokens);
          println!("AST: {:?}", ast);
        }

        Err(why) => {
          panic!("Unable to read line: {}", why);
        }
      }
    }
  }
}
<commit_msg>main: Add a FIXME about REPL<commit_after>extern crate clap;
extern crate codemap;
extern crate mask;

use clap::App;
use clap::Arg;
use codemap::CodeMap;
use std::fs::File;
use std::io::Write;
use std::io::prelude::*;
use std::io;
use std::path::Path;

fn print_tokens(map: &CodeMap, tokens: &Vec<codemap::Spanned<mask::lexer::Token>>) {
  let mut indent = 0;

  for token in tokens {
    match token.node {
      mask::lexer::Token::End | mask::lexer::Token::EOF => {
        println!("{:?}", token.node);
        for _ in 0..indent {
          print!(" ");
        }
      }

      mask::lexer::Token::Enter => {
        indent += 2;
        println!("{:?}", token.node);
        for _ in 0..indent {
          print!(" ");
        }
      }

      mask::lexer::Token::Exit => {
        indent -= 2;
        print!("{:?} ", token.node);
      }

      _ => {
        let span = map.look_up_span(token.span);
        print!("{:?} ", token.node);
        //print!("{}:{}:{}: {:?} ", span.file.name(), span.begin.line, span.begin.column, token.node);
        //print!("{:?}<{:?}> ", token.node, );
      }
    }
  }
}

fn main() {
  let argv = App::new("mask")
    .version("0.0.1")
    .author("John Weachock <jweachock@gmail.com>")
    .about("A programming language.")
    .arg(
      Arg::with_name("code")
        .short("c")
        .long("code")
        .value_name("CODE")
        .help("Mask code to execute. Overrides any specified module")
        .takes_value(true),
    )
    .arg(
      Arg::with_name("path")
        .takes_value(true)
        .index(1)
        .help("Mask module to execute"),
    )
    .get_matches();

  let mut map = CodeMap::new();

  if let Some(source) = argv.value_of("code") {
    let file = map.add_file(String::from("_stdin"), source.to_string());

    // FIXME this code is duplicated a lot, but that's because there's no
    // "module" component in the compiler yet
    let tokens = mask::lexer::lex(&file);
    let ast = mask::parser::parse(tokens);
    println!("AST: {:?}", ast);
  } else if let Some(filename) = argv.value_of("path") {
    let path = Path::new(&filename);
    let mut file = match File::open(path) {
      Ok(file) => file,
      Err(why) => panic!("Couldn't open {}: {}", path.display(), why),
    };

    let mut contents = String::new();
    let cm_file = match file.read_to_string(&mut contents) {
      Ok(_) => map.add_file(filename.to_string(), contents.to_string()),
      Err(why) => panic!("Couldn't read {}: {}", path.display(), why),
    };

    // see FIXME above
    let tokens = mask::lexer::lex(&cm_file);
    let ast = mask::parser::parse(tokens);
    println!("AST: {:?}", ast);
  } else {
    // FIXME needs to handle multiline statements
    // initial idea is to request an extra line when the AST matches
    // UnexpectedToken(End) | UnexpectedEOF
    // and then concatenate it to the previous line(s)
    loop {
      let mut buffer = String::new();
      print!("> ");
      io::stdout().flush();

      match io::stdin().read_line(&mut buffer) {
        Ok(nbytes) => {
          if nbytes == 0 || buffer == "quit\n" {
            println!("");
            break;
          }

          let file = map.add_file(String::from("_stdin"), buffer);

          // see FIXME above
          let tokens = mask::lexer::lex(&file);
          let ast = mask::parser::parse(tokens);
          println!("AST: {:?}", ast);
        }

        Err(why) => {
          panic!("Unable to read line: {}", why);
        }
      }
    }
  }
}
<|endoftext|>