<commit_before>extern crate euclid;
#[macro_use]
extern crate glium;
extern crate image;
extern crate vitral;
extern crate serde;
extern crate calx_color;
#[macro_use]
extern crate calx_resource;

mod backend;

use std::hash;
use image::GenericImage;
use std::collections::HashMap;
use std::ops::Deref;
use calx_color::color::*;
pub use euclid::{Point2D, Rect, Size2D};
pub use glium::{DisplayBuild, glutin};
pub use backend::Backend;
pub use calx_resource::{Loadable, Resource, ResourceCache, ResourceStore};

#[derive(Clone)]
struct DynamicImageShim(image::DynamicImage);

impl Loadable for DynamicImageShim {
    fn load(key: &String) -> Option<Self>
        where Self: Sized
    {
        image::open(key).ok().map(|x| DynamicImageShim(x))
    }
}

impl_store!(DYNAMIC_IMAGE, String, DynamicImageShim);

type Color = [f32; 4];

type ImageRef = usize;

#[derive(Copy, Clone, Debug)]
struct Frame {
    pub image: ImageRef,
    pub offset: Point2D<f32>,
    pub color: Color,
}

type Splat = Vec<Frame>;

#[derive(Clone)]
struct Brush(pub Vec<Splat>);

impl Deref for Brush {
    type Target = Vec<Splat>;

    #[inline(always)]
    fn deref(&self) -> &Vec<Splat> {
        &self.0
    }
}

// Brush implements Loadable so we can have a cache for it, but there's no actual implicit load
// method, brushes must be inserted manually in code.
//
// (We *could* make a load method later and have it read configuration files or something that
// specify te brush.)
impl Loadable for Brush {}

impl_store!(BRUSH, String, Brush);

type FrameImage = image::ImageBuffer<image::Rgba<u8>, Vec<u8>>;

#[derive(Clone, PartialEq, Eq, Debug)]
struct SubImageSpec {
    image: Resource<DynamicImageShim>,
    bounds: euclid::Rect<u32>,
}

impl SubImageSpec {
    pub fn new(path: String, bounds: euclid::Rect<u32>) -> Option<SubImageSpec> {
        if let Some(image) = Resource::new(path) {
            Some(SubImageSpec {
                image: image,
                bounds: bounds,
            })
        } else {
            None
        }
    }
}

impl Loadable<SubImageSpec> for FrameImage {
    fn load(spec: &SubImageSpec) -> Option<Self>
        where Self: Sized
    {
        // XXX: Using sub_image on spec.image would be neater, but can't use it here
        // because current image::SubImage must get a mutable access to the parent image and the
        // resource handle is immutable.
        Some(image::ImageBuffer::from_fn(spec.bounds.size.width, spec.bounds.size.height, |x, y| {
            spec.image.0.get_pixel(spec.bounds.origin.x + x, spec.bounds.origin.y + y)
        }))
    }
}

impl hash::Hash for SubImageSpec {
    fn hash<H: hash::Hasher>(&self, state: &mut H) {
        self.image.hash(state);
        self.bounds.origin.hash(state);
        self.bounds.size.hash(state);
    }
}

impl_store!(FRAME_IMAGE, SubImageSpec, FrameImage);

struct BrushBuilder<'a, V: 'a> {
    builder: &'a mut vitral::Builder<V>,
    image_file: Option<String>,
    brush: Vec<Splat>,
    frame_images: HashMap<SubImageSpec, usize>,
}

impl<'a, V: Copy + Eq + 'a> BrushBuilder<'a, V> {
    pub fn new(builder: &'a mut vitral::Builder<V>) -> BrushBuilder<'a, V> {
        BrushBuilder {
            builder: builder,
            image_file: None,
            brush: Vec::new(),
            frame_images: HashMap::new(),
        }
    }

    pub fn file(mut self, name: &str) -> Self {
        self.image_file = Some(name.to_string());
        self
    }

    fn get_frame(&mut self, key: &SubImageSpec) -> usize {
        // XXX: Crashy-crash unwrapping if you feed it bad data.
        if let Some(ret) = self.frame_images.get(key) {
            return *ret;
        }

        let image: Resource<FrameImage, SubImageSpec> = Resource::new(key.clone()).unwrap();
        let ret = self.builder.add_image(&*image);

        self.frame_images.insert(key.clone(), ret);

        ret
    }

    /// Add a new frame with the given bounding rectangle to the current splat.
    pub fn frame(mut self, x: u32, y: u32, w: u32, h: u32) -> Self {
        if self.brush.is_empty() {
            self.brush.push(Vec::new());
        }
        let filename = self.image_file.clone().expect("Image file not set");
        let spec = SubImageSpec::new(filename,
            Rect::new(Point2D::new(x, y), Size2D::new(w, h))).unwrap();

        let image = self.get_frame(&spec);

        let idx = self.brush.len() - 1;
        self.brush[idx].push(Frame { image: image, offset: Point2D::new(0.0, 0.0), color: [1.0, 1.0, 1.0, 1.0] });

        self
    }

    /// Set the color of the last frame.
    pub fn color<C: Into<calx_color::Rgba>>(mut self, c: C) -> Self {
        assert!(!self.brush.is_empty());
        let i = self.brush.len() - 1;
        assert!(!self.brush[i].is_empty());
        let j = self.brush[i].len() - 1;

        let c: calx_color::Rgba = c.into();

        self.brush[i][j].color = [c.r, c.g, c.b, c.a];

        self
    }

    /// Set the offset of the last frame.
    pub fn offset(mut self, x: i32, y: i32) -> Self {
        assert!(!self.brush.is_empty());
        let i = self.brush.len() - 1;
        assert!(!self.brush[i].is_empty());
        let j = self.brush[i].len() - 1;

        // Internally offset is floats because all screen geometry stuff is, but on the data spec
        // level we're pretty much operating on per-pixel level.
        self.brush[i][j].offset = Point2D::new(x as f32, y as f32);

        self
    }

    /// Start a new splat in the current brush.
    pub fn splat(mut self) -> Self {
        self.brush.push(Vec::new());
        self
    }

    /// Finish and name the current brush and start a new one.
    pub fn brush(mut self, name: &str) -> Self {
        use std::mem;

        let name = name.to_string();
        // Must be an original name.
        assert!(Brush::get_resource(&name).is_none());

        // Zero cached brush and copy the old value here so we can insert it.
        let mut brush = Vec::new();
        mem::swap(&mut brush, &mut self.brush);
        assert!(!brush.is_empty());

        Brush::insert_resource(name, Brush(brush));

        self
    }
}

fn init_brushes<V: Copy + Eq>(builder: &mut vitral::Builder<V>) {
    BrushBuilder::new(builder)
        .file("content/assets/props.png")
        .frame(32, 0, 32, 32).color(RED)
        .brush("cursor")
        ;
}

fn draw_splat(context: &mut backend::Context, offset: Point2D<f32>, splat: &Splat) {
    for frame in splat.iter() {
        context.draw_image(frame.image, offset + frame.offset, frame.color);
    }
}

pub fn main() {
    let display = glutin::WindowBuilder::new()
                      .build_glium()
                      .unwrap();

    let mut backend = Backend::new(&display);

    // Construct Vitral context.
    let mut context: backend::Context;
    let mut builder = vitral::Builder::new();

    init_brushes(&mut builder);

    context = builder.build(|img| backend.make_texture(&display, img));

    let font = context.default_font();

    loop {
        context.begin_frame();

        context.draw_text(font,
                          Point2D::new(4.0, 20.0),
                          [1.0, 1.0, 1.0, 1.0],
                          "Hello, world!");

        draw_splat(&mut context, Point2D::new(50.0, 50.0), &Brush::get_resource(&"cursor".to_string()).unwrap()[0]);

        if !backend.update(&display, &mut context) {
            return;
        }
    }
}
<commit_msg>Working towards terrain tiles<commit_after>extern crate euclid;
#[macro_use]
extern crate glium;
extern crate image;
extern crate vitral;
extern crate serde;
extern crate calx_color;
#[macro_use]
extern crate calx_resource;

mod backend;

use std::hash;
use image::GenericImage;
use std::collections::HashMap;
use std::ops::Deref;
use calx_color::color::*;
pub use euclid::{Point2D, Rect, Size2D};
pub use glium::{DisplayBuild, glutin};
pub use backend::Backend;
pub use calx_resource::{Loadable, Resource, ResourceCache, ResourceStore};

#[derive(Clone)]
struct DynamicImageShim(image::DynamicImage);

impl Loadable for DynamicImageShim {
    fn load(key: &String) -> Option<Self>
        where Self: Sized
    {
        image::open(key).ok().map(|x| DynamicImageShim(x))
    }
}

impl_store!(DYNAMIC_IMAGE, String, DynamicImageShim);

pub type Color = [f32; 4];

pub type ImageRef = usize;

#[derive(Copy, Clone, Debug)]
pub struct Frame {
    pub image: ImageRef,
    pub offset: Point2D<f32>,
    pub color: Color,
}

pub type Splat = Vec<Frame>;

#[derive(Clone)]
pub struct Brush(pub Vec<Splat>);

impl Deref for Brush {
    type Target = Vec<Splat>;

    #[inline(always)]
    fn deref(&self) -> &Vec<Splat> {
        &self.0
    }
}

// Brush implements Loadable so we can have a cache for it, but there's no actual implicit load
// method, brushes must be inserted manually in code.
//
// (We *could* make a load method later and have it read configuration files or something that
// specify te brush.)
impl Loadable for Brush {}

impl_store!(BRUSH, String, Brush);

type FrameImage = image::ImageBuffer<image::Rgba<u8>, Vec<u8>>;

#[derive(Clone, PartialEq, Eq, Debug)]
struct SubImageSpec {
    image: Resource<DynamicImageShim>,
    bounds: euclid::Rect<u32>,
}

impl SubImageSpec {
    pub fn new(path: String, bounds: euclid::Rect<u32>) -> Option<SubImageSpec> {
        if let Some(image) = Resource::new(path) {
            Some(SubImageSpec {
                image: image,
                bounds: bounds,
            })
        } else {
            None
        }
    }
}

impl Loadable<SubImageSpec> for FrameImage {
    fn load(spec: &SubImageSpec) -> Option<Self>
        where Self: Sized
    {
        // XXX: Using sub_image on spec.image would be neater, but can't use it here
        // because current image::SubImage must get a mutable access to the parent image and the
        // resource handle is immutable.
        Some(image::ImageBuffer::from_fn(spec.bounds.size.width, spec.bounds.size.height, |x, y| {
            spec.image.0.get_pixel(spec.bounds.origin.x + x, spec.bounds.origin.y + y)
        }))
    }
}

impl hash::Hash for SubImageSpec {
    fn hash<H: hash::Hasher>(&self, state: &mut H) {
        self.image.hash(state);
        self.bounds.origin.hash(state);
        self.bounds.size.hash(state);
    }
}

impl_store!(FRAME_IMAGE, SubImageSpec, FrameImage);

struct BrushBuilder<'a, V: 'a> {
    builder: &'a mut vitral::Builder<V>,
    image_file: Option<String>,
    brush: Vec<Splat>,
    frame_images: HashMap<SubImageSpec, usize>,
}

