<commit_before>#![cfg_attr(test, allow(dead_code))]

#![feature(collections)]
#![feature(fs)]
#![feature(io)]
#![feature(old_io)]

extern crate document;

use std::env;
use std::cmp::min;
use std::fs::File;
use std::io::{Read,Cursor};
use std::old_io::stdio;

use document::parser::Parser;

fn pretty_error(xml: &str, position: usize) -> &str {
    let s = &xml[position..];
    let l = s.chars().count();
    s.slice_chars(0, min(l, 15))
}

fn process_input<R>(input: R)
    where R: Read
{
    let mut input = input;
    let mut data = String::new();
    match input.read_to_string(&mut data) {
        Ok(x) => x,
        Err(x) => panic!("Can't read: {}", x),
    };

    let p = Parser::new();

    let package = match p.parse(&data) {
        Ok(d) => d,
        Err(point) => panic!("Unable to parse: {}", pretty_error(&data, point)),
    };

    // TODO: Remove buffering when std::io gets stdout
    let mut out = Vec::new();
    let d = package.as_document();
    document::writer::format_document(&d, &mut out).ok().expect("I can't output");

    stdio::stdout_raw().write_all(&out).unwrap();
}

fn main() {
    let mut args: Vec<_> = env::args().collect();

    let filename = args.remove(1);

    if filename == "-" {
        let data = stdio::stdin_raw().read_to_end().unwrap();
        process_input(Cursor::new(data));
    } else {
        let file = File::open(&filename).unwrap();
        process_input(file);
    }
}
<commit_msg>Filesystem feature is stable now<commit_after>#![cfg_attr(test, allow(dead_code))]

#![feature(collections)]
#![feature(io)]
#![feature(old_io)]

extern crate document;

use std::env;
use std::cmp::min;
use std::fs::File;
use std::io::{Read,Cursor};
use std::old_io::stdio;

use document::parser::Parser;

fn pretty_error(xml: &str, position: usize) -> &str {
    let s = &xml[position..];
    let l = s.chars().count();
    s.slice_chars(0, min(l, 15))
}

fn process_input<R>(input: R)
    where R: Read
{
    let mut input = input;
    let mut data = String::new();
    match input.read_to_string(&mut data) {
        Ok(x) => x,
        Err(x) => panic!("Can't read: {}", x),
    };

    let p = Parser::new();

    let package = match p.parse(&data) {
        Ok(d) => d,
        Err(point) => panic!("Unable to parse: {}", pretty_error(&data, point)),
    };

    // TODO: Remove buffering when std::io gets stdout
    let mut out = Vec::new();
    let d = package.as_document();
    document::writer::format_document(&d, &mut out).ok().expect("I can't output");

    stdio::stdout_raw().write_all(&out).unwrap();
}

fn main() {
    let mut args: Vec<_> = env::args().collect();

    let filename = args.remove(1);

    if filename == "-" {
        let data = stdio::stdin_raw().read_to_end().unwrap();
        process_input(Cursor::new(data));
    } else {
        let file = File::open(&filename).unwrap();
        process_input(file);
    }
}
<|endoftext|>


<commit_before>use nannou::prelude::*;
use nannou_audio as audio;
use nannou_audio::Buffer;
use ringbuf::{Consumer, Producer, RingBuffer};

fn main() {
    nannou::app(model).run();
}

struct Model {
    in_stream: audio::Stream<InModel>,
    out_stream: audio::Stream<OutModel>,
}

struct InModel {
    pub sender: Producer<[f32; 2]>,
}

struct OutModel {
    pub receiver: Consumer<[f32; 2]>,
}

fn model(app: &App) -> Model {
    // Create a window to receive key pressed events.
    app.new_window()
        .key_pressed(key_pressed)
        .view(view)
        .build()
        .unwrap();

    // Initialise the audio host so we can spawn an audio stream.
    let audio_host = audio::Host::new();

    let ring_buffer = RingBuffer::<[f32; 2]>::new(1024 * 2); // Add some latency
    let (mut prod, cons) = ring_buffer.split();
    let in_model = InModel { sender: prod };
    let in_stream = audio_host
        .new_input_stream(in_model)
        .capture(pass_in)
        .build()
        .unwrap();

    let out_model = OutModel { receiver: cons };
    let out_stream = audio_host
        .new_output_stream(out_model)
        .render(pass_out)
        .build()
        .unwrap();

    Model {
        in_stream,
        out_stream,
    }
}

fn pass_in(model: &mut InModel, buffer: &Buffer) {
    for frame in buffer.frames() {
        model.sender.push([frame[0], frame[1]]).unwrap();
    }
}

fn pass_out(model: &mut OutModel, buffer: &mut Buffer) {
    for frame in buffer.frames_mut() {
        let recording_frame = match model.receiver.pop() {
            Some(f) => f,
            None => [0.0, 0.0],
        };
        for (sample, recording_sample) in frame.iter_mut().zip(&recording_frame) {
            *sample = *recording_sample * 0.5;
        }
    }
}

fn key_pressed(_app: &App, model: &mut Model, key: Key) {
    match key {
        Key::Space => {
            model.in_stream.play().unwrap();
            model.out_stream.play().unwrap();
        }
        _ => {}
    }
}

fn view(app: &App, model: &Model, frame: Frame) {
    frame.clear(DIMGRAY);
}
<commit_msg>Refactor and add more comments<commit_after>//! Feeds back the input stream directly into the output stream
//!
//! You can play and pause the streams by pressing space key
use nannou::prelude::*;
use nannou_audio as audio;
use nannou_audio::Buffer;
use ringbuf::{Consumer, Producer, RingBuffer};

fn main() {
    nannou::app(model).run();
}

struct Model {
    in_stream: audio::Stream<InputModel>,
    out_stream: audio::Stream<OutputModel>,
}

struct InputModel {
    pub producer: Producer<[f32; 2]>,
}

struct OutputModel {
    pub consumer: Consumer<[f32; 2]>,
}

fn model(app: &App) -> Model {
    // Create a window to receive key pressed events.
    app.new_window()
        .key_pressed(key_pressed)
        .view(view)
        .build()
        .unwrap();

    // Initialise the audio host so we can spawn an audio stream.
    let audio_host = audio::Host::new();

    // Create a ring buffer and split it into producer and consumer
    let ring_buffer = RingBuffer::<[f32; 2]>::new(1024 * 2); // Add some latency
    let (prod, cons) = ring_buffer.split();

    // Create input model and input stream using that model
    let in_model = InputModel { producer: prod };
    let in_stream = audio_host
        .new_input_stream(in_model)
        .capture(pass_in)
        .build()
        .unwrap();

    // Create output model and output stream using that model
    let out_model = OutputModel { consumer: cons };
    let out_stream = audio_host
        .new_output_stream(out_model)
        .render(pass_out)
        .build()
        .unwrap();

    Model {
        in_stream,
        out_stream,
    }
}

fn pass_in(model: &mut InputModel, buffer: &Buffer) {
    for frame in buffer.frames() {
        model.producer.push([frame[0], frame[1]]).unwrap();
    }
}

fn pass_out(model: &mut OutputModel, buffer: &mut Buffer) {
    for frame in buffer.frames_mut() {
        let recording_frame = match model.consumer.pop() {
            Some(f) => f,
            None => [0.0, 0.0],
        };
        for (sample, recording_sample) in frame.iter_mut().zip(&recording_frame) {
            *sample = *recording_sample * 0.5;
        }
    }
}

fn key_pressed(_app: &App, model: &mut Model, key: Key) {
    match key {
        Key::Space => {
            if model.in_stream.is_paused() {
                model.in_stream.play().unwrap();
                model.out_stream.play().unwrap();
            } else {
                model.in_stream.pause().unwrap();
                model.out_stream.pause().unwrap();
            }
        }
        _ => {}
    }
}

fn view(_app: &App, _model: &Model, frame: Frame) {
    frame.clear(DIMGRAY);
}
<|endoftext|>


<commit_before>// Claxon -- A FLAC decoding library in Rust
// Copyright 2017 Ruud van Asseldonk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// A copy of the License has been included in the root of the repository.

// This file contains a minimal example of using Claxon and Hound to decode a
// flac file. This can be done more efficiently, but it is also more verbose.
// See the `decode` example for that.

extern crate claxon;
extern crate walkdir;
extern crate time;

use time::PreciseTime;
use std::io::{Seek, SeekFrom};

