<commit_before>//  rpc-perf - RPC Performance Testing
//  Copyright 2015 Twitter, Inc
//
//  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 common::*;
use request::BenchmarkConfig;
use tic::{Clocksource, Interest, Meters, Percentile, Receiver};
use std::time::Duration;

pub fn stats_receiver_init(
    config: &BenchmarkConfig,
    listen: Option<String>,
    waterfall: Option<String>,
    trace: Option<String>,
) -> Receiver<Stat> {
    let mut stats_config = Receiver::<Stat>::configure()
        .batch_size(1024)
        .capacity(4096)
        .duration(config.duration())
        .poll_delay(Some(Duration::new(0, MILLISECOND)))
        .windows(config.windows());

    if let Some(addr) = listen {
        stats_config = stats_config.http_listen(addr);
    }

    let mut stats_receiver = stats_config.build();

    let counts = vec![
        Stat::Window,
        Stat::ResponseOk,
        Stat::ResponseOkHit,
        Stat::ResponseOkMiss,
        Stat::ResponseError,
        Stat::ResponseTimeout,
        Stat::RequestPrepared,
        Stat::RequestSent,
        Stat::ConnectOk,
        Stat::ConnectError,
        Stat::ConnectTimeout,
        Stat::SocketCreate,
        Stat::SocketClose,
        Stat::SocketRead,
        Stat::SocketFlush,
        Stat::SocketWrite,
    ];

    for c in counts {
        stats_receiver.add_interest(Interest::Count(c));
    }

    for c in vec![
        Stat::ResponseOk,
        Stat::ResponseOkHit,
        Stat::ResponseOkMiss,
        Stat::ConnectOk,
    ]
    {
        stats_receiver.add_interest(Interest::Percentile(c));
    }

    if let Some(w) = waterfall {
        stats_receiver.add_interest(Interest::Waterfall(Stat::ResponseOk, w));
    }

    if let Some(t) = trace {
        stats_receiver.add_interest(Interest::Trace(Stat::ResponseOk, t));
    }

    stats_receiver
}

pub fn meters_delta(t0: &Meters<Stat>, t1: &Meters<Stat>, stat: &Stat) -> u64 {
    *t1.count(stat).unwrap_or(&0) - *t0.count(stat).unwrap_or(&0)
}

fn print_stats(t0: u64, m0: &Meters<Stat>, t1: u64, m1: &Meters<Stat>, clocksource: &Clocksource) -> f64 {
    let responses = meters_delta(&m0, &m1, &Stat::ResponseOk) +
        meters_delta(&m0, &m1, &Stat::ResponseError);

    let rate = responses as f64 /
        ((clocksource.convert(t1) - clocksource.convert(t0)) as f64 / SECOND as f64);

    let success_rate = if responses > 0 {
        100.0 * (responses - meters_delta(&m0, &m1, &Stat::ResponseError)) as f64 /
            (responses + meters_delta(&m0, &m1, &Stat::ResponseTimeout)) as f64
    } else {
        0.0
    };

    let hit = meters_delta(&m0, &m1, &Stat::ResponseOkHit);
    let miss = meters_delta(&m0, &m1, &Stat::ResponseOkMiss);

    let hit_rate = if (hit + miss) > 0 {
        100.0 * hit as f64 / (hit + miss) as f64
    } else {
        0.0
    };

    let inflight = *m1.count(&Stat::RequestSent).unwrap_or(&0) as i64 -
        *m1.count(&Stat::ResponseOk).unwrap_or(&0) as i64 -
        *m1.count(&Stat::ResponseError).unwrap_or(&0) as i64 -
        *m1.count(&Stat::ResponseTimeout).unwrap_or(&0) as i64;
    let open = *m1.count(&Stat::SocketCreate).unwrap_or(&0) as i64 -
        *m1.count(&Stat::SocketClose).unwrap_or(&0) as i64;
    info!(
        "Connections: Ok: {} Error: {} Timeout: {} Open: {}",
        meters_delta(&m0, &m1, &Stat::ConnectOk),
        meters_delta(&m0, &m1, &Stat::ConnectError),
        meters_delta(&m0, &m1, &Stat::ConnectTimeout),
        open
    );
    info!(
        "Sockets: Create: {} Close: {} Read: {} Write: {} Flush: {}",
        meters_delta(&m0, &m1, &Stat::SocketCreate),
        meters_delta(&m0, &m1, &Stat::SocketClose),
        meters_delta(&m0, &m1, &Stat::SocketRead),
        meters_delta(&m0, &m1, &Stat::SocketWrite),
        meters_delta(&m0, &m1, &Stat::SocketFlush)
    );
    info!(
        "Requests: Sent: {} Prepared: {} In-Flight: {}",
        meters_delta(&m0, &m1, &Stat::RequestSent),
        meters_delta(&m0, &m1, &Stat::RequestPrepared),
        inflight
    );
    info!(
        "Responses: Ok: {} Error: {} Timeout: {} Hit: {} Miss: {}",
        meters_delta(&m0, &m1, &Stat::ResponseOk),
        meters_delta(&m0, &m1, &Stat::ResponseError),
        meters_delta(&m0, &m1, &Stat::ResponseTimeout),
        meters_delta(&m0, &m1, &Stat::ResponseOkHit),
        meters_delta(&m0, &m1, &Stat::ResponseOkMiss)
    );
    info!(
        "Rate: {:.*} rps Success: {:.*} % Hit Rate: {:.*} %",
        2,
        rate,
        2,
        success_rate,
        2,
        hit_rate
    );
    display_percentiles(&m1, &Stat::ResponseOk, "Response OK");
    hit_rate
}

pub fn warmup(receiver: &mut Receiver<Stat>) -> f64 {
    let clocksource = receiver.get_clocksource().clone();
    let mut sender = receiver.get_sender().clone();
    sender.set_batch_size(1);

    let t0 = clocksource.counter();
    let m0 = receiver.clone_meters();

    debug!("warmup stats: collection ready");
    receiver.run_once();

    info!("-----");
    info!("Warmup");
    let t1 = clocksource.counter();
    let m1 = receiver.clone_meters();

    print_stats(t0, &m0, t1, &m1, &clocksource)
}

pub fn run(mut receiver: Receiver<Stat>, windows: usize, infinite: bool) {
    let mut window = 0;
    let mut next_window = window + windows;

    let clocksource = receiver.get_clocksource().clone();
    let mut sender = receiver.get_sender().clone();
    sender.set_batch_size(1);

    let mut t0 = clocksource.counter();
    let mut m0 = receiver.clone_meters();

    debug!("stats: collection ready");
    loop {
        receiver.run_once();
        let t1 = clocksource.counter();
        let m1 = receiver.clone_meters();

        print_stats(t0, &m0, t1, &m1, &clocksource);

        m0 = m1;
        t0 = t1;
        window += 1;

        if window > next_window {
            receiver.save_files();
            if infinite {
                next_window += windows;
                receiver.clear_heatmaps();
            } else {
                break;
            }
        }
    }
}