impl<'a, V: Copy + Eq + 'a> BrushBuilder<'a, V> {
    pub fn new(builder: &'a mut vitral::Builder<V>) -> BrushBuilder<'a, V> {
        BrushBuilder {
            builder: builder,
            image_file: None,
            brush: Vec::new(),
            frame_images: HashMap::new(),
        }
    }

    pub fn file(mut self, name: &str) -> Self {
        self.image_file = Some(name.to_string());
        self
    }

    fn get_frame(&mut self, key: &SubImageSpec) -> usize {
        // XXX: Crashy-crash unwrapping if you feed it bad data.
        if let Some(ret) = self.frame_images.get(key) {
            return *ret;
        }

        let image: Resource<FrameImage, SubImageSpec> = Resource::new(key.clone()).unwrap();
        let ret = self.builder.add_image(&*image);

        self.frame_images.insert(key.clone(), ret);

        ret
    }

    /// Add a new frame with the given bounding rectangle to the current splat.
    pub fn frame(mut self, x: u32, y: u32, w: u32, h: u32) -> Self {
        if self.brush.is_empty() {
            self.brush.push(Vec::new());
        }
        let filename = self.image_file.clone().expect("Image file not set");
        let spec = SubImageSpec::new(filename,
            Rect::new(Point2D::new(x, y), Size2D::new(w, h))).unwrap();

        let image = self.get_frame(&spec);

        let idx = self.brush.len() - 1;
        self.brush[idx].push(Frame { image: image, offset: Point2D::new(0.0, 0.0), color: [1.0, 1.0, 1.0, 1.0] });

        self
    }

    /// Set the color of the last frame.
    pub fn color<C: Into<calx_color::Rgba>>(mut self, c: C) -> Self {
        assert!(!self.brush.is_empty());
        let i = self.brush.len() - 1;
        assert!(!self.brush[i].is_empty());
        let j = self.brush[i].len() - 1;

        let c: calx_color::Rgba = c.into();

        self.brush[i][j].color = [c.r, c.g, c.b, c.a];

        self
    }

    /// Set the offset of the last frame.
    pub fn offset(mut self, x: i32, y: i32) -> Self {
        assert!(!self.brush.is_empty());
        let i = self.brush.len() - 1;
        assert!(!self.brush[i].is_empty());
        let j = self.brush[i].len() - 1;

        // Internally offset is floats because all screen geometry stuff is, but on the data spec
        // level we're pretty much operating on per-pixel level.
        self.brush[i][j].offset = Point2D::new(x as f32, y as f32);

        self
    }

    /// Start a new splat in the current brush.
    pub fn splat(mut self) -> Self {
        self.brush.push(Vec::new());
        self
    }

    /// Finish and name the current brush and start a new one.
    pub fn brush(mut self, name: &str) -> Self {
        use std::mem;

        let name = name.to_string();
        // Must be an original name.
        assert!(Brush::get_resource(&name).is_none());

        // Zero cached brush and copy the old value here so we can insert it.
        let mut brush = Vec::new();
        mem::swap(&mut brush, &mut self.brush);
        assert!(!brush.is_empty());

        Brush::insert_resource(name, Brush(brush));

        self
    }
}

fn init_brushes<V: Copy + Eq>(builder: &mut vitral::Builder<V>) {
    BrushBuilder::new(builder)
        .file("content/assets/floors.png")

        .frame(0, 0, 32, 32).offset(16, 16).brush("blank_floor")

        .frame(32, 0, 32, 32).offset(16, 16).color(DARKGREEN).brush("grass")

        .frame(64, 0, 32, 32).offset(16, 16).color(DARKGREEN).brush("grass2")

        .frame(32, 0, 32, 32).offset(16, 16).color(SLATEGRAY).brush("ground")

        .frame(96, 0, 32, 32).offset(16, 16).color(ROYALBLUE).brush("water")

        .file("content/assets/props.png")

        .frame(32, 0, 32, 32).color(RED).brush("cursor")

        .frame(160, 64, 32, 32).offset(16, 16).color(SADDLEBROWN)
        .frame(192, 64, 32, 32).offset(16, 16).color(GREEN).brush("tree")

        ;
}

fn draw_splat(context: &mut backend::Context, offset: Point2D<f32>, splat: &Splat) {
    for frame in splat.iter() {
        context.draw_image(frame.image, offset + frame.offset, frame.color);
    }
}

#[derive(Copy, Clone, Eq, PartialEq)]
pub enum Kind {
    Floor,
    Block,
    Water,
}

#[derive(Copy, Clone, Eq, PartialEq)]
pub enum Form {
    Simple,
    Block,
    Wall,
}

#[derive(Clone)]
pub struct Tile {
    pub brush: Resource<Brush>,
    pub kind: Kind,
    pub form: Form,
}

impl Loadable<u8> for Tile {}

impl_store!(TILE, u8, Tile);

pub fn main() {
    let display = glutin::WindowBuilder::new()
                      .build_glium()
                      .unwrap();

    let mut backend = Backend::new(&display);

    // Construct Vitral context.
    let mut context: backend::Context;
    let mut builder = vitral::Builder::new();

    init_brushes(&mut builder);

    context = builder.build(|img| backend.make_texture(&display, img));

    let font = context.default_font();

    loop {
        context.begin_frame();

        context.draw_text(font,
                          Point2D::new(4.0, 20.0),
                          [1.0, 1.0, 1.0, 1.0],
                          "Hello, world!");

        draw_splat(&mut context, Point2D::new(50.0, 50.0), &Brush::get_resource(&"tree".to_string()).unwrap()[0]);

        if !backend.update(&display, &mut context) {
            return;
        }
    }
}
<|endoftext|>


<commit_before>//TODO
//should directly test the plugins, because why not?
//maybe ladspa should have some testing facilities built in.

use super::get_ladspa_descriptor;
use ladspa::{Data, Port, PortConnection, PortData};
use std::cell::RefCell;
use std::thread;
use std::time::Duration;

const SAMPLE_RATE: u64 = 44100;

#[derive(Debug)]
enum OwnedPortData {
    AudioInput(Vec<Data>),
    AudioOutput(Vec<Data>),
    ControlInput(Data),
    ControlOutput(Data),
}

impl PartialEq for OwnedPortData {
    fn eq(&self, other: &Self) -> bool {
        use self::OwnedPortData::*;

        match *self {
            AudioInput(ref a) | AudioOutput(ref a) => {
                match *other {
                    AudioInput(ref b) | AudioOutput(ref b) => a == b,
                    _ => false,
                }
            },
            ControlInput(ref a) | ControlOutput(ref a) => {
                match *other {
                    ControlInput(ref b) | ControlOutput(ref b) => a == b,
                    _ => false,
                }
            }
        }
    }
}

struct OwnedPortConnection {
    port: Port,
    data: OwnedPortData,
}

fn make_owned_port_connections(ports: &[Port], size: usize, input_tag: f32, output_tag: f32) -> Vec<OwnedPortConnection> {
    use ladspa::PortDescriptor::*;

    let mut out = Vec::new();
    for port in ports {
        let data = match port.desc {
            AudioInput => OwnedPortData::AudioInput(vec![input_tag; size]),
            AudioOutput => OwnedPortData::AudioOutput(vec![output_tag; size]),
            ControlInput => OwnedPortData::ControlInput(0.0),
            ControlOutput => OwnedPortData::ControlOutput(0.0),
            Invalid => panic!(),
        };
        out.push(OwnedPortConnection {
            port: port.clone(),
            data: data,
        });
    }
    out
}

fn make_port_connections<'a>(owned: &'a mut [OwnedPortConnection]) -> Vec<PortConnection<'a>> {
    let mut out = Vec::new();
    for port in owned {
        let data = match port.data {
            OwnedPortData::AudioInput(ref data) => PortData::AudioInput(data),
            OwnedPortData::AudioOutput(ref mut data) => PortData::AudioOutput(RefCell::new(data)),
            OwnedPortData::ControlInput(ref data) => PortData::ControlInput(data),
            OwnedPortData::ControlOutput(ref mut data) => PortData::ControlOutput(RefCell::new(data)),
        };

        out.push(PortConnection {
            port: port.port,
            data: data,
        });
    }
    out
}

fn borrow_port_connections<'a>(ports: &'a [PortConnection<'a>]) -> Vec<&'a PortConnection<'a>> {
    ports.iter().map(|x| x).collect()
}

//TODO immediately: factor

#[test]
fn test_working_basic() {
    let sample_count = super::packet::BUFFER_SIZE;

    let tx_desc = get_ladspa_descriptor(0).unwrap();
    let rx_desc = get_ladspa_descriptor(1).unwrap();
    let mut tx = (tx_desc.new)(&tx_desc, SAMPLE_RATE);
    let mut rx = (rx_desc.new)(&rx_desc, SAMPLE_RATE);

    rx.activate();
    tx.activate();

    let mut tx_owned = make_owned_port_connections(&tx_desc.ports, sample_count, 1.0, 0.0);
    let mut rx_owned = make_owned_port_connections(&rx_desc.ports, sample_count, 0.0, 0.0);
    {
        let tx_ports = make_port_connections(&mut tx_owned);
        let rx_ports = make_port_connections(&mut rx_owned);
        let tx_ports = borrow_port_connections(&tx_ports);
        let rx_ports = borrow_port_connections(&rx_ports);

        tx.run(sample_count, &tx_ports);
        thread::sleep(Duration::from_millis(100)); // wait for recv
        rx.run(sample_count, &rx_ports);
    }

    for i in 0..2 {
        assert_eq!(tx_owned[i].data, rx_owned[i+2].data);
    }

    rx.deactivate();
    tx.deactivate();
}

#[test]
fn test_working_multi_packet() {
    let sample_count = super::packet::BUFFER_SIZE*4;

    let tx_desc = get_ladspa_descriptor(0).unwrap();
    let rx_desc = get_ladspa_descriptor(1).unwrap();
    let mut tx = (tx_desc.new)(&tx_desc, SAMPLE_RATE);
    let mut rx = (rx_desc.new)(&rx_desc, SAMPLE_RATE);

    rx.activate();
    tx.activate();

    let mut tx_owned = make_owned_port_connections(&tx_desc.ports, sample_count, 1.0, 0.0);
    let mut rx_owned = make_owned_port_connections(&rx_desc.ports, sample_count, 0.0, 0.0);
    {
        let tx_ports = make_port_connections(&mut tx_owned);
        let rx_ports = make_port_connections(&mut rx_owned);
        let tx_ports = borrow_port_connections(&tx_ports);
        let rx_ports = borrow_port_connections(&rx_ports);

        tx.run(sample_count, &tx_ports);
        thread::sleep(Duration::from_millis(100)); // wait for recv
        rx.run(sample_count, &rx_ports);
    }

    for i in 0..2 {
        assert_eq!(tx_owned[i].data, rx_owned[i+2].data);
    }

    rx.deactivate();
    tx.deactivate();
}
<commit_msg>The tests are running simultaneously, obviously they need to be on different channels...<commit_after>//TODO
//should directly test the plugins, because why not?
//maybe ladspa should have some testing facilities built in.

use super::get_ladspa_descriptor;
use ladspa::{Data, Port, PortConnection, PortData};
use std::cell::RefCell;
use std::thread;
use std::time::Duration;

const SAMPLE_RATE: u64 = 44100;

#[derive(Debug)]
enum OwnedPortData {
    AudioInput(Vec<Data>),
    AudioOutput(Vec<Data>),
    ControlInput(Data),
    ControlOutput(Data),
}

impl PartialEq for OwnedPortData {
    fn eq(&self, other: &Self) -> bool {
        use self::OwnedPortData::*;

        match *self {
            AudioInput(ref a) | AudioOutput(ref a) => {
                match *other {
                    AudioInput(ref b) | AudioOutput(ref b) => a == b,
                    _ => false,
                }
            },
            ControlInput(ref a) | ControlOutput(ref a) => {
                match *other {
                    ControlInput(ref b) | ControlOutput(ref b) => a == b,
                    _ => false,
                }
            }
        }
    }
}

struct OwnedPortConnection {
    port: Port,
    data: OwnedPortData,
}

//TODO port is fragile
fn make_owned_port_connections(ports: &[Port], size: usize, port_tag: f32, input_tag: f32, output_tag: f32) -> Vec<OwnedPortConnection> {
    use ladspa::PortDescriptor::*;

    let mut out = Vec::new();
    for port in ports {
        let data = match port.desc {
            AudioInput => OwnedPortData::AudioInput(vec![input_tag; size]),
            AudioOutput => OwnedPortData::AudioOutput(vec![output_tag; size]),
            ControlInput => OwnedPortData::ControlInput(port_tag),
            ControlOutput => OwnedPortData::ControlOutput(port_tag),
            Invalid => panic!(),
        };
        out.push(OwnedPortConnection {
            port: port.clone(),
            data: data,
        });
    }
    out
}

fn make_port_connections<'a>(owned: &'a mut [OwnedPortConnection]) -> Vec<PortConnection<'a>> {
    let mut out = Vec::new();
    for port in owned {
        let data = match port.data {
            OwnedPortData::AudioInput(ref data) => PortData::AudioInput(data),
            OwnedPortData::AudioOutput(ref mut data) => PortData::AudioOutput(RefCell::new(data)),
            OwnedPortData::ControlInput(ref data) => PortData::ControlInput(data),
            OwnedPortData::ControlOutput(ref mut data) => PortData::ControlOutput(RefCell::new(data)),
        };

        out.push(PortConnection {
            port: port.port,
            data: data,
        });
    }
    out
}