fn main() {
    use std::ffi::OsStr;
    let mut file_times_us = Vec::new();
    let mut bytes_per_sec = Vec::new();

    let wd = walkdir::WalkDir::new("testsamples/extra")
        .follow_links(true)
        .into_iter()
        .filter_map(|e| e.ok())
        .take(1024);

    for entry in wd {
        let path = entry.path();
        if path.is_file() && path.extension() == Some(OsStr::new("flac")) {
            let epoch = PreciseTime::now();
            let mut bytes = 0;

            // Read the file multiple times to amortize the walkdir cost.
            for _ in 0..10 {
                let reader = claxon::FlacReader::open(path).unwrap();

                // Note that these are not optimized away even though the results
                // are not used, because the expectation may fail.
                reader.get_tag("date").next().expect("date");
                reader.get_tag("originaldate").next().expect("originaldate");
                reader.get_tag("tracknumber").next().expect("tracknumber");
                reader.get_tag("tracktotal").next().expect("tracktotal");
                reader.get_tag("discnumber").next().expect("discnumber");
                reader.get_tag("disctotal").next().expect("disctotal");

                reader.get_tag("title").next().expect("title");
                reader.get_tag("album").next().expect("album");
                reader.get_tag("artist").next().expect("artist");
                reader.get_tag("albumartist").next().expect("albumartist");
                reader.get_tag("artistsort").next().expect("artistsort");
                reader.get_tag("albumartistsort").next().expect("albumartistsort");

                reader.get_tag("musicbrainz_trackid").next().expect("musicbrainz_trackid");
                reader.get_tag("musicbrainz_albumid").next().expect("musicbrainz_albumid");
                reader.get_tag("musicbrainz_artistid").next().expect("musicbrainz_artistid");
                reader.get_tag("musicbrainz_albumartistid").next().expect("musicbrainz_albumartistid");

                bytes += reader.into_inner().seek(SeekFrom::Current(0)).unwrap();
            }

            let duration_ns = epoch.to(PreciseTime::now()).num_nanoseconds().unwrap();
            file_times_us.push(duration_ns as f64 / 1000.0 / 10.0);
            bytes_per_sec.push(bytes as f64 / (duration_ns as f64 / 1.0e9) / 10.0);
        }
    }

    file_times_us.sort_by(|x, y| x.partial_cmp(y).unwrap());
    bytes_per_sec.sort_by(|x, y| x.partial_cmp(y).unwrap());

    let p10 = file_times_us[10 * file_times_us.len() / 100];
    let p50 = file_times_us[50 * file_times_us.len() / 100];
    let p90 = file_times_us[90 * file_times_us.len() / 100];
    let mean = file_times_us.iter().sum::<f64>() / (file_times_us.len() as f64);
    let p10_mibs = bytes_per_sec[10 * bytes_per_sec.len() / 100] / (1024.0 * 1024.0);

    // Output numbers compatible with tools/compare_benches.r.
    println!("{:>6.2} {:>6.2} {:>6.2} {:>6.2} {:>6.2}", p10, p50, p90, mean, p10_mibs);
}
<commit_msg>Keep more file descriptors open in metadata bench<commit_after>// Claxon -- A FLAC decoding library in Rust
// Copyright 2017 Ruud van Asseldonk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// A copy of the License has been included in the root of the repository.

// This file contains a minimal example of using Claxon and Hound to decode a
// flac file. This can be done more efficiently, but it is also more verbose.
// See the `decode` example for that.

extern crate claxon;
extern crate walkdir;
extern crate time;

use time::PreciseTime;
use std::io::{Seek, SeekFrom};

fn main() {
    use std::ffi::OsStr;
    let mut file_times_us = Vec::new();
    let mut bytes_per_sec = Vec::new();

    let wd = walkdir::WalkDir::new("testsamples/extra")
        .follow_links(true)
        .max_open(1024) // Prefer more file descriptors over allocating memory.
        .into_iter()
        .filter_map(|e| e.ok())
        .take(1024);

    for entry in wd {
        let path = entry.path();
        if path.is_file() && path.extension() == Some(OsStr::new("flac")) {
            let epoch = PreciseTime::now();
            let mut bytes = 0;

            // Read the file multiple times to amortize the walkdir cost.
            for _ in 0..10 {
                let reader = claxon::FlacReader::open(path).unwrap();

                // Note that these are not optimized away even though the results
                // are not used, because the expectation may fail.
                reader.get_tag("date").next().expect("date");
                reader.get_tag("originaldate").next().expect("originaldate");
                reader.get_tag("tracknumber").next().expect("tracknumber");
                reader.get_tag("tracktotal").next().expect("tracktotal");
                reader.get_tag("discnumber").next().expect("discnumber");
                reader.get_tag("disctotal").next().expect("disctotal");

                reader.get_tag("title").next().expect("title");
                reader.get_tag("album").next().expect("album");
                reader.get_tag("artist").next().expect("artist");
                reader.get_tag("albumartist").next().expect("albumartist");
                reader.get_tag("artistsort").next().expect("artistsort");
                reader.get_tag("albumartistsort").next().expect("albumartistsort");

                reader.get_tag("musicbrainz_trackid").next().expect("musicbrainz_trackid");
                reader.get_tag("musicbrainz_albumid").next().expect("musicbrainz_albumid");
                reader.get_tag("musicbrainz_artistid").next().expect("musicbrainz_artistid");
                reader.get_tag("musicbrainz_albumartistid").next().expect("musicbrainz_albumartistid");

                bytes += reader.into_inner().seek(SeekFrom::Current(0)).unwrap();
            }

            let duration_ns = epoch.to(PreciseTime::now()).num_nanoseconds().unwrap();
            file_times_us.push(duration_ns as f64 / 1000.0 / 10.0);
            bytes_per_sec.push(bytes as f64 / (duration_ns as f64 / 1.0e9) / 10.0);
        }
    }

    file_times_us.sort_by(|x, y| x.partial_cmp(y).unwrap());
    bytes_per_sec.sort_by(|x, y| x.partial_cmp(y).unwrap());

    let p10 = file_times_us[10 * file_times_us.len() / 100];
    let p50 = file_times_us[50 * file_times_us.len() / 100];
    let p90 = file_times_us[90 * file_times_us.len() / 100];
    let mean = file_times_us.iter().sum::<f64>() / (file_times_us.len() as f64);
    let p10_mibs = bytes_per_sec[10 * bytes_per_sec.len() / 100] / (1024.0 * 1024.0);

    // Output numbers compatible with tools/compare_benches.r.
    println!("{:>6.2} {:>6.2} {:>6.2} {:>6.2} {:>6.2}", p10, p50, p90, mean, p10_mibs);
}
<|endoftext|>


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

//! Message Authentication Codes.

/// `Mac` is the interface for MACs (Message Authentication Codes).
/// This interface should be used for authentication only, and not for other purposes
/// (for example, it should not be used to generate pseudorandom bytes).
pub trait Mac {
    // Compute message authentication code (MAC) for code data.
    fn compute_mac(&self, data: &[u8]) -> Result<Vec<u8>, crate::TinkError>;

    // Returns `()` if `mac` is a correct authentication code (MAC) for `data`,
    // otherwise it returns an error.
    fn verify_mac(&self, mac: &[u8], data: &[u8]) -> Result<(), crate::TinkError>;
}
<commit_msg>Add default implementation for Mac::verify_mac<commit_after>// Copyright 2020 The Tink-Rust Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

//! Message Authentication Codes.

/// `Mac` is the interface for MACs (Message Authentication Codes).
/// This interface should be used for authentication only, and not for other purposes
/// (for example, it should not be used to generate pseudorandom bytes).
pub trait Mac {
    // Compute message authentication code (MAC) for code data.
    fn compute_mac(&self, data: &[u8]) -> Result<Vec<u8>, crate::TinkError>;

    // Returns `()` if `mac` is a correct authentication code (MAC) for `data`,
    // otherwise it returns an error.
    fn verify_mac(&self, mac: &[u8], data: &[u8]) -> Result<(), crate::TinkError> {
        let computed = self.compute_mac(data)?;
        if crate::subtle::constant_time_compare(mac, &computed) {
            Ok(())
        } else {
            Err("Invalid MAC".into())
        }
    }
}
<|endoftext|>


<commit_before>use std::io::{self, Read, Write};
use std::sync::Arc;

use futures::{Future, Wake, Tokens, TOKENS_ALL, Poll};
use futures::stream::{Stream, Fuse};
use futuremio::*;

pub trait Parse: Sized + Send + 'static {
    type Parser: Default + Send + 'static;
    type Error: Send + 'static + From<io::Error>;

    fn parse(parser: &mut Self::Parser,
             buf: &Arc<Vec<u8>>,
             offset: usize)
             -> Option<Result<(Self, usize), Self::Error>>;
}

/// A stream for parsing from an underlying reader, using an unbounded internal
/// buffer.
pub struct ParseStream<R, P: Parse> {
    source: R,
    source_ready: ReadinessStream,
    read_ready: bool,
    parser: P::Parser,
    buf: Arc<Vec<u8>>,

    // how far into the buffer have we parsed? note: we drain lazily
    pos: usize,

    // is there new data that we need to try to parse?
    need_parse: bool,

    // has `source` yielded an EOF?
    eof: bool,
}

impl<R, P> ParseStream<R, P>
    where R: Read + Send + 'static,
          P: Parse
{
    pub fn new(source: R, source_ready: ReadinessStream) -> ParseStream<R, P> {
        ParseStream {
            source: source,
            source_ready: source_ready,
            read_ready: false,
            parser: Default::default(),
            buf: Arc::new(Vec::with_capacity(2048)),
            pos: 0,
            need_parse: false,
            eof: false,
        }
    }
}