fn display_percentiles(meters: &Meters<Stat>, stat: &Stat, label: &str) {
    info!(
        "Percentiles: {} (us): min: {} p50: {} p90: {} p99: {} p999: {} p9999: {} max: {}",
        label,
        meters
            .percentile(stat, Percentile("min".to_owned(), 0.0))
            .unwrap_or(&0)
            / 1000,
        meters
            .percentile(stat, Percentile("p50".to_owned(), 50.0))
            .unwrap_or(&0)
            / 1000,
        meters
            .percentile(stat, Percentile("p90".to_owned(), 90.0))
            .unwrap_or(&0)
            / 1000,
        meters
            .percentile(stat, Percentile("p99".to_owned(), 99.0))
            .unwrap_or(&0)
            / 1000,
        meters
            .percentile(stat, Percentile("p999".to_owned(), 99.9))
            .unwrap_or(&0)
            / 1000,
        meters
            .percentile(stat, Percentile("p9999".to_owned(), 99.99))
            .unwrap_or(&0)
            / 1000,
        meters
            .percentile(stat, Percentile("max".to_owned(), 100.0))
            .unwrap_or(&0)
            / 1000,
    );
}
<commit_msg>fix: too many windows before exit (#171)<commit_after>//  rpc-perf - RPC Performance Testing
//  Copyright 2015 Twitter, Inc
//
//  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 common::*;
use request::BenchmarkConfig;
use tic::{Clocksource, Interest, Meters, Percentile, Receiver};
use std::time::Duration;

pub fn stats_receiver_init(
    config: &BenchmarkConfig,
    listen: Option<String>,
    waterfall: Option<String>,
    trace: Option<String>,
) -> Receiver<Stat> {
    let mut stats_config = Receiver::<Stat>::configure()
        .batch_size(1024)
        .capacity(4096)
        .duration(config.duration())
        .poll_delay(Some(Duration::new(0, MILLISECOND)))
        .windows(config.windows());

    if let Some(addr) = listen {
        stats_config = stats_config.http_listen(addr);
    }

    let mut stats_receiver = stats_config.build();

    let counts = vec![
        Stat::Window,
        Stat::ResponseOk,
        Stat::ResponseOkHit,
        Stat::ResponseOkMiss,
        Stat::ResponseError,
        Stat::ResponseTimeout,
        Stat::RequestPrepared,
        Stat::RequestSent,
        Stat::ConnectOk,
        Stat::ConnectError,
        Stat::ConnectTimeout,
        Stat::SocketCreate,
        Stat::SocketClose,
        Stat::SocketRead,
        Stat::SocketFlush,
        Stat::SocketWrite,
    ];

    for c in counts {
        stats_receiver.add_interest(Interest::Count(c));
    }

    for c in vec![
        Stat::ResponseOk,
        Stat::ResponseOkHit,
        Stat::ResponseOkMiss,
        Stat::ConnectOk,
    ]
    {
        stats_receiver.add_interest(Interest::Percentile(c));
    }

    if let Some(w) = waterfall {
        stats_receiver.add_interest(Interest::Waterfall(Stat::ResponseOk, w));
    }

    if let Some(t) = trace {
        stats_receiver.add_interest(Interest::Trace(Stat::ResponseOk, t));
    }

    stats_receiver
}

pub fn meters_delta(t0: &Meters<Stat>, t1: &Meters<Stat>, stat: &Stat) -> u64 {
    *t1.count(stat).unwrap_or(&0) - *t0.count(stat).unwrap_or(&0)
}

fn print_stats(t0: u64, m0: &Meters<Stat>, t1: u64, m1: &Meters<Stat>, clocksource: &Clocksource) -> f64 {
    info!("-----");
    let responses = meters_delta(&m0, &m1, &Stat::ResponseOk) +
        meters_delta(&m0, &m1, &Stat::ResponseError);

    let rate = responses as f64 /
        ((clocksource.convert(t1) - clocksource.convert(t0)) as f64 / SECOND as f64);

    let success_rate = if responses > 0 {
        100.0 * (responses - meters_delta(&m0, &m1, &Stat::ResponseError)) as f64 /
            (responses + meters_delta(&m0, &m1, &Stat::ResponseTimeout)) as f64
    } else {
        0.0
    };

    let hit = meters_delta(&m0, &m1, &Stat::ResponseOkHit);
    let miss = meters_delta(&m0, &m1, &Stat::ResponseOkMiss);

    let hit_rate = if (hit + miss) > 0 {
        100.0 * hit as f64 / (hit + miss) as f64
    } else {
        0.0
    };

    let inflight = *m1.count(&Stat::RequestSent).unwrap_or(&0) as i64 -
        *m1.count(&Stat::ResponseOk).unwrap_or(&0) as i64 -
        *m1.count(&Stat::ResponseError).unwrap_or(&0) as i64 -
        *m1.count(&Stat::ResponseTimeout).unwrap_or(&0) as i64;
    let open = *m1.count(&Stat::SocketCreate).unwrap_or(&0) as i64 -
        *m1.count(&Stat::SocketClose).unwrap_or(&0) as i64;
    info!(
        "Connections: Ok: {} Error: {} Timeout: {} Open: {}",
        meters_delta(&m0, &m1, &Stat::ConnectOk),
        meters_delta(&m0, &m1, &Stat::ConnectError),
        meters_delta(&m0, &m1, &Stat::ConnectTimeout),
        open
    );
    info!(
        "Sockets: Create: {} Close: {} Read: {} Write: {} Flush: {}",
        meters_delta(&m0, &m1, &Stat::SocketCreate),
        meters_delta(&m0, &m1, &Stat::SocketClose),
        meters_delta(&m0, &m1, &Stat::SocketRead),
        meters_delta(&m0, &m1, &Stat::SocketWrite),
        meters_delta(&m0, &m1, &Stat::SocketFlush)
    );
    info!(
        "Requests: Sent: {} Prepared: {} In-Flight: {}",
        meters_delta(&m0, &m1, &Stat::RequestSent),
        meters_delta(&m0, &m1, &Stat::RequestPrepared),
        inflight
    );
    info!(
        "Responses: Ok: {} Error: {} Timeout: {} Hit: {} Miss: {}",
        meters_delta(&m0, &m1, &Stat::ResponseOk),
        meters_delta(&m0, &m1, &Stat::ResponseError),
        meters_delta(&m0, &m1, &Stat::ResponseTimeout),
        meters_delta(&m0, &m1, &Stat::ResponseOkHit),
        meters_delta(&m0, &m1, &Stat::ResponseOkMiss)
    );
    info!(
        "Rate: {:.*} rps Success: {:.*} % Hit Rate: {:.*} %",
        2,
        rate,
        2,
        success_rate,
        2,
        hit_rate
    );
    display_percentiles(&m1, &Stat::ResponseOk, "Response OK");
    hit_rate
}

pub fn warmup(receiver: &mut Receiver<Stat>) -> f64 {
    let clocksource = receiver.get_clocksource().clone();
    let mut sender = receiver.get_sender().clone();
    sender.set_batch_size(1);

    let t0 = clocksource.counter();
    let m0 = receiver.clone_meters();

    debug!("warmup stats: collection ready");
    receiver.run_once();

    info!("-----");
    info!("Warmup");
    let t1 = clocksource.counter();
    let m1 = receiver.clone_meters();

    print_stats(t0, &m0, t1, &m1, &clocksource)
}

pub fn run(mut receiver: Receiver<Stat>, windows: usize, infinite: bool) {
    let mut window = 0;
    let mut next_window = window + windows;

    let clocksource = receiver.get_clocksource().clone();
    let mut sender = receiver.get_sender().clone();
    sender.set_batch_size(1);

    let mut t0 = clocksource.counter();
    let mut m0 = receiver.clone_meters();

    debug!("stats: collection ready");
    loop {
        receiver.run_once();
        let t1 = clocksource.counter();
        let m1 = receiver.clone_meters();

        print_stats(t0, &m0, t1, &m1, &clocksource);

        m0 = m1;
        t0 = t1;
        window += 1;

        if window >= next_window {
            receiver.save_files();
            if infinite {
                next_window += windows;
                receiver.clear_heatmaps();
            } else {
                break;
            }
        }
    }
}

fn display_percentiles(meters: &Meters<Stat>, stat: &Stat, label: &str) {
    info!(
        "Percentiles: {} (us): min: {} p50: {} p90: {} p99: {} p999: {} p9999: {} max: {}",
        label,
        meters
            .percentile(stat, Percentile("min".to_owned(), 0.0))
            .unwrap_or(&0)
            / 1000,
        meters
            .percentile(stat, Percentile("p50".to_owned(), 50.0))
            .unwrap_or(&0)
            / 1000,
        meters
            .percentile(stat, Percentile("p90".to_owned(), 90.0))
            .unwrap_or(&0)
            / 1000,
        meters
            .percentile(stat, Percentile("p99".to_owned(), 99.0))
            .unwrap_or(&0)
            / 1000,
        meters
            .percentile(stat, Percentile("p999".to_owned(), 99.9))
            .unwrap_or(&0)
            / 1000,
        meters
            .percentile(stat, Percentile("p9999".to_owned(), 99.99))
            .unwrap_or(&0)
            / 1000,
        meters
            .percentile(stat, Percentile("max".to_owned(), 100.0))
            .unwrap_or(&0)
            / 1000,
    );
}
<|endoftext|>


<commit_before>use numeric::LNumeric;
use std::io;
use std::vec;

#[deriving(Eq)]
pub enum LDatum<T> {
    LIdent(@str),
    LString(~str),
    LChar(char),
    LBool(bool),
    LNum(LNumeric),
    LCons(@LDatum<T>, @LDatum<T>),
    LNil,
    LVector(~[@LDatum<T>]),
    LExt(T),
}

#[deriving(Eq)]
pub enum Quotation
{
    Quote,
    QuasiQuote,
    Unquote,
}

impl<T: ToStr> ToStr for LDatum<T> {
    fn to_str(&self) -> ~str {
        do io::with_str_writer |wr| {
            write_ldatum(wr, self)
        }
    }
}

impl<T> LDatum<T> {
    pub fn to_list(&self) -> Option<~[@LDatum<T>]> {
        match *self {
            LCons(h, t) => datum_to_list(h, t),
            LNil => Some(~[]),
            _ => None,
        }
    }

    pub fn from_list(list: &[@LDatum<T>]) -> @LDatum<T> {
        match list {
            [] => @LNil,
            [h, ..t] => @LCons(h, LDatum::from_list(t)),
        }
    }
}

impl<T: ToStr> LDatum<T> {
    pub fn write(&self, wr: @io::Writer) {
        write_ldatum(wr, self)
    }
}

priv fn datum_to_list<T>(head: @LDatum<T>, tail: @LDatum<T>) -> Option<~[@LDatum<T>]> {
    let mut x: @LDatum<T> = tail;
    let mut list_flag = false;

    let list =
    do vec::build |push| {
        push(head);
        loop {
            match *x {
                LCons(h, t) => {
                    push(h);
                    x = t;
                },
                LNil => break,
                _ => {
                    list_flag = true;
                    break
                },
            }
        }
    };

    if list_flag {
        None
    } else {
        Some(list)
    }
}

priv fn write_ldatum<T: ToStr>(wr: @io::Writer, &v: &LDatum<T>) {
    match v {
        LIdent(s) => wr.write_str(s),
        LString(s) => {
            wr.write_char('"');
            wr.write_str(s);
            wr.write_char('"');
        },
        LChar(' ') => wr.write_str("#\\space"),
        LChar('\n') => wr.write_str("#\\newline"),
        LChar(c) => {
            wr.write_str("#\\");
            wr.write_char(c);
        },
        LBool(true) => wr.write_str("#t"),
        LBool(false) => wr.write_str("#f"),
        LNum(f) => wr.write_str(f.to_str()),
        LCons(ref head, ref tail) => {
            match is_quote(head, tail) {
                Some((name, v)) => {
                    let ch = match name {
                        Quote => '\'',
                        Unquote => ',',
                        QuasiQuote => '`',
                    };
                    wr.write_char(ch);
                    write_ldatum(wr, v);
                },
                None => {
                    wr.write_char('(');
                    write_ldatum(wr, *head);
                    write_list(wr, *tail);
                },
            }
        },
        LNil => wr.write_str("()"),
        LVector(v) => {
            wr.write_str("#(");
            match v {
                [] => (),
                [head, .. tail] => {
                    write_ldatum(wr, head);
                    for tail.each |&x| {
                        wr.write_char(' ');
                        write_ldatum(wr, x);
                    }
                }
            }
            wr.write_char(')');
        }
        LExt(v) => {
            wr.write_str(v.to_str());
        },
    }
}

pub fn is_quote<T>(&head: &@LDatum<T>, &tail: &@LDatum<T>) -> Option<(Quotation, @LDatum<T>)> {
    match *head {
        LIdent(name) =>
            match *tail {
                LCons(v, @LNil) => if name == @"quote" {
                        Some((Quote, v))
                    } else if name == @"quasiquote" {
                        Some((QuasiQuote, v))
                    } else if name == @"unquote" {
                        Some((Unquote, v))
                    } else {
                        None
                    },
                _ => None
            },
        _ =>
            None,
    }
}

priv fn write_list<T: ToStr>(wr: @io::Writer, &v: &LDatum<T>) {
    match v {
        LCons(head, tail) => {
            wr.write_char(' ');
            write_ldatum(wr, head);
            write_list(wr, tail);
        },
        LNil => wr.write_char(')'),
        _ => {
            wr.write_str(" . ");
            write_ldatum(wr, &v);
            wr.write_char(')');
        },
    }
}
<commit_msg>new function Datum::write_raw<commit_after>use numeric::LNumeric;
use std::io;
use std::vec;

#[deriving(Eq)]
pub enum LDatum<T> {
    LIdent(@str),
    LString(~str),
    LChar(char),
    LBool(bool),
    LNum(LNumeric),
    LCons(@LDatum<T>, @LDatum<T>),
    LNil,
    LVector(~[@LDatum<T>]),
    LExt(T),
}

#[deriving(Eq)]
pub enum Quotation
{
    Quote,
    QuasiQuote,
    Unquote,
}

impl<T: ToStr> ToStr for LDatum<T> {
    fn to_str(&self) -> ~str {
        do io::with_str_writer |wr| {
            write_ldatum(wr, self, true)
        }
    }
}

impl<T> LDatum<T> {
    pub fn to_list(&self) -> Option<~[@LDatum<T>]> {
        match *self {
            LCons(h, t) => datum_to_list(h, t),
            LNil => Some(~[]),
            _ => None,
        }
    }

    pub fn from_list(list: &[@LDatum<T>]) -> @LDatum<T> {
        match list {
            [] => @LNil,
            [h, ..t] => @LCons(h, LDatum::from_list(t)),
        }
    }
}

impl<T: ToStr> LDatum<T> {
    pub fn write(&self, wr: @io::Writer) {
        write_ldatum(wr, self, true)
    }

    pub fn write_raw(&self, wr: @io::Writer) {
        write_ldatum(wr, self, false)
    }
}

priv fn datum_to_list<T>(head: @LDatum<T>, tail: @LDatum<T>) -> Option<~[@LDatum<T>]> {
    let mut x: @LDatum<T> = tail;
    let mut list_flag = false;

    let list =
    do vec::build |push| {
        push(head);
        loop {
            match *x {
                LCons(h, t) => {
                    push(h);
                    x = t;
                },
                LNil => break,
                _ => {
                    list_flag = true;
                    break
                },
            }
        }
    };

    if list_flag {
        None
    } else {
        Some(list)
    }
}

priv fn write_ldatum<T: ToStr>(wr: @io::Writer, &v: &LDatum<T>, display: bool) {
    match v {
        LIdent(s) => wr.write_str(s),
        LString(s) => {
            if display {
                wr.write_char('"');
                wr.write_str(s.escape_default());
                wr.write_char('"');
            } else {
                wr.write_str(s);
            }
        },
        LChar(' ') => wr.write_str("#\\space"),
        LChar('\n') => wr.write_str("#\\newline"),
        LChar(c) => {
            wr.write_str("#\\");
            wr.write_char(c);
        },
        LBool(true) => wr.write_str("#t"),
        LBool(false) => wr.write_str("#f"),
        LNum(f) => wr.write_str(f.to_str()),
        LCons(ref head, ref tail) => {
            match is_quote(head, tail) {
                Some((name, v)) => {
                    let ch = match name {
                        Quote => '\'',
                        Unquote => ',',
                        QuasiQuote => '`',
                    };
                    wr.write_char(ch);
                    write_ldatum(wr, v, display);
                },
                None => {
                    wr.write_char('(');
                    write_ldatum(wr, *head, display);
                    write_list(wr, *tail, display);
                },
            }
        },
        LNil => wr.write_str("()"),
        LVector(v) => {
            wr.write_str("#(");
            match v {
                [] => (),
                [head, .. tail] => {
                    write_ldatum(wr, head, display);
                    for tail.each |&x| {
                        wr.write_char(' ');
                        write_ldatum(wr, x, display);
                    }
                }
            }
            wr.write_char(')');
        }
        LExt(v) => {
            wr.write_str(v.to_str());
        },
    }
}

pub fn is_quote<T>(&head: &@LDatum<T>, &tail: &@LDatum<T>) -> Option<(Quotation, @LDatum<T>)> {
    match *head {
        LIdent(name) =>
            match *tail {
                LCons(v, @LNil) => if name == @"quote" {
                        Some((Quote, v))
                    } else if name == @"quasiquote" {
                        Some((QuasiQuote, v))
                    } else if name == @"unquote" {
                        Some((Unquote, v))
                    } else {
                        None
                    },
                _ => None
            },
        _ =>
            None,
    }
}

priv fn write_list<T: ToStr>(wr: @io::Writer, &v: &LDatum<T>, display: bool) {
    match v {
        LCons(head, tail) => {
            wr.write_char(' ');
            write_ldatum(wr, head, display);
            write_list(wr, tail, display);
        },
        LNil => wr.write_char(')'),
        _ => {
            wr.write_str(" . ");
            write_ldatum(wr, &v, display);
            wr.write_char(')');
        },
    }
}
<|endoftext|>


<commit_before>use clap::{App, ArgMatches};
use log;

extern crate env_logger;

pub type ToResult<T> = Result<T, ToError>;

#[derive(Debug)]
pub enum ToError {
    Log(log::SetLoggerError),
}

// TODO: add custom displays for these errors.
// * SEE: https://jadpole.github.io/rust/many-error-types
// * SEE: http://lucumr.pocoo.org/2014/11/6/error-handling-in-rust/
impl From<log::SetLoggerError> for ToError {
    fn from(err: log::SetLoggerError) -> ToError {
        ToError::Log(err)
    }
}

#[derive(Debug)]
pub struct Request {
    // pub name: String,
    // pub directory: PathBuf,
    pub action: Action,
}

impl Request {
    fn new() -> Request {
        Request { action: Action::Put }
    }
}

#[derive(Debug, PartialEq)]
pub enum Action {
    Get,
    Put,
    Delete,
    List,
    Last,
    ChangeDirectory,
}

pub fn get_request() -> ToResult<Request> {
    let yaml = load_yaml!("cli.yml");
    let app = App::from_yaml(yaml);
    let matches = app.get_matches();

    return get(matches);
}

pub fn get_request_from(args: Vec<&str>) -> ToResult<Request> {
    let yaml = load_yaml!("cli.yml");
    let app = App::from_yaml(yaml);
    let matches = app.get_matches_from(args);

    return get(matches);
}

fn get(matches: ArgMatches) -> ToResult<Request> {
    info!("building request from clap::{:?}", matches);

    let request = Request::new();
    return Ok(request);
}

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

    fn run(mut args: Vec<&str>) -> Request {
        let logger_result = env_logger::init();
        assert!(logger_result.is_ok());

        args.insert(0, "to");

        let result = get_request_from(args);
        assert!(result.is_ok());

        return result.unwrap();
    }

    #[test]
    fn basic() {
        let request = get_request();
        assert!(request.is_ok());
    }

    #[test]
    fn basic_from_vec() -> () {
        let args = vec!["foo", "bar"];
        let request = run(args);

        // assert_eq!(request.name, "foo");
        // assert_eq!(request.directory, "bar");
        assert_eq!(request.action, Action::Put);
    }
}
<commit_msg>Adds test and stub for full Request struct.<commit_after>use clap::{App, ArgMatches};
use std::path::{PathBuf};
use log;