fn borrow_port_connections<'a>(ports: &'a [PortConnection<'a>]) -> Vec<&'a PortConnection<'a>> {
    ports.iter().map(|x| x).collect()
}

//TODO immediately: factor

#[test]
fn test_working_basic() {
    let sample_count = super::packet::BUFFER_SIZE;

    let tx_desc = get_ladspa_descriptor(0).unwrap();
    let rx_desc = get_ladspa_descriptor(1).unwrap();
    let mut tx = (tx_desc.new)(&tx_desc, SAMPLE_RATE);
    let mut rx = (rx_desc.new)(&rx_desc, SAMPLE_RATE);

    rx.activate();
    tx.activate();

    let mut tx_owned = make_owned_port_connections(&tx_desc.ports, sample_count, 0.0, 1.0, 0.0);
    let mut rx_owned = make_owned_port_connections(&rx_desc.ports, sample_count, 0.0, 0.0, 0.0);
    {
        let tx_ports = make_port_connections(&mut tx_owned);
        let rx_ports = make_port_connections(&mut rx_owned);
        let tx_ports = borrow_port_connections(&tx_ports);
        let rx_ports = borrow_port_connections(&rx_ports);

        tx.run(sample_count, &tx_ports);
        thread::sleep(Duration::from_millis(100)); // wait for recv
        rx.run(sample_count, &rx_ports);
    }

    for i in 0..2 {
        assert_eq!(tx_owned[i].data, rx_owned[i+2].data);
    }

    rx.deactivate();
    tx.deactivate();
}

#[test]
fn test_working_multi_packet() {
    let sample_count = super::packet::BUFFER_SIZE*4;

    let tx_desc = get_ladspa_descriptor(0).unwrap();
    let rx_desc = get_ladspa_descriptor(1).unwrap();
    let mut tx = (tx_desc.new)(&tx_desc, SAMPLE_RATE);
    let mut rx = (rx_desc.new)(&rx_desc, SAMPLE_RATE);

    rx.activate();
    tx.activate();

    let mut tx_owned = make_owned_port_connections(&tx_desc.ports, sample_count, 1.0, 1.0, 0.0);
    let mut rx_owned = make_owned_port_connections(&rx_desc.ports, sample_count, 1.0, 0.0, 0.0);
    {
        let tx_ports = make_port_connections(&mut tx_owned);
        let rx_ports = make_port_connections(&mut rx_owned);
        let tx_ports = borrow_port_connections(&tx_ports);
        let rx_ports = borrow_port_connections(&rx_ports);

        tx.run(sample_count, &tx_ports);
        thread::sleep(Duration::from_millis(100)); // wait for recv
        rx.run(sample_count, &rx_ports);
    }

    for i in 0..2 {
        assert_eq!(tx_owned[i].data, rx_owned[i+2].data);
    }

    rx.deactivate();
    tx.deactivate();
}
<|endoftext|>


<commit_before>/*
 * A simple program that aims to extract various string constants from a JAR file (Java)
 */

extern crate classreader;
extern crate zip;
extern crate docopt;
extern crate serde;
extern crate java_properties;
extern crate shannon_entropy;

use docopt::Docopt;
use serde::Deserialize;
use classreader::*;
use std::fs::File;
use java_properties::PropertiesIter;
use std::io::BufReader;
use shannon_entropy::shannon_entropy;

const USAGE: &'static str = "
Java Strings extractor.

Usage:
  jstrings [-e] <source>...
  jstrings [-t <threshold>] <source>...
  jstrings (-h | --help)

Options:
  -e              Print average entropy of each string (average of entropy of each word in the string)
  -t <threshold>  Do not print string with entropy below threshold. Implies entropy computation.
  -h --help       Show this screen.

Source can be one or more class or jar files.
";

#[derive(Debug, Deserialize)]
struct Args {
    flag_e: bool,
    flag_t: Option<f32>,
    arg_source: Vec<String>
}

type Printer = Box<Fn(&str)>;

fn main() {
    let args: Args = Docopt::new(USAGE)
                            .and_then(|d| d.deserialize())
                            .unwrap_or_else(|e| e.exit());
    let printer = printer_factory(&args);
    for f in args.arg_source {
        if f.ends_with(".class") {
            process_class_file(&f, &printer);
        } else if f.ends_with(".jar") {
            process_jar_file(&f, &printer);
        } else if f.ends_with(".properties") {
            process_properties_file(&f, &printer);
        }
    }
}

fn process_jar_file(file_name: &str, printer: &Printer) {
    let file = File::open(file_name).expect("couldn't find a file!");
    let mut zip = zip::ZipArchive::new(file).expect("could not read JAR");
    for i in 0..zip.len() {
        let mut class_file = zip.by_index(i).unwrap();
        if class_file.name().ends_with(".class") {
            let class = ClassReader::new_from_reader(&mut class_file).unwrap();
            process_class(&class, printer);
        } else if class_file.name().ends_with(".properties") {
            process_properties(class_file, printer);
        }
    }
}

fn process_class_file(file_name: &str, printer: &Printer) {
    let class = ClassReader::new_from_path(file_name).unwrap();
    process_class(&class, printer);
}

fn process_class(class: &Class, printer: &Printer) {
    assert_eq!(0xCAFEBABE, class.magic);
    for jstr in &class.constant_pool {
		if let ConstantPoolInfo::String(index) = *jstr {
			printer(get_string(class, index as usize));
		}
    }
}

/// Get constant from a pool, correcting for java's 1-based indexes.
fn get_const(class: &Class, i: usize) -> &ConstantPoolInfo {
    &class.constant_pool[i - 1]
}

/// Get string from constant pool
fn get_string(class: &Class, index: usize) -> &str {
    match *get_const(class, index) {
        ConstantPoolInfo::Utf8(ref s) => s,
        _ => "?"
    }
}

fn process_properties_file(file_name: &str, printer: &Printer) {
    let f = File::open(file_name).expect("couldn't find a file!");
    process_properties(BufReader::new(f), printer);
}

fn process_properties<R: std::io::Read>(f: R, printer: &Printer) {
    PropertiesIter::new(f).read_into(|_, v| {
      printer(&v);
    }).expect("failed to read a properties file");
}

// Output variants
fn printer_factory(args: &Args) -> Printer {
	if let Some(t) = args.flag_t {
		return Box::new(move |s: &str| {
				let e = average_entropy(s);
				if e >= t {
					println!("{:>6.2} {}", e, s)
				}
			})
	}
    if args.flag_e {
        return Box::new(print_entropy)
    }
    Box::new(print_only)
}

fn print_only(s: &str) {
    println!("{}", s)
}

fn print_entropy(s: &str) {
    println!("{:>6.2} {}", average_entropy(s), s)
}

fn average_entropy(s: &str) -> f32 {
    let tuple = s.split_whitespace().map(shannon_entropy).fold( (0.0, 0),
      |acc, w| (acc.0 + w, acc.1 + 1));
    tuple.0 / tuple.1 as f32
}
<commit_msg>Remove warnings<commit_after>/*
 * A simple program that aims to extract various string constants from a JAR file (Java)
 */

extern crate classreader;
extern crate zip;
extern crate docopt;
extern crate serde;
extern crate java_properties;
extern crate shannon_entropy;

use docopt::Docopt;
use serde::Deserialize;
use classreader::*;
use std::fs::File;
use java_properties::PropertiesIter;
use std::io::BufReader;
use shannon_entropy::shannon_entropy;

const USAGE: &'static str = "
Java Strings extractor.

Usage:
  jstrings [-e] <source>...
  jstrings [-t <threshold>] <source>...
  jstrings (-h | --help)

Options:
  -e              Print average entropy of each string (average of entropy of each word in the string)
  -t <threshold>  Do not print string with entropy below threshold. Implies entropy computation.
  -h --help       Show this screen.

Source can be one or more class or jar files.
";

#[derive(Debug, Deserialize)]
struct Args {
    flag_e: bool,
    flag_t: Option<f32>,
    arg_source: Vec<String>
}

type Printer = Box<dyn Fn(&str)>;

fn main() {
    let args: Args = Docopt::new(USAGE)
                            .and_then(|d| d.deserialize())
                            .unwrap_or_else(|e| e.exit());
    let printer = printer_factory(&args);
    for f in args.arg_source {
        if f.ends_with(".class") {
            process_class_file(&f, &printer);
        } else if f.ends_with(".jar") {
            process_jar_file(&f, &printer);
        } else if f.ends_with(".properties") {
            process_properties_file(&f, &printer);
        }
    }
}

fn process_jar_file(file_name: &str, printer: &Printer) {
    let file = File::open(file_name).expect("couldn't find a file!");
    let mut zip = zip::ZipArchive::new(file).expect("could not read JAR");
    for i in 0..zip.len() {
        let mut class_file = zip.by_index(i).unwrap();
        if class_file.name().ends_with(".class") {
			if let Ok(class) = ClassReader::new_from_reader(&mut class_file) {
				process_class(&class, printer);
			}
        } else if class_file.name().ends_with(".properties") {
            process_properties(class_file, printer);
        }
    }
}

fn process_class_file(file_name: &str, printer: &Printer) {
    let class = ClassReader::new_from_path(file_name).unwrap();
    process_class(&class, printer);
}

fn process_class(class: &Class, printer: &Printer) {
    assert_eq!(0xCAFEBABE, class.magic);
    for jstr in &class.constant_pool {
		if let ConstantPoolInfo::String(index) = *jstr {
			printer(get_string(class, index as usize));
		}
    }
}

/// Get constant from a pool, correcting for java's 1-based indexes.
fn get_const(class: &Class, i: usize) -> &ConstantPoolInfo {
    &class.constant_pool[i - 1]
}

/// Get string from constant pool
fn get_string(class: &Class, index: usize) -> &str {
    match *get_const(class, index) {
        ConstantPoolInfo::Utf8(ref s) => s,
        _ => "?"
    }
}

fn process_properties_file(file_name: &str, printer: &Printer) {
    let f = File::open(file_name).expect("couldn't find a file!");
    process_properties(BufReader::new(f), printer);
}

fn process_properties<R: std::io::Read>(f: R, printer: &Printer) {
    PropertiesIter::new(f).read_into(|_, v| {
      printer(&v);
    }).expect("failed to read a properties file");
}

// Output variants
fn printer_factory(args: &Args) -> Printer {
	if let Some(t) = args.flag_t {
		return Box::new(move |s: &str| {
				let e = average_entropy(s);
				if e >= t {
					println!("{:>6.2} {}", e, s)
				}
			})
	}
    if args.flag_e {
        return Box::new(print_entropy)
    }
    Box::new(print_only)
}

fn print_only(s: &str) {
    println!("{}", s)
}

fn print_entropy(s: &str) {
    println!("{:>6.2} {}", average_entropy(s), s)
}

fn average_entropy(s: &str) -> f32 {
    let tuple = s.split_whitespace().map(shannon_entropy).fold( (0.0, 0),
      |acc, w| (acc.0 + w, acc.1 + 1));
    tuple.0 / tuple.1 as f32
}
<|endoftext|>


<commit_before>extern crate terminal;

#[cfg(test)]
mod tests {
  use terminal::Screen;

  #[test]
  fn initialize_screen() {
    let screen = Screen::open();
    assert!(screen.is_ok())
  }

  #[test]
  fn resize_screen() {
    let screen = Screen::open();
    let resize = screen.unwrap().resize(20,20);
    assert!(resize.is_ok())
  }

  #[test]
  fn get_vte() {
    let screen = Screen::open();
    let vte = screen.unwrap().vte();
    assert!(vte.is_ok())
  }
}<commit_msg>Remove trivial tests<commit_after><|endoftext|>


<commit_before>#[macro_use]
extern crate log;
extern crate fern;
extern crate time;
extern crate hyper;
extern crate rustc_serialize;
extern crate getopts;

use std::fs::OpenOptions;
use std::io::{Write, Read};
use getopts::Options;
use std::env;

mod keys;

use keys::KeySource;

// TODO: figure out how to resolve ~/ or get the user's home directory path.
const AUTHORIZED_KEYS_PATH: &'static str = "/Users/dpetersen/.ssh/authorized_keys";