// TODO: move this into method
fn read<R: Read>(socket: &mut R, input: &mut Vec<u8>) -> io::Result<(usize, bool)> {
    loop {
        match socket.read(unsafe { slice_to_end(input) }) {
            Ok(0) => {
                trace!("socket EOF");
                return Ok((0, true))
            }
            Ok(n) => {
                trace!("socket read {} bytes", n);
                unsafe {
                    let len = input.len();
                    input.set_len(len + n);
                }
                return Ok((n, false));
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => return Ok((0, false)),
            Err(e) => return Err(e),
        }
    }

    unsafe fn slice_to_end(v: &mut Vec<u8>) -> &mut [u8] {
        use std::slice;
        if v.capacity() == 0 {
            v.reserve(16);
        }
        if v.capacity() == v.len() {
            v.reserve(1);
        }
        slice::from_raw_parts_mut(v.as_mut_ptr().offset(v.len() as isize),
                                  v.capacity() - v.len())
    }
}

impl<R, P> Stream for ParseStream<R, P>
    where R: Read + Send + 'static,
          P: Parse
{
    type Item = P;
    type Error = P::Error;

    fn poll(&mut self, tokens: &Tokens) -> Poll<Option<P>, P::Error> {
        loop {
            if self.need_parse {
                debug!("attempting to parse");
                match P::parse(&mut self.parser, &self.buf, self.pos) {
                    Some(Ok((i, n))) => {
                        self.pos += n;
                        return Poll::Ok(Some(i))
                    }
                    Some(Err(e)) => return Poll::Err(e),
                    None => {
                        self.need_parse = false;
                    }
                }

                // Fast path if we can get mutable access to our own current
                // buffer.
                let mut drained = false;
                if let Some(buf) = Arc::get_mut(&mut self.buf) {
                    buf.drain(..self.pos);
                    drained = true;
                }

                // If we couldn't get access above then we give ourself a new
                // buffer here.
                if !drained {
                    let mut v = Vec::with_capacity(2048);
                    v.extend_from_slice(&self.buf[self.pos..]);
                    self.buf = Arc::new(v);
                }
                self.pos = 0;
            }

            if self.eof {
                return Poll::Ok(None)
            }

            if !self.read_ready {
                match try_poll!(self.source_ready.poll(tokens)) {
                    Err(e) => return Poll::Err(e.into()),
                    Ok(Some(())) => self.read_ready = true,
                    Ok(None) => unreachable!(),
                }
            }

            let buf = Arc::get_mut(&mut self.buf).unwrap();
            match read(&mut self.source, buf) {
                Ok((n, eof)) => {
                    self.eof = eof;
                    self.need_parse = self.need_parse || n > 0;
                    self.read_ready = n > 0;
                }
                Err(e) => return Poll::Err(e.into()),
            }
        }
    }

    fn schedule(&mut self, wake: &Arc<Wake>) {
        // TODO: think through this carefully...
        if self.need_parse {
            // Empty tokens because in a `need_parse` situation, we'll attempt
            // to parse regardless of tokens
            wake.wake(&Tokens::empty())
        } else {
            self.source_ready.schedule(wake)
        }
    }
}

// TODO: make this a method
fn write<W: Write>(sink: &mut W, buf: &mut Vec<u8>) -> io::Result<()> {
    loop {
        match sink.write(&buf) {
            Ok(0) => {
                // TODO: copied from mio example, clean up
                return Err(io::Error::new(io::ErrorKind::Other, "early eof2"));
            }
            Ok(n) => {
                // TODO: consider draining more lazily, i.e. only just before
                //       returning
                buf.drain(..n);
                if buf.len() == 0 {
                    return Ok(());
                }
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => return Ok(()),
            Err(e) => return Err(e),
        }
    }
}

pub trait Serialize: Send + 'static {
    fn serialize(&self, buf: &mut Vec<u8>);
}

/// Serialize a stream of items into a writer, using an unbounded internal
/// buffer.
///
/// Represented as a future which yields () on successfully writing the entire
/// stream (which requires the stream to terminate), or an error if there is any
/// error along the way.
pub struct StreamWriter<W, S> {
    sink: W,
    sink_ready: ReadinessStream,
    write_ready: bool,
    items: Fuse<S>,
    buf: Vec<u8>,
}

impl<W, S> StreamWriter<W, S>
    where W: Write + Send + 'static,
          S: Stream,
          S::Item: Serialize,
          S::Error: From<io::Error>
{
    pub fn new(sink: W, sink_ready: ReadinessStream, items: S) -> StreamWriter<W, S> {
        StreamWriter {
            sink: sink,
            sink_ready: sink_ready,
            write_ready: false,
            items: items.fuse(),
            buf: Vec::with_capacity(2048),
        }
    }
}

impl<W, S> Future for StreamWriter<W, S>
    where W: Write + Send + 'static,
          S: Stream,
          S::Item: Serialize,
          S::Error: From<io::Error>
{
    type Item = ();
    type Error = S::Error;

    fn poll(&mut self, tokens: &Tokens) -> Poll<(), S::Error> {
        // make sure to pass down `tokens` only on the *first* poll for items
        let mut tokens_for_items = tokens;
        loop {
            match self.items.poll(tokens_for_items) {
                Poll::Err(e) => return Poll::Err(e),
                Poll::Ok(Some(item)) => {
                    debug!("got an item to serialize!");
                    item.serialize(&mut self.buf);
                    tokens_for_items = &TOKENS_ALL;
                }
                Poll::Ok(None) |
                Poll::NotReady => break,
            }
        }

        // TODO: optimization for case where we just transitioned from no bytes
        // to write to having bytes to write; in that case, we should try to
        // write regardless of sink_ready.poll, because we haven't asked for a
        // readiness notifcation. Saves a trip around the event loop.

        while self.buf.len() > 0 {
            if !self.write_ready {
                match try_poll!(self.sink_ready.poll(tokens)) {
                    Err(e) => return Poll::Err(e.into()),
                    Ok(Some(())) => self.write_ready = true,

                    // TODO: this should translate to an error
                    Ok(None) => return Poll::NotReady,
                }
            }

            debug!("trying to write some data");
            let before = self.buf.len();
            if let Err(e) = write(&mut self.sink, &mut self.buf) {
                return Poll::Err(e.into())
            }
            if before == self.buf.len() {
                self.write_ready = false;
            }
        }

        if self.items.is_done() {
            // Nothing more to write to sink, and no more incoming items; we're done!
            Poll::Ok(())
        } else {
            Poll::NotReady
        }
    }

    fn schedule(&mut self, wake: &Arc<Wake>) {
        // wake up on writability only if we have something to write
        if self.buf.len() > 0 {
            self.sink_ready.schedule(wake);
        }

        // for now, we are always happy to write more items into our unbounded buffer
        self.items.schedule(wake);
    }
}
<commit_msg>Pull out write readiness in StreamWriter ASAP<commit_after>use std::io::{self, Read, Write};
use std::sync::Arc;

use futures::{Future, Wake, Tokens, TOKENS_ALL, Poll};
use futures::stream::{Stream, Fuse};
use futuremio::*;

pub trait Parse: Sized + Send + 'static {
    type Parser: Default + Send + 'static;
    type Error: Send + 'static + From<io::Error>;

    fn parse(parser: &mut Self::Parser,
             buf: &Arc<Vec<u8>>,
             offset: usize)
             -> Option<Result<(Self, usize), Self::Error>>;
}

/// A stream for parsing from an underlying reader, using an unbounded internal
/// buffer.
pub struct ParseStream<R, P: Parse> {
    source: R,
    source_ready: ReadinessStream,
    read_ready: bool,
    parser: P::Parser,
    buf: Arc<Vec<u8>>,

    // how far into the buffer have we parsed? note: we drain lazily
    pos: usize,

    // is there new data that we need to try to parse?
    need_parse: bool,

    // has `source` yielded an EOF?
    eof: bool,
}

impl<R, P> ParseStream<R, P>
    where R: Read + Send + 'static,
          P: Parse
{
    pub fn new(source: R, source_ready: ReadinessStream) -> ParseStream<R, P> {
        ParseStream {
            source: source,
            source_ready: source_ready,
            read_ready: false,
            parser: Default::default(),
            buf: Arc::new(Vec::with_capacity(2048)),
            pos: 0,
            need_parse: false,
            eof: false,
        }
    }
}