extern crate env_logger;

pub type ToResult<T> = Result<T, ToError>;

#[derive(Debug)]
pub enum ToError {
    Log(log::SetLoggerError),
}

// TODO: add custom displays for these errors.
// * SEE: https://jadpole.github.io/rust/many-error-types
// * SEE: http://lucumr.pocoo.org/2014/11/6/error-handling-in-rust/
impl From<log::SetLoggerError> for ToError {
    fn from(err: log::SetLoggerError) -> ToError {
        ToError::Log(err)
    }
}

#[derive(Debug)]
pub struct Request {
    pub name: String,
    pub directory: PathBuf,
    pub action: Action,
}

impl Request {
    fn new(action: Action) -> Request {
        Request {
            name: String::from("foo"),
            directory: PathBuf::from("bar"),
            action: action,
        }
    }
}

#[derive(Debug, PartialEq)]
pub enum Action {
    Get,
    Put,
    Delete,
    List,
    Last,
    ChangeDirectory,
}

pub fn get_request() -> ToResult<Request> {
    let yaml = load_yaml!("cli.yml");
    let app = App::from_yaml(yaml);
    let matches = app.get_matches();

    return get(matches);
}

pub fn get(matches: ArgMatches) -> ToResult<Request> {
    info!("building request from clap::{:?}", matches);

    let request = Request::new(Action::ChangeDirectory);
    return Ok(request);
}

#[cfg(test)]
mod tests {
    extern crate env_logger;
    extern crate clap;

    use super::*;
    use std::path::{PathBuf};

    fn run(mut args: Vec<&str>) -> Request {
        let logger_result = env_logger::init();
        assert!(logger_result.is_ok());

        args.insert(0, "to");

        let yaml = load_yaml!("cli.yml");
        let app = clap::App::from_yaml(yaml);
        let matches = app.get_matches_from(args);

        let result = get(matches);
        assert!(result.is_ok());

        return result.unwrap();
    }

    #[test]
    fn basic() {
        let request = get_request();
        assert!(request.is_ok());
    }

    #[test]
    fn to_name() -> () {
        let args = vec!["foo"];
        let request = run(args);

        assert_eq!(request.action, Action::ChangeDirectory);
        assert_eq!(request.name, "foo");
        assert_eq!(request.directory, PathBuf::from("bar"));
    }
}
<|endoftext|>


<commit_before>extern crate clap;
use clap::{App, ArgMatches};

struct ConfigBase {
    verbosity : bool,
    debugging : bool,
}

pub struct ModuleConfig {
    base : ConfigBase,
    load : bool,
}

impl ModuleConfig {
    pub fn new() -> ModuleConfig {
        ModuleConfig {
            base: ConfigBase {
                verbosity: false,
                debugging: false,
            },
            load: false,
        }
    }
}

pub struct Config {
    base            : ConfigBase,
    module_configs  : Vec<ModuleConfig>,
}

impl Config {
    pub fn new() -> Config {
        Config {
            base: ConfigBase {
                verbosity: false,
                debugging: false,
            },
            module_configs: vec![],
        }
    }
}

pub fn configure(config : &mut Config) {
    let yaml = load_yaml!("../etc/cli.yml");
    let matches = App::from_yaml(yaml).get_matches();

    parse_global_cfg(&matches, &mut config.base);

    if let Some(matches) = matches.subcommand_matches("test") {
        if matches.is_present("verbose") {
            println!("Printing verbosely...");
        } else {
            println!("Printing normally...");
        }
    }
}

fn parse_global_cfg(matches : &ArgMatches<>, config : &mut ConfigBase) {
    if matches.is_present("verbose") {
        config.verbosity = true;
    }

    if matches.is_present("debugging") {
        config.debugging = true;
    }
}

<commit_msg>Minify function<commit_after>extern crate clap;
use clap::{App, ArgMatches};

struct ConfigBase {
    verbosity : bool,
    debugging : bool,
}

pub struct ModuleConfig {
    base : ConfigBase,
    load : bool,
}

impl ModuleConfig {
    pub fn new() -> ModuleConfig {
        ModuleConfig {
            base: ConfigBase {
                verbosity: false,
                debugging: false,
            },
            load: false,
        }
    }
}

pub struct Config {
    base            : ConfigBase,
    module_configs  : Vec<ModuleConfig>,
}