fn init_logging() {
    let logger_config = fern::DispatchConfig {
        format: Box::new(|msg: &str, level: &log::LogLevel, _location: &log::LogLocation| {
            format!("[{}][{}] {}", time::now().strftime("%H:%M:%S").unwrap(), level, msg)
        }),
        output: vec![fern::OutputConfig::stdout()],
        level: log::LogLevelFilter::Debug,
    };

    if let Err(e) = fern::init_global_logger(logger_config, log::LogLevelFilter::Trace) {
        panic!("Failed to initialize global logger: {}", e);
    }
}

fn main() {
    init_logging();
    let args: Vec<String> = env::args().collect();
    let mut opts = Options::new();
    opts.optflag("r", "real", "actually hit the GitHub API. This is a dev option that I'm going to remove eventually");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m }
        Err(f) => { panic!(f.to_string()) }
    };

    let write_result = if matches.opt_present("r") {
        write_keys(keys::GitHubAPI)
    } else {
        write_keys(keys::Hardcoded)
    };

    match write_result {
        Ok(count) => println!("Wrote {} key(s)!", count),
        Err(e) => panic!("There was a problem writing the keys: {}", e),
    }
}

fn write_keys<T: KeySource>(source: T) -> std::io::Result<usize> {
    let found_keys = source.get_keys();
    let file = OpenOptions::new()
        .read(true)
        .write(true)
        .append(true)
        .create(true)
        .open(AUTHORIZED_KEYS_PATH);

    match file {
        Ok(mut f) => {
            let mut written_count = 0;
            let mut existing_keys = String::new();
            f.read_to_string(&mut existing_keys).ok().expect("Failed reading authorized_keys!");

            for key in &found_keys {
                if existing_keys.contains(&key.key) {
                    debug!("Skipping key '{}', already exists", key.id);
                    continue
                }

                info!("Writing key '{}'", key.id);
                match f.write_all(&key.to_authorized_keys_line().as_bytes()) {
                    Ok(_) => written_count += 1,
                    Err(e) => return Result::Err(e),
                }
            }

            return Result::Ok(written_count)
        },
        Err(e) => return Result::Err(e),
    }
}
<commit_msg>Slightly less jenk use of the KeySource trait?<commit_after>#[macro_use]
extern crate log;
extern crate fern;
extern crate time;
extern crate hyper;
extern crate rustc_serialize;
extern crate getopts;

use std::fs::OpenOptions;
use std::io::{Write, Read};
use getopts::Options;
use std::env;

mod keys;

use keys::{GitHubKey, KeySource};

// TODO: figure out how to resolve ~/ or get the user's home directory path.
const AUTHORIZED_KEYS_PATH: &'static str = "/Users/dpetersen/.ssh/authorized_keys";

fn main() {
    init_logging();

    let args: Vec<String> = env::args().collect();
    let mut opts = Options::new();
    opts.optflag("r", "real", "actually hit the GitHub API. This is a dev option that I'm going to remove eventually");
    let matches = match opts.parse(&args[1..]) {
        Ok(m) => { m }
        Err(f) => { panic!(f.to_string()) }
    };

    let keys = if matches.opt_present("r") {
        keys_from_source(keys::GitHubAPI)
    } else {
        keys_from_source(keys::Hardcoded)
    };

    match write_keys(keys) {
        Ok(count) => println!("Wrote {} key(s)!", count),
        Err(e) => panic!("There was a problem writing the keys: {}", e),
    }
}

fn init_logging() {
    let logger_config = fern::DispatchConfig {
        format: Box::new(|msg: &str, level: &log::LogLevel, _location: &log::LogLocation| {
            format!("[{}][{}] {}", time::now().strftime("%H:%M:%S").unwrap(), level, msg)
        }),
        output: vec![fern::OutputConfig::stdout()],
        level: log::LogLevelFilter::Debug,
    };

    if let Err(e) = fern::init_global_logger(logger_config, log::LogLevelFilter::Trace) {
        panic!("Failed to initialize global logger: {}", e);
    }
}

fn keys_from_source<T: KeySource>(source: T) -> Vec<GitHubKey> {
    return source.get_keys()
}

fn write_keys(keys: Vec<GitHubKey>) -> std::io::Result<usize> {
    let file = OpenOptions::new()
        .read(true)
        .write(true)
        .append(true)
        .create(true)
        .open(AUTHORIZED_KEYS_PATH);

    match file {
        Ok(mut f) => {
            let mut written_count = 0;
            let mut existing_keys = String::new();
            f.read_to_string(&mut existing_keys).ok().expect("Failed reading authorized_keys!");

            for key in &keys {
                if existing_keys.contains(&key.key) {
                    debug!("Skipping key '{}', already exists", key.id);
                    continue
                }

                info!("Writing key '{}'", key.id);
                match f.write_all(&key.to_authorized_keys_line().as_bytes()) {
                    Ok(_) => written_count += 1,
                    Err(e) => return Result::Err(e),
                }
            }

            return Result::Ok(written_count)
        },
        Err(e) => return Result::Err(e),
    }
}
<|endoftext|>


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

struct Graph {
	vertices: HashMap<i64, Box<Vertex>>,
}

impl Graph {
	fn new() -> Box<Graph> {
		let vertices: HashMap<i64, Box<Vertex>> = HashMap::new();
		Box::new(Graph{vertices:vertices})
	}
	fn add_vertex(&mut self) -> VertexProxy {
		let new_id = 1;
		let v = Vertex::new(new_id);

		let ptr: *const Box<Vertex> = &v as *const Box<Vertex>;

		self.vertices.insert(new_id, v);

		// return the proxy which knows it's own id
		VertexProxy{id:new_id, v: ptr}
	}
}

struct Vertex {
	id: i64,
	edges: *mut Vec<Edge>,
}

impl Vertex {
	fn new(id: i64) -> Box<Vertex> {

		let mut edges : Vec<Edge> = Vec::new();
		let edges_ptr :	*mut Vec<Edge> = &mut edges;
		let vertex = Vertex{id:id, edges:edges_ptr};
		let mut v = Box::new(vertex);
		return v;
	}

	fn query(self) {

	}
}

#[derive(Show)]
struct VertexProxy {
	id: i64,
	v: *const Box<Vertex>,
}

//let i: u32 = 1;
//// explicit cast
//let p_imm: *const u32 = &i as *const u32;
//let mut m: u32 = 2;
//// implicit coercion
//let p_mut: *mut u32 = &mut m;
//
//unsafe {
//let ref_imm: &u32 = &*p_imm;
//let ref_mut: &mut u32 = &mut *p_mut;
//}

impl VertexProxy {
	fn add_edge(& self, to_vertex: &VertexProxy) {
		unsafe {
			let in_vertex =  &* self .v;
			let out_vertex = &*to_vertex.v;
		}
		// create the edge
		let e = Edge{from_vertex: self.v,
					 to_vertex:   to_vertex.v};

	}
}

struct Edge {
	from_vertex: *const Box<Vertex>,
	to_vertex: *const Box<Vertex>
}

fn main() {
	let mut g = Graph::new();

    println!("Hello, world!");
}

#[test]
fn test_unsafe_vertex() {
	let mut g = Graph::new();
	let mut v1 = g.add_vertex();
}

#[test]
fn test_add_edge() {
	let mut g = Graph::new();
	let mut v1 = g.add_vertex();
	let mut v2 = g.add_vertex();
	v2.add_edge(&v2);

}
<commit_msg>proper vertex ids<commit_after>use std::mem;
use std::collections::HashMap;
use std::mem::transmute;

struct Graph {
	elements: i64,
	vertices: HashMap<i64, Box<Vertex>>,
}

impl Graph {
	fn new() -> Box<Graph> {
		let vertices: HashMap<i64, Box<Vertex>> = HashMap::new();
		Box::new(Graph{elements:0, vertices:vertices})
	}
	fn add_vertex(&mut self) -> VertexProxy {
		let new_id = self.elements + 1;
		self.elements += 1;
		let v = Vertex::new(new_id);

		let ptr: *const Box<Vertex> = &v as *const Box<Vertex>;

		self.vertices.insert(new_id, v);

		// return the proxy which knows it's own id
		VertexProxy{id:new_id, v: ptr}
	}
}

struct Vertex {
	id: i64,
	edges: *mut Vec<Edge>,
}

impl Vertex {
	fn new(id: i64) -> Box<Vertex> {

		let mut edges : Vec<Edge> = Vec::new();
		let edges_ptr :	*mut Vec<Edge> = &mut edges;
		let vertex = Vertex{id:id, edges:edges_ptr};
		let mut v = Box::new(vertex);
		return v;
	}

	fn query(self) {

	}
}

#[derive(Show)]
struct VertexProxy {
	id: i64,
	v: *const Box<Vertex>,
}

//let i: u32 = 1;
//// explicit cast
//let p_imm: *const u32 = &i as *const u32;
//let mut m: u32 = 2;
//// implicit coercion
//let p_mut: *mut u32 = &mut m;
//
//unsafe {
//let ref_imm: &u32 = &*p_imm;
//let ref_mut: &mut u32 = &mut *p_mut;
//}

impl VertexProxy {
	fn add_edge(& self, to_vertex: &VertexProxy) {
		unsafe {
			let in_vertex =  &* self .v;
			let out_vertex = &*to_vertex.v;
		}
		// create the edge
		let e = Edge{from_vertex: self.v,
					 to_vertex:   to_vertex.v};

	}
}

struct Edge {
	from_vertex: *const Box<Vertex>,
	to_vertex: *const Box<Vertex>
}

fn main() {
	let mut g = Graph::new();

    println!("Hello, world!");
}

#[test]
fn test_unsafe_vertex() {
	let mut g = Graph::new();
	let mut v1 = g.add_vertex();
	assert!(v1.id == 1);

	let mut v2 = g.add_vertex();
	assert!(v2.id == 2);
}

#[test]
fn test_add_edge() {
	let mut g = Graph::new();
	let mut v1 = g.add_vertex();
	let mut v2 = g.add_vertex();
	v2.add_edge(&v2);

}
<|endoftext|>


<commit_before>extern crate sassers;
extern crate docopt;

use docopt::Docopt;
use std::fs::File;
use std::io::Read;
use std::path::Path;

fn main() {
    const VERSION: &'static str = env!("CARGO_PKG_VERSION");
    static USAGE: &'static str = "
Usage:
    sassers [-t <style>] <inputfile>
    sassers [-vh]

Options:
    -h, --help                   Show this message
    -v, --version                Show the version
    -t <style>, --style <style>  Output style [default: nested]
    ";

    let args = Docopt::new(USAGE)
                      .and_then(|d| d.parse())
                      .unwrap_or_else(|e| e.exit());

    if args.get_bool("-v") {
        println!("{}", VERSION);
    } else {
        let style = args.get_str("-t");
        let inputfile = args.get_str("<inputfile>");

        let mut sass = String::new();
        File::open(&Path::new(&inputfile)).unwrap().read_to_string(&mut sass).unwrap();

        match sassers::compile(&sass, style) {
            Ok(compiled) => println!("{}", compiled),
            Err(msg) => println!("Compilation failed: {}", msg),
        }
    }
}
<commit_msg>Print nicer error messages for myself<commit_after>extern crate sassers;
extern crate docopt;

use docopt::Docopt;
use std::fs::File;
use std::io::Read;
use std::path::Path;

fn main() {
    const VERSION: &'static str = env!("CARGO_PKG_VERSION");
    static USAGE: &'static str = "
Usage:
    sassers [-t <style>] <inputfile>
    sassers [-vh]

Options:
    -h, --help                   Show this message
    -v, --version                Show the version
    -t <style>, --style <style>  Output style [default: nested]
    ";

    let args = Docopt::new(USAGE)
                      .and_then(|d| d.parse())
                      .unwrap_or_else(|e| e.exit());

    if args.get_bool("-v") {
        println!("{}", VERSION);
    } else {
        let style = args.get_str("-t");
        let inputfile = args.get_str("<inputfile>");

        let mut sass = String::new();
        let mut file = match File::open(&Path::new(&inputfile)) {
            Ok(f) => f,
            Err(msg) => panic!("File not found! {}", msg),
        };
        match file.read_to_string(&mut sass) {
            Ok(_) => {
                match sassers::compile(&sass, style) {
                    Ok(compiled) => println!("{}", compiled),
                    Err(msg) => println!("Compilation failed: {}", msg),
                }
            },
            Err(msg) => panic!("Could not read file! {}", msg),
        }
    }
}
<|endoftext|>