// TODO: move this into method
fn read<R: Read>(socket: &mut R, input: &mut Vec<u8>) -> io::Result<(usize, bool)> {
    loop {
        match socket.read(unsafe { slice_to_end(input) }) {
            Ok(0) => {
                trace!("socket EOF");
                return Ok((0, true))
            }
            Ok(n) => {
                trace!("socket read {} bytes", n);
                unsafe {
                    let len = input.len();
                    input.set_len(len + n);
                }
                return Ok((n, false));
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => return Ok((0, false)),
            Err(e) => return Err(e),
        }
    }

    unsafe fn slice_to_end(v: &mut Vec<u8>) -> &mut [u8] {
        use std::slice;
        if v.capacity() == 0 {
            v.reserve(16);
        }
        if v.capacity() == v.len() {
            v.reserve(1);
        }
        slice::from_raw_parts_mut(v.as_mut_ptr().offset(v.len() as isize),
                                  v.capacity() - v.len())
    }
}

impl<R, P> Stream for ParseStream<R, P>
    where R: Read + Send + 'static,
          P: Parse
{
    type Item = P;
    type Error = P::Error;

    fn poll(&mut self, tokens: &Tokens) -> Poll<Option<P>, P::Error> {
        loop {
            if self.need_parse {
                debug!("attempting to parse");
                match P::parse(&mut self.parser, &self.buf, self.pos) {
                    Some(Ok((i, n))) => {
                        self.pos += n;
                        return Poll::Ok(Some(i))
                    }
                    Some(Err(e)) => return Poll::Err(e),
                    None => {
                        self.need_parse = false;
                    }
                }

                // Fast path if we can get mutable access to our own current
                // buffer.
                let mut drained = false;
                if let Some(buf) = Arc::get_mut(&mut self.buf) {
                    buf.drain(..self.pos);
                    drained = true;
                }

                // If we couldn't get access above then we give ourself a new
                // buffer here.
                if !drained {
                    let mut v = Vec::with_capacity(2048);
                    v.extend_from_slice(&self.buf[self.pos..]);
                    self.buf = Arc::new(v);
                }
                self.pos = 0;
            }

            if self.eof {
                return Poll::Ok(None)
            }

            if !self.read_ready {
                match try_poll!(self.source_ready.poll(tokens)) {
                    Err(e) => return Poll::Err(e.into()),
                    Ok(Some(())) => self.read_ready = true,
                    Ok(None) => unreachable!(),
                }
            }

            let buf = Arc::get_mut(&mut self.buf).unwrap();
            match read(&mut self.source, buf) {
                Ok((n, eof)) => {
                    self.eof = eof;
                    self.need_parse = self.need_parse || n > 0;
                    self.read_ready = n > 0;
                }
                Err(e) => return Poll::Err(e.into()),
            }
        }
    }

    fn schedule(&mut self, wake: &Arc<Wake>) {
        // TODO: think through this carefully...
        if self.need_parse {
            // Empty tokens because in a `need_parse` situation, we'll attempt
            // to parse regardless of tokens
            wake.wake(&Tokens::empty())
        } else {
            self.source_ready.schedule(wake)
        }
    }
}

// TODO: make this a method
fn write<W: Write>(sink: &mut W, buf: &mut Vec<u8>) -> io::Result<()> {
    loop {
        match sink.write(&buf) {
            Ok(0) => {
                // TODO: copied from mio example, clean up
                return Err(io::Error::new(io::ErrorKind::Other, "early eof2"));
            }
            Ok(n) => {
                // TODO: consider draining more lazily, i.e. only just before
                //       returning
                buf.drain(..n);
                if buf.len() == 0 {
                    return Ok(());
                }
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => return Ok(()),
            Err(e) => return Err(e),
        }
    }
}

pub trait Serialize: Send + 'static {
    fn serialize(&self, buf: &mut Vec<u8>);
}

/// Serialize a stream of items into a writer, using an unbounded internal
/// buffer.
///
/// Represented as a future which yields () on successfully writing the entire
/// stream (which requires the stream to terminate), or an error if there is any
/// error along the way.
pub struct StreamWriter<W, S> {
    sink: W,
    sink_ready: ReadinessStream,
    write_ready: bool,
    items: Fuse<S>,
    buf: Vec<u8>,
}

impl<W, S> StreamWriter<W, S>
    where W: Write + Send + 'static,
          S: Stream,
          S::Item: Serialize,
          S::Error: From<io::Error>
{
    pub fn new(sink: W, sink_ready: ReadinessStream, items: S) -> StreamWriter<W, S> {
        StreamWriter {
            sink: sink,
            sink_ready: sink_ready,
            write_ready: false,
            items: items.fuse(),
            buf: Vec::with_capacity(2048),
        }
    }
}

impl<W, S> Future for StreamWriter<W, S>
    where W: Write + Send + 'static,
          S: Stream,
          S::Item: Serialize,
          S::Error: From<io::Error>
{
    type Item = ();
    type Error = S::Error;

    fn poll(&mut self, tokens: &Tokens) -> Poll<(), S::Error> {
        // First up, grab any responses we have and serialize them into our
        // local buffer. Make sure to pass down `tokens` only on the *first*
        // poll for items
        //
        // TODO: limit this loop on the size of `self.buf`.
        let mut tokens_for_items = tokens;
        loop {
            match self.items.poll(tokens_for_items) {
                Poll::Err(e) => return Poll::Err(e),
                Poll::Ok(Some(item)) => {
                    debug!("got an item to serialize!");
                    item.serialize(&mut self.buf);
                    tokens_for_items = &TOKENS_ALL;
                }
                Poll::Ok(None) |
                Poll::NotReady => break,
            }
        }

        // TODO: optimization for case where we just transitioned from no bytes
        // to write to having bytes to write; in that case, we should try to
        // write regardless of sink_ready.poll, because we haven't asked for a
        // readiness notifcation. Saves a trip around the event loop.

        // Now that we might have some responses to write, try to write them.
        // Note that we always execute at least one iteration of this loop to
        // attempt to pull out write readiness ASAP. If a response is being
        // calculated we can learn that we're ready for a write immediately and
        // write as soon as it's ready when it comes around.
        //
        // If, however, we have no data to write and there are no more responses
        // that will come out, then we don't need to wait for write readiness.
        loop {
            if !self.write_ready && (self.buf.len() > 0 || !self.items.is_done()) {
                match try_poll!(self.sink_ready.poll(tokens)) {
                    Err(e) => return Poll::Err(e.into()),
                    Ok(Some(())) => self.write_ready = true,

                    // TODO: this should translate to an error
                    Ok(None) => return Poll::NotReady,
                }
            }

            // If we're here then either
            //
            // (a) write_ready is true
            // (b) the response stream is done
            //
            // If we have an empty fuffer for either of these cases then we have
            // nothing left to do, and are either done with iterating or need to
            // do some more work.
            if self.buf.len() == 0 {
                if self.items.is_done() {
                    return Poll::Ok(())
                } else {
                    return Poll::NotReady
                }
            }

            debug!("trying to write some data");
            let before = self.buf.len();
            if let Err(e) = write(&mut self.sink, &mut self.buf) {
                return Poll::Err(e.into())
            }

            // If we didn't fail but we also didn't write anything, then we're
            // no longer ready to write and we may need to poll some more.
            if before == self.buf.len() {
                self.write_ready = false;
            }
        }
    }

    fn schedule(&mut self, wake: &Arc<Wake>) {
        // wake up on writability only if we have something to write
        if self.buf.len() > 0 {
            self.sink_ready.schedule(wake);
        }

        // for now, we are always happy to write more items into our unbounded buffer
        self.items.schedule(wake);
    }
}
<|endoftext|>


<commit_before>//! Fractal Global Location module
//!
//! This module holds the Fractal Global Address, and Geological location data type objects.

#[cfg(feature = "json-types")]
use rustc_serialize::json;

/// The particulars of the place where an organization or person resides
#[derive(PartialEq, Debug, Clone, RustcEncodable, RustcDecodable)]
pub struct Address {
    /// First Address
    address1: String,
    /// Second Address
    address2: Option<String>,
    /// The City
    city: String,
    /// The State
    state: String,
    /// The Zip Code
    zip: String,
    /// The Country
    country: String,
}

impl Address {
    /// Creates a new `Address`
    pub fn new<S: AsRef<str>>(address1: S,
                              address2: Option<S>,
                              city: S,
                              state: S,
                              zip: S,
                              country: S)
                              -> Address {
        Address {
            address1: address1.as_ref().to_owned(),
            address2: match address2 {
                Some(s) => Some(s.as_ref().to_owned()),
                None => None,
            },
            city: city.as_ref().to_owned(),
            state: state.as_ref().to_owned(),
            zip: zip.as_ref().to_owned(),
            country: country.as_ref().to_owned(),
        }
    }

    /// Returns address line 1
    pub fn get_address1(&self) -> &String {
        &self.address1
    }

    /// Returns address line 2
    pub fn get_address2(&self) -> Option<&String> {
        self.address2.as_ref()
    }

    /// Returns the city
    pub fn get_city(&self) -> &str {
        &self.city
    }

    /// Returns the state
    pub fn get_state(&self) -> &str {
        &self.state
    }

    /// Returns the zip code
    pub fn get_zip(&self) -> &String {
        &self.zip
    }

    /// Returns the country
    pub fn get_country(&self) -> &String {
        &self.country
    }
}

#[cfg(feature = "json-types")]
impl json::ToJson for Address {
    fn to_json(&self) -> json::Json {
        let mut object = json::Object::new();
        let _ = object.insert(String::from("address1"), self.address1.to_json());
        let _ = object.insert(String::from("address2"), self.address2.to_json());
        let _ = object.insert(String::from("city"), self.city.to_json());
        let _ = object.insert(String::from("state"), self.state.to_json());
        let _ = object.insert(String::from("zip"), self.zip.to_json());
        let _ = object.insert(String::from("country"), self.country.to_json());
        json::Json::Object(object)
    }
}
<commit_msg>Changed results of address getters<commit_after>//! Fractal Global Location module
//!
//! This module holds the Fractal Global Address, and Geological location data type objects.

#[cfg(feature = "json-types")]
use rustc_serialize::json;

/// The particulars of the place where an organization or person resides
#[derive(PartialEq, Debug, Clone, RustcEncodable, RustcDecodable)]
pub struct Address {
    /// First Address
    address1: String,
    /// Second Address
    address2: Option<String>,
    /// The City
    city: String,
    /// The State
    state: String,
    /// The Zip Code
    zip: String,
    /// The Country
    country: String,
}

impl Address {
    /// Creates a new `Address`
    pub fn new<S: AsRef<str>>(address1: S,
                              address2: Option<S>,
                              city: S,
                              state: S,
                              zip: S,
                              country: S)
                              -> Address {
        Address {
            address1: address1.as_ref().to_owned(),
            address2: match address2 {
                Some(s) => Some(s.as_ref().to_owned()),
                None => None,
            },
            city: city.as_ref().to_owned(),
            state: state.as_ref().to_owned(),
            zip: zip.as_ref().to_owned(),
            country: country.as_ref().to_owned(),
        }
    }

    /// Returns address line 1
    pub fn get_address1(&self) -> &str {
        &self.address1
    }

    /// Returns address line 2
    pub fn get_address2(&self) -> Option<&str> {
        match self.address2 {
            Some(ref addr2) => Some(addr2),
            None => None,
        }
    }

    /// Returns the city
    pub fn get_city(&self) -> &str {
        &self.city
    }

    /// Returns the state
    pub fn get_state(&self) -> &str {
        &self.state
    }

    /// Returns the zip code
    pub fn get_zip(&self) -> &str {
        &self.zip
    }

    /// Returns the country
    pub fn get_country(&self) -> &str {
        &self.country
    }
}

#[cfg(feature = "json-types")]
impl json::ToJson for Address {
    fn to_json(&self) -> json::Json {
        let mut object = json::Object::new();
        let _ = object.insert(String::from("address1"), self.address1.to_json());
        let _ = object.insert(String::from("address2"), self.address2.to_json());
        let _ = object.insert(String::from("city"), self.city.to_json());
        let _ = object.insert(String::from("state"), self.state.to_json());
        let _ = object.insert(String::from("zip"), self.zip.to_json());
        let _ = object.insert(String::from("country"), self.country.to_json());
        json::Json::Object(object)
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

use std::ops::{
    BitXor,
    Deref,
};
use vector::Vector;

pub use self::mat::Mat;

pub mod mat;
pub mod vector;
pub mod matrix_vector;
pub mod matrix;

pub enum Trans<A> {
    T(A),
    H(A),
}

impl<A> Deref for Trans<A> {
    type Target = A;

    fn deref(&self) -> &A {
        match self {
            &Trans::T(ref v) => v,
            &Trans::H(ref v) => v,
        }
    }
}

pub enum Marker {
    T,
    H,
}

impl<'a, T> BitXor<Marker> for &'a Vector<T>
{
    type Output = Trans<&'a Vector<T>>;

    fn bitxor(self, m: Marker) -> Trans<&'a Vector<T>> {
        match m {
            Marker::T => Trans::T(self),
            Marker::H => Trans::H(self),
        }
    }
}
<commit_msg>Transpose matrices<commit_after>// Copyright 2015 Michael Yang. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

use std::ops::{
    BitXor,
    Deref,
};
use matrix::Matrix;
use vector::Vector;

pub use self::mat::Mat;

pub mod mat;
pub mod vector;
pub mod matrix_vector;
pub mod matrix;

pub enum Trans<A> {
    T(A),
    H(A),
}

impl<A> Deref for Trans<A> {
    type Target = A;

    fn deref(&self) -> &A {
        match self {
            &Trans::T(ref v) => v,
            &Trans::H(ref v) => v,
        }
    }
}

pub enum Marker {
    T,
    H,
}

impl<'a, T> BitXor<Marker> for &'a Vector<T>
{
    type Output = Trans<&'a Vector<T>>;

    fn bitxor(self, m: Marker) -> Trans<&'a Vector<T>> {
        match m {
            Marker::T => Trans::T(self),
            Marker::H => Trans::H(self),
        }
    }
}

impl<'a, T> BitXor<Marker> for &'a Matrix<T>
{
    type Output = Trans<&'a Matrix<T>>;

    fn bitxor(self, m: Marker) -> Trans<&'a Matrix<T>> {
        match m {
            Marker::T => Trans::T(self),
            Marker::H => Trans::H(self),
        }
    }
}
<|endoftext|>