impl Config {
    pub fn new() -> Config {
        Config {
            base: ConfigBase {
                verbosity: false,
                debugging: false,
            },
            module_configs: vec![],
        }
    }
}

pub fn configure(config : &mut Config) {
    let yaml = load_yaml!("../etc/cli.yml");
    let matches = App::from_yaml(yaml).get_matches();

    parse_global_cfg(&matches, &mut config.base);

    if let Some(matches) = matches.subcommand_matches("test") {
        if matches.is_present("verbose") {
            println!("Printing verbosely...");
        } else {
            println!("Printing normally...");
        }
    }
}

fn parse_global_cfg(matches : &ArgMatches<>, config : &mut ConfigBase) {
    config.verbosity = matches.is_present("verbose");
    config.debugging = matches.is_present("debugging");
}

<|endoftext|>


<commit_before>// Copyright 2013-2014 The Rust Project Developers.
// Copyright 2018 The Uuid Project Developers.
//
// See the COPYRIGHT file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use crate::{error::*, std::fmt, Uuid};
use serde::{
    de::{self, Error as _},
    Deserialize, Deserializer, Serialize, Serializer,
};

impl Serialize for Uuid {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        if serializer.is_human_readable() {
            serializer
                .serialize_str(self.to_hyphenated().encode_lower(&mut [0; 36]))
        } else {
            self.as_bytes().serialize(serializer)
        }
    }
}

impl<'de> Deserialize<'de> for Uuid {
    fn deserialize<D: Deserializer<'de>>(
        deserializer: D,
    ) -> Result<Self, D::Error> {
        fn de_error<E: de::Error>(e: Error) -> E {
            E::custom(format_args!("UUID parsing failed: {}", e))
        }

        if deserializer.is_human_readable() {
            struct UuidVisitor;

            impl<'vi> de::Visitor<'vi> for UuidVisitor {
                type Value = Uuid;

                fn expecting(
                    &self,
                    formatter: &mut fmt::Formatter<'_>,
                ) -> fmt::Result {
                    write!(formatter, "a UUID string")
                }

                fn visit_str<E: de::Error>(
                    self,
                    value: &str,
                ) -> Result<Uuid, E> {
                    value.parse::<Uuid>().map_err(de_error)
                }

                fn visit_bytes<E: de::Error>(
                    self,
                    value: &[u8],
                ) -> Result<Uuid, E> {
                    Uuid::from_slice(value).map_err(de_error)
                }

                fn visit_seq<A>(self, mut seq: A) -> Result<Uuid, A::Error>
                where
                    A: de::SeqAccess<'vi>,
                {
                    #[rustfmt::skip]
                    let bytes = [
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                    ];

                    Ok(Uuid::from_bytes(bytes))
                }
            }

            deserializer.deserialize_str(UuidVisitor)
        } else {
            let bytes: [u8; 16] = Deserialize::deserialize(deserializer)?;

            Ok(Uuid::from_bytes(bytes))
        }
    }
}

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

    use serde_test::{Compact, Configure, Readable, Token};

    #[test]
    fn test_serialize_readable_string() {
        let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
        let u = Uuid::parse_str(uuid_str).unwrap();
        serde_test::assert_tokens(&u.readable(), &[Token::Str(uuid_str)]);
    }

    #[test]
    fn test_deserialize_readable_compact() {
        let uuid_bytes = b"F9168C5E-CEB2-4F";
        let u = Uuid::from_slice(uuid_bytes).unwrap();

        serde_test::assert_de_tokens(
            &u.readable(),
            &[
                serde_test::Token::Tuple { len: 16 },
                serde_test::Token::U8(uuid_bytes[0]),
                serde_test::Token::U8(uuid_bytes[1]),
                serde_test::Token::U8(uuid_bytes[2]),
                serde_test::Token::U8(uuid_bytes[3]),
                serde_test::Token::U8(uuid_bytes[4]),
                serde_test::Token::U8(uuid_bytes[5]),
                serde_test::Token::U8(uuid_bytes[6]),
                serde_test::Token::U8(uuid_bytes[7]),
                serde_test::Token::U8(uuid_bytes[8]),
                serde_test::Token::U8(uuid_bytes[9]),
                serde_test::Token::U8(uuid_bytes[10]),
                serde_test::Token::U8(uuid_bytes[11]),
                serde_test::Token::U8(uuid_bytes[12]),
                serde_test::Token::U8(uuid_bytes[13]),
                serde_test::Token::U8(uuid_bytes[14]),
                serde_test::Token::U8(uuid_bytes[15]),
                serde_test::Token::TupleEnd,
            ],
        );
    }

    #[test]
    fn test_deserialize_readable_bytes() {
        let uuid_bytes = b"F9168C5E-CEB2-4F";
        let u = Uuid::from_slice(uuid_bytes).unwrap();

        serde_test::assert_de_tokens(
            &u.readable(),
            &[serde_test::Token::Bytes(uuid_bytes)],
        );
    }

    #[test]
    fn test_serialize_compact() {
        let uuid_bytes = b"F9168C5E-CEB2-4F";
        let u = Uuid::from_slice(uuid_bytes).unwrap();
        serde_test::assert_tokens(
            &u.compact(),
            &[
                serde_test::Token::Tuple { len: 16 },
                serde_test::Token::U8(uuid_bytes[0]),
                serde_test::Token::U8(uuid_bytes[1]),
                serde_test::Token::U8(uuid_bytes[2]),
                serde_test::Token::U8(uuid_bytes[3]),
                serde_test::Token::U8(uuid_bytes[4]),
                serde_test::Token::U8(uuid_bytes[5]),
                serde_test::Token::U8(uuid_bytes[6]),
                serde_test::Token::U8(uuid_bytes[7]),
                serde_test::Token::U8(uuid_bytes[8]),
                serde_test::Token::U8(uuid_bytes[9]),
                serde_test::Token::U8(uuid_bytes[10]),
                serde_test::Token::U8(uuid_bytes[11]),
                serde_test::Token::U8(uuid_bytes[12]),
                serde_test::Token::U8(uuid_bytes[13]),
                serde_test::Token::U8(uuid_bytes[14]),
                serde_test::Token::U8(uuid_bytes[15]),
                serde_test::Token::TupleEnd,
            ],
        );
    }

    #[test]
    fn test_de_failure() {
        serde_test::assert_de_tokens_error::<Readable<Uuid>>(
            &[Token::Str("hello_world")],
            "UUID parsing failed: invalid length: expected one of [36, 32], found 11",
        );

        serde_test::assert_de_tokens_error::<Compact<Uuid>>(
            &[Token::Bytes(b"hello_world")],
            "invalid type: byte array, expected an array of length 16",
        );
    }
}
<commit_msg>add Serialize impls for format adapters<commit_after>// Copyright 2013-2014 The Rust Project Developers.
// Copyright 2018 The Uuid Project Developers.
//
// See the COPYRIGHT file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use crate::{error::*, std::fmt, Uuid, fmt::{Hyphenated, HyphenatedRef, Simple, SimpleRef, Urn, UrnRef}};
use serde::{
    de::{self, Error as _},
    Deserialize, Deserializer, Serialize, Serializer,
};

impl Serialize for Uuid {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        if serializer.is_human_readable() {
            serializer
                .serialize_str(self.to_hyphenated().encode_lower(&mut Uuid::encode_buffer()))
        } else {
            self.as_bytes().serialize(serializer)
        }
    }
}

impl Serialize for Hyphenated {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
    }
}

impl Serialize for HyphenatedRef<'_> {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
    }
}

impl Serialize for Simple {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
    }
}

impl Serialize for SimpleRef<'_> {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
    }
}

impl Serialize for Urn {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
    }
}

impl Serialize for UrnRef<'_> {
    fn serialize<S: Serializer>(
        &self,
        serializer: S,
    ) -> Result<S::Ok, S::Error> {
        serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
    }
}