<commit_before>mod scanner;
mod ast;
mod pretty_printer;
mod parser;
mod interpreter;
//mod lexical_scope_resolver;

extern crate itertools;

use std::env;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use pretty_printer::PrettyPrint;
use interpreter::{Interpreter, StatementInterpreter, Value, RuntimeError};
use ast::Statement;

#[derive(Debug)]
enum RunResult {
    Ok,
    IoError(String),
    InputError(Vec<InputError>),
    RuntimeError(RuntimeError),
}

#[derive(Debug)]
enum InputError {
    ScannerError(scanner::ScannerError),
    ParserError(parser::ParseError),
}

fn scan_and_parse(parser: &mut parser::Parser,
                  source: &str)
                  -> Result<Vec<ast::Statement>, Vec<InputError>> {
    let (tokens, scanner_errors) = scanner::scan(source);
    let mut errors: Vec<InputError> = scanner_errors
        .iter()
        .map(|e| InputError::ScannerError(e.clone()))
        .collect();
    match parser.parse(&tokens) {
        Ok(expr) => {
            if errors.is_empty() {
                Ok(expr)
            } else {
                Err(errors)
            }
        }
        Err(parse_errors) => {
            for error in parse_errors {
                errors.push(InputError::ParserError(error))
            }
            Err(errors)
        }
    }
}

fn run(parser: &mut parser::Parser, interpreter: &mut Interpreter, source: &str) -> RunResult {
    match scan_and_parse(parser, source) {
        Ok(statements) => {
            for statement in statements {
                match interpreter.execute(&statement) {
                    Ok(_) => (),
                    Err(e) => return RunResult::RuntimeError(e),
                }
            }
            RunResult::Ok
        }
        Err(e) => RunResult::InputError(e),
    }
}

fn run_file(file_name: &str) -> RunResult {
    match File::open(file_name) {
        Err(_) => {
            RunResult::IoError("Error opening file".into()) // TODO: add context
        }
        Ok(mut file) => {
            let mut parser = parser::Parser::new();
            let mut interpreter = StatementInterpreter::new();
            let mut source = String::new();
            match file.read_to_string(&mut source) {
                Err(_) => {
                    RunResult::IoError("Error reading file".into()) // TODO: add context
                }
                Ok(_) => run(&mut parser, &mut interpreter, &source),
            }
        }
    }
}

struct LoggingInterpreter {
    interpreter: StatementInterpreter,
}

impl LoggingInterpreter {
    fn new() -> LoggingInterpreter {
        LoggingInterpreter { interpreter: StatementInterpreter::new() }
    }
}

impl Interpreter for LoggingInterpreter {
    fn execute(&mut self, statement: &Statement) -> Result<Option<Value>, RuntimeError> {
        println!("{:?}", statement.pretty_print());
        let result = self.interpreter.execute(statement);
        {
            if let Ok(Some(ref value)) = result {
                println!("{:?}", value);
            };
        }
        result
    }
}

fn run_prompt() -> RunResult {
    println!("Rulox - A lox interpreter written in Rust");
    let mut parser = parser::Parser::new();
    let mut interpreter = LoggingInterpreter::new();
    let _ = io::stdout().flush(); //TODO: is this okay?
    loop {
        print!("> ");
        let _ = io::stdout().flush();
        let mut source = String::new();
        let _ = io::stdin().read_line(&mut source);
        // TODO: add a way to exit
        let result = run(&mut parser, &mut interpreter, &source);
        match result {
            RunResult::Ok => (),
            _ => {
                println!("{:?}", result);
                let _ = io::stdout().flush();
            }
        }
    }
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let result = match args.len() {
        // The first argument is the program name
        1 => run_prompt(),
        2 => run_file(&args[1]),
        _ => {
            println!("Usage: rulox [script]");
            RunResult::Ok
        }
    };
    let exit_code = match result {
        RunResult::Ok => 0,
        _ => {
            println!("{:?}", result);
            1
        }
    };
    std::process::exit(exit_code)
}
<commit_msg>Cleaned import<commit_after>mod scanner;
mod ast;
mod pretty_printer;
mod parser;
mod interpreter;
//mod lexical_scope_resolver;

extern crate itertools;

use std::env;
use std::fs::File;
use std::io;
use std::io::prelude::*;
use pretty_printer::PrettyPrint;
use interpreter::{Interpreter, StatementInterpreter, Value, RuntimeError};
use parser::{Parser, ParseError};
use ast::Statement;

#[derive(Debug)]
enum RunResult {
    Ok,
    IoError(String),
    InputError(Vec<InputError>),
    RuntimeError(RuntimeError),
}

#[derive(Debug)]
enum InputError {
    ScannerError(scanner::ScannerError),
    ParserError(ParseError),
}

fn scan_and_parse(parser: &mut Parser,
                  source: &str)
                  -> Result<Vec<ast::Statement>, Vec<InputError>> {
    let (tokens, scanner_errors) = scanner::scan(source);
    let mut errors: Vec<InputError> = scanner_errors
        .iter()
        .map(|e| InputError::ScannerError(e.clone()))
        .collect();
    match parser.parse(&tokens) {
        Ok(expr) => {
            if errors.is_empty() {
                Ok(expr)
            } else {
                Err(errors)
            }
        }
        Err(parse_errors) => {
            for error in parse_errors {
                errors.push(InputError::ParserError(error))
            }
            Err(errors)
        }
    }
}

fn run(parser: &mut Parser, interpreter: &mut Interpreter, source: &str) -> RunResult {
    match scan_and_parse(parser, source) {
        Ok(statements) => {
            for statement in statements {
                match interpreter.execute(&statement) {
                    Ok(_) => (),
                    Err(e) => return RunResult::RuntimeError(e),
                }
            }
            RunResult::Ok
        }
        Err(e) => RunResult::InputError(e),
    }
}

fn run_file(file_name: &str) -> RunResult {
    match File::open(file_name) {
        Err(_) => {
            RunResult::IoError("Error opening file".into()) // TODO: add context
        }
        Ok(mut file) => {
            let mut parser = Parser::new();
            let mut interpreter = StatementInterpreter::new();
            let mut source = String::new();
            match file.read_to_string(&mut source) {
                Err(_) => {
                    RunResult::IoError("Error reading file".into()) // TODO: add context
                }
                Ok(_) => run(&mut parser, &mut interpreter, &source),
            }
        }
    }
}

struct LoggingInterpreter {
    interpreter: StatementInterpreter,
}

impl LoggingInterpreter {
    fn new() -> LoggingInterpreter {
        LoggingInterpreter { interpreter: StatementInterpreter::new() }
    }
}

impl Interpreter for LoggingInterpreter {
    fn execute(&mut self, statement: &Statement) -> Result<Option<Value>, RuntimeError> {
        println!("{:?}", statement.pretty_print());
        let result = self.interpreter.execute(statement);
        {
            if let Ok(Some(ref value)) = result {
                println!("{:?}", value);
            };
        }
        result
    }
}

fn run_prompt() -> RunResult {
    println!("Rulox - A lox interpreter written in Rust");
    let mut parser = Parser::new();
    let mut interpreter = LoggingInterpreter::new();
    let _ = io::stdout().flush(); //TODO: is this okay?
    loop {
        print!("> ");
        let _ = io::stdout().flush();
        let mut source = String::new();
        let _ = io::stdin().read_line(&mut source);
        // TODO: add a way to exit
        let result = run(&mut parser, &mut interpreter, &source);
        match result {
            RunResult::Ok => (),
            _ => {
                println!("{:?}", result);
                let _ = io::stdout().flush();
            }
        }
    }
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let result = match args.len() {
        // The first argument is the program name
        1 => run_prompt(),
        2 => run_file(&args[1]),
        _ => {
            println!("Usage: rulox [script]");
            RunResult::Ok
        }
    };
    let exit_code = match result {
        RunResult::Ok => 0,
        _ => {
            println!("{:?}", result);
            1
        }
    };
    std::process::exit(exit_code)
}
<|endoftext|>


<commit_before>#[macro_use] extern crate lazy_static;

extern crate chrono;
extern crate iron;
extern crate router;
extern crate rusqlite;
extern crate sha2;
extern crate url;

use chrono::*;

use iron::prelude::*;
use iron::Url;
use iron::modifiers::Redirect;
use iron::status::Status;

use router::Router;

use rusqlite::Connection;

use sha2::digest::Digest;
use sha2::sha2::Sha256;

use url::form_urlencoded;

use std::env;
use std::sync::Mutex;

lazy_static! {
    static ref DB_CONN: Mutex<Connection> = {
        let db = env::var("SHORT_DB").unwrap();
        let c = Connection::open(db).unwrap();
        Mutex::new(c)
    };
}

// A simple macro to return early if the URL can't parse.
macro_rules! try_url {
    ($url:expr) => {
        match Url::parse($url) {
            Ok(_) => { },
            Err(_) => {
                return Ok(Response::with((Status::BadRequest, "Malformed URL")));
            }
        }
    }
}

fn create_shortened_url(long_url: &str) -> IronResult<Response> {
    let mut hash = Sha256::new();
    hash.input_str(long_url);
    let locator = hash.result_str();

    let db = DB_CONN.lock().unwrap();
    let timestamp = Local::now().to_rfc3339();
    db.execute("INSERT INTO urls VALUES (NULL, $1, $2, $3)",
        &[&timestamp, &long_url, &&locator[0..7]]).unwrap();

    // TODO: update this status.
    Ok(Response::with((Status::Ok, &locator[0..7])))
}

/// Given a long URL, see if it already exists in the table, else create an entry and return
/// it.
///
/// A 200 means that a shortened URL already exists and has been returned. A 201
/// response means that a new shortened URL has been created.
fn check_or_shorten_url(long_url: &str) -> IronResult<Response> {
    // The scoping here is needed because the lock will only be released once it drops
    // out of scope.
    {
        let db = DB_CONN.lock().unwrap();
        let mut stmt = db.prepare("SELECT locator FROM urls WHERE url = (?)").unwrap();
        let mut row = stmt.query_map::<String, _>(&[&long_url], |r| r.get(0)).unwrap();

        if let Some(l) = row.next() {
            return Ok(Response::with((Status::Ok, l.unwrap())));
        }
    }
    create_shortened_url(long_url)
}

/// The handler to shorten a URL.
fn shorten_handler(req: &mut Request) -> IronResult<Response> {
    match req.url.query {
        None => { Ok(Response::with((Status::BadRequest, "URL missing in query"))) },
        Some(ref s) => {
            let mut query_string = form_urlencoded::parse(s.as_bytes());

            if let Some(long_url) = query_string.next() {
                try_url!(&*long_url.1);
                check_or_shorten_url(&*long_url.1)
            } else {
                Ok(Response::with((Status::BadRequest, "Malformed query string")))
            }
        }
    }
}

/// The handler that redirects to the long URL.
fn redirect_handler(req: &mut Request) -> IronResult<Response> {
    let locator = req.extensions.get::<Router>().unwrap().find("locator").unwrap();
    let db = DB_CONN.lock().unwrap();
    let mut stmt = db.prepare("SELECT url FROM urls WHERE locator = (?)").unwrap();
    let mut row = stmt.query_map::<String, _>(&[&locator], |r| r.get(0)).unwrap();

    if let Some(u) = row.next() {
        let long_url = Url::parse(&u.unwrap()).unwrap();
        Ok(Response::with((Status::MovedPermanently, Redirect(long_url))))
    } else {
        Ok(Response::with((Status::NotFound, "Not found")))
    }
}

fn main() {
    let mut router = Router::new();
    router.get("/shorten", shorten_handler);
    router.get("/:locator", redirect_handler);

    Iron::new(router).http("localhost:3000").unwrap();
}
<commit_msg>add the base URL<commit_after>#[macro_use] extern crate lazy_static;

extern crate chrono;
extern crate iron;
extern crate router;
extern crate rusqlite;
extern crate sha2;
extern crate url;

use chrono::*;

use iron::prelude::*;
use iron::Url;
use iron::modifiers::Redirect;
use iron::status::Status;