<commit_before>use std::borrow::Borrow;
use std::cmp::min;
use std::io::Write;
use std::io;

use rustbox::{RustBox, Style, Color};

static LINEBREAK : char = '↳';

pub struct MsgArea {
    msgs   : Vec<Line>,

    width  : i32,
    height : i32,

    /// Vertical scroll
    scroll : i32,

    // TODO: logging
}

struct Line {
    /// A line. INVARIANT: Not longer than the width of the widget.
    msg : String,

    /// Is this continuation of previous line?
    continuation : bool,
}

impl MsgArea {
    pub fn new(width : i32, height : i32) -> MsgArea {
        MsgArea {
            msgs: Vec::new(),
            width: width,
            height: height,
            scroll: 0,
        }
    }

    pub fn add_msg(&mut self, msg : &Vec<char>) {
        // Decide whether to scroll
        let need_to_scroll = self.scroll + self.height == self.msgs.len() as i32;

        // Add the line(s)
        let mut msg_slice : &[char] = msg.borrow();
        let mut lines : Vec<Line> = Vec::with_capacity(1);
        while msg_slice.len() != 0 {
            let first_line = lines.len() == 0;
            let split = if first_line { self.width } else { self.width - 1 };

            let (line, rest) = msg_slice.split_at(min(msg_slice.len(), split as usize));
            msg_slice = rest;

            if first_line {
                lines.push(Line {
                    msg: line.iter().cloned().collect(),
                    continuation: false,
                });
            } else {
                let mut string : String = line.iter().cloned().collect();
                string.insert(0, LINEBREAK);
                lines.push(Line {
                    msg: string,
                    continuation: true,
                });
            }
        }

        if need_to_scroll {
            self.scroll += lines.len() as i32;
        }

        self.msgs.append(&mut lines);
    }

    pub fn add_msg_str(&mut self, msg_str : &str) {
        writeln!(&mut io::stderr(), "adding msg: {:?}", msg_str);
        self.add_msg(&msg_str.chars().collect());
    }

    pub fn draw(&self, rustbox : &RustBox, pos_x : i32, pos_y : i32) {
        let mut row = self.height - 1;
        let mut line_idx = min(self.scroll + self.height, self.msgs.len() as i32 - 1);
        while line_idx >= 0 {
            rustbox.print(pos_x as usize, (pos_y + row) as usize,
                          Style::empty(), Color::Blue, Color::Default,
                          &self.msgs[line_idx as usize].msg);
            row -= 1;
            line_idx -= 1;
        }
    }
}
<commit_msg>slightly improve continuation line rendering<commit_after>use std::borrow::Borrow;
use std::cmp::min;
use std::io::Write;
use std::io;

use rustbox::{RustBox, Style, Color};

static LINEBREAK : char = '↳';

pub struct MsgArea {
    msgs   : Vec<Line>,

    width  : i32,
    height : i32,

    /// Vertical scroll
    scroll : i32,

    // TODO: logging
}

struct Line {
    /// A line. INVARIANT: Not longer than the width of the widget.
    msg : String,

    /// Is this continuation of previous line?
    continuation : bool,
}

impl MsgArea {
    pub fn new(width : i32, height : i32) -> MsgArea {
        MsgArea {
            msgs: Vec::new(),
            width: width,
            height: height,
            scroll: 0,
        }
    }

    pub fn add_msg(&mut self, msg : &Vec<char>) {
        // Decide whether to scroll
        let need_to_scroll = self.scroll + self.height == self.msgs.len() as i32;

        // Add the line(s)
        let mut msg_slice : &[char] = msg.borrow();
        let mut lines : Vec<Line> = Vec::with_capacity(1);
        while msg_slice.len() != 0 {
            let first_line = lines.len() == 0;
            let split = if first_line { self.width } else { self.width - 1 };

            let (line, rest) = msg_slice.split_at(min(msg_slice.len(), split as usize));
            msg_slice = rest;

            lines.push(Line {
                msg: line.iter().cloned().collect(),
                continuation: !first_line,
            });
        }

        if need_to_scroll {
            self.scroll += lines.len() as i32;
        }

        self.msgs.append(&mut lines);
    }

    pub fn add_msg_str(&mut self, msg_str : &str) {
        writeln!(&mut io::stderr(), "adding msg: {:?}", msg_str);
        self.add_msg(&msg_str.chars().collect());
    }

    pub fn draw(&self, rustbox : &RustBox, pos_x : i32, pos_y : i32) {
        let mut row = self.height - 1;
        let mut line_idx = min(self.scroll + self.height, self.msgs.len() as i32 - 1);
        while line_idx >= 0 {
            let line = &self.msgs[line_idx as usize];

            if line.continuation {
                rustbox.print_char(pos_x as usize, (pos_y + row) as usize,
                                   Style::empty(), Color::Blue, Color::Default,
                                   LINEBREAK);
            }

            let pos_x = if line.continuation { pos_x + 1 } else { pos_x };

            rustbox.print(pos_x as usize, (pos_y + row) as usize,
                          Style::empty(), Color::Blue, Color::Default,
                          &line.msg);

            row -= 1;
            line_idx -= 1;
        }
    }
}
<|endoftext|>


<commit_before>//! The nodes.

use std::collections::hash_map::DefaultHasher;
use std::collections::HashMap;
use std::fmt;

mod comment;
mod text;
mod value;

pub use self::comment::Comment;
pub use self::text::Text;
pub use self::value::Value;

/// Attributes.
pub type Attributes = HashMap<String, Value>;

/// Child nodes.
pub type Children = Vec<Box<dyn Node>>;

/// A node.
pub trait Node: 'static + fmt::Debug + fmt::Display + NodeDefaultHash + NodeClone {
    /// Append a child node.
    fn append<T>(&mut self, _: T)
    where
        Self: Sized,
        T: Node;

    /// Assign an attribute.
    fn assign<T, U>(&mut self, _: T, _: U)
    where
        Self: Sized,
        T: Into<String>,
        U: Into<Value>;
}

#[doc(hidden)]
pub trait NodeClone {
    fn clone(&self) -> Box<dyn Node>;
}

impl<T> NodeClone for T
where
    T: Node + Clone,
{
    #[inline]
    fn clone(&self) -> Box<dyn Node> {
        Box::new(Clone::clone(self))
    }
}

impl Clone for Box<dyn Node> {
    #[inline]
    fn clone(&self) -> Self {
        NodeClone::clone(&**self)
    }
}

#[doc(hidden)]
pub trait NodeDefaultHash {
    /// Get default hash
    fn default_hash(&self, state: &mut DefaultHasher);
}

impl NodeDefaultHash for Box<dyn Node> {
    fn default_hash(&self, state: &mut DefaultHasher) {
        NodeDefaultHash::default_hash(&**self, state)
    }
}

macro_rules! node(
    ($struct_name:ident::$field_name:ident) => (
        impl $struct_name {
            /// Append a node.
            pub fn add<T>(mut self, node: T) -> Self
            where
                T: crate::node::Node,
            {
                crate::node::Node::append(&mut self, node);
                self
            }

            /// Assign an attribute.
            #[inline]
            pub fn set<T, U>(mut self, name: T, value: U) -> Self
            where
                T: Into<String>,
                U: Into<crate::node::Value>,
            {
                crate::node::Node::assign(&mut self, name, value);
                self
            }

            #[inline]
            pub fn get_inner(&self) -> &Element {
                &self.inner
            }
        }

        impl crate::node::Node for $struct_name {
            #[inline]
            fn append<T>(&mut self, node: T)
            where
                T: crate::node::Node,
            {
                self.$field_name.append(node);
            }

            #[inline]
            fn assign<T, U>(&mut self, name: T, value: U)
            where
                T: Into<String>,
                U: Into<crate::node::Value>,
            {
                self.$field_name.assign(name, value);
            }
        }

        impl ::std::fmt::Display for $struct_name {
            #[inline]
            fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                self.$field_name.fmt(formatter)
            }
        }
    );
);