impl<'de> Deserialize<'de> for Uuid {
    fn deserialize<D: Deserializer<'de>>(
        deserializer: D,
    ) -> Result<Self, D::Error> {
        fn de_error<E: de::Error>(e: Error) -> E {
            E::custom(format_args!("UUID parsing failed: {}", e))
        }

        if deserializer.is_human_readable() {
            struct UuidVisitor;

            impl<'vi> de::Visitor<'vi> for UuidVisitor {
                type Value = Uuid;

                fn expecting(
                    &self,
                    formatter: &mut fmt::Formatter<'_>,
                ) -> fmt::Result {
                    write!(formatter, "a UUID string")
                }

                fn visit_str<E: de::Error>(
                    self,
                    value: &str,
                ) -> Result<Uuid, E> {
                    value.parse::<Uuid>().map_err(de_error)
                }

                fn visit_bytes<E: de::Error>(
                    self,
                    value: &[u8],
                ) -> Result<Uuid, E> {
                    Uuid::from_slice(value).map_err(de_error)
                }

                fn visit_seq<A>(self, mut seq: A) -> Result<Uuid, A::Error>
                where
                    A: de::SeqAccess<'vi>,
                {
                    #[rustfmt::skip]
                    let bytes = [
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                        match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(16, &self)) },
                    ];

                    Ok(Uuid::from_bytes(bytes))
                }
            }

            deserializer.deserialize_str(UuidVisitor)
        } else {
            let bytes: [u8; 16] = Deserialize::deserialize(deserializer)?;

            Ok(Uuid::from_bytes(bytes))
        }
    }
}

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

    use serde_test::{Compact, Configure, Readable, Token};

    #[test]
    fn test_serialize_readable_string() {
        let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
        let u = Uuid::parse_str(uuid_str).unwrap();
        serde_test::assert_tokens(&u.readable(), &[Token::Str(uuid_str)]);
    }

    #[test]
    fn test_deserialize_readable_compact() {
        let uuid_bytes = b"F9168C5E-CEB2-4F";
        let u = Uuid::from_slice(uuid_bytes).unwrap();

        serde_test::assert_de_tokens(
            &u.readable(),
            &[
                serde_test::Token::Tuple { len: 16 },
                serde_test::Token::U8(uuid_bytes[0]),
                serde_test::Token::U8(uuid_bytes[1]),
                serde_test::Token::U8(uuid_bytes[2]),
                serde_test::Token::U8(uuid_bytes[3]),
                serde_test::Token::U8(uuid_bytes[4]),
                serde_test::Token::U8(uuid_bytes[5]),
                serde_test::Token::U8(uuid_bytes[6]),
                serde_test::Token::U8(uuid_bytes[7]),
                serde_test::Token::U8(uuid_bytes[8]),
                serde_test::Token::U8(uuid_bytes[9]),
                serde_test::Token::U8(uuid_bytes[10]),
                serde_test::Token::U8(uuid_bytes[11]),
                serde_test::Token::U8(uuid_bytes[12]),
                serde_test::Token::U8(uuid_bytes[13]),
                serde_test::Token::U8(uuid_bytes[14]),
                serde_test::Token::U8(uuid_bytes[15]),
                serde_test::Token::TupleEnd,
            ],
        );
    }

    #[test]
    fn test_deserialize_readable_bytes() {
        let uuid_bytes = b"F9168C5E-CEB2-4F";
        let u = Uuid::from_slice(uuid_bytes).unwrap();

        serde_test::assert_de_tokens(
            &u.readable(),
            &[serde_test::Token::Bytes(uuid_bytes)],
        );
    }

    #[test]
    fn test_serialize_hyphenated() {
        let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
        let u = Uuid::parse_str(uuid_str).unwrap();
        serde_test::assert_ser_tokens(&u.to_hyphenated(), &[Token::Str(uuid_str)]);
    }

    #[test]
    fn test_serialize_simple() {
        let uuid_str = "f9168c5eceb24faab6bf329bf39fa1e4";
        let u = Uuid::parse_str(uuid_str).unwrap();
        serde_test::assert_ser_tokens(&u.to_simple(), &[Token::Str(uuid_str)]);
    }

    #[test]
    fn test_serialize_urn() {
        let uuid_str = "urn:uuid:f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
        let u = Uuid::parse_str(uuid_str).unwrap();
        serde_test::assert_ser_tokens(&u.to_urn(), &[Token::Str(uuid_str)]);
    }

    #[test]
    fn test_serialize_compact() {
        let uuid_bytes = b"F9168C5E-CEB2-4F";
        let u = Uuid::from_slice(uuid_bytes).unwrap();
        serde_test::assert_tokens(
            &u.compact(),
            &[
                serde_test::Token::Tuple { len: 16 },
                serde_test::Token::U8(uuid_bytes[0]),
                serde_test::Token::U8(uuid_bytes[1]),
                serde_test::Token::U8(uuid_bytes[2]),
                serde_test::Token::U8(uuid_bytes[3]),
                serde_test::Token::U8(uuid_bytes[4]),
                serde_test::Token::U8(uuid_bytes[5]),
                serde_test::Token::U8(uuid_bytes[6]),
                serde_test::Token::U8(uuid_bytes[7]),
                serde_test::Token::U8(uuid_bytes[8]),
                serde_test::Token::U8(uuid_bytes[9]),
                serde_test::Token::U8(uuid_bytes[10]),
                serde_test::Token::U8(uuid_bytes[11]),
                serde_test::Token::U8(uuid_bytes[12]),
                serde_test::Token::U8(uuid_bytes[13]),
                serde_test::Token::U8(uuid_bytes[14]),
                serde_test::Token::U8(uuid_bytes[15]),
                serde_test::Token::TupleEnd,
            ],
        );
    }

    #[test]
    fn test_de_failure() {
        serde_test::assert_de_tokens_error::<Readable<Uuid>>(
            &[Token::Str("hello_world")],
            "UUID parsing failed: invalid length: expected one of [36, 32], found 11",
        );

        serde_test::assert_de_tokens_error::<Compact<Uuid>>(
            &[Token::Bytes(b"hello_world")],
            "invalid type: byte array, expected an array of length 16",
        );
    }
}
<|endoftext|>


<commit_before>use instruction::{ Instruction, Register, Address, Value };
use rand;
use rand::Rng;

const INSTRUCTION_SIZE: u16 = 2;

pub struct Cpu {
    memory: [u8; 4096],
    registers: [u8; 16],
    index: u16,
    pc: u16,
    stack: [u16; 16],
    sp: u16,
    pub draw_flag: bool,
    pub faulted: bool,
}

impl Cpu {
    pub fn new(game_data: Vec<u8>) -> Cpu {
        let mut memory = [0; 4096];
        for (i, byte) in game_data.iter().enumerate() {
            memory[0x200 + i] = byte.clone();
        }

        Cpu {
            memory: memory,
            registers: [0; 16],
            index: 0,
            pc: 0x200,
            stack: [0; 16],
            sp: 0,
            draw_flag: false,
            faulted: false,
        }
    }

    pub fn cycle(&mut self) {
        if self.faulted {
            return
        }

        let raw_instruction = self.read_next_instruction();
        let instruction = Instruction::parse(raw_instruction);

        println!("[PC:0x{:X}] [RAW:0x{:X}] {}", self.pc, raw_instruction, instruction);

        if instruction == Instruction::InvalidOperation {
            self.faulted = true;
        } else {
            self.execute_instruction(instruction);
            self.print_registers();
        }
    }

    fn read_next_instruction(&self) -> (u16) {
        let upper = self.memory[self.pc as usize] as u16;
        let lower = self.memory[(self.pc + 1) as usize] as u16;
        upper << 8 | lower
    }

    fn execute_instruction(&mut self, instruction: Instruction) {
        match instruction {
            Instruction::Load(r, v) => self.load_value(r, v),
            Instruction::SetIndexRegister(a) => self.set_index(a),
            Instruction::Random(r, v) => self.rand(r, v),
            Instruction::Jump(a) => self.jump(a),
            Instruction::SkipIfEqual(r, v) => self.skip_equal(r, v),
            Instruction::Draw(r1, r2, v) => self.skip(),
            Instruction::Add(r, v) => self.add(r, v),
            Instruction::Assign(r1, r2) => self.assign(r1, r2),
            Instruction::InvalidOperation => {},
        };
    }

    fn read_register(&self, register: Register) -> Value {
        self.registers[register as usize]
    }

    fn set_register(&mut self, register: Register, value: Value) {
        self.registers[register as usize] = value;
    }

    fn skip(&mut self) {
        self.pc += 2;
    }

    fn load_value(&mut self, register: Register, value: Value) {
        self.set_register(register, value);
        self.pc += INSTRUCTION_SIZE;
    }

    fn add(&mut self, register: Register, value: Value) {
        let current_value = self.read_register(register);
        self.set_register(register, current_value + value);
        self.pc += INSTRUCTION_SIZE;
    }

    fn set_index(&mut self, addr: Address) {
        self.index = addr;
        self.pc += INSTRUCTION_SIZE;
    }

    fn jump(&mut self, addr: Address) {
        self.pc = addr;
    }

    fn skip_equal(&mut self, register: Register, value: Value) {
        let reg_val = self.read_register(register);
        let pc_skip = if reg_val == value {
            INSTRUCTION_SIZE * 2
        } else {
            INSTRUCTION_SIZE
        };
        self.pc += pc_skip;
    }

    fn assign(&mut self, register1: Register, register2: Register) {
        let reg2_val = self.read_register(register2);
        self.set_register(register1, reg2_val);
        self.pc += 2;
    }

    fn rand(&mut self, register: Register, value: Value) {
        let rand_val = rand::thread_rng().gen::<u8>();
        self.set_register(register, value & rand_val);
        self.pc += 2;
    }

    fn print_registers(&self) {
        let reg = self.registers;
        println!("V0:{} V1:{} V2:{} V3:{} V4:{} V5:{} V6:{} V7:{}",
            reg[0], reg[1], reg[2], reg[3], reg[4], reg[5], reg[6], reg[7]);
        println!("V8:{} V9:{} VA:{} VB:{} VC:{} VD:{} VE:{} VF:{}",
            reg[8], reg[9], reg[10], reg[11], reg[12], reg[13], reg[14], reg[15]);
    }
}
<commit_msg>Implemented timers<commit_after>use instruction::{ Instruction, Register, Address, Value };
use rand;
use rand::Rng;

const INSTRUCTION_SIZE: u16 = 2;

pub struct Cpu {
    memory: [u8; 4096],
    registers: [u8; 16],
    index: u16,
    pc: u16,
    stack: [u16; 16],
    sp: u16,
    del_timer: u8,
    sound_timer: u8,
    pub draw_flag: bool,
    pub faulted: bool,
}

impl Cpu {
    pub fn new(game_data: Vec<u8>) -> Cpu {
        let mut memory = [0; 4096];
        for (i, byte) in game_data.iter().enumerate() {
            memory[0x200 + i] = byte.clone();
        }

        Cpu {
            memory: memory,
            registers: [0; 16],
            index: 0,
            pc: 0x200,
            stack: [0; 16],
            sp: 0,
            draw_flag: false,
            faulted: false,
        }
    }

    pub fn cycle(&mut self) {
        if self.faulted {
            return
        }

        let raw_instruction = self.read_next_instruction();
        let instruction = Instruction::parse(raw_instruction);

        println!("[PC:0x{:X}] [RAW:0x{:X}] {}", self.pc, raw_instruction, instruction);

        if instruction == Instruction::InvalidOperation {
            self.faulted = true;
        } else {
            self.execute_instruction(instruction);
            self.print_registers();
            self.handle_timers();
        }
    }

    fn read_next_instruction(&self) -> (u16) {
        let upper = self.memory[self.pc as usize] as u16;
        let lower = self.memory[(self.pc + 1) as usize] as u16;
        upper << 8 | lower
    }

    fn execute_instruction(&mut self, instruction: Instruction) {
        match instruction {
            Instruction::Load(r, v) => self.load_value(r, v),
            Instruction::SetIndexRegister(a) => self.set_index(a),
            Instruction::Random(r, v) => self.rand(r, v),
            Instruction::Jump(a) => self.jump(a),
            Instruction::SkipIfEqual(r, v) => self.skip_equal(r, v),
            Instruction::Draw(r1, r2, v) => self.skip(),
            Instruction::Add(r, v) => self.add(r, v),
            Instruction::Assign(r1, r2) => self.assign(r1, r2),
            Instruction::InvalidOperation => {},
        };
    }

    fn handle_timers(&mut self) {
        if self.del_timer > 0 {
            self.del_timer -= 1;
        }

        if self.sound_timer > 0 {
            // BEEP!
            self.sound_timer -= 1;
        }
    }

    fn read_register(&self, register: Register) -> Value {
        self.registers[register as usize]
    }

    fn set_register(&mut self, register: Register, value: Value) {
        self.registers[register as usize] = value;
    }

    fn skip(&mut self) {
        self.pc += 2;
    }

    fn load_value(&mut self, register: Register, value: Value) {
        self.set_register(register, value);
        self.pc += INSTRUCTION_SIZE;
    }

    fn add(&mut self, register: Register, value: Value) {
        let current_value = self.read_register(register);
        self.set_register(register, current_value + value);
        self.pc += INSTRUCTION_SIZE;
    }