use router::Router;

use rusqlite::Connection;

use sha2::digest::Digest;
use sha2::sha2::Sha256;

use url::form_urlencoded;

use std::env;
use std::sync::Mutex;

const HOST: &'static str = "http://yaus.pw/";

lazy_static! {
    static ref DB_CONN: Mutex<Connection> = {
        let db = env::var("SHORT_DB").unwrap();
        let c = Connection::open(db).unwrap();
        Mutex::new(c)
    };
}

// A simple macro to return early if the URL can't parse.
macro_rules! try_url {
    ($url:expr) => {
        match Url::parse($url) {
            Ok(_) => { },
            Err(_) => {
                return Ok(Response::with((Status::BadRequest, "Malformed URL")));
            }
        }
    }
}

fn create_shortened_url(long_url: &str) -> IronResult<Response> {
    let mut hash = Sha256::new();
    hash.input_str(long_url);
    let locator = hash.result_str();

    let db = DB_CONN.lock().unwrap();
    let timestamp = Local::now().to_rfc3339();
    db.execute("INSERT INTO urls VALUES (NULL, $1, $2, $3)",
        &[&timestamp, &long_url, &&locator[0..7]]).unwrap();

    Ok(Response::with((Status::Ok, [HOST, &locator[0..7]].join(""))))
}

/// Given a long URL, see if it already exists in the table, else create an entry and return
/// it.
///
/// A 200 means that a shortened URL already exists and has been returned. A 201
/// response means that a new shortened URL has been created.
fn check_or_shorten_url(long_url: &str) -> IronResult<Response> {
    // The scoping here is needed because the lock will only be released once it drops
    // out of scope.
    {
        let db = DB_CONN.lock().unwrap();
        let mut stmt = db.prepare("SELECT locator FROM urls WHERE url = (?)").unwrap();
        let mut row = stmt.query_map::<String, _>(&[&long_url], |r| r.get(0)).unwrap();

        if let Some(l) = row.next() {
            return Ok(Response::with((Status::Created, [HOST, &l.unwrap()].join(""))));
        }
    }
    create_shortened_url(long_url)
}

/// The handler to shorten a URL.
fn shorten_handler(req: &mut Request) -> IronResult<Response> {
    match req.url.query {
        None => { Ok(Response::with((Status::BadRequest, "URL missing in query"))) },
        Some(ref s) => {
            let mut query_string = form_urlencoded::parse(s.as_bytes());

            if let Some(long_url) = query_string.next() {
                try_url!(&*long_url.1);
                check_or_shorten_url(&*long_url.1)
            } else {
                Ok(Response::with((Status::BadRequest, "Malformed query string")))
            }
        }
    }
}

/// The handler that redirects to the long URL.
fn redirect_handler(req: &mut Request) -> IronResult<Response> {
    let locator = req.extensions.get::<Router>().unwrap().find("locator").unwrap();
    let db = DB_CONN.lock().unwrap();
    let mut stmt = db.prepare("SELECT url FROM urls WHERE locator = (?)").unwrap();
    let mut row = stmt.query_map::<String, _>(&[&locator], |r| r.get(0)).unwrap();

    if let Some(u) = row.next() {
        let long_url = Url::parse(&u.unwrap()).unwrap();
        Ok(Response::with((Status::MovedPermanently, Redirect(long_url))))
    } else {
        Ok(Response::with((Status::NotFound, "Not found")))
    }
}

fn main() {
    let mut router = Router::new();
    router.get("/shorten", shorten_handler);
    router.get("/:locator", redirect_handler);

    Iron::new(router).http("localhost:3000").unwrap();
}
<|endoftext|>


<commit_before>extern crate ghqrs;
extern crate clap;

use clap::{Arg, App, SubCommand};

fn main() {
  let matches = App::new("ghqrs")
    .about("Remote management")
    .version("0.0.1")
    .author("Yusuke Sasaki <yusuke.sasaki.nuem@gmail.com>")
    .subcommand(SubCommand::with_name("get")
      .about("Clone or sync with remote repository")
      .arg(Arg::with_name("project")
        .multiple(true)
        .required(true)
        .help("repository name or URL"))
      .arg(Arg::with_name("skip_pull")
        .long("skip-pull")
        .help("Skip to clone if the repository has already existed"))
      .arg(Arg::with_name("shallow")
        .long("shallow")
        .help("Do shallow clone")))
    .subcommand(SubCommand::with_name("list")
      .about("List locally cloned repositories")
      .arg(Arg::with_name("exact")
        .short("e")
        .long("exact")
        .help("Perform an exact match"))
      .arg(Arg::with_name("fullpath")
        .short("p")
        .long("full-path")
        .help("print full paths"))
      .arg(Arg::with_name("unique")
        .short("u")
        .long("unique")
        .help("Print unique subpaths"))
      .arg(Arg::with_name("query")))
    .subcommand(SubCommand::with_name("root")
      .about("Show repositories's root")
      .arg(Arg::with_name("all")
        .short("a")
        .long("all")
        .help("Show all roots")))
    .get_matches();

  let exitcode = match matches.subcommand_name() {
    Some(ref s) => {
      let ref matches = matches.subcommand_matches(s).unwrap();
      match *s {
        "get" => {
          let projects = matches.values_of("project").unwrap().map(ToOwned::to_owned).collect();
          let skip_pull = matches.is_present("skip-pull");
          let shallow = matches.is_present("shallow");
          ghqrs::command_get(projects, skip_pull, shallow)
        }
        "list" => {
          let exact = matches.is_present("exact");
          let fullpath = matches.is_present("fullpath");
          let unique = matches.is_present("unique");
          let query = matches.value_of("query").map(ToOwned::to_owned);
          ghqrs::command_list(exact, fullpath, unique, query)
        }
        "root" => {
          let all = matches.is_present("all");
          ghqrs::command_root(all)
        }
        _ => panic!("invalid subcommand: {}", s),
      }
    }
    None => panic!("Invalid subcommand"),
  };
  std::process::exit(exitcode);
}
<commit_msg>improve parsing of command-line arguments<commit_after>extern crate ghqrs;
extern crate clap;

use clap::{Arg, App, AppSettings, SubCommand};

fn main() {
  let matches = App::new("ghqrs")
    .about("Manages cloned repositories from Git hostings")
    .version(env!("CARGO_PKG_VERSION"))
    .author("Yusuke Sasaki <yusuke.sasaki.nuem@gmail.com>")
    .setting(AppSettings::VersionlessSubcommands)
    .setting(AppSettings::SubcommandRequiredElseHelp)
    .subcommand(SubCommand::with_name("get")
      .about("Clone or sync with remote repository")
      .arg(Arg::with_name("project")
        .multiple(true)
        .required(true)
        .help("repository name or URL"))
      .arg(Arg::with_name("skip_pull")
        .long("skip-pull")
        .help("Skip to clone if the repository has already existed"))
      .arg(Arg::with_name("shallow")
        .long("shallow")
        .help("Do shallow clone")))
    .subcommand(SubCommand::with_name("list")
      .about("List locally cloned repositories")
      .arg(Arg::with_name("exact")
        .short("e")
        .long("exact")
        .help("Perform an exact match"))
      .arg(Arg::with_name("fullpath")
        .short("p")
        .long("full-path")
        .help("print full paths"))
      .arg(Arg::with_name("unique")
        .short("u")
        .long("unique")
        .help("Print unique subpaths"))
      .arg(Arg::with_name("query")))
    .subcommand(SubCommand::with_name("root")
      .about("Show repositories's root")
      .arg(Arg::with_name("all")
        .short("a")
        .long("all")
        .help("Show all roots")))
    .get_matches();

  let exitcode = if let Some(ref s) = matches.subcommand_name() {
    let ref matches = matches.subcommand_matches(s).unwrap();
    match *s {
      "get" => {
        let projects = matches.values_of("project").unwrap().map(ToOwned::to_owned).collect();
        let skip_pull = matches.is_present("skip-pull");
        let shallow = matches.is_present("shallow");
        ghqrs::command_get(projects, skip_pull, shallow)
      }
      "list" => {
        let exact = matches.is_present("exact");
        let fullpath = matches.is_present("fullpath");
        let unique = matches.is_present("unique");
        let query = matches.value_of("query").map(ToOwned::to_owned);
        ghqrs::command_list(exact, fullpath, unique, query)
      }
      "root" => {
        let all = matches.is_present("all");
        ghqrs::command_root(all)
      }
      _ => unreachable!(),
    }
  } else {
    unreachable!()
  };
  std::process::exit(exitcode);
}
<|endoftext|>


<commit_before>//! Command line utility for querying and working with Iridium SBD messages.

extern crate chrono;
extern crate docopt;
extern crate log;
extern crate rustc_serialize;
extern crate sbd;

use std::io::Write;
use std::path::Path;
use std::process;
use std::str;

use docopt::Docopt;
use rustc_serialize::json;

use sbd::directip::Server;
use sbd::storage::FilesystemStorage;
use sbd::mo::{Message, SessionStatus};

const USAGE: &'static str = "
Iridium Short Burst Data (SBD) message utility.

Usage:
    sbd \
                             info <file>
    sbd payload <file>
    sbd serve <addr> <directory> \
                             [--logfile=<logfile>]
    sbd (-h | --help)
    sbd --version

\
                             Options:
    -h --help               Show this information
    \
                             --version               Show version
    --logfile=<logfile>     \
                             Logfile [default: /var/log/iridiumd.log]
";

#[derive(Debug, RustcDecodable)]
struct Args {
    cmd_info: bool,
    cmd_payload: bool,
    cmd_serve: bool,
    arg_addr: String,
    arg_directory: String,
    arg_file: String,
    flag_logfile: String,
}

struct Logger<P: AsRef<Path>> {
    path: P,
}

impl<P: AsRef<Path> + Send + Sync> log::Log for Logger<P> {
    fn enabled(&self, metadata: &log::LogMetadata) -> bool {
        metadata.level() <= log::LogLevel::Debug
    }

    fn log(&self, record: &log::LogRecord) {
        if self.enabled(record.metadata()) {
            let mut file = std::fs::OpenOptions::new()
                               .create(true)
                               .write(true)
                               .append(true)
                               .open(&self.path)
                               .unwrap();
            file.write_all(format!("({}) {}: {}\n",
                                   chrono::UTC::now().format("%Y-%m-%d %H:%M:%S"),
                                   record.level(),
                                   record.args())
                               .as_bytes())
                .unwrap();
        }
    }
}

#[derive(RustcEncodable)]
pub struct ReadableMessage {
    protocol_revision_number: u8,
    cdr_reference: u32,
    imei: String,
    session_status: SessionStatus,
    momsn: u16,
    mtmsn: u16,
    time_of_session: String,
    payload: String,
}

impl ReadableMessage {
    fn new(m: &Message) -> ReadableMessage {
        ReadableMessage {
            protocol_revision_number: m.protocol_revision_number(),
            cdr_reference: m.cdr_reference(),
            imei: m.imei().to_string(),
            session_status: m.session_status(),
            momsn: m.momsn(),
            mtmsn: m.mtmsn(),
            time_of_session: m.time_of_session().to_rfc2822(),
            payload: str::from_utf8(m.payload_ref()).unwrap_or("<binary payload>").to_string(),
        }
    }
}

fn main() {
    let args: Args = Docopt::new(USAGE)
                         .and_then(|d| Ok(d.version(Some(env!("CARGO_PKG_VERSION").to_string()))))
                         .and_then(|d| d.decode())
                         .unwrap_or_else(|e| e.exit());

    if args.cmd_info {
        match Message::from_path(&args.arg_file) {
            Ok(ref message) => {
                let ref message = ReadableMessage::new(message);
                let j = json::as_pretty_json(message);
                println!("{}", j);
            }
            Err(err) => {
                println!("ERROR: Unable to read message: {}", err);
                process::exit(1);
            }
        }
    }
    if args.cmd_payload {
        match Message::from_path(&args.arg_file) {
            Ok(message) => {
                println!("{}",
                         str::from_utf8(message.payload_ref()).unwrap_or_else(|e| {
                             println!("ERROR: Unable to convert payload to utf8: {}", e);
                             process::exit(1);
                         }));
            }
            Err(err) => {
                println!("ERROR: Unable to extract payload: {}", err);
                process::exit(1);
            }
        }
    }
    if args.cmd_serve {
        log::set_logger(|max_log_level| {
            max_log_level.set(log::LogLevelFilter::Debug);
            Box::new(Logger { path: args.flag_logfile.clone() })
        })
            .unwrap_or_else(|e| {
                println!("ERROR: Could not create logger: {}", e);
                process::exit(1);
            });
        let storage = FilesystemStorage::open(&args.arg_directory).unwrap_or_else(|e| {
            println!("ERROR: Could not open storage: {}", e);
            process::exit(1);
        });
        let mut server = Server::new(&args.arg_addr[..], storage);
        match server.bind() {
            Ok(()) => server.serve_forever(),
            Err(err) => {
                println!("ERROR: Could not bind to socket: {}", err);
                process::exit(1);
            }
        }
    }
}
<commit_msg>Add info command with json pretty printing<commit_after>//! Command line utility for querying and working with Iridium SBD messages.