pub mod element;
<commit_msg>Hide get_inner<commit_after>//! The nodes.

use std::collections::hash_map::DefaultHasher;
use std::collections::HashMap;
use std::fmt;

mod comment;
mod text;
mod value;

pub use self::comment::Comment;
pub use self::text::Text;
pub use self::value::Value;

/// Attributes.
pub type Attributes = HashMap<String, Value>;

/// Child nodes.
pub type Children = Vec<Box<dyn Node>>;

/// A node.
pub trait Node: 'static + fmt::Debug + fmt::Display + NodeDefaultHash + NodeClone {
    /// Append a child node.
    fn append<T>(&mut self, _: T)
    where
        Self: Sized,
        T: Node;

    /// Assign an attribute.
    fn assign<T, U>(&mut self, _: T, _: U)
    where
        Self: Sized,
        T: Into<String>,
        U: Into<Value>;
}

#[doc(hidden)]
pub trait NodeClone {
    fn clone(&self) -> Box<dyn Node>;
}

impl<T> NodeClone for T
where
    T: Node + Clone,
{
    #[inline]
    fn clone(&self) -> Box<dyn Node> {
        Box::new(Clone::clone(self))
    }
}

impl Clone for Box<dyn Node> {
    #[inline]
    fn clone(&self) -> Self {
        NodeClone::clone(&**self)
    }
}

#[doc(hidden)]
pub trait NodeDefaultHash {
    /// Get default hash
    fn default_hash(&self, state: &mut DefaultHasher);
}

impl NodeDefaultHash for Box<dyn Node> {
    fn default_hash(&self, state: &mut DefaultHasher) {
        NodeDefaultHash::default_hash(&**self, state)
    }
}

macro_rules! node(
    ($struct_name:ident::$field_name:ident) => (
        impl $struct_name {
            /// Append a node.
            pub fn add<T>(mut self, node: T) -> Self
            where
                T: crate::node::Node,
            {
                crate::node::Node::append(&mut self, node);
                self
            }

            /// Assign an attribute.
            #[inline]
            pub fn set<T, U>(mut self, name: T, value: U) -> Self
            where
                T: Into<String>,
                U: Into<crate::node::Value>,
            {
                crate::node::Node::assign(&mut self, name, value);
                self
            }

            #[doc(hidden)]
            #[inline]
            pub fn get_inner(&self) -> &Element {
                &self.inner
            }
        }

        impl crate::node::Node for $struct_name {
            #[inline]
            fn append<T>(&mut self, node: T)
            where
                T: crate::node::Node,
            {
                self.$field_name.append(node);
            }

            #[inline]
            fn assign<T, U>(&mut self, name: T, value: U)
            where
                T: Into<String>,
                U: Into<crate::node::Value>,
            {
                self.$field_name.assign(name, value);
            }
        }

        impl ::std::fmt::Display for $struct_name {
            #[inline]
            fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                self.$field_name.fmt(formatter)
            }
        }
    );
);

pub mod element;
<|endoftext|>


<commit_before>/// Represents a position within a substrate.
/// Each position coordinate is mapped to an input of a CPPN.
pub trait Position {
    fn coords(&self) -> &[f64];
    fn distance(&self, other: &Self) -> f64;
}

pub struct Position2d([f64; 2]);

impl Position2d {
    #[inline(always)]
    pub fn new(x: f64, y: f64) -> Position2d {
        Position2d([x, y])
    }

    #[inline(always)]
    pub fn x(&self) -> f64 {
        self.0[0]
    }

    #[inline(always)]
    pub fn y(&self) -> f64 {
        self.0[1]
    }
}

impl Position for Position2d {
    #[inline(always)]
    fn coords(&self) -> &[f64] {
        &self.0
    }

    #[inline]
    fn distance(&self, other: &Self) -> f64 {
        ((self.x() - other.x()).powi(2) + (self.y() - other.y()).powi(2)).sqrt()
    }
}
<commit_msg>Add interpolation methods<commit_after>/// Represents a position within a substrate.
/// Each position coordinate is mapped to an input of a CPPN.
pub trait Position {
    fn coords(&self) -> &[f64];
    fn distance(&self, other: &Self) -> f64;

    /// Linearly interpolates between `self` and `other`.
    /// For t = 0.0 this should return `self`. For t = 1.0 this
    /// should return `other`.
    fn interpolate(&self, other: &Self, t: f64) -> Self;

    fn interpolate_multi(&self, other: &Self, t: &Self) -> Self;
}

pub struct Position2d([f64; 2]);

impl Position2d {
    #[inline(always)]
    pub fn new(x: f64, y: f64) -> Position2d {
        Position2d([x, y])
    }

    #[inline(always)]
    pub fn x(&self) -> f64 {
        self.0[0]
    }

    #[inline(always)]
    pub fn y(&self) -> f64 {
        self.0[1]
    }

    #[inline(always)]
    pub fn xy(&self) -> (f64, f64) {
        (self.0[0], self.0[1])
    }

}

impl Position for Position2d {
    #[inline(always)]
    fn coords(&self) -> &[f64] {
        &self.0
    }

    #[inline]
    fn distance(&self, other: &Self) -> f64 {
        ((self.x() - other.x()).powi(2) + (self.y() - other.y()).powi(2)).sqrt()
    }

    fn interpolate(&self, other: &Self, t: f64) -> Self {
        let x = self.x() * (1.0 - t) + other.x() * t;
        let y = self.y() * (1.0 - t) + other.y() * t;
        Position2d([x, y])
    }

    fn interpolate_multi(&self, other: &Self, t: &Self) -> Self {
        let tx = t.x();
        let ty = t.y();
        let x = self.x() * (1.0 - tx) + other.x() * tx;
        let y = self.y() * (1.0 - ty) + other.y() * ty;
        Position2d([x, y])
    }
}

#[test]
fn test_interpolate_one_axis() {
    let a = Position2d::new(-1.0, 0.0);
    let b = Position2d::new(1.0, 0.0);

    assert_eq!((-1.0, 0.0), a.interpolate(&b, 0.0).xy());
    assert_eq!((0.0, 0.0),  a.interpolate(&b, 0.5).xy());
    assert_eq!((1.0, 0.0),  a.interpolate(&b, 1.0).xy());
}

#[test]
fn test_interpolate_two_axes() {
    let a = Position2d::new(-1.0, 1.0);
    let b = Position2d::new(1.0, -1.0);

    assert_eq!((-1.0, 1.0), a.interpolate(&b, 0.0).xy());
    assert_eq!((0.0, 0.0),  a.interpolate(&b, 0.5).xy());
    assert_eq!((1.0, -1.0),  a.interpolate(&b, 1.0).xy());
}

#[test]
fn test_interpolate_multi() {
    let a = Position2d::new(-1.0, 1.0);
    let b = Position2d::new(1.0, -1.0);

    assert_eq!((-1.0, -1.0), a.interpolate_multi(&b, &Position2d::new(0.0, 1.0)).xy());
    assert_eq!((0.0, 0.0),  a.interpolate_multi(&b, &Position2d::new(0.5, 0.5)).xy());
    assert_eq!((1.0, 1.0),  a.interpolate_multi(&b, &Position2d::new(1.0, 0.0)).xy());
}
<|endoftext|>


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

use failure::SyncFailure;
use handlebars::Handlebars;
use clap;
use std::io::Write;
use std::path::Path;
use std::process::Command;

use common::ui::{UI, Status};
use export_docker::Result;
use error::Error;

pub const DEFAULT_OPERATOR_VERSION: &'static str = "0.5.1";
pub const OPERATOR_REPO_URL: &'static str = "https://habitat-sh.github.io/\
                                             habitat-operator/helm/charts/stable/";

// Helm requirements.yaml template
const DEPSFILE: &'static str = include_str!("../defaults/HelmDeps.hbs");

pub struct Deps {
    operator_version: String,
    update: bool,
}

impl Deps {
    pub fn new_for_cli_matches(matches: &clap::ArgMatches) -> Self {
        Deps {
            operator_version: matches
                .value_of("OPERATOR_VERSION")
                .unwrap_or(DEFAULT_OPERATOR_VERSION)
                .to_owned(),
            update: matches.is_present("DOWNLOAD_DEPS"),
        }
    }

    pub fn generate(&mut self, write: &mut Write) -> Result<()> {
        let out = self.into_string()?;
        write.write(out.as_bytes())?;

        Ok(())
    }

    pub fn download<P: AsRef<Path>>(&self, dir: P, ui: &mut UI) -> Result<()> {
        if !self.update {
            return Ok(());
        }

        Command::new("helm")
            .arg("repo")
            .arg("add")
            .arg("habitat-operator")
            .arg(OPERATOR_REPO_URL)
            .spawn()
            .map_err(|_| Error::HelmLaunchFailed)
            .and_then(|mut c| if !c.wait()
                .map_err(|_| Error::HelmLaunchFailed)?
                .success()
            {
                Err(Error::HelmNotSetup(
                    String::from("Failed to update chart dependencies"),
                ))?
            } else {
                Ok(())
            })?;

        ui.status(Status::Downloading, "dependencies")?;

        Command::new("helm")
            .arg("dep")
            .arg("up")
            .arg(dir.as_ref().as_os_str())
            .spawn()?
            .wait()
            .map(|_| ())
            .map_err(From::from)
    }