    fn set_index(&mut self, addr: Address) {
        self.index = addr;
        self.pc += INSTRUCTION_SIZE;
    }

    fn jump(&mut self, addr: Address) {
        self.pc = addr;
    }

    fn skip_equal(&mut self, register: Register, value: Value) {
        let reg_val = self.read_register(register);
        let pc_skip = if reg_val == value {
            INSTRUCTION_SIZE * 2
        } else {
            INSTRUCTION_SIZE
        };
        self.pc += pc_skip;
    }

    fn assign(&mut self, register1: Register, register2: Register) {
        let reg2_val = self.read_register(register2);
        self.set_register(register1, reg2_val);
        self.pc += 2;
    }

    fn rand(&mut self, register: Register, value: Value) {
        let rand_val = rand::thread_rng().gen::<u8>();
        self.set_register(register, value & rand_val);
        self.pc += 2;
    }

    fn print_registers(&self) {
        let reg = self.registers;
        println!("V0:{} V1:{} V2:{} V3:{} V4:{} V5:{} V6:{} V7:{}",
            reg[0], reg[1], reg[2], reg[3], reg[4], reg[5], reg[6], reg[7]);
        println!("V8:{} V9:{} VA:{} VB:{} VC:{} VD:{} VE:{} VF:{}",
            reg[8], reg[9], reg[10], reg[11], reg[12], reg[13], reg[14], reg[15]);
    }
}
<|endoftext|>


<commit_before>use super::Queue;

pub struct Node<V, K: Copy + PartialOrd = char> {
    c: K,
    left:  Option<Box<Node<V, K>>>,
    mid:   Option<Box<Node<V, K>>>,
    right: Option<Box<Node<V, K>>>,
    val: Option<V>,
}

impl<K: PartialOrd + Copy , V> Node<V, K> {
    fn new(c: K) -> Node<V, K> {
        Node {
            c: c,
            left: None,
            mid: None,
            right: None,
            val: None
        }
    }

    fn put(mut x: Option<Box<Node<V, K>>>, key: &[K], val: Option<V>, d: usize) -> (Option<Box<Node<V, K>>>, Option<V>) {
        let replaced;
        let c = key[d];
        if x.is_none() {
            if val.is_none() {  // no need to call put further
                return (x, None);
            }
            x = Some(Box::new(Node::new(c)));
        }
        let xc = x.as_ref().unwrap().c;
        if c < xc {
            let (left, repl) = Node::put(x.as_mut().unwrap().left.take(), key, val, d);
            x.as_mut().map(|n| n.left = left);
            replaced = repl;
        } else if c > xc {
            let (right, repl) = Node::put(x.as_mut().unwrap().right.take(), key, val, d);
            x.as_mut().map(|n| n.right = right);
            replaced = repl;
        } else if d < key.len()-1 {
            let (mid, repl) = Node::put(x.as_mut().unwrap().mid.take(), key, val, d+1);
            x.as_mut().map(|n| n.mid = mid);
            replaced = repl;
        } else {
            replaced = x.as_mut().unwrap().val.take();
            x.as_mut().map(|n| n.val = val);
        }
        (x, replaced)
    }

    fn get<'a>(x: Option<&'a Box<Node<V, K>>>, key: &[K], d: usize) -> Option<&'a Box<Node<V, K>>> {
        if x.is_none() {
            return None;
        }
        let c = key[d];
        let xc = x.unwrap().c;
        if c < xc {
            Node::get(x.unwrap().left.as_ref(), key, d)
        } else if c > xc {
            Node::get(x.unwrap().right.as_ref(), key, d)
        } else if d < key.len()-1 {
            Node::get(x.unwrap().mid.as_ref(), key, d+1)
        } else {
            x
        }
    }

    fn collect(x: Option<&Box<Node<V, K>>>, mut prefix: Vec<K>, queue: &mut Queue<Vec<K>>) {
        if x.is_none() {
            return;
        }
        Node::collect(x.unwrap().left.as_ref(), prefix.clone(), queue);
        let xc = x.unwrap().c;
        prefix.push(xc);
        if x.unwrap().val.is_some() {
            queue.enqueue(prefix.clone());
        }
        Node::collect(x.unwrap().mid.as_ref(), prefix.clone(), queue);
        prefix.pop();
        Node::collect(x.unwrap().right.as_ref(), prefix, queue);
    }

    fn longest_prefix_of<'a>(mut x: Option<&Box<Node<V, K>>>, query: &'a [K]) -> Option<&'a [K]> {
        let mut length = 0;
        let mut i = 0;
        while x.is_some() && i < query.len() {
            let c = query[i];
            let xc = x.unwrap().c;
            if c < xc {
                x = x.unwrap().left.as_ref();
            } else if c > xc {
                x = x.unwrap().right.as_ref();
            } else {
                i += 1;
                if x.unwrap().val.is_some() {
                    length = i;
                }
                x = x.unwrap().mid.as_ref();
            }
        }
        if length == 0 {
            None
        } else {
            Some(&query[..length])
        }
    }
}

/// Symbol table with string keys, implemented using a ternary search trie (TST).
pub struct TernarySearchTrie<V, K: PartialOrd + Copy = char> {
    root: Option<Box<Node<V, K>>>,
    n: usize
}

impl<K: PartialOrd + Copy, V> TernarySearchTrie<V, K>  {
    pub fn new() -> TernarySearchTrie<V, K> {
        TernarySearchTrie { root: None, n: 0 }
    }

    pub fn put(&mut self, key: &[K], val: V) {
        let (root, replaced) = Node::put(self.root.take(), key, Some(val), 0);
        self.root = root;
        // replace old val? or insert new?
        if replaced.is_none() {
            self.n += 1;
        }
    }

    pub fn get(&self, key: &[K]) -> Option<&V> {
        assert!(key.len() > 0, "key must have length >= 1");
        Node::get(self.root.as_ref(), key, 0).map_or(None, |n| n.val.as_ref())
    }

    pub fn delete(&mut self, key: &[K]) {
        let (root, replaced) = Node::put(self.root.take(), key, None, 0);
        self.root = root;
        // deleted?
        if replaced.is_some() {
            self.n -= 1;
        }
    }

    pub fn size(&self) -> usize {
        self.n
    }

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

    pub fn contains(&self, key: &[K]) -> bool {
        self.get(key).is_some()
    }

    pub fn longest_prefix_of<'a>(&self, query: &'a [K]) -> Option<&'a [K]> {
        Node::longest_prefix_of(self.root.as_ref(), query)
    }

    pub fn keys_with_prefix(&self, prefix: &[K]) -> Vec<Vec<K>> {
        let mut queue = Queue::new();
        let x = Node::get(self.root.as_ref(), prefix, 0);
        if x.is_some() {
            if x.unwrap().val.is_some() {
                queue.enqueue(prefix.into());
            }
            Node::collect(x.unwrap().mid.as_ref(), prefix.into(), &mut queue);
        }
        queue.into_iter().collect()
    }

    pub fn keys(&self) -> Vec<Vec<K>> {
        let mut queue = Queue::new();
        Node::collect(self.root.as_ref(), vec![], &mut queue);
        queue.into_iter().collect()
    }
}

#[test]
fn test_tst() {
    let mut t = TernarySearchTrie::new();
    assert_eq!(t.size(), 0);
    t.put(b"name", "Andelf");
    assert_eq!(t.size(), 1);
    assert!(t.contains(b"name"));
    t.put(b"name", "Fledna");
    assert_eq!(t.size(), 1);
    t.put(b"language", "Rust");
    assert_eq!(t.size(), 2);

    assert_eq!(t.get(b"name"), Some(&"Fledna"));
    assert_eq!(t.get(b"whatever"), None);

    t.delete(b"name");
    assert_eq!(t.size(), 1);
    assert_eq!(t.get(b"name"), None);

    t.put(b"name", "Lednaf");
    assert!(t.keys().contains(&"name".into()));
    assert!(t.keys().contains(&"language".into()));
    assert!(t.keys_with_prefix(b"lang").contains(&"language".into()));

    t.put(b"ban", "2333");
    t.put(b"banana", "2333");
    assert_eq!(t.longest_prefix_of(b"bananananana").unwrap(), b"banana");
}
<commit_msg>TernarySearchTrie: add get_mut()<commit_after>use super::Queue;

pub struct Node<V, K: Copy + PartialOrd = char> {
    c: K,
    left:  Option<Box<Node<V, K>>>,
    mid:   Option<Box<Node<V, K>>>,
    right: Option<Box<Node<V, K>>>,
    val: Option<V>,
}

impl<K: PartialOrd + Copy , V> Node<V, K> {
    fn new(c: K) -> Node<V, K> {
        Node {
            c: c,
            left: None,
            mid: None,
            right: None,
            val: None
        }
    }

    fn put(mut x: Option<Box<Node<V, K>>>, key: &[K], val: Option<V>, d: usize) -> (Option<Box<Node<V, K>>>, Option<V>) {
        let replaced;
        let c = key[d];
        if x.is_none() {
            if val.is_none() {  // no need to call put further
                return (x, None);
            }
            x = Some(Box::new(Node::new(c)));
        }
        let xc = x.as_ref().unwrap().c;
        if c < xc {
            let (left, repl) = Node::put(x.as_mut().unwrap().left.take(), key, val, d);
            x.as_mut().map(|n| n.left = left);
            replaced = repl;
        } else if c > xc {
            let (right, repl) = Node::put(x.as_mut().unwrap().right.take(), key, val, d);
            x.as_mut().map(|n| n.right = right);
            replaced = repl;
        } else if d < key.len()-1 {
            let (mid, repl) = Node::put(x.as_mut().unwrap().mid.take(), key, val, d+1);
            x.as_mut().map(|n| n.mid = mid);
            replaced = repl;
        } else {
            replaced = x.as_mut().unwrap().val.take();
            x.as_mut().map(|n| n.val = val);
        }
        (x, replaced)
    }