extern crate chrono;
extern crate docopt;
extern crate log;
extern crate rustc_serialize;
extern crate sbd;

use std::io::Write;
use std::path::Path;
use std::process;
use std::str;

use docopt::Docopt;
use rustc_serialize::json;

use sbd::directip::Server;
use sbd::storage::FilesystemStorage;
use sbd::mo::{Message, SessionStatus};

const USAGE: &'static str = "
Iridium Short Burst Data (SBD) message utility.

Usage:
    sbd \
                             info <file> [--compact]
    sbd payload <file>
    sbd serve <addr> \
                             <directory> [--logfile=<logfile>]
    sbd (-h | --help)
    sbd \
                             --version

Options:
    -h --help               Show this \
                             information
    --version               Show version
    \
                             --logfile=<logfile>     Logfile [default: /var/log/iridiumd.log]
    \
                             --compact               Don't pretty-print the JSON
";

#[derive(Debug, RustcDecodable)]
struct Args {
    cmd_info: bool,
    cmd_payload: bool,
    cmd_serve: bool,
    arg_addr: String,
    arg_directory: String,
    arg_file: String,
    flag_logfile: String,
    flag_compact: bool,
}

struct Logger<P: AsRef<Path>> {
    path: P,
}

impl<P: AsRef<Path> + Send + Sync> log::Log for Logger<P> {
    fn enabled(&self, metadata: &log::LogMetadata) -> bool {
        metadata.level() <= log::LogLevel::Debug
    }

    fn log(&self, record: &log::LogRecord) {
        if self.enabled(record.metadata()) {
            let mut file = std::fs::OpenOptions::new()
                               .create(true)
                               .write(true)
                               .append(true)
                               .open(&self.path)
                               .unwrap();
            file.write_all(format!("({}) {}: {}\n",
                                   chrono::UTC::now().format("%Y-%m-%d %H:%M:%S"),
                                   record.level(),
                                   record.args())
                               .as_bytes())
                .unwrap();
        }
    }
}

#[derive(RustcEncodable)]
pub struct ReadableMessage {
    protocol_revision_number: u8,
    cdr_reference: u32,
    imei: String,
    session_status: SessionStatus,
    momsn: u16,
    mtmsn: u16,
    time_of_session: String,
    payload: String,
}

impl ReadableMessage {
    fn new(m: &Message) -> ReadableMessage {
        ReadableMessage {
            protocol_revision_number: m.protocol_revision_number(),
            cdr_reference: m.cdr_reference(),
            imei: m.imei().to_string(),
            session_status: m.session_status(),
            momsn: m.momsn(),
            mtmsn: m.mtmsn(),
            time_of_session: m.time_of_session().to_rfc2822(),
            payload: str::from_utf8(m.payload_ref()).unwrap_or("<binary payload>").to_string(),
        }
    }
}

fn main() {
    let args: Args = Docopt::new(USAGE)
                         .and_then(|d| Ok(d.version(Some(env!("CARGO_PKG_VERSION").to_string()))))
                         .and_then(|d| d.decode())
                         .unwrap_or_else(|e| e.exit());

    if args.cmd_info {
        match Message::from_path(&args.arg_file) {
            Ok(ref message) => {
                let ref message = ReadableMessage::new(message);
                if args.flag_compact {
                    println!("{}", json::as_json(message));
                } else {
                    println!("{}", json::as_pretty_json(message));
                };
            }
            Err(err) => {
                println!("ERROR: Unable to read message: {}", err);
                process::exit(1);
            }
        }
    }
    if args.cmd_payload {
        match Message::from_path(&args.arg_file) {
            Ok(message) => {
                println!("{}",
                         str::from_utf8(message.payload_ref()).unwrap_or_else(|e| {
                             println!("ERROR: Unable to convert payload to utf8: {}", e);
                             process::exit(1);
                         }));
            }
            Err(err) => {
                println!("ERROR: Unable to extract payload: {}", err);
                process::exit(1);
            }
        }
    }
    if args.cmd_serve {
        log::set_logger(|max_log_level| {
            max_log_level.set(log::LogLevelFilter::Debug);
            Box::new(Logger { path: args.flag_logfile.clone() })
        })
            .unwrap_or_else(|e| {
                println!("ERROR: Could not create logger: {}", e);
                process::exit(1);
            });
        let storage = FilesystemStorage::open(&args.arg_directory).unwrap_or_else(|e| {
            println!("ERROR: Could not open storage: {}", e);
            process::exit(1);
        });
        let mut server = Server::new(&args.arg_addr[..], storage);
        match server.bind() {
            Ok(()) => server.serve_forever(),
            Err(err) => {
                println!("ERROR: Could not bind to socket: {}", err);
                process::exit(1);
            }
        }
    }
}
<|endoftext|>


<commit_before>extern crate rusudoku;

use std::io;
use std::io::BufRead;
use std::mem;

fn main() {
    let mut lines = io::BufReader::new(io::stdin()).lines();
    let grid = rusudoku::grid::Grid::read(&mut lines);
    let mut grid = match grid {
        Ok(grid) => grid,
        Err(err) => {
            println!("Couldn't read puzzle: {}", err);
            return;
        },
    };

    let rules = rusudoku::rules::Rules::new_standard(grid.size());
    let rules = match rules {
        Ok(rules) => rules,
        Err(_) => {
            println!("Couldn't create rules for sudoku problem {} cells wide.", grid.size());
            return;
        },
    };

    let mut partitioner = rusudoku::solver::Partitioner::new(&rules);
    let mut vetoes: Vec<_> = grid.vetoes().collect();
    while vetoes.len() > 0 {
        partitioner.veto(vetoes.iter().cloned());
        grid.veto(vetoes.iter().cloned());
        vetoes = mem::replace(&mut partitioner.inferences, vec![]);
    }

    print!("{}", grid);
}
<commit_msg>Improved error-handling of executable.<commit_after>extern crate rusudoku;

use std::io;
use std::io::BufRead;
use std::mem;

// I'm under the impression user-errors shouldn't be handled via panics, and main() was
// getting a bit cluttered from error-handling... Hopefully this'll help with readability.
// This is like .expect(), except it takes format strings and exits the process instead of
// panicking.
macro_rules! expect {
    ($result:expr, $err:ident => $($err_msg:expr),+) => {
        match $result {
            Ok(value) => value,
            Err($err) => {
                use std::io::{stderr, Write};
                use std::process;
                let _ = writeln!(&mut stderr(), $($err_msg),*);
                process::exit(1);
            }
        }
    }
}

fn main() {
    let mut lines = io::BufReader::new(io::stdin()).lines();

    let grid = rusudoku::grid::Grid::read(&mut lines);
    let mut grid = expect!(grid, err => "Couldn't read puzzle: {}", err);

    let rules = rusudoku::rules::Rules::new_standard(grid.size());
    let rules = expect!(rules, err => "Couldn't create rules for sudoku problem {} cells wide.",
                                      err.size());

    let mut partitioner = rusudoku::solver::Partitioner::new(&rules);

    let mut vetoes: Vec<_> = grid.vetoes().collect();
    while vetoes.len() > 0 {
        partitioner.veto(vetoes.iter().cloned());
        grid.veto(vetoes.iter().cloned());
        vetoes = mem::replace(&mut partitioner.inferences, vec![]);
    }

    print!("{}", grid);
}
<|endoftext|>


<commit_before>use std::env;
use std::ffi::{OsStr, OsString};
use std::io::{self, Write};
use std::path::PathBuf;
use std::process::{self, Command};

#[cfg(unix)]
use std::process::{Child, Stdio};

extern crate isatty;
use isatty::{stdout_isatty, stderr_isatty};

#[cfg(unix)]
extern crate tempdir;
#[cfg(unix)]
use tempdir::TempDir;

fn main() {
    let result = cargo_expand();
    process::exit(match result {
        Ok(code) => code,
        Err(err) => {
            let _ = writeln!(&mut io::stderr(), "{}", err);
            1
        }
    });
}

#[cfg(windows)]
fn cargo_expand() -> io::Result<i32> {
    // Build cargo command
    let mut cmd = Command::new("cargo");
    cmd.args(&wrap_args(env::args_os(), None));
    run(cmd)
}

#[cfg(unix)]
fn cargo_expand() -> io::Result<i32> {
    let args: Vec<_> = env::args_os().collect();
    match args.last().unwrap().to_str().unwrap_or("") {
        "--filter-cargo" => filter_err(ignore_cargo_err),
        "--filter-rustfmt" => filter_err(ignore_rustfmt_err),
        _ => {}
    }

    macro_rules! shell {
        ($($arg:expr)*) => {
            &[$(OsStr::new(&$arg)),*]
        };
    }

    let which_rustfmt = which(&["rustfmt"]);
    let which_pygmentize = if stdout_isatty() {
        which(&["pygmentize", "-l", "rust"])
    } else {
        None
    };

    let outdir = if which_rustfmt.is_some() || which_pygmentize.is_some() {
        Some(TempDir::new("cargo-expand").expect("failed to create tmp file"))
    } else {
        None
    };
    let outfile = outdir.as_ref().map(|dir| dir.path().join("expanded"));

    // Build cargo command
    let mut cmd = Command::new("cargo");
    cmd.args(&wrap_args(args.clone(), outfile.as_ref()));

    // Pipe to a tmp file to separate out any println output from build scripts
    if let Some(outfile) = outfile {
        let mut filter_cargo = Vec::new();
        filter_cargo.extend(args.iter().map(OsString::as_os_str));
        filter_cargo.push(OsStr::new("--filter-cargo"));

        let _wait = try!(cmd.pipe_to(shell!("cat"), Some(&filter_cargo)));
        try!(run(cmd));
        drop(_wait);

        cmd = Command::new("cat");
        cmd.arg(outfile);
    }

    // Pipe to rustfmt
    let _wait = match which_rustfmt {
        Some(ref fmt) => {
            let args: Vec<_> = env::args_os().collect();
            let mut filter_rustfmt = Vec::new();
            filter_rustfmt.extend(args.iter().map(OsString::as_os_str));
            filter_rustfmt.push(OsStr::new("--filter-rustfmt"));

            Some((
                // Work around $crate issue https://github.com/rust-lang/rust/issues/38016
                try!(cmd.pipe_to(shell!("sed" "s/$crate/XCRATE/g"), None)),
                try!(cmd.pipe_to(shell!(fmt), None)),
                try!(cmd.pipe_to(shell!("sed" "s/XCRATE/$crate/g"), Some(&filter_rustfmt))),
            ))
        }
        None => None,
    };

    // Pipe to pygmentize
    let _wait = match which_pygmentize {
        Some(pyg) => Some(try!(cmd.pipe_to(shell!(pyg "-l" "rust"), None))),
        None => None,
    };

    run(cmd)
}

fn run(mut cmd: Command) -> io::Result<i32> {
    cmd.status().map(|status| status.code().unwrap_or(1))
}

#[cfg(unix)]
struct Wait(Vec<Child>);

#[cfg(unix)]
impl Drop for Wait {
    fn drop(&mut self) {
        for child in &mut self.0 {
            if let Err(err) = child.wait() {
                let _ = writeln!(&mut io::stderr(), "{}", err);
            }
        }
    }
}

#[cfg(unix)]
trait PipeTo {
    fn pipe_to(&mut self, out: &[&OsStr], err: Option<&[&OsStr]>) -> io::Result<Wait>;
}