    // TODO: Implement TryInto trait instead when it's in stable std crate
    fn into_string(&self) -> Result<String> {
        let json = json!({
            "operator_version": self.operator_version,
            "operator_repo_url": OPERATOR_REPO_URL,
        });

        Handlebars::new()
            .template_render(DEPSFILE, &json)
            .map_err(SyncFailure::new)
            .map_err(From::from)
    }
}
<commit_msg>pkg-export-helm: Disable addition of operator dep into charts<commit_after>// Copyright (c) 2018 Chef Software Inc. and/or applicable contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use failure::SyncFailure;
use handlebars::Handlebars;
use clap;
use std::io::Write;
use std::path::Path;
use std::process::Command;

use common::ui::{UI, Status};
use export_docker::Result;
use error::Error;

pub const DEFAULT_OPERATOR_VERSION: &'static str = "0.5.1";
pub const OPERATOR_REPO_URL: &'static str = "https://habitat-sh.github.io/\
                                             habitat-operator/helm/charts/stable/";

// Helm requirements.yaml template
const DEPSFILE: &'static str = include_str!("../defaults/HelmDeps.hbs");

pub struct Deps {
    operator_version: String,
    update: bool,
}

impl Deps {
    pub fn new_for_cli_matches(matches: &clap::ArgMatches) -> Self {
        Deps {
            operator_version: matches
                .value_of("OPERATOR_VERSION")
                .unwrap_or(DEFAULT_OPERATOR_VERSION)
                .to_owned(),
            update: matches.is_present("DOWNLOAD_DEPS"),
        }
    }

    pub fn generate(&mut self, write: &mut Write) -> Result<()> {
        // TODO: Until this Helm issue is resolved or has a decent workaround, let's skip the
        //       operator dependency:
        //
        //       https://github.com/kubernetes/helm/issues/3632
        //
        //let out = self.into_string()?;
        let out = String::new();
        write.write(out.as_bytes())?;

        Ok(())
    }

    pub fn download<P: AsRef<Path>>(&self, dir: P, ui: &mut UI) -> Result<()> {
        if !self.update {
            return Ok(());
        }

        Command::new("helm")
            .arg("repo")
            .arg("add")
            .arg("habitat-operator")
            .arg(OPERATOR_REPO_URL)
            .spawn()
            .map_err(|_| Error::HelmLaunchFailed)
            .and_then(|mut c| if !c.wait()
                .map_err(|_| Error::HelmLaunchFailed)?
                .success()
            {
                Err(Error::HelmNotSetup(
                    String::from("Failed to update chart dependencies"),
                ))?
            } else {
                Ok(())
            })?;

        ui.status(Status::Downloading, "dependencies")?;

        Command::new("helm")
            .arg("dep")
            .arg("up")
            .arg(dir.as_ref().as_os_str())
            .spawn()?
            .wait()
            .map(|_| ())
            .map_err(From::from)
    }

    // TODO: Implement TryInto trait instead when it's in stable std crate
    #[allow(dead_code)]
    fn into_string(&self) -> Result<String> {
        let json = json!({
            "operator_version": self.operator_version,
            "operator_repo_url": OPERATOR_REPO_URL,
        });

        Handlebars::new()
            .template_render(DEPSFILE, &json)
            .map_err(SyncFailure::new)
            .map_err(From::from)
    }
}
<|endoftext|>


<commit_before>#![allow(unused_mut)]
// Bug in the compiler with Arc/Mutex references.

extern crate iron;
extern crate http;
extern crate persistent;

use std::io::net::ip::Ipv4Addr;
use persistent::Persistent;
use http::status;
use iron::{Request, Response, Alloy, Iron, ServerT};
use iron::middleware::{Status, Continue};
use iron::mixin::Serve;

pub struct HitCounter;

fn hit_counter(_: &mut Request, _: &mut Response, alloy: &mut Alloy) -> Status {
    // Bug in the compiler
    let mut count = alloy.find::<Persistent<uint, HitCounter>>().unwrap().data.write();
    *count += 1;
    println!("{} hits!", *count);
    Continue
}

fn serve_hits(_: &mut Request, res: &mut Response, alloy: &mut Alloy) {
    let mut count = alloy.find::<Persistent<uint, HitCounter>>().unwrap().data.read();
    let _ = res.serve(status::Ok, format!("{} hits!", *count).as_slice());
}

fn main() {
    let mut server: ServerT = Iron::new();
    let counter: Persistent<uint, HitCounter> = Persistent::new(0u);
    server.link(counter);
    server.link(hit_counter);
    server.link(serve_hits);
    server.listen(Ipv4Addr(127, 0, 0, 1), 3001);
}

<commit_msg>(doc) Updated example for chain.link changes.<commit_after>#![allow(unused_mut)]
// Bug in the compiler with Arc/Mutex references.

extern crate iron;
extern crate http;
extern crate persistent;

use std::io::net::ip::Ipv4Addr;
use persistent::Persistent;
use http::status;
use iron::{Request, Response, Alloy, Iron, ServerT, Chain};
use iron::middleware::{Status, Continue};
use iron::mixin::Serve;

pub struct HitCounter;

fn hit_counter(_: &mut Request, _: &mut Response, alloy: &mut Alloy) -> Status {
    // Bug in the compiler
    let mut count = alloy.find::<Persistent<uint, HitCounter>>().unwrap().data.write();
    *count += 1;
    println!("{} hits!", *count);
    Continue
}

fn serve_hits(_: &mut Request, res: &mut Response, alloy: &mut Alloy) {
    let mut count = alloy.find::<Persistent<uint, HitCounter>>().unwrap().data.read();
    let _ = res.serve(status::Ok, format!("{} hits!", *count).as_slice());
}

fn main() {
    let mut server: ServerT = Iron::new();
    let counter: Persistent<uint, HitCounter> = Persistent::new(0u);
    server.chain.link(counter);
    server.chain.link(hit_counter);
    server.chain.link(serve_hits);
    server.listen(Ipv4Addr(127, 0, 0, 1), 3001);
}

<|endoftext|>


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

use bytes::BytesMut;
use byteorder::{LittleEndian, ByteOrder};
use tokio_io::codec::{Decoder, Encoder};

use std::io;

use messages::{HEADER_LENGTH, MessageBuffer, RawMessage};
use super::error::other_error;

pub const MAX_MESSAGE_LEN: usize = 1024 * 1024; // 1 MB

#[derive(Debug)]
pub struct MessagesCodec;

impl Decoder for MessagesCodec {
    type Item = RawMessage;
    type Error = io::Error;

    fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, io::Error> {
        // Read header
        if buf.len() < HEADER_LENGTH {
            return Ok(None);
        }
        // Check payload len
        let total_len = LittleEndian::read_u32(&buf[6..10]) as usize;
        if total_len > MAX_MESSAGE_LEN {
            return Err(other_error(format!(
                "Received message is too long: {}, maximum allowed length is {}",
                total_len,
                MAX_MESSAGE_LEN
            )));
        }

        // Read message
        if buf.len() >= total_len {
            let data = buf.split_to(total_len).to_vec();
            let raw = RawMessage::from(MessageBuffer::from_vec(data));
            return Ok(Some(raw));
        }
        Ok(None)
    }
}

impl Encoder for MessagesCodec {
    type Item = RawMessage;
    type Error = io::Error;

    fn encode(&mut self, msg: Self::Item, buf: &mut BytesMut) -> io::Result<()> {
        buf.extend_from_slice(msg.as_ref().as_ref());
        Ok(())
    }
}
<commit_msg>Emit error if message header is too short<commit_after>// Copyright 2017 The Exonum Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use bytes::BytesMut;
use byteorder::{LittleEndian, ByteOrder};
use tokio_io::codec::{Decoder, Encoder};

use std::io;

use messages::{HEADER_LENGTH, MessageBuffer, RawMessage};
use super::error::other_error;

pub const MAX_MESSAGE_LEN: usize = 1024 * 1024; // 1 MB

#[derive(Debug)]
pub struct MessagesCodec;

impl Decoder for MessagesCodec {
    type Item = RawMessage;
    type Error = io::Error;

    fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, io::Error> {
        // Check end
        if buf.is_empty() {
            return Ok(None);
        }
        // Read header
        if buf.len() < HEADER_LENGTH {
            return Err(other_error(format!(
                "Received message is shorter than header: {}, header length is {}",
                buf.len(),
                HEADER_LENGTH
            )));
        }
        // Check payload len
        let total_len = LittleEndian::read_u32(&buf[6..10]) as usize;
        if total_len > MAX_MESSAGE_LEN {
            return Err(other_error(format!(
                "Received message is too long: {}, maximum allowed length is {}",
                total_len,
                MAX_MESSAGE_LEN
            )));
        }

        // Read message
        if buf.len() >= total_len {
            let data = buf.split_to(total_len).to_vec();
            let raw = RawMessage::from(MessageBuffer::from_vec(data));
            return Ok(Some(raw));
        }
        Ok(None)
    }
}

impl Encoder for MessagesCodec {
    type Item = RawMessage;
    type Error = io::Error;