    fn get<'a>(x: Option<&'a Box<Node<V, K>>>, key: &[K], d: usize) -> Option<&'a Box<Node<V, K>>> {
        if x.is_none() {
            return None;
        }
        let c = key[d];
        let xc = x.unwrap().c;
        if c < xc {
            Node::get(x.unwrap().left.as_ref(), key, d)
        } else if c > xc {
            Node::get(x.unwrap().right.as_ref(), key, d)
        } else if d < key.len()-1 {
            Node::get(x.unwrap().mid.as_ref(), key, d+1)
        } else {
            x
        }
    }

    fn get_mut<'a>(x: Option<&'a mut Box<Node<V, K>>>, key: &[K], d: usize) -> Option<&'a mut Box<Node<V, K>>> {
        if x.is_none() {
            return None;
        }
        let c = key[d];
        let xc = x.as_ref().unwrap().c;
        if c < xc {
            Node::get_mut(x.unwrap().left.as_mut(), key, d)
        } else if c > xc {
            Node::get_mut(x.unwrap().right.as_mut(), key, d)
        } else if d < key.len()-1 {
            Node::get_mut(x.unwrap().mid.as_mut(), key, d+1)
        } else {
            x
        }
    }

    fn collect(x: Option<&Box<Node<V, K>>>, mut prefix: Vec<K>, queue: &mut Queue<Vec<K>>) {
        if x.is_none() {
            return;
        }
        Node::collect(x.unwrap().left.as_ref(), prefix.clone(), queue);
        let xc = x.unwrap().c;
        prefix.push(xc);
        if x.unwrap().val.is_some() {
            queue.enqueue(prefix.clone());
        }
        Node::collect(x.unwrap().mid.as_ref(), prefix.clone(), queue);
        prefix.pop();
        Node::collect(x.unwrap().right.as_ref(), prefix, queue);
    }

    fn longest_prefix_of<'a>(mut x: Option<&Box<Node<V, K>>>, query: &'a [K]) -> Option<&'a [K]> {
        let mut length = 0;
        let mut i = 0;
        while x.is_some() && i < query.len() {
            let c = query[i];
            let xc = x.unwrap().c;
            if c < xc {
                x = x.unwrap().left.as_ref();
            } else if c > xc {
                x = x.unwrap().right.as_ref();
            } else {
                i += 1;
                if x.unwrap().val.is_some() {
                    length = i;
                }
                x = x.unwrap().mid.as_ref();
            }
        }
        if length == 0 {
            None
        } else {
            Some(&query[..length])
        }
    }
}

/// Symbol table with string keys, implemented using a ternary search trie (TST).
pub struct TernarySearchTrie<V, K: PartialOrd + Copy = char> {
    root: Option<Box<Node<V, K>>>,
    n: usize
}

impl<K: PartialOrd + Copy, V> TernarySearchTrie<V, K>  {
    pub fn new() -> TernarySearchTrie<V, K> {
        TernarySearchTrie { root: None, n: 0 }
    }

    pub fn put(&mut self, key: &[K], val: V) {
        let (root, replaced) = Node::put(self.root.take(), key, Some(val), 0);
        self.root = root;
        // replace old val? or insert new?
        if replaced.is_none() {
            self.n += 1;
        }
    }

    pub fn get(&self, key: &[K]) -> Option<&V> {
        assert!(key.len() > 0, "key must have length >= 1");
        Node::get(self.root.as_ref(), key, 0).map_or(None, |n| n.val.as_ref())
    }

    pub fn get_mut(&mut self, key: &[K]) -> Option<&mut V> {
        assert!(key.len() > 0, "key must have length >= 1");
        Node::get_mut(self.root.as_mut(), key, 0).map_or(None, |n| n.val.as_mut())
    }

    pub fn delete(&mut self, key: &[K]) {
        let (root, replaced) = Node::put(self.root.take(), key, None, 0);
        self.root = root;
        // deleted?
        if replaced.is_some() {
            self.n -= 1;
        }
    }

    pub fn size(&self) -> usize {
        self.n
    }

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

    pub fn contains(&self, key: &[K]) -> bool {
        self.get(key).is_some()
    }

    pub fn longest_prefix_of<'a>(&self, query: &'a [K]) -> Option<&'a [K]> {
        Node::longest_prefix_of(self.root.as_ref(), query)
    }

    pub fn keys_with_prefix(&self, prefix: &[K]) -> Vec<Vec<K>> {
        let mut queue = Queue::new();
        let x = Node::get(self.root.as_ref(), prefix, 0);
        if x.is_some() {
            if x.unwrap().val.is_some() {
                queue.enqueue(prefix.into());
            }
            Node::collect(x.unwrap().mid.as_ref(), prefix.into(), &mut queue);
        }
        queue.into_iter().collect()
    }

    pub fn keys(&self) -> Vec<Vec<K>> {
        let mut queue = Queue::new();
        Node::collect(self.root.as_ref(), vec![], &mut queue);
        queue.into_iter().collect()
    }
}

#[test]
fn test_tst() {
    let mut t = TernarySearchTrie::new();
    assert_eq!(t.size(), 0);
    t.put(b"name", "Andelf");
    assert_eq!(t.size(), 1);
    assert!(t.contains(b"name"));
    t.put(b"name", "Fledna");
    assert_eq!(t.size(), 1);
    t.put(b"language", "Rust");
    assert_eq!(t.size(), 2);

    assert_eq!(t.get(b"name"), Some(&"Fledna"));
    assert_eq!(t.get(b"whatever"), None);

    t.delete(b"name");
    assert_eq!(t.size(), 1);
    assert_eq!(t.get(b"name"), None);

    t.put(b"name", "Lednaf");
    assert!(t.keys().contains(&"name".into()));
    assert!(t.keys().contains(&"language".into()));
    assert!(t.keys_with_prefix(b"lang").contains(&"language".into()));

    t.put(b"ban", "2333");
    t.put(b"banana", "2333");
    assert_eq!(t.longest_prefix_of(b"bananananana").unwrap(), b"banana");

    t.get_mut(b"banana").map(|v| *v = "46666");
    assert_eq!(t.get(b"banana").unwrap(), &"46666");
}
<|endoftext|>


<commit_before>extern crate mio;
extern crate rand;

use mio::{EventLoop,Token,TryWrite};
use mio::tcp::*;
use mio::udp::*;
use mio::buf::*;
use rand::{thread_rng, Rng};
use std::fs::File;
use std::io::*;

trait QuoteProviderImpl {
  fn get_quote(&self, usize) -> String;
  fn get_random_quote(&self) -> String;
  fn new() -> Self;
}

struct QuoteProvider {
  quotes: Vec<String>,
}

impl QuoteProviderImpl for QuoteProvider {

  fn get_quote(&self, index: usize) -> String {
    //todo: pointers not clones?
    self.quotes[index].clone()
  }

  fn get_random_quote(&self) -> String {
    //todo: cache rng for improved perf
    let mut rng = thread_rng();
    let index: usize = rng.gen_range(0, self.quotes.len());
    self.get_quote(index)
  }

  fn new() -> QuoteProvider {
    let mut quotes: Vec<String> = Vec::new();
    println!("Reading wisdom...");
    //todo: check exists
    //todo: pass in as arg
    let path = "../../src/server/wisdom.txt";
    let result = File::open(path);
    match result {
        Ok(file) => {
            let reader = BufReader::new(file);
            for line in reader.lines() {
                match line {
                    Ok (line_str) => {
                        if line_str.len() > 0 {
                            quotes.push(line_str + "\r\n");
                        } else {
                            println!("Skipped blank line in file.");
                        }
                    },
                    Err(e) => println!("Invalid line. Skipping... {:?}",e)
                }
            }

        },
        Err(e) => println!("Failed to open wisdom file {:?}. {:?}", path, e)
    }

    QuoteProvider {quotes: quotes}
  }
}

const TCP_SERVER: mio::Token = mio::Token(0);
const UDP_SERVER: mio::Token = mio::Token(1);

struct Pong {
    tcp_server: TcpListener,
    udp_server: UdpSocket,
    quote_provider: QuoteProvider
}

impl mio::Handler for Pong {
    type Timeout = ();
    type Message = ();

    fn readable(&mut self, event_loop: &mut mio::EventLoop<Pong>, token: mio::Token, hint: mio::ReadHint) {
        match token {
            TCP_SERVER => {
                println!("the server socket is ready to accept a TCP connection");
                match self.tcp_server.accept() {
                    Ok(Some(mut connection)) => {
                        println!("accepted a socket {:?}", connection);
                        let quote = self.quote_provider.get_random_quote();
                        connection.write_slice(quote.as_bytes());
                    }
                    Ok(None) => {
                        println!("the server socket wasn't actually ready");
                    }
                    Err(e) => {
                        println!("listener.accept() errored: {}", e);
                        event_loop.shutdown();
                    }
                }
            }
            UDP_SERVER => {
                println!("the server socket is ready to accept a UDP connection");
                //let mut buf = [0, ..10];
                match self.udp_server.recv_from(buf) {
                    Ok((amt, src)) => {
                        // Send a reply to the socket we received data from
                        //let buf = buf.mut_slice_to(amt);
                        //buf.reverse();
                        //self.udp_server.send_to(buf, src);
                    }
                    Err(e) => println!("couldn't receive a datagram: {}", e)
                }
            }
            _ => panic!("Received unknown token"),
        }
    }

    fn writable(&mut self, event_loop: &mut EventLoop<Pong>, token: Token) {
        match token {
            TCP_SERVER => println!("received writable for token 0"),
            _ => panic!("Unexpected token")
        };
    }
}

fn main() {

    let quote_provider: QuoteProvider = QuoteProviderImpl::new();
    println!("Sample quote: {:?}", quote_provider.get_random_quote());

    let address = "0.0.0.0:6567".parse().unwrap();
    let tcp_server = TcpListener::bind(&address).unwrap();
    let udp_server = UdpSocket::v4().unwrap();
    udp_server.bind(&address);

    let mut event_loop = mio::EventLoop::new().unwrap();
    let _ = event_loop.register(&tcp_server, TCP_SERVER);

    println!("running pingpong server");
    let _ = event_loop.run(&mut Pong
    {
        tcp_server: tcp_server,
        udp_server: udp_server,
        quote_provider: quote_provider
    });

    drop(udp_server); // close the socket
    drop(tcp_server);

}<commit_msg>udp server impl, but no response<commit_after>extern crate mio;
extern crate rand;

use mio::{EventLoop,Token,TryWrite, Interest, PollOpt};
use mio::tcp::*;
use mio::udp::*;
use mio::buf::*;
use rand::{thread_rng, Rng};
use std::fs::File;
use std::io::*;

trait QuoteProviderImpl {
  fn get_quote(&self, usize) -> String;
  fn get_random_quote(&self) -> String;
  fn new() -> Self;
}

struct QuoteProvider {
  quotes: Vec<String>,
}

impl QuoteProviderImpl for QuoteProvider {

  fn get_quote(&self, index: usize) -> String {
    //todo: pointers not clones?
    self.quotes[index].clone()
  }

  fn get_random_quote(&self) -> String {
    //todo: cache rng for improved perf
    let mut rng = thread_rng();
    let index: usize = rng.gen_range(0, self.quotes.len());
    self.get_quote(index)
  }