#[cfg(unix)]
impl PipeTo for Command {
    fn pipe_to(&mut self, out: &[&OsStr], err: Option<&[&OsStr]>) -> io::Result<Wait> {
        use std::os::unix::io::{AsRawFd, FromRawFd};

        self.stdout(Stdio::piped());
        if err.is_some() {
            self.stderr(Stdio::piped());
        }

        let child = try!(self.spawn());

        *self = Command::new(out[0]);
        self.args(&out[1..]);
        self.stdin(unsafe {
            Stdio::from_raw_fd(child.stdout.as_ref().map(AsRawFd::as_raw_fd).unwrap())
        });

        match err {
            None => {
                Ok(Wait(vec![child]))
            }
            Some(err) => {
                let mut errcmd = Command::new(err[0]);
                errcmd.args(&err[1..]);
                errcmd.stdin(unsafe {
                    Stdio::from_raw_fd(child.stderr.as_ref().map(AsRawFd::as_raw_fd).unwrap())
                });
                errcmd.stdout(Stdio::null());
                errcmd.stderr(Stdio::inherit());
                let spawn = try!(errcmd.spawn());
                Ok(Wait(vec![spawn, child]))
            }
        }
    }
}

// Based on https://github.com/rsolomo/cargo-check
fn wrap_args<I>(it: I, outfile: Option<&PathBuf>) -> Vec<OsString>
    where I: IntoIterator<Item=OsString>
{
    let mut args = vec!["rustc".into()];
    let mut ends_with_test = false;
    let mut ends_with_example = false;
    let mut has_color = false;

    let mut it = it.into_iter().skip(2);
    for arg in &mut it {
        if arg == *"--" {
            break;
        }
        ends_with_test = arg == *"--test";
        ends_with_example = arg == *"--example";
        has_color |= arg.to_str().unwrap_or("").starts_with("--color");
        args.push(arg.into());
    }

    if ends_with_test {
        // Expand the `test.rs` test by default.
        args.push("test".into());
    }

    if ends_with_example {
        // Expand the `example.rs` example by default.
        args.push("example".into());
    }

    if !has_color {
        let color = stdout_isatty() && stderr_isatty();
        let setting = if color { "always" } else { "never" };
        args.push(format!("--color={}", setting).into());
    }

    args.push("--".into());
    if let Some(path) = outfile {
        args.push("-o".into());
        args.push(path.into());
    }
    args.push("-Zunstable-options".into());
    args.push("--pretty=expanded".into());
    args.extend(it);
    args
}

#[cfg(unix)]
fn which(cmd: &[&str]) -> Option<OsString> {
    if env::args_os().find(|arg| arg == "--help").is_some() {
        None
    } else {
        match env::var_os(&cmd[0].to_uppercase()) {
            Some(which) => {
                if which.is_empty() {
                    None
                } else {
                    Some(which)
                }
            }
            None => {
                let in_path = Command::new(cmd[0])
                    .args(&cmd[1..])
                    .stdin(Stdio::null())
                    .stdout(Stdio::null())
                    .stderr(Stdio::null())
                    .spawn()
                    .is_ok();
                if in_path {
                    Some(cmd[0].into())
                } else {
                    None
                }
            }
        }
    }
}

#[cfg(unix)]
fn filter_err(ignore: fn(&str) -> bool) -> ! {
    let mut line = String::new();
    while let Ok(n) = io::stdin().read_line(&mut line) {
        if n == 0 {
            break;
        }
        if !ignore(&line) {
            let _ = write!(&mut io::stderr(), "{}", line);
        }
        line.clear();
    }
    process::exit(0);
}

#[cfg(unix)]
fn ignore_rustfmt_err(line: &str) -> bool {
    line.trim().is_empty()
        || line.trim_right().ends_with("line exceeded maximum length (sorry)")
        || line.trim_right().ends_with("left behind trailing whitespace (sorry)")
}

#[cfg(unix)]
fn ignore_cargo_err(line: &str) -> bool {
    line.trim().is_empty()
        || line.contains("ignoring specified output filename because multiple outputs were requested")
        || line.contains("ignoring --out-dir flag due to -o flag.")
}
<commit_msg>Color even if redirecting stdout<commit_after>use std::env;
use std::ffi::{OsStr, OsString};
use std::io::{self, Write};
use std::path::PathBuf;
use std::process::{self, Command};

#[cfg(unix)]
use std::process::{Child, Stdio};

extern crate isatty;
use isatty::{stdout_isatty, stderr_isatty};

#[cfg(unix)]
extern crate tempdir;
#[cfg(unix)]
use tempdir::TempDir;

fn main() {
    let result = cargo_expand();
    process::exit(match result {
        Ok(code) => code,
        Err(err) => {
            let _ = writeln!(&mut io::stderr(), "{}", err);
            1
        }
    });
}

#[cfg(windows)]
fn cargo_expand() -> io::Result<i32> {
    // Build cargo command
    let mut cmd = Command::new("cargo");
    cmd.args(&wrap_args(env::args_os(), None));
    run(cmd)
}

#[cfg(unix)]
fn cargo_expand() -> io::Result<i32> {
    let args: Vec<_> = env::args_os().collect();
    match args.last().unwrap().to_str().unwrap_or("") {
        "--filter-cargo" => filter_err(ignore_cargo_err),
        "--filter-rustfmt" => filter_err(ignore_rustfmt_err),
        _ => {}
    }

    macro_rules! shell {
        ($($arg:expr)*) => {
            &[$(OsStr::new(&$arg)),*]
        };
    }

    let which_rustfmt = which(&["rustfmt"]);
    let which_pygmentize = if stdout_isatty() {
        which(&["pygmentize", "-l", "rust"])
    } else {
        None
    };

    let outdir = if which_rustfmt.is_some() || which_pygmentize.is_some() {
        Some(TempDir::new("cargo-expand").expect("failed to create tmp file"))
    } else {
        None
    };
    let outfile = outdir.as_ref().map(|dir| dir.path().join("expanded"));

    // Build cargo command
    let mut cmd = Command::new("cargo");
    cmd.args(&wrap_args(args.clone(), outfile.as_ref()));

    // Pipe to a tmp file to separate out any println output from build scripts
    if let Some(outfile) = outfile {
        let mut filter_cargo = Vec::new();
        filter_cargo.extend(args.iter().map(OsString::as_os_str));
        filter_cargo.push(OsStr::new("--filter-cargo"));

        let _wait = try!(cmd.pipe_to(shell!("cat"), Some(&filter_cargo)));
        try!(run(cmd));
        drop(_wait);

        cmd = Command::new("cat");
        cmd.arg(outfile);
    }

    // Pipe to rustfmt
    let _wait = match which_rustfmt {
        Some(ref fmt) => {
            let args: Vec<_> = env::args_os().collect();
            let mut filter_rustfmt = Vec::new();
            filter_rustfmt.extend(args.iter().map(OsString::as_os_str));
            filter_rustfmt.push(OsStr::new("--filter-rustfmt"));

            Some((
                // Work around $crate issue https://github.com/rust-lang/rust/issues/38016
                try!(cmd.pipe_to(shell!("sed" "s/$crate/XCRATE/g"), None)),
                try!(cmd.pipe_to(shell!(fmt), None)),
                try!(cmd.pipe_to(shell!("sed" "s/XCRATE/$crate/g"), Some(&filter_rustfmt))),
            ))
        }
        None => None,
    };

    // Pipe to pygmentize
    let _wait = match which_pygmentize {
        Some(pyg) => Some(try!(cmd.pipe_to(shell!(pyg "-l" "rust"), None))),
        None => None,
    };

    run(cmd)
}

fn run(mut cmd: Command) -> io::Result<i32> {
    cmd.status().map(|status| status.code().unwrap_or(1))
}

#[cfg(unix)]
struct Wait(Vec<Child>);

#[cfg(unix)]
impl Drop for Wait {
    fn drop(&mut self) {
        for child in &mut self.0 {
            if let Err(err) = child.wait() {
                let _ = writeln!(&mut io::stderr(), "{}", err);
            }
        }
    }
}

#[cfg(unix)]
trait PipeTo {
    fn pipe_to(&mut self, out: &[&OsStr], err: Option<&[&OsStr]>) -> io::Result<Wait>;
}

#[cfg(unix)]
impl PipeTo for Command {
    fn pipe_to(&mut self, out: &[&OsStr], err: Option<&[&OsStr]>) -> io::Result<Wait> {
        use std::os::unix::io::{AsRawFd, FromRawFd};

        self.stdout(Stdio::piped());
        if err.is_some() {
            self.stderr(Stdio::piped());
        }

        let child = try!(self.spawn());

        *self = Command::new(out[0]);
        self.args(&out[1..]);
        self.stdin(unsafe {
            Stdio::from_raw_fd(child.stdout.as_ref().map(AsRawFd::as_raw_fd).unwrap())
        });

        match err {
            None => {
                Ok(Wait(vec![child]))
            }
            Some(err) => {
                let mut errcmd = Command::new(err[0]);
                errcmd.args(&err[1..]);
                errcmd.stdin(unsafe {
                    Stdio::from_raw_fd(child.stderr.as_ref().map(AsRawFd::as_raw_fd).unwrap())
                });
                errcmd.stdout(Stdio::null());
                errcmd.stderr(Stdio::inherit());
                let spawn = try!(errcmd.spawn());
                Ok(Wait(vec![spawn, child]))
            }
        }
    }
}

// Based on https://github.com/rsolomo/cargo-check
fn wrap_args<I>(it: I, outfile: Option<&PathBuf>) -> Vec<OsString>
    where I: IntoIterator<Item=OsString>
{
    let mut args = vec!["rustc".into()];
    let mut ends_with_test = false;
    let mut ends_with_example = false;
    let mut has_color = false;

    let mut it = it.into_iter().skip(2);
    for arg in &mut it {
        if arg == *"--" {
            break;
        }
        ends_with_test = arg == *"--test";
        ends_with_example = arg == *"--example";
        has_color |= arg.to_str().unwrap_or("").starts_with("--color");
        args.push(arg.into());
    }

    if ends_with_test {
        // Expand the `test.rs` test by default.
        args.push("test".into());
    }

    if ends_with_example {
        // Expand the `example.rs` example by default.
        args.push("example".into());
    }

    if !has_color {
        let color = stderr_isatty();
        let setting = if color { "always" } else { "never" };
        args.push(format!("--color={}", setting).into());
    }

    args.push("--".into());
    if let Some(path) = outfile {
        args.push("-o".into());
        args.push(path.into());
    }
    args.push("-Zunstable-options".into());
    args.push("--pretty=expanded".into());
    args.extend(it);
    args
}

#[cfg(unix)]
fn which(cmd: &[&str]) -> Option<OsString> {
    if env::args_os().find(|arg| arg == "--help").is_some() {
        None
    } else {
        match env::var_os(&cmd[0].to_uppercase()) {
            Some(which) => {
                if which.is_empty() {
                    None
                } else {
                    Some(which)
                }
            }
            None => {
                let in_path = Command::new(cmd[0])
                    .args(&cmd[1..])
                    .stdin(Stdio::null())
                    .stdout(Stdio::null())
                    .stderr(Stdio::null())
                    .spawn()
                    .is_ok();
                if in_path {
                    Some(cmd[0].into())
                } else {
                    None
                }
            }
        }
    }
}

#[cfg(unix)]
fn filter_err(ignore: fn(&str) -> bool) -> ! {
    let mut line = String::new();
    while let Ok(n) = io::stdin().read_line(&mut line) {
        if n == 0 {
            break;
        }
        if !ignore(&line) {
            let _ = write!(&mut io::stderr(), "{}", line);
        }
        line.clear();
    }
    process::exit(0);
}

#[cfg(unix)]
fn ignore_rustfmt_err(line: &str) -> bool {
    line.trim().is_empty()
        || line.trim_right().ends_with("line exceeded maximum length (sorry)")
        || line.trim_right().ends_with("left behind trailing whitespace (sorry)")
}

#[cfg(unix)]
fn ignore_cargo_err(line: &str) -> bool {
    line.trim().is_empty()
        || line.contains("ignoring specified output filename because multiple outputs were requested")
        || line.contains("ignoring --out-dir flag due to -o flag.")
}
<|endoftext|>