    fn encode(&mut self, msg: Self::Item, buf: &mut BytesMut) -> io::Result<()> {
        buf.extend_from_slice(msg.as_ref().as_ref());
        Ok(())
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2016-2018 The http-serve developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE.txt or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT.txt or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Test program which serves a local file on `http://127.0.0.1:1337/`.
//!
//! Performs file IO on a separate thread pool from the reactor so that it doesn't block on
//! local disk. Supports HEAD, conditional GET, and byte range requests. Some commands to try:
//!
//! ```
//! $ curl --head http://127.0.0.1/
//! $ curl http://127.0.0.1:1337 > /dev/null
//! $ curl -v -H 'Range: bytes=1-10' http://127.0.0.1:1337/
//! $ curl -v -H 'Range: bytes=1-10,30-40' http://127.0.0.1:1337/
//! ```

use bytes::Bytes;
use futures_util::future;
use http::{Request, Response};
use http_serve::ChunkedReadFile;
use hyper::service::{make_service_fn, service_fn};
use hyper::Body;

struct Context {
    path: std::ffi::OsString,
}

type BoxedError = Box<dyn std::error::Error + Send + Sync>;

async fn serve(ctx: &'static Context, req: Request<Body>) -> Result<Response<Body>, BoxedError> {
    let f = tokio::task::block_in_place::<_, Result<ChunkedReadFile<Bytes, BoxedError>, BoxedError>>(
        move || {
            let f = std::fs::File::open(&ctx.path)?;
            let headers = http::header::HeaderMap::new();
            Ok(ChunkedReadFile::new(f, headers)?)
        },
    )?;
    Ok(http_serve::serve(f, &req))
}

#[tokio::main]
async fn main() -> Result<(), BoxedError> {
    let mut args = std::env::args_os();
    if args.len() != 2 {
        eprintln!("Expected serve [FILENAME]");
        std::process::exit(1);
    }
    let path = args.nth(1).unwrap();

    let ctx: &'static Context = Box::leak(Box::new(Context { path: path }));

    env_logger::init();
    let addr = ([127, 0, 0, 1], 1337).into();
    let make_svc = make_service_fn(move |_conn| {
        future::ok::<_, std::convert::Infallible>(service_fn(move |req| serve(ctx, req)))
    });
    let server = hyper::Server::bind(&addr).serve(make_svc);
    println!(
        "Serving {} on http://{} with 1 thread.",
        ctx.path.to_string_lossy(),
        server.local_addr()
    );
    server.await?;

    Ok(())
}
<commit_msg>fix doc comment in serve_file<commit_after>// Copyright (c) 2016-2018 The http-serve developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE.txt or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT.txt or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Test program which serves a local file on `http://127.0.0.1:1337/`.
//!
//! Performs file IO on a separate thread pool from the reactor so that it doesn't block on
//! local disk. Supports HEAD, conditional GET, and byte range requests. Some commands to try:
//!
//! ```text
//! $ curl --head http://127.0.0.1:1337/
//! $ curl http://127.0.0.1:1337 > /dev/null
//! $ curl -v -H 'Range: bytes=1-10' http://127.0.0.1:1337/
//! $ curl -v -H 'Range: bytes=1-10,30-40' http://127.0.0.1:1337/
//! ```

use bytes::Bytes;
use futures_util::future;
use http::{Request, Response};
use http_serve::ChunkedReadFile;
use hyper::service::{make_service_fn, service_fn};
use hyper::Body;

struct Context {
    path: std::ffi::OsString,
}

type BoxedError = Box<dyn std::error::Error + Send + Sync>;

async fn serve(ctx: &'static Context, req: Request<Body>) -> Result<Response<Body>, BoxedError> {
    let f = tokio::task::block_in_place::<_, Result<ChunkedReadFile<Bytes, BoxedError>, BoxedError>>(
        move || {
            let f = std::fs::File::open(&ctx.path)?;
            let headers = http::header::HeaderMap::new();
            Ok(ChunkedReadFile::new(f, headers)?)
        },
    )?;
    Ok(http_serve::serve(f, &req))
}

#[tokio::main]
async fn main() -> Result<(), BoxedError> {
    let mut args = std::env::args_os();
    if args.len() != 2 {
        eprintln!("Expected serve [FILENAME]");
        std::process::exit(1);
    }
    let path = args.nth(1).unwrap();

    let ctx: &'static Context = Box::leak(Box::new(Context { path: path }));

    env_logger::init();
    let addr = ([127, 0, 0, 1], 1337).into();
    let make_svc = make_service_fn(move |_conn| {
        future::ok::<_, std::convert::Infallible>(service_fn(move |req| serve(ctx, req)))
    });
    let server = hyper::Server::bind(&addr).serve(make_svc);
    println!(
        "Serving {} on http://{} with 1 thread.",
        ctx.path.to_string_lossy(),
        server.local_addr()
    );
    server.await?;

    Ok(())
}
<|endoftext|>


<commit_before>// Copyright (C) 2016  ParadoxSpiral
//
// This file is part of mpv-rs.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

extern crate crossbeam;

use mpv::*;

use std::process;
use std::path::Path;
use std::time::Duration;
use std::thread;

pub fn exec() {
    let mpv = UninitializedParent::new(true).unwrap();
    mpv.set_option(&mut Property::new("cache-initial", Data::new(1))).unwrap();
    // mpv.set_option(&mut Property::new("ao-volume", Data::new(100))).unwrap();
    // mpv.set_option(&mut Property::new("ao-mute", Data::new(false)));
    mpv.set_option(&mut Property::new("volume", Data::new(10))).unwrap();
    mpv.set_option(&mut Property::new("no-video", Data::new(true))).unwrap();
    mpv.set_option(&mut Property::new("ytdl", Data::new(true))).unwrap();
    let mpv = mpv.init().unwrap();

    crossbeam::scope(|scope| {
        scope.spawn(|| {
            let iter = mpv.observe_all(&[Event::FileLoaded,
                                         Event::StartFile,
                                         Event::Seek,
                                         Event::PlaybackRestart,
                                         Event::EndFile(None)])
                          .unwrap();

            for vec in iter {
                if let Some(&Ok(Event::EndFile(ref v))) = vec.iter().find(|e| {
                    if e.is_ok() {
                        if let Event::EndFile(_) = *e.as_ref().unwrap() {
                            return true;
                        }
                    }
                    false
                }) {
                    println!("File ended! Reason: {:?}", v);
                    process::exit(0);
                } else {
                    println!("playback_events: {:?}", vec);
                };
            }
        });
        scope.spawn(|| {
            let iter = mpv.observe_all(&[Event::PropertyChange(Property::new("volume",
                                                                             Data::new(0))),
                                         Event::PropertyChange(Property::new("pause",
                                                                             Data::new(false)))])
                          .unwrap();

            for vec in iter {
                println!("prop_events: {:?}", vec);
            }
        });
        scope.spawn(|| {
            let iter = mpv.observe_all(&[Event::LogMessage(LogMessage::new(LogLevel::Info))])
                          .unwrap();

            for vec in iter {
                println!("log_events: {:#?}", vec);
            }
        });

        mpv.playlist(&PlaylistOp::Loadfiles(&[File::new(Path::new("https://www.youtube.\
                                                                   com/watch?v=DLzxrzFCyOs"),
                                                        FileState::AppendPlay,
                                                        None)]))
           .unwrap();

        thread::sleep(Duration::from_secs(3));

        mpv.set_property(&mut Property::new("volume", Data::new(25))).unwrap();

        thread::sleep(Duration::from_secs(30));

        mpv.playlist(&PlaylistOp::NextForce).unwrap();
    });
}
<commit_msg>Remove bloat in example<commit_after>// Copyright (C) 2016  ParadoxSpiral
//
// This file is part of mpv-rs.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

extern crate crossbeam;

use mpv::*;

use std::process;
use std::path::Path;
use std::time::Duration;
use std::thread;

pub fn exec() {
    let mpv = UninitializedParent::new(true).unwrap();
    mpv.set_option(&mut Property::new("cache-initial", Data::new(1))).unwrap();
    mpv.set_option(&mut Property::new("volume", Data::new(10))).unwrap();
    mpv.set_option(&mut Property::new("no-video", Data::new(true))).unwrap();
    mpv.set_option(&mut Property::new("ytdl", Data::new(true))).unwrap();
    let mpv = mpv.init().unwrap();

    crossbeam::scope(|scope| {
        scope.spawn(|| {
            let iter = mpv.observe_all(&[Event::FileLoaded,
                                         Event::StartFile,
                                         Event::Seek,
                                         Event::PlaybackRestart,
                                         Event::EndFile(None)])
                          .unwrap();

            for vec in iter {
                if let Some(&Ok(Event::EndFile(ref v))) = vec.iter().find(|e| {
                    if e.is_ok() {
                        if let Event::EndFile(_) = *e.as_ref().unwrap() {
                            return true;
                        }
                    }
                    false
                }) {
                    println!("File ended! Reason: {:?}", v);
                    process::exit(0);
                } else {
                    println!("playback_events: {:?}", vec);
                };
            }
        });
        scope.spawn(|| {
            let iter = mpv.observe_all(&[Event::PropertyChange(Property::new("volume",
                                                                             Data::new(0))),
                                         Event::PropertyChange(Property::new("pause",
                                                                             Data::new(false)))])
                          .unwrap();

            for vec in iter {
                println!("prop_events: {:?}", vec);
            }
        });
        scope.spawn(|| {
            let iter = mpv.observe_all(&[Event::LogMessage(LogMessage::new(LogLevel::Info))])
                          .unwrap();

            for vec in iter {
                println!("log_events: {:#?}", vec);
            }
        });

        mpv.playlist(&PlaylistOp::Loadfiles(&[File::new(Path::new("https://www.youtube.\
                                                                   com/watch?v=DLzxrzFCyOs"),
                                                        FileState::AppendPlay,
                                                        None)]))
           .unwrap();

        thread::sleep(Duration::from_secs(3));

        mpv.set_property(&mut Property::new("volume", Data::new(25))).unwrap();

        thread::sleep(Duration::from_secs(30));

        mpv.playlist(&PlaylistOp::NextForce).unwrap();
    });
}
<|endoftext|>