  fn new() -> QuoteProvider {
    let mut quotes: Vec<String> = Vec::new();
    println!("Reading wisdom...");
    //todo: check exists
    //todo: pass in as arg
    let path = "../../src/server/wisdom.txt";
    let result = File::open(path);
    match result {
        Ok(file) => {
            let reader = BufReader::new(file);
            for line in reader.lines() {
                match line {
                    Ok (line_str) => {
                        if line_str.len() > 0 {
                            quotes.push(line_str + "\r\n");
                        } else {
                            println!("Skipped blank line in file.");
                        }
                    },
                    Err(e) => println!("Invalid line. Skipping... {:?}",e)
                }
            }

        },
        Err(e) => println!("Failed to open wisdom file {:?}. {:?}", path, e)
    }

    QuoteProvider {quotes: quotes}
  }
}

const TCP_SERVER: mio::Token = mio::Token(0);
const UDP_SERVER: mio::Token = mio::Token(1);

struct Pong {
    tcp_server: TcpListener,
    udp_server: UdpSocket,
    quote_provider: QuoteProvider
}

impl mio::Handler for Pong {
    type Timeout = ();
    type Message = ();

    fn readable(&mut self, event_loop: &mut mio::EventLoop<Pong>, token: mio::Token, hint: mio::ReadHint) {
        match token {
            TCP_SERVER => {
                println!("the server socket is ready to accept a TCP connection");
                match self.tcp_server.accept() {
                    Ok(Some(mut connection)) => {
                        println!("accepted a socket {:?}", connection);
                        let quote = self.quote_provider.get_random_quote();
                        match connection.write_slice(quote.as_bytes()) {
                            Ok(x) => println!("Wrote to tcp"),
                            Err(e) => println!("Failed to write")

                        }
                    }
                    Ok(None) => {
                        println!("the server socket wasn't actually ready")
                    }
                    Err(e) => {
                        println!("listener.accept() errored: {}", e);
                        event_loop.shutdown();
                    }
                }
            }
            UDP_SERVER => {
                println!("the server socket is ready to accept a UDP connection");
                let mut buf = [0; 128];
                match self.udp_server.recv_from(&mut MutSliceBuf::wrap(&mut buf)) {
                    Ok(Some(addr)) => {
                        let mut quote = self.quote_provider.get_random_quote();
                        let mut quote_buf = SliceBuf::wrap(&mut quote.as_bytes());
                        match self.udp_server.send_to(&mut quote_buf, &addr) {
                            Ok(_) => println!("Wrote to udp"),
                            Err(e) => println!("Faile to write to udp")
                        }
                    }
                    Ok(None) => println!("Couldn't write to socket? Or was it just empty?"),
                    Err(e) => println!("couldn't receive a datagram: {}", e)
                }
            }
            _ => panic!("Received unknown token"),
        }
    }

    fn writable(&mut self, event_loop: &mut EventLoop<Pong>, token: Token) {
        match token {
            TCP_SERVER => println!("received writable for TCP_SERVER"),
            UDP_SERVER => println!("received writable for UDP_SERVER"),
            _ => panic!("Unexpected token")
        };
    }
}

fn main() {

    let quote_provider: QuoteProvider = QuoteProviderImpl::new();
    println!("Sample quote: {:?}", quote_provider.get_random_quote());

    let address = "0.0.0.0:6567".parse().unwrap();
    let tcp_server = TcpListener::bind(&address).unwrap();
    let udp_server = UdpSocket::v4().unwrap();
    let _ = udp_server.bind(&address);

    let mut event_loop = mio::EventLoop::new().unwrap();
    let _ = event_loop.register_opt(&tcp_server, TCP_SERVER, Interest::all(), PollOpt::edge());
    let _ = event_loop.register_opt(&udp_server, UDP_SERVER, Interest::readable(), PollOpt::edge());

    println!("running pingpong server");
    let mut pong = Pong
    {
        tcp_server: tcp_server,
        udp_server: udp_server,
        quote_provider: quote_provider
    };
    let _ = event_loop.run(&mut pong);

    drop(pong.udp_server); // close the socket
    drop(pong.tcp_server);

}<|endoftext|>


<commit_before>use crate::chain::Chain;
use crate::error::ErrorImpl;
use core::fmt::{self, Debug, Write};

impl ErrorImpl<()> {
    pub(crate) fn display(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.error())?;

        if f.alternate() {
            for cause in self.chain().skip(1) {
                write!(f, ": {}", cause)?;
            }
        }

        Ok(())
    }

    pub(crate) fn debug(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let error = self.error();

        if f.alternate() {
            return Debug::fmt(error, f);
        }

        write!(f, "{}", error)?;

        if let Some(cause) = error.source() {
            write!(f, "\n\nCaused by:")?;
            let multiple = cause.source().is_some();
            for (n, error) in Chain::new(cause).enumerate() {
                writeln!(f)?;
                let mut indented = Indented {
                    inner: f,
                    ind: if multiple { Some(n) } else { None },
                    started: false,
                };
                write!(indented, "{}", error)?;
            }
        }

        #[cfg(backtrace)]
        {
            use std::backtrace::BacktraceStatus;

            let backtrace = self.backtrace();
            if let BacktraceStatus::Captured = backtrace.status() {
                let mut backtrace = backtrace.to_string();
                if backtrace.starts_with("stack backtrace:") {
                    // Capitalize to match "Caused by:"
                    backtrace.replace_range(0..1, "S");
                }
                backtrace.truncate(backtrace.trim_end().len());
                write!(f, "\n\n{}", backtrace)?;
            }
        }

        Ok(())
    }
}

struct Indented<'a, D> {
    inner: &'a mut D,
    ind: Option<usize>,
    started: bool,
}

impl<T> Write for Indented<'_, T>
where
    T: Write,
{
    fn write_str(&mut self, s: &str) -> fmt::Result {
        for (ind, line) in s.split('\n').enumerate() {
            if !self.started {
                self.started = true;
                match self.ind {
                    Some(ind) => self.inner.write_fmt(format_args!("{: >5}: ", ind))?,
                    None => self.inner.write_fmt(format_args!("    "))?,
                }
            } else if ind > 0 {
                self.inner.write_char('\n')?;
                if self.ind.is_some() {
                    self.inner.write_fmt(format_args!("       "))?;
                } else {
                    self.inner.write_fmt(format_args!("    "))?;
                }
            }

            self.inner.write_fmt(format_args!("{}", line))?;
        }

        Ok(())
    }
}

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

    #[test]
    fn one_digit() {
        let input = "verify\nthis";
        let expected = "    2: verify\n       this";
        let mut output = String::new();

        Indented {
            inner: &mut output,
            ind: Some(2),
            started: false,
        }
        .write_str(input)
        .unwrap();

        assert_eq!(expected, output);
    }

    #[test]
    fn two_digits() {
        let input = "verify\nthis";
        let expected = "   12: verify\n       this";
        let mut output = String::new();

        Indented {
            inner: &mut output,
            ind: Some(12),
            started: false,
        }
        .write_str(input)
        .unwrap();

        assert_eq!(expected, output);
    }

    #[test]
    fn no_digits() {
        let input = "verify\nthis";
        let expected = "    verify\n    this";
        let mut output = String::new();

        Indented {
            inner: &mut output,
            ind: None,
            started: false,
        }
        .write_str(input)
        .unwrap();

        assert_eq!(expected, output);
    }
}
<commit_msg>Simplify string writing in Indented<commit_after>use crate::chain::Chain;
use crate::error::ErrorImpl;
use core::fmt::{self, Debug, Write};

impl ErrorImpl<()> {
    pub(crate) fn display(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.error())?;

        if f.alternate() {
            for cause in self.chain().skip(1) {
                write!(f, ": {}", cause)?;
            }
        }

        Ok(())
    }

    pub(crate) fn debug(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let error = self.error();

        if f.alternate() {
            return Debug::fmt(error, f);
        }

        write!(f, "{}", error)?;

        if let Some(cause) = error.source() {
            write!(f, "\n\nCaused by:")?;
            let multiple = cause.source().is_some();
            for (n, error) in Chain::new(cause).enumerate() {
                writeln!(f)?;
                let mut indented = Indented {
                    inner: f,
                    ind: if multiple { Some(n) } else { None },
                    started: false,
                };
                write!(indented, "{}", error)?;
            }
        }

        #[cfg(backtrace)]
        {
            use std::backtrace::BacktraceStatus;

            let backtrace = self.backtrace();
            if let BacktraceStatus::Captured = backtrace.status() {
                let mut backtrace = backtrace.to_string();
                if backtrace.starts_with("stack backtrace:") {
                    // Capitalize to match "Caused by:"
                    backtrace.replace_range(0..1, "S");
                }
                backtrace.truncate(backtrace.trim_end().len());
                write!(f, "\n\n{}", backtrace)?;
            }
        }

        Ok(())
    }
}

struct Indented<'a, D> {
    inner: &'a mut D,
    ind: Option<usize>,
    started: bool,
}

impl<T> Write for Indented<'_, T>
where
    T: Write,
{
    fn write_str(&mut self, s: &str) -> fmt::Result {
        for (ind, line) in s.split('\n').enumerate() {
            if !self.started {
                self.started = true;
                match self.ind {
                    Some(ind) => write!(self.inner, "{: >5}: ", ind)?,
                    None => self.inner.write_str("    ")?,
                }
            } else if ind > 0 {
                self.inner.write_char('\n')?;
                if self.ind.is_some() {
                    self.inner.write_str("       ")?;
                } else {
                    self.inner.write_str("    ")?;
                }
            }

            self.inner.write_str(line)?;
        }

        Ok(())
    }
}

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

    #[test]
    fn one_digit() {
        let input = "verify\nthis";
        let expected = "    2: verify\n       this";
        let mut output = String::new();

        Indented {
            inner: &mut output,
            ind: Some(2),
            started: false,
        }
        .write_str(input)
        .unwrap();

        assert_eq!(expected, output);
    }

    #[test]
    fn two_digits() {
        let input = "verify\nthis";
        let expected = "   12: verify\n       this";
        let mut output = String::new();

        Indented {
            inner: &mut output,
            ind: Some(12),
            started: false,
        }
        .write_str(input)
        .unwrap();

        assert_eq!(expected, output);
    }

    #[test]
    fn no_digits() {
        let input = "verify\nthis";
        let expected = "    verify\n    this";
        let mut output = String::new();

        Indented {
            inner: &mut output,
            ind: None,
            started: false,
        }
        .write_str(input)
        .unwrap();

        assert_eq!(expected, output);
    }
}
<|endoftext|>