<commit_before>use rand::random;

#[derive(Debug,PartialEq)]
pub struct SrcBlock {
    pub name: String,
    pub src: Vec<SrcKind>
}

#[derive(Debug,PartialEq)]
pub struct DefBlock {
    pub name: String,
    pub defs: Vec<(String,VarKind)>
}

#[derive(Debug,PartialEq)]
pub enum BlockKind {
    Src(SrcBlock),
    Def(DefBlock),
}

/// delimited by new line
#[derive(Debug,PartialEq)]
pub enum SrcKind {
    Logic(String, LogicKind), // ex: item_logic has_item

    // references logic in env and emits varkind;
    // logic must resolve to true
    // ex: if item_logic give_quest
    If(ExpectKind, VarKind),

    Composite(String,ExpectKind,Vec<String>),
    Next(String), // ends execution and begins next node
}

#[derive(Debug,PartialEq)]
pub enum ExpectKind {
    All,
    Any,
    None,

    Ref(String) // references env variable set from logic
}
impl ExpectKind {
    pub fn parse(s: String) -> ExpectKind {
        match &s[..] {
            "all" => ExpectKind::All,
            "any" => ExpectKind::Any,
            "none" => ExpectKind::None,
            _ => ExpectKind::Ref(s),
        }
    }
}

impl SrcKind {
    pub fn parse(mut exp: Vec<String>) -> SrcKind {
        if exp[0] == "if" {
            if exp.len() == 3 {
                let last = exp.pop().unwrap();
                SrcKind::If(ExpectKind::parse(exp.pop().unwrap()),
                            VarKind::parse(last))
            }
            else { panic!("ERROR: Uneven IF Logic {:?}",exp) }
        }
        else if exp[0] == "next" {
            if exp.len() == 2 {
                SrcKind::Next(exp.pop().unwrap())
            }
            else { panic!("ERROR: Uneven NEXT Logic {:?}",exp) }
        }
        else {
            let keys = exp.remove(0);
            let mut keys: Vec<&str> = keys.split_terminator(':').collect();

            if keys.len() < 2 { // regular logic
                SrcKind::Logic(keys.pop().unwrap().to_owned(),
                               LogicKind::parse(exp))
            }
            else { // composite type
                let kind = ExpectKind::parse(keys.pop().unwrap().to_owned());
                match kind { // only formal expected types allowed
                    ExpectKind::Ref(_) => { panic!("ERROR: Informal ExpectKind found {:?}", kind) },
                    _ => {}
                }
                SrcKind::Composite(keys.pop().unwrap().to_owned(),
                                   kind,
                                   exp)
            }
        }
    }
}

/// delimited by new line
/// should resolve to boolean
#[derive(Debug,PartialEq)]
pub enum LogicKind {
    GT(String,f32), // weight > 1
    LT(String,f32),

    //boolean checks
    Is(String),
    IsNot(String),
}

impl LogicKind {
    pub fn parse(mut exp: Vec<String>) -> LogicKind {
        let len = exp.len();

        if len == 1 {
            let mut exp = exp.pop().unwrap();
            let inv = exp.remove(0);
            if inv == '!' {
                LogicKind::IsNot(exp)
            }
            else {
                LogicKind::Is(exp)
            }
        }
        else if len == 3 {
            let var = exp.pop().unwrap();
            let var = VarKind::parse(var);

            match var {
                VarKind::Num(num) => {
                    let sym = exp.pop().unwrap();
                    let key = exp.pop().unwrap();

                    if sym == ">" {
                        LogicKind::GT(key,num)
                    }
                    else if sym == "<" {
                        LogicKind::LT(key,num)
                    }
                    else { panic!("ERROR: Invalid LogicKind Syntax") }
                },
                _ => { panic!("ERROR: Invalid LogicKind Value {:?}",exp) }
            }
        }
        else { panic!("ERROR: Unbalanced LogicKind Syntax ({:?})",exp) }
    }
}

#[derive(Debug,PartialEq)]
pub enum VarKind {
    String(String),
    Num(f32),
    Bool(bool),
}

impl VarKind {
    pub fn parse(t: String) -> VarKind {
        let val;

        if let Ok(v) = t.parse::<f32>() {
            val = VarKind::Num(v);
        }
        else if let Ok(v) = t.parse::<bool>() {
            val = VarKind::Bool(v);
        }
        else { val = VarKind::String(t) }

        val
    }
}

pub struct Parser;
impl Parser {
    pub fn parse_blocks (src: &str) -> Vec<BlockKind> {
        let mut v = vec!();
        let mut exp = String::new();
        let mut exps: Vec<String> = vec!();
        let mut block: Option<BlockKind> = None;

        let mut in_string = false;
        let mut in_comment = false;
        let mut in_vec = false;

        for c in src.chars() {
            if c == '[' { in_vec = true; continue }
            else if c == ']' { in_vec = false; }
            else if c == '#' && !in_string { in_comment = true; }
            else if  c == '\n' && in_comment && !in_string {
                in_comment = false;
                continue;
            }

            if c == '\n' && in_vec { continue }

            if (c == ']' ||
                c == '#' ||
                c == '\n')
                && !in_string
            {
                for n in exp.split_whitespace() {
                    exps.push(n.trim().to_owned());
                }
                exp = String::new();

                if exps.len() < 1 { continue }

                // determine block type
                if block.is_none() {
                    let name = exps.pop().unwrap();

                    if name == "def" {
                        let b = DefBlock {
                            name: exps.pop().unwrap(),
                            defs: vec!()
                        };

                        block = Some(BlockKind::Def(b));
                    }
                    else {
                        let b = SrcBlock {
                            name: name,
                            src: vec!()
                        };

                        block = Some(BlockKind::Src(b));
                    }
                }
                else { // build block type
                    let mut qsyms = vec!();
                    for n in exps.iter_mut() {
                        if n.chars().next().expect("ERROR: Empty QSYM") == '\'' {
                            let mut qsym = "__".to_owned();
                            let sym = n[1..].trim().to_owned();
                            qsym.push_str(&random::<u16>().to_string());

                            qsyms.push(qsym.clone());
                            qsyms.push(sym);
                            *n = qsym;
                        }
                    }

                    match block {
                        Some(BlockKind::Def(ref mut b)) => {
                            b.defs.push((exps[0].to_owned(),
                                         VarKind::parse(exps[1].to_owned())));
                        },
                        Some(BlockKind::Src(ref mut b)) => {
                            println!("EXPS{:?}",exps);
                            if qsyms.len() > 1 {
                                b.src.push(SrcKind::parse(qsyms));
                            }

                            b.src.push(SrcKind::parse(exps));
                        },
                        _ => {}
                    }

                    exps = vec!();
                }
            }
            else if c == '"' && !in_comment {
                in_string = !in_string;
                if in_string {
                    for n in exp.split_whitespace() {
                        exps.push(n.trim().to_owned());
                    }
                    exp = String::new();
                }
                else if !in_string {
                    exps.push(exp);
                    exp = String::new();
                }
            }
            else if c == ';' && !in_string && !in_comment {
                //fail otherwise, block should be built!
                v.push(block.unwrap());
                block = None;
            }
            else {
                if !in_comment {
                    exp.push(c);
                }
            }
        }

        v
    }
}
<commit_msg>remove debug print<commit_after>use rand::random;

#[derive(Debug,PartialEq)]
pub struct SrcBlock {
    pub name: String,
    pub src: Vec<SrcKind>
}

#[derive(Debug,PartialEq)]
pub struct DefBlock {
    pub name: String,
    pub defs: Vec<(String,VarKind)>
}

#[derive(Debug,PartialEq)]
pub enum BlockKind {
    Src(SrcBlock),
    Def(DefBlock),
}

/// delimited by new line
#[derive(Debug,PartialEq)]
pub enum SrcKind {
    Logic(String, LogicKind), // ex: item_logic has_item

    // references logic in env and emits varkind;
    // logic must resolve to true
    // ex: if item_logic give_quest
    If(ExpectKind, VarKind),

    Composite(String,ExpectKind,Vec<String>),
    Next(String), // ends execution and begins next node
}

#[derive(Debug,PartialEq)]
pub enum ExpectKind {
    All,
    Any,
    None,

    Ref(String) // references env variable set from logic
}
impl ExpectKind {
    pub fn parse(s: String) -> ExpectKind {
        match &s[..] {
            "all" => ExpectKind::All,
            "any" => ExpectKind::Any,
            "none" => ExpectKind::None,
            _ => ExpectKind::Ref(s),
        }
    }
}

impl SrcKind {
    pub fn parse(mut exp: Vec<String>) -> SrcKind {
        if exp[0] == "if" {
            if exp.len() == 3 {
                let last = exp.pop().unwrap();
                SrcKind::If(ExpectKind::parse(exp.pop().unwrap()),
                            VarKind::parse(last))
            }
            else { panic!("ERROR: Uneven IF Logic {:?}",exp) }
        }
        else if exp[0] == "next" {
            if exp.len() == 2 {
                SrcKind::Next(exp.pop().unwrap())
            }
            else { panic!("ERROR: Uneven NEXT Logic {:?}",exp) }
        }
        else {
            let keys = exp.remove(0);
            let mut keys: Vec<&str> = keys.split_terminator(':').collect();

            if keys.len() < 2 { // regular logic
                SrcKind::Logic(keys.pop().unwrap().to_owned(),
                               LogicKind::parse(exp))
            }
            else { // composite type
                let kind = ExpectKind::parse(keys.pop().unwrap().to_owned());
                match kind { // only formal expected types allowed
                    ExpectKind::Ref(_) => { panic!("ERROR: Informal ExpectKind found {:?}", kind) },
                    _ => {}
                }
                SrcKind::Composite(keys.pop().unwrap().to_owned(),
                                   kind,
                                   exp)
            }
        }
    }
}

/// delimited by new line
/// should resolve to boolean
#[derive(Debug,PartialEq)]
pub enum LogicKind {
    GT(String,f32), // weight > 1
    LT(String,f32),

    //boolean checks
    Is(String),
    IsNot(String),
}

impl LogicKind {
    pub fn parse(mut exp: Vec<String>) -> LogicKind {
        let len = exp.len();

        if len == 1 {
            let mut exp = exp.pop().unwrap();
            let inv = exp.remove(0);
            if inv == '!' {
                LogicKind::IsNot(exp)
            }
            else {
                LogicKind::Is(exp)
            }
        }
        else if len == 3 {
            let var = exp.pop().unwrap();
            let var = VarKind::parse(var);

            match var {
                VarKind::Num(num) => {
                    let sym = exp.pop().unwrap();
                    let key = exp.pop().unwrap();

                    if sym == ">" {
                        LogicKind::GT(key,num)
                    }
                    else if sym == "<" {
                        LogicKind::LT(key,num)
                    }
                    else { panic!("ERROR: Invalid LogicKind Syntax") }
                },
                _ => { panic!("ERROR: Invalid LogicKind Value {:?}",exp) }
            }
        }
        else { panic!("ERROR: Unbalanced LogicKind Syntax ({:?})",exp) }
    }
}

#[derive(Debug,PartialEq)]
pub enum VarKind {
    String(String),
    Num(f32),
    Bool(bool),
}

impl VarKind {
    pub fn parse(t: String) -> VarKind {
        let val;

        if let Ok(v) = t.parse::<f32>() {
            val = VarKind::Num(v);
        }
        else if let Ok(v) = t.parse::<bool>() {
            val = VarKind::Bool(v);
        }
        else { val = VarKind::String(t) }

        val
    }
}

pub struct Parser;
impl Parser {
    pub fn parse_blocks (src: &str) -> Vec<BlockKind> {
        let mut v = vec!();
        let mut exp = String::new();
        let mut exps: Vec<String> = vec!();
        let mut block: Option<BlockKind> = None;

        let mut in_string = false;
        let mut in_comment = false;
        let mut in_vec = false;

        for c in src.chars() {
            if c == '[' { in_vec = true; continue }
            else if c == ']' { in_vec = false; }
            else if c == '#' && !in_string { in_comment = true; }
            else if  c == '\n' && in_comment && !in_string {
                in_comment = false;
                continue;
            }

            if c == '\n' && in_vec { continue }

            if (c == ']' ||
                c == '#' ||
                c == '\n')
                && !in_string
            {
                for n in exp.split_whitespace() {
                    exps.push(n.trim().to_owned());
                }
                exp = String::new();

                if exps.len() < 1 { continue }

                // determine block type
                if block.is_none() {
                    let name = exps.pop().unwrap();

                    if name == "def" {
                        let b = DefBlock {
                            name: exps.pop().unwrap(),
                            defs: vec!()
                        };

                        block = Some(BlockKind::Def(b));
                    }
                    else {
                        let b = SrcBlock {
                            name: name,
                            src: vec!()
                        };

                        block = Some(BlockKind::Src(b));
                    }
                }
                else { // build block type
                    let mut qsyms = vec!();
                    for n in exps.iter_mut() {
                        if n.chars().next().expect("ERROR: Empty QSYM") == '\'' {
                            let mut qsym = "__".to_owned();
                            let sym = n[1..].trim().to_owned();
                            qsym.push_str(&random::<u16>().to_string());

                            qsyms.push(qsym.clone());
                            qsyms.push(sym);
                            *n = qsym;
                        }
                    }

                    match block {
                        Some(BlockKind::Def(ref mut b)) => {
                            b.defs.push((exps[0].to_owned(),
                                         VarKind::parse(exps[1].to_owned())));
                        },
                        Some(BlockKind::Src(ref mut b)) => {
                            //println!("EXPS{:?}",exps); //DEBUG
                            if qsyms.len() > 1 {
                                b.src.push(SrcKind::parse(qsyms));
                            }

                            b.src.push(SrcKind::parse(exps));
                        },
                        _ => {}
                    }

                    exps = vec!();
                }
            }
            else if c == '"' && !in_comment {
                in_string = !in_string;
                if in_string {
                    for n in exp.split_whitespace() {
                        exps.push(n.trim().to_owned());
                    }
                    exp = String::new();
                }
                else if !in_string {
                    exps.push(exp);
                    exp = String::new();
                }
            }
            else if c == ';' && !in_string && !in_comment {
                //fail otherwise, block should be built!
                v.push(block.unwrap());
                block = None;
            }
            else {
                if !in_comment {
                    exp.push(c);
                }
            }
        }

        v
    }
}
<|endoftext|>


<commit_before>//! Periodic timer
use core::u16;

use cast::{u16, u32};
use stm32f103xx::{Rcc, tim2, TIM2, TIM3, TIM4, TIM5};

use frequency;

pub use hal::timer::Timer as halTimer;

/// Specialized `Result` type
pub type Result<T> = ::core::result::Result<T, Error>;

/// An error
pub struct Error {
    _0: (),
}

/// General purpose timer
pub struct Timer<'a>{
    /// general purpose timer
    pub timer: &'a tim2::RegisterBlock,
}

impl<'a> Timer<'a>{
    /// return new timer
    pub fn new(timer: &'a tim2::RegisterBlock) -> Timer {
        Timer{timer}
    }

    /// initialize timer to frequency
    pub fn init(&self, rcc: &Rcc, ticks: u32) {
        // Power up peripherals
        // check which memory block this timer is pointing to
        match &*self.timer as *const _{
            x if x == TIM2.get() as *const _ => rcc.apb1enr.modify(|_, w| w.tim2en().enabled()),
            x if x == TIM3.get() as *const _ => rcc.apb1enr.modify(|_, w| w.tim3en().enabled()),
            x if x == TIM4.get() as *const _ => rcc.apb1enr.modify(|_, w| w.tim4en().enabled()),
            x if x == TIM5.get() as *const _ => rcc.apb1enr.modify(|_, w| w.tim5en().enabled()),
            _ => {},
        }

        let speeds = frequency::ClockSpeeds::get(rcc);

        //let ratio = speeds.apb1 / frequency;
        let psc = u16((ticks - 1) / u32(u16::MAX)).unwrap();
        self.timer.psc.write(|w| w.psc().bits(psc));
        let arr = u16(ticks / u32(psc + 1)).unwrap();
        self.timer.arr.write(|w| w.arr().bits(arr));

        self.timer.dier.write(|w| unsafe { w.uie().bits(1) });
        self.timer.cr1.write(|w| w.opm().continuous());
    }

    /// Clears the update event flag
    ///
    /// Returns `Err` if no update event has occurred
    pub fn clear_update_flag(&self) -> Result<()> {
        if self.timer.sr.read().uif().is_no_update() {
            Err(Error { _0: () })
        } else {
            self.timer.sr.modify(|_, w| w.uif().clear());
            Ok(())
        }
    }
}

impl<'a> halTimer for Timer<'a>{
    fn pause(&self){
            self.timer.cr1.modify(|_, w| w.cen().disabled());
    }

    fn resume(&self){
            self.timer.cr1.modify(|_, w| w.cen().enabled());
    }
}<commit_msg>using ticks to set up timer, so no need for frequecny<commit_after>//! Periodic timer
use core::u16;

use cast::{u16, u32};
use stm32f103xx::{Rcc, tim2, TIM2, TIM3, TIM4, TIM5};

pub use hal::timer::Timer as halTimer;

/// Specialized `Result` type
pub type Result<T> = ::core::result::Result<T, Error>;

/// An error
pub struct Error {
    _0: (),
}

/// General purpose timer
pub struct Timer<'a>{
    /// general purpose timer
    pub timer: &'a tim2::RegisterBlock,
}

impl<'a> Timer<'a>{
    /// return new timer
    pub fn new(timer: &'a tim2::RegisterBlock) -> Timer {
        Timer{timer}
    }

    /// initialize timer to frequency
    pub fn init(&self, rcc: &Rcc, ticks: u32) {
        // Power up peripherals
        // check which memory block this timer is pointing to
        match &*self.timer as *const _{
            x if x == TIM2.get() as *const _ => rcc.apb1enr.modify(|_, w| w.tim2en().enabled()),
            x if x == TIM3.get() as *const _ => rcc.apb1enr.modify(|_, w| w.tim3en().enabled()),
            x if x == TIM4.get() as *const _ => rcc.apb1enr.modify(|_, w| w.tim4en().enabled()),
            x if x == TIM5.get() as *const _ => rcc.apb1enr.modify(|_, w| w.tim5en().enabled()),
            _ => {},
        }

        let psc = u16((ticks - 1) / u32(u16::MAX)).unwrap();
        self.timer.psc.write(|w| w.psc().bits(psc));
        let arr = u16(ticks / u32(psc + 1)).unwrap();
        self.timer.arr.write(|w| w.arr().bits(arr));

        self.timer.dier.write(|w| unsafe { w.uie().bits(1) });
        self.timer.cr1.write(|w| w.opm().continuous());
    }

    /// Clears the update event flag
    ///
    /// Returns `Err` if no update event has occurred
    pub fn clear_update_flag(&self) -> Result<()> {
        if self.timer.sr.read().uif().is_no_update() {
            Err(Error { _0: () })
        } else {
            self.timer.sr.modify(|_, w| w.uif().clear());
            Ok(())
        }
    }
}

impl<'a> halTimer for Timer<'a>{
    fn pause(&self){
            self.timer.cr1.modify(|_, w| w.cen().disabled());
    }

    fn resume(&self){
            self.timer.cr1.modify(|_, w| w.cen().enabled());
    }
}<|endoftext|>


<commit_before>use errors;

// see OSC Type Tag String: http://opensoundcontrol.org/spec-1_0
// padding: zero bytes (n*4)

#[derive(Debug)]
pub enum OscType {
    Int(i32),
    Float(f32),
    String(String),
    Blob(Vec<u8>),
    Time(u32, u32),
    // nonstandard argument types
    // ignore them if not implemented
    Long(i64),
    Double(f64),
    Char(char),
    Color(u32), // byte-order: RGBA
    True,
    False,
    Midi(OscMidiMessage),
    Nil,
    Inf,
    Array(Vec<OscType>),
}

#[derive(Debug)]
pub struct OscMidiMessage {
    pub port: u8,
    pub status: u8,
    pub data1: u8, // maybe use an enum for data?
    pub data2: u8,
}

/// An *osc packet* can contain an *osc message* or a bundle of nested messages
/// which is called *osc bundle*.
#[derive(Debug)]
pub enum OscPacket {
    Message(OscMessage),
    Bundle(OscBundle),
}

#[derive(Debug)]
pub struct OscMessage {
    pub addr: String,
    pub args: Option<Vec<OscType>>,
}

#[derive(Debug)]
pub struct OscBundle {
    pub timetag: OscType,
    pub content: Vec<OscPacket>,
}

pub type OscResult<T> = Result<T, errors::OscError>;
<commit_msg>Combine True/False to Bool with boolean argument<commit_after>use errors;

// see OSC Type Tag String: http://opensoundcontrol.org/spec-1_0
// padding: zero bytes (n*4)

#[derive(Debug)]
pub enum OscType {
    Int(i32),
    Float(f32),
    String(String),
    Blob(Vec<u8>),
    Time(u32, u32),
    // nonstandard argument types
    // ignore them if not implemented
    Long(i64),
    Double(f64),
    Char(char),
    Color(u32), // byte-order: RGBA
    Midi(OscMidiMessage),
    Bool(bool),
    Nil,
    Inf,
    Array(Vec<OscType>),
}

#[derive(Debug)]
pub struct OscMidiMessage {
    pub port: u8,
    pub status: u8,
    pub data1: u8, // maybe use an enum for data?
    pub data2: u8,
}

/// An *osc packet* can contain an *osc message* or a bundle of nested messages
/// which is called *osc bundle*.
#[derive(Debug)]
pub enum OscPacket {
    Message(OscMessage),
    Bundle(OscBundle),
}

#[derive(Debug)]
pub struct OscMessage {
    pub addr: String,
    pub args: Option<Vec<OscType>>,
}

#[derive(Debug)]
pub struct OscBundle {
    pub timetag: OscType,
    pub content: Vec<OscPacket>,
}

pub type OscResult<T> = Result<T, errors::OscError>;
<|endoftext|>


<commit_before>//! Type conversions for binding parameters and getting query results.

use super::{PreparedStatement, ResultRow,
            ColIx, ParamIx};
use super::{
    SqliteResult,
};
use super::ColumnType::SQLITE_NULL;

use time;

/// Values that can be bound to parameters in prepared statements.
pub trait ToSql {
    /// Bind the `ix`th parameter to this value (`self`).
    fn to_sql(&self, s: &mut PreparedStatement, ix: ParamIx) -> SqliteResult<()>;
}

/// A trait for result values from a query.
///
/// cf [sqlite3 result values][column].
///
/// *inspired by sfackler's FromSql (and some haskell bindings?)*
///
/// [column]: http://www.sqlite.org/c3ref/column_blob.html
///
///   - *TODO: consider a `types` submodule*
///   - *TODO: many more implementors, including Option<T>*
pub trait FromSql {
    /// Try to extract a `Self` type value from the `col`th colum of a `ResultRow`.
    fn from_sql(row: &mut ResultRow, col: ColIx) -> SqliteResult<Self>;
}

impl ToSql for i32 {
    fn to_sql(&self, s: &mut PreparedStatement, ix: ParamIx) -> SqliteResult<()> {
        s.bind_int(ix, *self)
    }
}

impl FromSql for i32 {
    fn from_sql(row: &mut ResultRow, col: ColIx) -> SqliteResult<i32> { Ok(row.column_int(col)) }
}

impl ToSql for i64 {
    fn to_sql(&self, s: &mut PreparedStatement, ix: ParamIx) -> SqliteResult<()> {
        s.bind_int64(ix, *self)
    }
}

impl FromSql for i64 {
    fn from_sql(row: &mut ResultRow, col: ColIx) -> SqliteResult<i64> { Ok(row.column_int64(col)) }
}

impl ToSql for f64 {
    fn to_sql(&self, s: &mut PreparedStatement, ix: ParamIx) -> SqliteResult<()> {
        s.bind_double(ix, *self)
    }
}

impl FromSql for f64 {
    fn from_sql(row: &mut ResultRow, col: ColIx) -> SqliteResult<f64> { Ok(row.column_double(col)) }
}

impl<T: ToSql + Clone> ToSql for Option<T> {
    fn to_sql(&self, s: &mut PreparedStatement, ix: ParamIx) -> SqliteResult<()> {
        match (*self).clone() {
            Some(x) => x.to_sql(s, ix),
            None => s.bind_null(ix)
        }
    }
}

impl<T: FromSql + Clone> FromSql for Option<T> {
    fn from_sql(row: &mut ResultRow, col: ColIx) -> SqliteResult<Option<T>> {
        match row.column_type(col) {
            SQLITE_NULL => Ok(None),
            _ => FromSql::from_sql(row, col).map(|x| Some(x))
        }
    }
}

impl ToSql for String {
    fn to_sql(&self, s: &mut PreparedStatement, ix: ParamIx) -> SqliteResult<()> {
        s.bind_text(ix, (*self).as_slice())
    }
}

impl FromSql for String {
    fn from_sql(row: &mut ResultRow, col: ColIx) -> SqliteResult<String> {
        Ok(row.column_text(col).unwrap_or(String::new()))
    }
}

/// Format of sqlite date strings
///
/// From [Date And Time Functions][lang_datefunc]:
/// > The datetime() function returns "YYYY-MM-DD HH:MM:SS"
/// [lang_datefunc]: http://www.sqlite.org/lang_datefunc.html
pub static SQLITE_TIME_FMT: &'static str = "%F %T";

impl FromSql for time::Tm {
    fn from_sql(row: &mut ResultRow, col: ColIx) -> SqliteResult<time::Tm> {
        let txt = row.column_text(col).unwrap_or(String::new());
        let t = time::strptime(txt.as_slice(), SQLITE_TIME_FMT)
            .unwrap(); // unit tests ensure SQLITE_TIME_FMT is ok
        Ok(t)
    }
}

impl ToSql for time::Timespec {
    fn to_sql(&self, s: &mut PreparedStatement, ix: ParamIx) -> SqliteResult<()> {
        let timestr = time::at_utc(*self).strftime(SQLITE_TIME_FMT)
            .unwrap() // unit tests ensure SQLITE_TIME_FMT is ok
            .to_string();
        s.bind_text(ix, timestr.as_slice())
    }
}

impl FromSql for time::Timespec {
    /// TODO: propagate error message
    fn from_sql(row: &mut ResultRow, col: ColIx) -> SqliteResult<time::Timespec> {
        let tmo: SqliteResult<time::Tm> = FromSql::from_sql(row, col);
        tmo.map(|tm| tm.to_timespec())
    }
}

#[cfg(test)]
mod tests {
    use time::Tm;
    use super::super::{DatabaseConnection, SqliteResult};
    use super::super::{ResultRowAccess};

    #[test]
    fn get_tm() {
        fn go() -> SqliteResult<()> {
            let mut conn = try!(DatabaseConnection::in_memory());
            let mut stmt = try!(
                conn.prepare("select datetime('2001-01-01', 'weekday 3', '3 hours')"));
            let mut results = stmt.execute();
            match results.step() {
                Some(Ok(ref mut row)) => {
                    assert_eq!(
                        row.get::<u32, Tm>(0),
                        Tm { tm_sec: 0,
                             tm_min: 0,
                             tm_hour: 3,
                             tm_mday: 3,
                             tm_mon: 0,
                             tm_year: 101,
                             tm_wday: 0,
                             tm_yday: 0,
                             tm_isdst: 0,
                             tm_utcoff: 0,
                             tm_nsec: 0
                        });
                    Ok(())
                },
                None => panic!("no row"),
                Some(Err(oops)) =>  panic!("error: {:?}", oops)
            }
        }
        go().unwrap();
    }
}

// Local Variables:
// flycheck-rust-crate-root: "lib.rs"
// End:
<commit_msg>Fix panic when extracting a misformatted Tm<commit_after>//! Type conversions for binding parameters and getting query results.

use super::{PreparedStatement, ResultRow,
            ColIx, ParamIx};
use super::{
    SqliteResult, SqliteErrorCode, SqliteError,
};
use super::ColumnType::SQLITE_NULL;

use std::error::FromError;

use time;

/// Values that can be bound to parameters in prepared statements.
pub trait ToSql {
    /// Bind the `ix`th parameter to this value (`self`).
    fn to_sql(&self, s: &mut PreparedStatement, ix: ParamIx) -> SqliteResult<()>;
}

/// A trait for result values from a query.
///
/// cf [sqlite3 result values][column].
///
/// *inspired by sfackler's FromSql (and some haskell bindings?)*
///
/// [column]: http://www.sqlite.org/c3ref/column_blob.html
///
///   - *TODO: consider a `types` submodule*
///   - *TODO: many more implementors, including Option<T>*
pub trait FromSql {
    /// Try to extract a `Self` type value from the `col`th colum of a `ResultRow`.
    fn from_sql(row: &mut ResultRow, col: ColIx) -> SqliteResult<Self>;
}

impl ToSql for i32 {
    fn to_sql(&self, s: &mut PreparedStatement, ix: ParamIx) -> SqliteResult<()> {
        s.bind_int(ix, *self)
    }
}

impl FromSql for i32 {
    fn from_sql(row: &mut ResultRow, col: ColIx) -> SqliteResult<i32> { Ok(row.column_int(col)) }
}

impl ToSql for i64 {
    fn to_sql(&self, s: &mut PreparedStatement, ix: ParamIx) -> SqliteResult<()> {
        s.bind_int64(ix, *self)
    }
}

impl FromSql for i64 {
    fn from_sql(row: &mut ResultRow, col: ColIx) -> SqliteResult<i64> { Ok(row.column_int64(col)) }
}

impl ToSql for f64 {
    fn to_sql(&self, s: &mut PreparedStatement, ix: ParamIx) -> SqliteResult<()> {
        s.bind_double(ix, *self)
    }
}

impl FromSql for f64 {
    fn from_sql(row: &mut ResultRow, col: ColIx) -> SqliteResult<f64> { Ok(row.column_double(col)) }
}

impl<T: ToSql + Clone> ToSql for Option<T> {
    fn to_sql(&self, s: &mut PreparedStatement, ix: ParamIx) -> SqliteResult<()> {
        match (*self).clone() {
            Some(x) => x.to_sql(s, ix),
            None => s.bind_null(ix)
        }
    }
}

impl<T: FromSql + Clone> FromSql for Option<T> {
    fn from_sql(row: &mut ResultRow, col: ColIx) -> SqliteResult<Option<T>> {
        match row.column_type(col) {
            SQLITE_NULL => Ok(None),
            _ => FromSql::from_sql(row, col).map(|x| Some(x))
        }
    }
}

impl ToSql for String {
    fn to_sql(&self, s: &mut PreparedStatement, ix: ParamIx) -> SqliteResult<()> {
        s.bind_text(ix, (*self).as_slice())
    }
}

impl FromSql for String {
    fn from_sql(row: &mut ResultRow, col: ColIx) -> SqliteResult<String> {
        Ok(row.column_text(col).unwrap_or(String::new()))
    }
}

/// Format of sqlite date strings
///
/// From [Date And Time Functions][lang_datefunc]:
/// > The datetime() function returns "YYYY-MM-DD HH:MM:SS"
/// [lang_datefunc]: http://www.sqlite.org/lang_datefunc.html
pub static SQLITE_TIME_FMT: &'static str = "%F %T";

impl FromSql for time::Tm {
    fn from_sql(row: &mut ResultRow, col: ColIx) -> SqliteResult<time::Tm> {
        let txt = row.column_text(col).unwrap_or(String::new());
        Ok( try!(time::strptime(txt.as_slice(), SQLITE_TIME_FMT)) )
    }
}

impl FromError<time::ParseError> for SqliteError {
    fn from_error(err: time::ParseError) -> SqliteError {
        SqliteError {
            kind: SqliteErrorCode::SQLITE_MISMATCH,
            desc: "Time did not match expected format",
            detail: Some(format!("Time parsing error: {}", err)),
        }
    }
}

impl ToSql for time::Timespec {
    fn to_sql(&self, s: &mut PreparedStatement, ix: ParamIx) -> SqliteResult<()> {
        let timestr = time::at_utc(*self).strftime(SQLITE_TIME_FMT)
            .unwrap() // unit tests ensure SQLITE_TIME_FMT is ok
            .to_string();
        s.bind_text(ix, timestr.as_slice())
    }
}

impl FromSql for time::Timespec {
    /// TODO: propagate error message
    fn from_sql(row: &mut ResultRow, col: ColIx) -> SqliteResult<time::Timespec> {
        let tmo: SqliteResult<time::Tm> = FromSql::from_sql(row, col);
        tmo.map(|tm| tm.to_timespec())
    }
}

#[cfg(test)]
mod tests {
    use time::Tm;
    use super::super::{DatabaseConnection, SqliteResult, ResultSet};
    use super::super::{ResultRowAccess};

    fn with_query<T, F>(sql: &str, mut f: F) -> SqliteResult<T>
        where F: FnMut(&mut ResultSet) -> T
    {
        let mut db = try!(DatabaseConnection::in_memory());
        let mut s = try!(db.prepare(sql));
        let mut rows = s.execute();
        Ok(f(&mut rows))
    }

    #[test]
    fn get_tm() {
        fn go() -> SqliteResult<()> {
            let mut conn = try!(DatabaseConnection::in_memory());
            let mut stmt = try!(
                conn.prepare("select datetime('2001-01-01', 'weekday 3', '3 hours')"));
            let mut results = stmt.execute();
            match results.step() {
                Some(Ok(ref mut row)) => {
                    assert_eq!(
                        row.get::<u32, Tm>(0),
                        Tm { tm_sec: 0,
                             tm_min: 0,
                             tm_hour: 3,
                             tm_mday: 3,
                             tm_mon: 0,
                             tm_year: 101,
                             tm_wday: 0,
                             tm_yday: 0,
                             tm_isdst: 0,
                             tm_utcoff: 0,
                             tm_nsec: 0
                        });
                    Ok(())
                },
                None => panic!("no row"),
                Some(Err(oops)) =>  panic!("error: {:?}", oops)
            }
        }
        go().unwrap();
    }

    #[test]
    fn get_invalid_tm() {
        with_query("select 'not a time'", |&mut: results| {
            match results.step() {
                Some(Ok(ref mut row)) => {
                    let x : SqliteResult<Tm> = row.get_opt(0u32);
                    assert!(x.is_err());
                },
                None => panic!("no row"),
                Some(Err(oops)) =>  panic!("error: {:?}", oops)
            };
        }).unwrap();
    }
}

// Local Variables:
// flycheck-rust-crate-root: "lib.rs"
// End:
<|endoftext|>


<commit_before>use std::process::Output;
use cr_result::{CrResult, err_message};

pub fn check_output(out: &Output) -> CrResult<()> {
    if out.status.success() {
        return Ok(());
    }

    err_message(format!("{}\n{}\n",
                        String::from_utf8_lossy(&out.stdout),
                        String::from_utf8_lossy(&out.stderr)))
}
<commit_msg>Only use stderr output as error message of failed processes<commit_after>use std::process::Output;
use cr_result::{CrResult, err_message};

pub fn check_output(out: &Output) -> CrResult<()> {
    if out.status.success() {
        return Ok(());
    }

    err_message(String::from_utf8_lossy(&out.stderr).into_owned())
}
<|endoftext|>


<commit_before>//! Contains the different types of values understood by XML-RPC.

use utils::{escape_xml, format_datetime};

use base64::encode;
use iso8601::DateTime;

use std::collections::BTreeMap;
use std::io::{self, Write};

/// The possible XML-RPC values.
#[derive(Clone, Debug, PartialEq)]
pub enum Value {
    /// `<i4>` or `<int>`, 32-bit signed integer.
    Int(i32),
    /// `<i8>`, 64-bit signed integer.
    ///
    /// This is a non-standard feature that may not be supported on all servers
    /// or clients.
    Int64(i64),
    /// `<boolean>`, 0 == `false`, 1 == `true`.
    Bool(bool),
    /// `<string>`
    // FIXME zero-copy? `Cow<'static, ..>`?
    String(String),
    /// `<double>`
    Double(f64),
    /// `<dateTime.iso8601>`, an ISO 8601 formatted date/time value.
    DateTime(DateTime),
    /// `<base64>`, base64-encoded binary data.
    Base64(Vec<u8>),

    /// `<struct>`, a mapping of named values.
    Struct(BTreeMap<String, Value>),
    /// `<array>`, a list of arbitrary (heterogeneous) values.
    Array(Vec<Value>),

    /// `</nil>`
    ///
    /// Ref: https://web.archive.org/web/20050911054235/http://ontosys.com/xml-rpc/extensions.php
    Nil
}

impl Value {
    /// Formats this `Value` as an XML `<value>` element.
    pub fn write_as_xml<W: Write>(&self, fmt: &mut W) -> io::Result<()> {
        writeln!(fmt, "<value>")?;

        match *self {
            Value::Int(i) => {
                writeln!(fmt, "<i4>{}</i4>", i)?;
            }
            Value::Int64(i) => {
                writeln!(fmt, "<i8>{}</i8>", i)?;
            }
            Value::Bool(b) => {
                writeln!(fmt, "<boolean>{}</boolean>", if b { "1" } else { "0" })?;
            }
            Value::String(ref s) => {
                writeln!(fmt, "<string>{}</string>", escape_xml(s))?;
            }
            Value::Double(d) => {
                writeln!(fmt, "<double>{}</double>", d)?;
            }
            Value::DateTime(date_time) => {
                writeln!(fmt, "<dateTime.iso8601>{}</dateTime.iso8601>", format_datetime(&date_time))?;
            }
            Value::Base64(ref data) => {
                writeln!(fmt, "<base64>{}</base64>", encode(data))?;
            }
            Value::Struct(ref map) => {
                writeln!(fmt, "<struct>")?;
                for (ref name, ref value) in map {
                    writeln!(fmt, "<member>")?;
                    writeln!(fmt, "<name>{}</name>", escape_xml(name))?;
                    value.write_as_xml(fmt)?;
                    writeln!(fmt, "</member>")?;
                }
                writeln!(fmt, "</struct>")?;
            }
            Value::Array(ref array) => {
                writeln!(fmt, "<array>")?;
                writeln!(fmt, "<data>")?;
                for value in array {
                    value.write_as_xml(fmt)?;
                }
                writeln!(fmt, "</data>")?;
                writeln!(fmt, "</array>")?;
            }
            Value::Nil => {
                writeln!(fmt, "<nil/>")?;
            }
        }

        writeln!(fmt, "</value>")?;
        Ok(())
    }
}

impl From<i32> for Value {
    fn from(other: i32) -> Self {
        Value::Int(other)
    }
}

impl From<i64> for Value {
    fn from(other: i64) -> Self {
        Value::Int64(other)
    }
}

impl From<bool> for Value {
    fn from(other: bool) -> Self {
        Value::Bool(other)
    }
}

impl From<String> for Value {
    fn from(other: String) -> Self {
        Value::String(other)
    }
}

impl<'a> From<&'a str> for Value {
    fn from(other: &'a str) -> Self {
        Value::String(other.to_string())
    }
}

impl From<f64> for Value {
    fn from(other: f64) -> Self {
        Value::Double(other)
    }
}

impl From<DateTime> for Value {
    fn from(other: DateTime) -> Self {
        Value::DateTime(other)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::str;
    use std::collections::BTreeMap;

    #[test]
    fn escapes_strings() {
        let mut output: Vec<u8> = Vec::new();

        Value::from("<xml> string").write_as_xml(&mut output).unwrap();
        assert_eq!(str::from_utf8(&output).unwrap(), "<value>\n<string><xml>&nbsp;string</string>\n</value>\n");
    }

    #[test]
    fn escapes_struct_member_names() {
        let mut output: Vec<u8> = Vec::new();
        let mut map: BTreeMap<String, Value> = BTreeMap::new();
        map.insert("x&<x".to_string(), Value::from(true));

        Value::Struct(map).write_as_xml(&mut output).unwrap();
        assert_eq!(str::from_utf8(&output).unwrap(), "<value>\n<struct>\n<member>\n<name>x&<x</name>\n<value>\n<boolean>1</boolean>\n</value>\n</member>\n</struct>\n</value>\n");
    }
}
<commit_msg>Clarify docs for extensions<commit_after>//! Contains the different types of values understood by XML-RPC.

use utils::{escape_xml, format_datetime};

use base64::encode;
use iso8601::DateTime;

use std::collections::BTreeMap;
use std::io::{self, Write};

/// The possible XML-RPC values.
#[derive(Clone, Debug, PartialEq)]
pub enum Value {
    /// `<i4>` or `<int>`, 32-bit signed integer.
    Int(i32),
    /// `<i8>`, 64-bit signed integer.
    ///
    /// This is an XMLRPC extension and may not be supported by all clients / servers.
    Int64(i64),
    /// `<boolean>`, 0 == `false`, 1 == `true`.
    Bool(bool),
    /// `<string>`
    // FIXME zero-copy? `Cow<'static, ..>`?
    String(String),
    /// `<double>`
    Double(f64),
    /// `<dateTime.iso8601>`, an ISO 8601 formatted date/time value.
    DateTime(DateTime),
    /// `<base64>`, base64-encoded binary data.
    Base64(Vec<u8>),

    /// `<struct>`, a mapping of named values.
    Struct(BTreeMap<String, Value>),
    /// `<array>`, a list of arbitrary (heterogeneous) values.
    Array(Vec<Value>),

    /// `</nil>`, the empty (Unit) value.
    ///
    /// This is an XMLRPC [extension][ext] and may not be supported by all clients / servers.
    ///
    /// [ext]: https://web.archive.org/web/20050911054235/http://ontosys.com/xml-rpc/extensions.php
    Nil
}

impl Value {
    /// Formats this `Value` as an XML `<value>` element.
    pub fn write_as_xml<W: Write>(&self, fmt: &mut W) -> io::Result<()> {
        writeln!(fmt, "<value>")?;

        match *self {
            Value::Int(i) => {
                writeln!(fmt, "<i4>{}</i4>", i)?;
            }
            Value::Int64(i) => {
                writeln!(fmt, "<i8>{}</i8>", i)?;
            }
            Value::Bool(b) => {
                writeln!(fmt, "<boolean>{}</boolean>", if b { "1" } else { "0" })?;
            }
            Value::String(ref s) => {
                writeln!(fmt, "<string>{}</string>", escape_xml(s))?;
            }
            Value::Double(d) => {
                writeln!(fmt, "<double>{}</double>", d)?;
            }
            Value::DateTime(date_time) => {
                writeln!(fmt, "<dateTime.iso8601>{}</dateTime.iso8601>", format_datetime(&date_time))?;
            }
            Value::Base64(ref data) => {
                writeln!(fmt, "<base64>{}</base64>", encode(data))?;
            }
            Value::Struct(ref map) => {
                writeln!(fmt, "<struct>")?;
                for (ref name, ref value) in map {
                    writeln!(fmt, "<member>")?;
                    writeln!(fmt, "<name>{}</name>", escape_xml(name))?;
                    value.write_as_xml(fmt)?;
                    writeln!(fmt, "</member>")?;
                }
                writeln!(fmt, "</struct>")?;
            }
            Value::Array(ref array) => {
                writeln!(fmt, "<array>")?;
                writeln!(fmt, "<data>")?;
                for value in array {
                    value.write_as_xml(fmt)?;
                }
                writeln!(fmt, "</data>")?;
                writeln!(fmt, "</array>")?;
            }
            Value::Nil => {
                writeln!(fmt, "<nil/>")?;
            }
        }

        writeln!(fmt, "</value>")?;
        Ok(())
    }
}

impl From<i32> for Value {
    fn from(other: i32) -> Self {
        Value::Int(other)
    }
}

impl From<i64> for Value {
    fn from(other: i64) -> Self {
        Value::Int64(other)
    }
}

impl From<bool> for Value {
    fn from(other: bool) -> Self {
        Value::Bool(other)
    }
}

impl From<String> for Value {
    fn from(other: String) -> Self {
        Value::String(other)
    }
}

impl<'a> From<&'a str> for Value {
    fn from(other: &'a str) -> Self {
        Value::String(other.to_string())
    }
}

impl From<f64> for Value {
    fn from(other: f64) -> Self {
        Value::Double(other)
    }
}

impl From<DateTime> for Value {
    fn from(other: DateTime) -> Self {
        Value::DateTime(other)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::str;
    use std::collections::BTreeMap;

    #[test]
    fn escapes_strings() {
        let mut output: Vec<u8> = Vec::new();

        Value::from("<xml> string").write_as_xml(&mut output).unwrap();
        assert_eq!(str::from_utf8(&output).unwrap(), "<value>\n<string><xml>&nbsp;string</string>\n</value>\n");
    }

    #[test]
    fn escapes_struct_member_names() {
        let mut output: Vec<u8> = Vec::new();
        let mut map: BTreeMap<String, Value> = BTreeMap::new();
        map.insert("x&<x".to_string(), Value::from(true));

        Value::Struct(map).write_as_xml(&mut output).unwrap();
        assert_eq!(str::from_utf8(&output).unwrap(), "<value>\n<struct>\n<member>\n<name>x&<x</name>\n<value>\n<boolean>1</boolean>\n</value>\n</member>\n</struct>\n</value>\n");
    }
}
<|endoftext|>


<commit_before>extern crate winapi;
extern crate kernel32;

use super::{LanguageRange,Locale};

fn get_user_default_locale() -> Result<LanguageRange<'static>, &'static str> {
    let mut buf = [0u16; 85];
    let len = unsafe {
        kernel32::GetUserDefaultLocaleName(buf.as_mut_ptr(), buf.len() as i32)
    };
    if len > 0 {
        let s = String::from_utf16_lossy(&buf[..(len as usize - 1)]);
        return LanguageRange::new(&*s).map(|x| x.into_static());
    }
    // TODO: Fall back to GetUserDefaultLCID and/or GetLocaleInfoW
    // GetLocaleInfo(Ex) with LOCALE_SISO639LANGNAME and LOCALE_SISO3166CTRYNAME might be of some
    // utility too
    return Err("Could not detect locale");
}

fn get_system_default_locale() -> Result<LanguageRange<'static>, &'static str> {
    let mut buf = [0u16; 85];
    let len = unsafe {
        kernel32::GetSystemDefaultLocaleName(buf.as_mut_ptr(), buf.len() as i32)
    };
    if len > 0 {
        let s = String::from_utf16_lossy(&buf[..(len as usize - 1)]);
        return LanguageRange::new(&*s).map(|x| x.into_static());
    }
    // TODO: Fall back to GetUserDefaultLCID and/or GetLocaleInfoW
    // GetLocaleInfo(Ex) with LOCALE_SISO639LANGNAME and LOCALE_SISO3166CTRYNAME might be of some
    // utility too
    return Err("Could not detect locale");
}

pub fn system_locale() -> Option<Locale> {
    let mut loc =
        if let Ok(lr) = get_user_default_locale() {
            Some(Locale::from(lr))
        } else {
            None
        };
    if let Ok(lr) = get_system_default_locale() {
        if loc.is_none() {
            loc = Some(Locale::from(lr));
        } else {
            loc.iter_mut().next().unwrap().add(&lr);
        }
    }
    loc
}
<commit_msg>Use GetUserPreferredUILanguages on Windows<commit_after>extern crate winapi;
extern crate kernel32;

use super::{LanguageRange,Locale};

fn get_user_default_locale() -> Result<LanguageRange<'static>, &'static str> {
    let mut buf = [0u16; 85];
    let len = unsafe {
        kernel32::GetUserDefaultLocaleName(buf.as_mut_ptr(), buf.len() as i32)
    };
    if len > 0 {
        let s = String::from_utf16_lossy(&buf[..(len as usize - 1)]);
        return LanguageRange::new(&*s).map(|x| x.into_static());
    }
    // TODO: Fall back to GetUserDefaultLCID and/or GetLocaleInfoW
    // GetLocaleInfo(Ex) with LOCALE_SISO639LANGNAME and LOCALE_SISO3166CTRYNAME might be of some
    // utility too
    return Err("Could not detect locale");
}

fn get_system_default_locale() -> Result<LanguageRange<'static>, &'static str> {
    let mut buf = [0u16; 85];
    let len = unsafe {
        kernel32::GetSystemDefaultLocaleName(buf.as_mut_ptr(), buf.len() as i32)
    };
    if len > 0 {
        let s = String::from_utf16_lossy(&buf[..(len as usize - 1)]);
        return LanguageRange::new(&*s).map(|x| x.into_static());
    }
    // TODO: Fall back to GetUserDefaultLCID and/or GetLocaleInfoW
    // GetLocaleInfo(Ex) with LOCALE_SISO639LANGNAME and LOCALE_SISO3166CTRYNAME might be of some
    // utility too
    return Err("Could not detect locale");
}

const MUI_LANGUAGE_NAME: winapi::c_ulong = 0x8; // from winnls.h

fn get_user_preferred_languages() -> Vec<LanguageRange<'static>> {
    let mut buf = [0u16; 5 * 85 + 1];
    let mut n_langs = 0;
    let mut len = buf.len() as winapi::c_ulong;
    let res = unsafe {
        kernel32::GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &mut n_langs, buf.as_mut_ptr(), &mut len)
    };
    if res != 0 && len > 1 {
        let s = String::from_utf16_lossy(&buf[..(len as usize - 2)]);
        return s.split('\0')
            .filter_map(|x| LanguageRange::new(x).ok())
            .map(|x| x.into_static())
            .collect();
    }
    return Vec::new();
}

// User default language is the primary language. If user preferred UI languages returns anything, the
// first item is considered override for messages and the rest is fallbacks. And last fallback is
// system default language.
pub fn system_locale() -> Option<Locale> {
    let mut loc =
        if let Ok(lr) = get_user_default_locale() {
            Some(Locale::from(lr))
        } else {
            None
        };
    let mut msg_locs = get_user_preferred_languages();
    if !msg_locs.is_empty() {
        if loc.is_none() {
            loc = Some(Locale::from(msg_locs.remove(0)));
        } else {
            loc.as_mut().unwrap().add_category("messages", &msg_locs.remove(0));
        }
        debug_assert!(!loc.is_none());
        for l in msg_locs {
            loc.as_mut().unwrap().add(&l);
        }
    }
    if let Ok(lr) = get_system_default_locale() {
        if loc.is_none() {
            loc = Some(Locale::from(lr));
        } else {
            loc.as_mut().unwrap().add(&lr);
        }
    }
    loc
}
<|endoftext|>


<commit_before>
extern crate rs6502;

#[test]
fn INTEGRATION_CPU_can_add_basic_numbers_in_accumulator() {
    let asm = "
        LDA #$20
        ADC #$10    ; A register should equal 48
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(2);

    assert_eq!(0x30, cpu.registers.A);
}

#[test]
fn INTEGRATION_CPU_can_add_binary_coded_decimal_numbers_in_accumulator() {
    let asm = "
        SED
        LDA #$20
        ADC #$05    ; A register should equal 0x25
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(3);

    assert_eq!(0x25, cpu.registers.A);
}

#[test]
fn INTEGRATION_CPU_can_add_mixed_mode_numbers_in_accumulator() {
    let asm = "
        LDA #$20
        ADC #10    ; A register should equal 0x2A
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(2);

    assert_eq!(0x2A, cpu.registers.A);
}

#[test]
fn INTEGRATION_CPU_can_store_bytes_in_memory() {
    let asm = "
        LDA #$20
        STA $2000
        LDA #10
        STA $2001
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(4);

    assert_eq!(0x20, cpu.memory[0x2000]);
    assert_eq!(0x0A, cpu.memory[0x2001]);
    assert_eq!(0x00, cpu.memory[0x2002]);
}

#[test]
fn INTEGRATION_CPU_can_overwrite_own_memory() {
    let asm = "
        LDA #$20
        STA $C006
        LDA #10
        STA $2000
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(4);

    assert_eq!(0x20, cpu.memory[0x2000]);
}

#[test]
fn INTEGRATION_CPU_can_load_byte_into_memory_and_logical_AND_it_with_A_register() {
    let asm = "
        LDA #$0F
        STA $2000   ; Load the mask 0x0F into $2000
        LDA #$FF    ; Load 0xFF into A
        AND $2000   ; AND it with 0x0F
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(4);

    assert_eq!(0x0F, cpu.memory[0x2000]);
}

#[test]
fn INTEGRATION_CPU_can_load_byte_into_memory_and_logical_AND_it_with_A_register_using_a_variable
    () {
    let asm = "
        MEMORY_LOCATION = $2000

        LDA #$0F
        STA MEMORY_LOCATION     ; Load the mask 0x0F into $2000
        LDA #$FF                ; Load 0xFF into A
        AND MEMORY_LOCATION     ; AND it with 0x0F
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(4);

    assert_eq!(0x0F, cpu.memory[0x2000]);
}

#[test]
fn INTEGRATION_CPU_does_not_branch_on_clear_carry_flag() {
    let asm = "
        LDA #$FE
        ADC #1      ; This won't cause a carry
        BCC FINISH
        LDA #$00    ; Clear the A register
    FINISH:
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(3);

    assert_eq!(0xFF, cpu.registers.A);
}

#[test]
fn INTEGRATION_CPU_can_branch_on_carry_flag() {
    let asm = "
        LDA #$FE
        ADC #10     ; This will cause a carry
        BCC FINISH
        LDA #$00    ; Clear the A register
    FINISH:
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(4);

    assert_eq!(0x00, cpu.registers.A);
}

#[test]
fn INTEGRATION_CPU_can_branch_on_carry_flag_to_correct_offset() {
    let asm = "
        LDA #$FE
        ADC #1      ; This will not cause a carry, and execution
        BCC FINISH  ; should jump to the FINISH label
        LDA #$00
        LDA #$01
        LDA #$02
        LDA #$03
        LDA #$04
    FINISH:
        LDA #$AA
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(5);

    assert_eq!(0xAA, cpu.registers.A);
}

#[test]
fn INTEGRATION_CPU_can_loop_on_bcc() {
    let asm = "
        LDA #$F0
    ADDER:
        ADC #1
        BCC ADDER
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(30);

    assert_eq!(0xFF, cpu.registers.A);
}

#[test]
fn INTEGRATION_CPU_can_branch_on_bcs() {
    let asm = "
        LDA #$FE
        ADC #$05    ; This will carry
        BCS FINISH
        LDA #$00
    FINISH:
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(30);

    assert_eq!(0x03, cpu.registers.A);
}

#[test]
fn INTEGRATION_CPU_can_branch_on_beq() {
    let asm = "
        LDA #$FF
        ADC #$01    ; This will result in a zero result
        BEQ FINISH
        LDA #$FF
    FINISH:
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(30);

    assert_eq!(0x00, cpu.registers.A);
}

#[test]
fn INTEGRATION_CPU_does_not_branch_on_beq() {
    let asm = "
        LDA #$F0
        ADC #$01
        BEQ FINISH
        LDA #$FF    ; The branch above should not be taken
    FINISH:         ; and this should load 0xFF into A
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(30);

    assert_eq!(0xFF, cpu.registers.A);
}<commit_msg>Add Integration test for BIT<commit_after>
extern crate rs6502;

#[test]
fn INTEGRATION_CPU_can_add_basic_numbers_in_accumulator() {
    let asm = "
        LDA #$20
        ADC #$10    ; A register should equal 48
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(2);

    assert_eq!(0x30, cpu.registers.A);
}

#[test]
fn INTEGRATION_CPU_can_add_binary_coded_decimal_numbers_in_accumulator() {
    let asm = "
        SED
        LDA #$20
        ADC #$05    ; A register should equal 0x25
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(3);

    assert_eq!(0x25, cpu.registers.A);
}

#[test]
fn INTEGRATION_CPU_can_add_mixed_mode_numbers_in_accumulator() {
    let asm = "
        LDA #$20
        ADC #10    ; A register should equal 0x2A
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(2);

    assert_eq!(0x2A, cpu.registers.A);
}

#[test]
fn INTEGRATION_CPU_can_store_bytes_in_memory() {
    let asm = "
        LDA #$20
        STA $2000
        LDA #10
        STA $2001
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(4);

    assert_eq!(0x20, cpu.memory[0x2000]);
    assert_eq!(0x0A, cpu.memory[0x2001]);
    assert_eq!(0x00, cpu.memory[0x2002]);
}

#[test]
fn INTEGRATION_CPU_can_overwrite_own_memory() {
    let asm = "
        LDA #$20
        STA $C006
        LDA #10
        STA $2000
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(4);

    assert_eq!(0x20, cpu.memory[0x2000]);
}

#[test]
fn INTEGRATION_CPU_can_load_byte_into_memory_and_logical_AND_it_with_A_register() {
    let asm = "
        LDA #$0F
        STA $2000   ; Load the mask 0x0F into $2000
        LDA #$FF    ; Load 0xFF into A
        AND $2000   ; AND it with 0x0F
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(4);

    assert_eq!(0x0F, cpu.memory[0x2000]);
}

#[test]
fn INTEGRATION_CPU_can_load_byte_into_memory_and_logical_AND_it_with_A_register_using_a_variable
    () {
    let asm = "
        MEMORY_LOCATION = $2000

        LDA #$0F
        STA MEMORY_LOCATION     ; Load the mask 0x0F into $2000
        LDA #$FF                ; Load 0xFF into A
        AND MEMORY_LOCATION     ; AND it with 0x0F
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(4);

    assert_eq!(0x0F, cpu.memory[0x2000]);
}

#[test]
fn INTEGRATION_CPU_does_not_branch_on_clear_carry_flag() {
    let asm = "
        LDA #$FE
        ADC #1      ; This won't cause a carry
        BCC FINISH
        LDA #$00    ; Clear the A register
    FINISH:
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(3);

    assert_eq!(0xFF, cpu.registers.A);
}

#[test]
fn INTEGRATION_CPU_can_branch_on_carry_flag() {
    let asm = "
        LDA #$FE
        ADC #10     ; This will cause a carry
        BCC FINISH
        LDA #$00    ; Clear the A register
    FINISH:
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(4);

    assert_eq!(0x00, cpu.registers.A);
}

#[test]
fn INTEGRATION_CPU_can_branch_on_carry_flag_to_correct_offset() {
    let asm = "
        LDA #$FE
        ADC #1      ; This will not cause a carry, and execution
        BCC FINISH  ; should jump to the FINISH label
        LDA #$00
        LDA #$01
        LDA #$02
        LDA #$03
        LDA #$04
    FINISH:
        LDA #$AA
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(5);

    assert_eq!(0xAA, cpu.registers.A);
}

#[test]
fn INTEGRATION_CPU_can_loop_on_bcc() {
    let asm = "
        LDA #$F0
    ADDER:
        ADC #1
        BCC ADDER
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(30);

    assert_eq!(0xFF, cpu.registers.A);
}

#[test]
fn INTEGRATION_CPU_can_branch_on_bcs() {
    let asm = "
        LDA #$FE
        ADC #$05    ; This will carry
        BCS FINISH
        LDA #$00
    FINISH:
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(30);

    assert_eq!(0x03, cpu.registers.A);
}

#[test]
fn INTEGRATION_CPU_can_branch_on_beq() {
    let asm = "
        LDA #$FF
        ADC #$01    ; This will result in a zero result
        BEQ FINISH
        LDA #$FF
    FINISH:
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(30);

    assert_eq!(0x00, cpu.registers.A);
}

#[test]
fn INTEGRATION_CPU_does_not_branch_on_beq() {
    let asm = "
        LDA #$F0
        ADC #$01
        BEQ FINISH
        LDA #$FF    ; The branch above should not be taken
    FINISH:         ; and this should load 0xFF into A
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(30);

    assert_eq!(0xFF, cpu.registers.A);
}

#[test]
fn INTEGRATION_CPU_preserves_flags_on_bit() {
    let asm = "
        LDA #$0F
        STA $44
        LDA #$F0
        BIT $44
        BEQ FINISH
        LDA #$35    ; The branch above will be taken
    FINISH:         ; because 0x0F & 0xF0 will be 0x00
    ";

    let mut cpu = rs6502::Cpu::new();
    let mut assembler = rs6502::Assembler::new();

    let bytecode = assembler.assemble_string(asm).unwrap();
    cpu.load(&bytecode[..], None);

    cpu.step_n(30);

    assert_eq!(0xF0, cpu.registers.A);
}<|endoftext|>


<commit_before>#[macro_use]
extern crate nom;
//extern crate serialize;

use nom::{IResult,FlatMapper,Mapper,Producer,ProducerState,FileProducer};
use nom::IResult::*;

use std::str;
use std::collections::HashMap;
//use serialize::hex::ToHex;

pub trait HexDisplay {
      /// Converts the value of `self` to a hex value, returning the owned
      ///     /// string.
  fn to_hex(&self, chunk_size: usize) -> String;
}

static CHARS: &'static[u8] = b"0123456789abcdef";

impl HexDisplay for [u8] {
    fn to_hex(&self, chunk_size: usize) -> String {
      let mut v = Vec::with_capacity(self.len() * 3);
      let mut i = 0;
      for chunk in self.chunks(chunk_size) {
        let s = format!("{:08x}", i);
        let s2: &str = &s;
        for &ch in s.as_bytes().iter() {
          v.push(ch);
        }
        v.push('\t' as u8);

        i = i + chunk_size;

        for &byte in chunk {
          v.push(CHARS[(byte >> 4) as usize]);
          v.push(CHARS[(byte & 0xf) as usize]);
          v.push(' ' as u8);
        }
        if chunk_size > chunk.len() {
          for i in 0..(chunk_size - chunk.len()) {
            v.push(' ' as u8);
            v.push(' ' as u8);
            v.push(' ' as u8);
          }
        }
        v.push('\t' as u8);

        for &byte in chunk {
          if (byte >=32 && byte <= 126) || byte >= 128 {
            v.push(byte);
          } else {
            v.push('.' as u8);
          }
        }
        v.push('\n' as u8);
      }

      unsafe {
        String::from_utf8_unchecked(v)
      }
    }
}

take!(offset_parser 4);
fn mp4_box(input:&[u8]) -> IResult<&[u8], &[u8]> {

  match offset_parser(input) {
    Done(i, offset_bytes) => {
      let offset:u32 = (offset_bytes[3] as u32) + (offset_bytes[2] as u32) * 0x100 + (offset_bytes[1] as u32) * 0x10000 + (offset_bytes[0] as u32) * 0x1000000;
      let sz: usize = offset as usize;
      if i.len() >= sz {
        return Done(&i[(sz-4)..], &i[0..(sz-4)])
      } else {
        return Incomplete(0)
      }
    },
    e => e
  }
}

#[derive(PartialEq,Eq,Debug)]
struct FileType<'a> {
  major_brand:         &'a str,
  major_brand_version: &'a [u8],
  compatible_brands:   Vec<&'a str>
}

#[derive(PartialEq,Eq,Debug)]
enum MP4Box<'a> {
  Ftyp(FileType<'a>),
  Moov,
  Free
}

take!(offset 4);
tag!(ftyp    "ftyp".as_bytes());

fn brand_name(input:&[u8]) -> IResult<&[u8],&str> {
  take!(major_brand_bytes 4);
  major_brand_bytes(input).map_res(str::from_utf8)
}
take!(major_brand_version 4);
many0!(compatible_brands<&[u8],&str> brand_name);

fn filetype_parser<'a>(input: &'a[u8]) -> IResult<&'a [u8], FileType<'a> > {
  chaining_parser!(input, ||{FileType{major_brand: m, major_brand_version:v, compatible_brands: c}},
    m: brand_name,
    v: major_brand_version,
    c: compatible_brands,)
}

o!(filetype <&[u8], FileType>  ftyp ~ [ filetype_parser ]);

fn filetype_box(input:&[u8]) -> IResult<&[u8], MP4Box> {
  //FIXME: flat_map should work here
  //mp4_box(input).flat_map(filetype)
  match mp4_box(input) {
    Done(i, o) => {
      match filetype(o) {
        Done(i2, o2) => {
          Done(i, MP4Box::Ftyp(o2))
        },
        a => Error(0)
      }
    },
    a => Error(0)
  }
}

tag!(free    "ftyp".as_bytes());
fn free_box(input:&[u8]) -> IResult<&[u8], MP4Box> {
  match mp4_box(input) {
    Done(i, o) => {
      match free(o) {
        Done(i2, o2) => {
          Done(i, MP4Box::Free)
        },
        a => Error(0)
      }
    },
    a => Error(0)
  }
}

alt!(box_parser<&[u8], MP4Box>, filetype_box | free_box);

fn parse_mp4_file(filename: &str) {
  FileProducer::new(filename, 150).map(|producer: FileProducer| {
    let mut p = producer;
    match p.produce() {
      ProducerState::Data(bytes) => {
        println!("bytes:\n{}", bytes.to_hex(8));
        match filetype_box(bytes) {
          Done(i, o) => {
            match o {
              MP4Box::Ftyp(f) => println!("parsed ftyp: {:?}", f),
              MP4Box::Moov    => println!("found moov box"),
              MP4Box::Free    => println!("found free box")
            }
            println!("remaining:\n{}", i.to_hex(8))
          },
          a => println!("error: {:?}", a)
        }
      },
      _ => println!("got error")
    }
    /*//p.push(|par| {println!("parsed file: {}", par); par});
    //p.push(|par| par.flat_map(print));
    fn pr<'a,'b,'c>(data: &[u8]) -> IResult<'b,&[u8], &[u8]> {
      println!("bytes: {:?}", &data[0..20]);
      //Done("".as_bytes(), data).map_res(str::from_utf8);
      Done("".as_bytes(),"".as_bytes())
    }
    pusher!(ps, pr);
    ps(&mut p);
    */
    assert!(false);
  });

}
#[test]
fn file_test() {
  parse_mp4_file("small.mp4");
}
#[test]
fn bunny_test() {
  parse_mp4_file("bigbuckbunny.mp4");
}
<commit_msg>match on box_parser<commit_after>#[macro_use]
extern crate nom;
//extern crate serialize;

use nom::{IResult,FlatMapper,Mapper,Producer,ProducerState,FileProducer};
use nom::IResult::*;

use std::str;
use std::collections::HashMap;
//use serialize::hex::ToHex;

pub trait HexDisplay {
      /// Converts the value of `self` to a hex value, returning the owned
      ///     /// string.
  fn to_hex(&self, chunk_size: usize) -> String;
}

static CHARS: &'static[u8] = b"0123456789abcdef";

impl HexDisplay for [u8] {
    fn to_hex(&self, chunk_size: usize) -> String {
      let mut v = Vec::with_capacity(self.len() * 3);
      let mut i = 0;
      for chunk in self.chunks(chunk_size) {
        let s = format!("{:08x}", i);
        let s2: &str = &s;
        for &ch in s.as_bytes().iter() {
          v.push(ch);
        }
        v.push('\t' as u8);

        i = i + chunk_size;

        for &byte in chunk {
          v.push(CHARS[(byte >> 4) as usize]);
          v.push(CHARS[(byte & 0xf) as usize]);
          v.push(' ' as u8);
        }
        if chunk_size > chunk.len() {
          for i in 0..(chunk_size - chunk.len()) {
            v.push(' ' as u8);
            v.push(' ' as u8);
            v.push(' ' as u8);
          }
        }
        v.push('\t' as u8);

        for &byte in chunk {
          if (byte >=32 && byte <= 126) || byte >= 128 {
            v.push(byte);
          } else {
            v.push('.' as u8);
          }
        }
        v.push('\n' as u8);
      }

      unsafe {
        String::from_utf8_unchecked(v)
      }
    }
}

fn mp4_box(input:&[u8]) -> IResult<&[u8], &[u8]> {

  take!(offset_parser 4);
  match offset_parser(input) {
    Done(i, offset_bytes) => {
      let offset:u32 = (offset_bytes[3] as u32) + (offset_bytes[2] as u32) * 0x100 + (offset_bytes[1] as u32) * 0x10000 + (offset_bytes[0] as u32) * 0x1000000;
      let sz: usize = offset as usize;
      if i.len() >= sz {
        return Done(&i[(sz-4)..], &i[0..(sz-4)])
      } else {
        return Incomplete(0)
      }
    },
    e => e
  }
}

#[derive(PartialEq,Eq,Debug)]
struct FileType<'a> {
  major_brand:         &'a str,
  major_brand_version: &'a [u8],
  compatible_brands:   Vec<&'a str>
}

#[derive(PartialEq,Eq,Debug)]
enum MP4Box<'a> {
  Ftyp(FileType<'a>),
  Moov,
  Free
}

take!(offset 4);
tag!(ftyp    "ftyp".as_bytes());

fn brand_name(input:&[u8]) -> IResult<&[u8],&str> {
  take!(major_brand_bytes 4);
  major_brand_bytes(input).map_res(str::from_utf8)
}
take!(major_brand_version 4);
many0!(compatible_brands<&[u8],&str> brand_name);

fn filetype_parser<'a>(input: &'a[u8]) -> IResult<&'a [u8], FileType<'a> > {
  chaining_parser!(input, ||{FileType{major_brand: m, major_brand_version:v, compatible_brands: c}},
    m: brand_name,
    v: major_brand_version,
    c: compatible_brands,)
}

o!(filetype <&[u8], FileType>  ftyp ~ [ filetype_parser ]);

fn filetype_box(input:&[u8]) -> IResult<&[u8], MP4Box> {
  //FIXME: flat_map should work here
  //mp4_box(input).flat_map(filetype)
  match mp4_box(input) {
    Done(i, o) => {
      match filetype(o) {
        Done(i2, o2) => {
          Done(i, MP4Box::Ftyp(o2))
        },
        a => Error(0)
      }
    },
    a => Error(0)
  }
}

tag!(free    "ftyp".as_bytes());
fn free_box(input:&[u8]) -> IResult<&[u8], MP4Box> {
  match mp4_box(input) {
    Done(i, o) => {
      match free(o) {
        Done(i2, o2) => {
          Done(i, MP4Box::Free)
        },
        a => Error(0)
      }
    },
    a => Error(0)
  }
}

alt!(box_parser<&[u8], MP4Box>, filetype_box | free_box);

fn parse_mp4_file(filename: &str) {
  FileProducer::new(filename, 150).map(|producer: FileProducer| {
    let mut p = producer;
    match p.produce() {
      ProducerState::Data(bytes) => {
        println!("bytes:\n{}", bytes.to_hex(8));
        match box_parser(bytes) {
          Done(i, o) => {
            match o {
              MP4Box::Ftyp(f) => println!("parsed ftyp: {:?}", f),
              MP4Box::Moov    => println!("found moov box"),
              MP4Box::Free    => println!("found free box")
            }
            println!("remaining:\n{}", i.to_hex(8))
          },
          a => println!("error: {:?}", a)
        }
      },
      _ => println!("got error")
    }
    /*//p.push(|par| {println!("parsed file: {}", par); par});
    //p.push(|par| par.flat_map(print));
    fn pr<'a,'b,'c>(data: &[u8]) -> IResult<'b,&[u8], &[u8]> {
      println!("bytes: {:?}", &data[0..20]);
      //Done("".as_bytes(), data).map_res(str::from_utf8);
      Done("".as_bytes(),"".as_bytes())
    }
    pusher!(ps, pr);
    ps(&mut p);
    */
    assert!(false);
  });

}
#[test]
fn file_test() {
  parse_mp4_file("small.mp4");
}
#[test]
fn bunny_test() {
  parse_mp4_file("bigbuckbunny.mp4");
}
<|endoftext|>


<commit_before>#[crate_id="github.com/sfackler/rust-phf#phf:0.0"];
#[crate_type="lib"];
#[feature(managed_boxes, macro_registrar)];

extern mod syntax;

use std::vec::VecIterator;

use syntax::ast;
use syntax::ast::{Name, TokenTree, LitStr, MutImmutable, Expr, ExprVec, ExprLit};
use syntax::codemap::Span;
use syntax::ext::base::{SyntaxExtension,
                        ExtCtxt,
                        MacResult,
                        MRExpr,
                        NormalTT,
                        SyntaxExpanderTT,
                        SyntaxExpanderTTExpanderWithoutContext};
use syntax::parse;
use syntax::parse::token;
use syntax::parse::token::{COMMA, EOF, FAT_ARROW};

pub struct PhfMap<T> {
    #[doc(hidden)]
    entries: &'static [(&'static str, T)],
}

impl<T> Container for PhfMap<T> {
    fn len(&self) -> uint {
        self.entries.len()
    }
}

impl<T> Map<&'static str, T> for PhfMap<T> {
    fn find<'a>(&'a self, key: & &'static str) -> Option<&'a T> {
        self.entries.bsearch(|&(val, _)| val.cmp(key)).map(|idx| {
            let (_, ref val) = self.entries[idx];
            val
        })
    }
}

impl<T> PhfMap<T> {
    pub fn entries<'a>(&'a self) -> PhfMapEntries<'a, T> {
        PhfMapEntries { iter: self.entries.iter() }
    }

    pub fn keys<'a>(&'a self) -> PhfMapKeys<'a, T> {
        PhfMapKeys { iter: self.entries() }
    }

    pub fn values<'a>(&'a self) -> PhfMapValues<'a, T> {
        PhfMapValues { iter: self.entries() }
    }
}

pub struct PhfMapEntries<'a, T> {
    priv iter: VecIterator<'a, (&'static str, T)>,
}

impl<'a, T> Iterator<(&'static str, &'a T)> for PhfMapEntries<'a, T> {
    fn next(&mut self) -> Option<(&'static str, &'a T)> {
        self.iter.next().map(|&(key, ref value)| (key, value))
    }
}

pub struct PhfMapKeys<'a, T> {
    priv iter: PhfMapEntries<'a, T>,
}

impl<'a, T> Iterator<&'static str> for PhfMapKeys<'a, T> {
    fn next(&mut self) -> Option<&'static str> {
        self.iter.next().map(|(key, _)| key)
    }
}

pub struct PhfMapValues<'a, T> {
    priv iter: PhfMapEntries<'a, T>,
}

impl<'a, T> Iterator<&'a T> for PhfMapValues<'a, T> {
    fn next(&mut self) -> Option<&'a T> {
        self.iter.next().map(|(_, value)| value)
    }
}

#[macro_registrar]
#[doc(hidden)]
pub fn macro_registrar(register: |Name, SyntaxExtension|) {
    register(token::intern("phf_map"),
             NormalTT(~SyntaxExpanderTT {
                expander: SyntaxExpanderTTExpanderWithoutContext(expand_mphf_map),
                span: None
             },
             None));
}

fn expand_mphf_map(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> MacResult {
    let mut parser = parse::new_parser_from_tts(cx.parse_sess(), cx.cfg(),
                                                tts.to_owned());
    let mut pairs = ~[];

    while parser.token != EOF {
        let key = parser.parse_expr();

        let key_str = match key.node {
            ExprLit(lit) => {
                match lit.node {
                    LitStr(s, _) => s,
                    _ => cx.span_fatal(key.span, "expected string literal"),
                }
            }
            _ => cx.span_fatal(key.span, "expected string literal"),
        };

        if !parser.eat(&FAT_ARROW) {
            cx.span_fatal(parser.span, "expected `=>`");
        }

        let value = parser.parse_expr();

        pairs.push((key_str, key, value));

        if !parser.eat(&COMMA) && parser.token != EOF {
            cx.span_fatal(parser.span, "expected `,`");
        }
    }

    pairs.sort_by(|&(ref a, _, _), &(ref b, _, _)| a.cmp(b));

    for window in pairs.windows(2) {
        let (ref a, ref a_expr, _) = window[0];
        let (ref b, ref b_expr, _) = window[1];
        if a == b {
            cx.span_err(sp, format!("duplicate key \"{}\"", *a));
            cx.span_err(a_expr.span, "one occurrence here");
            cx.span_err(b_expr.span, "one occurrence here");
        }
    }
    cx.parse_sess().span_diagnostic.handler().abort_if_errors();

    let entries = pairs.move_iter()
        .map(|(_, key, value)| quote_expr!(&*cx, ($key, $value)))
        .collect();
    let entries = @Expr {
        id: ast::DUMMY_NODE_ID,
        node: ExprVec(entries, MutImmutable),
        span: sp,
    };

    MRExpr(quote_expr!(cx, PhfMap { entries: &'static $entries }))
}
<commit_msg>Inline all the things<commit_after>#[crate_id="github.com/sfackler/rust-phf#phf:0.0"];
#[crate_type="lib"];
#[feature(managed_boxes, macro_registrar)];

extern mod syntax;

use std::vec::VecIterator;

use syntax::ast;
use syntax::ast::{Name, TokenTree, LitStr, MutImmutable, Expr, ExprVec, ExprLit};
use syntax::codemap::Span;
use syntax::ext::base::{SyntaxExtension,
                        ExtCtxt,
                        MacResult,
                        MRExpr,
                        NormalTT,
                        SyntaxExpanderTT,
                        SyntaxExpanderTTExpanderWithoutContext};
use syntax::parse;
use syntax::parse::token;
use syntax::parse::token::{COMMA, EOF, FAT_ARROW};

pub struct PhfMap<T> {
    #[doc(hidden)]
    entries: &'static [(&'static str, T)],
}

impl<T> Container for PhfMap<T> {
    #[inline]
    fn len(&self) -> uint {
        self.entries.len()
    }
}

impl<T> Map<&'static str, T> for PhfMap<T> {
    #[inline]
    fn find<'a>(&'a self, key: & &'static str) -> Option<&'a T> {
        self.entries.bsearch(|&(val, _)| val.cmp(key)).map(|idx| {
            let (_, ref val) = self.entries[idx];
            val
        })
    }
}

impl<T> PhfMap<T> {
    #[inline]
    pub fn entries<'a>(&'a self) -> PhfMapEntries<'a, T> {
        PhfMapEntries { iter: self.entries.iter() }
    }

    #[inline]
    pub fn keys<'a>(&'a self) -> PhfMapKeys<'a, T> {
        PhfMapKeys { iter: self.entries() }
    }

    #[inline]
    pub fn values<'a>(&'a self) -> PhfMapValues<'a, T> {
        PhfMapValues { iter: self.entries() }
    }
}

pub struct PhfMapEntries<'a, T> {
    priv iter: VecIterator<'a, (&'static str, T)>,
}

impl<'a, T> Iterator<(&'static str, &'a T)> for PhfMapEntries<'a, T> {
    #[inline]
    fn next(&mut self) -> Option<(&'static str, &'a T)> {
        self.iter.next().map(|&(key, ref value)| (key, value))
    }
}

pub struct PhfMapKeys<'a, T> {
    priv iter: PhfMapEntries<'a, T>,
}

impl<'a, T> Iterator<&'static str> for PhfMapKeys<'a, T> {
    #[inline]
    fn next(&mut self) -> Option<&'static str> {
        self.iter.next().map(|(key, _)| key)
    }
}

pub struct PhfMapValues<'a, T> {
    priv iter: PhfMapEntries<'a, T>,
}

impl<'a, T> Iterator<&'a T> for PhfMapValues<'a, T> {
    #[inline]
    fn next(&mut self) -> Option<&'a T> {
        self.iter.next().map(|(_, value)| value)
    }
}

#[macro_registrar]
#[doc(hidden)]
pub fn macro_registrar(register: |Name, SyntaxExtension|) {
    register(token::intern("phf_map"),
             NormalTT(~SyntaxExpanderTT {
                expander: SyntaxExpanderTTExpanderWithoutContext(expand_mphf_map),
                span: None
             },
             None));
}

fn expand_mphf_map(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> MacResult {
    let mut parser = parse::new_parser_from_tts(cx.parse_sess(), cx.cfg(),
                                                tts.to_owned());
    let mut pairs = ~[];

    while parser.token != EOF {
        let key = parser.parse_expr();

        let key_str = match key.node {
            ExprLit(lit) => {
                match lit.node {
                    LitStr(s, _) => s,
                    _ => cx.span_fatal(key.span, "expected string literal"),
                }
            }
            _ => cx.span_fatal(key.span, "expected string literal"),
        };

        if !parser.eat(&FAT_ARROW) {
            cx.span_fatal(parser.span, "expected `=>`");
        }

        let value = parser.parse_expr();

        pairs.push((key_str, key, value));

        if !parser.eat(&COMMA) && parser.token != EOF {
            cx.span_fatal(parser.span, "expected `,`");
        }
    }

    pairs.sort_by(|&(ref a, _, _), &(ref b, _, _)| a.cmp(b));

    for window in pairs.windows(2) {
        let (ref a, ref a_expr, _) = window[0];
        let (ref b, ref b_expr, _) = window[1];
        if a == b {
            cx.span_err(sp, format!("duplicate key \"{}\"", *a));
            cx.span_err(a_expr.span, "one occurrence here");
            cx.span_err(b_expr.span, "one occurrence here");
        }
    }
    cx.parse_sess().span_diagnostic.handler().abort_if_errors();

    let entries = pairs.move_iter()
        .map(|(_, key, value)| quote_expr!(&*cx, ($key, $value)))
        .collect();
    let entries = @Expr {
        id: ast::DUMMY_NODE_ID,
        node: ExprVec(entries, MutImmutable),
        span: sp,
    };

    MRExpr(quote_expr!(cx, PhfMap { entries: &'static $entries }))
}
<|endoftext|>


<commit_before><commit_msg>Remove spurious file<commit_after><|endoftext|>


<commit_before>//! Logging scopes for slog-rs
//!
//! Logging scopes are convinience functionality for slog-rs to free user from manually passing
//! `Logger` objects around.
//!
//! Set of macros is also provided as an alternative to original `slog` crate macros, for logging
//! directly to `Logger` of the current logging scope.
//!
//! Note: Part of a `slog` logging philosophy is ability to freely express logging contexts
//! according to logical structure, rather than code structure. By using logging scopes the logging
//! context is tied to code flow again, which is less expressive.
//!
//! It is generally advised **NOT** to use `slog_scope` in libraries. Read more in
//! [slog-rs FAQ](https://github.com/slog-rs/slog/wiki/FAQ#do-i-have-to-pass-logger-around)
//!
//! ```
//! #[macro_use(o, slog_info, slog_log, slog_record, slog_record_static, slog_b)]
//! extern crate slog;
//! #[macro_use]
//! extern crate slog_scope;
//! extern crate slog_term;
//!
//! use slog::Drain;
//!
//! fn foo() {
//!     slog_info!(slog_scope::logger(), "foo");
//!     info!("foo"); // Same as above, but more ergonomic.
//! }
//!
//! fn main() {
//!     let plain = slog_term::PlainSyncDecorator::new(std::io::stdout());
//!     let log = slog::Logger::root(
//!         slog_term::FullFormat::new(plain)
//!         .build().fuse(), o!()
//!     );
//!
//!     slog_scope::set_global_logger(log);
//!     slog_scope::scope(slog_scope::logger().new(o!("scope" => "1")),
//!         || foo()
//!     );
//! }

#![warn(missing_docs)]

#[macro_use(o)]
extern crate slog;
#[macro_use]
extern crate lazy_static;
extern crate crossbeam;

use slog::*;

use std::sync::Arc;
use std::cell::RefCell;
use crossbeam::sync::ArcCell;

/// Log a critical level message using current scope logger
#[macro_export] macro_rules! crit( ($($args:tt)+) => { slog_crit![$crate::logger(), $($args)+]; };);
/// Log a error level message using current scope logger
#[macro_export] macro_rules! error( ($($args:tt)+) => { slog_error![$crate::logger(), $($args)+]; };);
/// Log a warning level message using current scope logger
#[macro_export] macro_rules! warn( ($($args:tt)+) => { slog_warn![$crate::logger(), $($args)+]; };);
/// Log a info level message using current scope logger
#[macro_export] macro_rules! info( ($($args:tt)+) => { slog_info![$crate::logger(), $($args)+]; };);
/// Log a debug level message using current scope logger
#[macro_export] macro_rules! debug( ($($args:tt)+) => { slog_debug![$crate::logger(), $($args)+]; };);
/// Log a trace level message using current scope logger
#[macro_export] macro_rules! trace( ($($args:tt)+) => { slog_trace![$crate::logger(), $($args)+]; };);

thread_local! {
    static TL_SCOPES: RefCell<Vec<slog::Logger>> = RefCell::new(Vec::with_capacity(8))
}

lazy_static! {
    static ref GLOBAL_LOGGER : ArcCell<slog::Logger> = ArcCell::new(
        Arc::new(
            slog::Logger::root(slog::Discard, o!()).into_erased()
        )
    );
}

/// Set global `Logger` that is returned by calls like `logger()` outside of any logging scope.
pub fn set_global_logger(l: slog::Logger) {
    let _ = GLOBAL_LOGGER.set(Arc::new(l));
}

struct ScopeGuard;

impl ScopeGuard {
    fn new(logger: slog::Logger) -> Self {
        TL_SCOPES.with(|s| {
            s.borrow_mut().push(logger);
        });

        ScopeGuard
    }
}

impl Drop for ScopeGuard {
    fn drop(&mut self) {
        TL_SCOPES.with(|s| {
            s.borrow_mut().pop().expect("TL_SCOPES should contain a logger");
        })
    }
}

/// Access the `Logger` for the current logging scope
pub fn logger() -> Logger {
    TL_SCOPES.with(|s| {
        let s = s.borrow();
        match s.last() {
          Some(logger) => logger.clone(),
          None => (*GLOBAL_LOGGER.get()).clone(),
        }
    })
}

/// Execute code in a logging scope
///
/// Logging scopes allow using a `slog::Logger` without explicitly
/// passing it in the code.
///
/// At any time current active `Logger` for a given thread can be retrived
/// with `logger()` call.
///
/// Logging scopes can be nested and are panic safe.
///
/// `logger` is the `Logger` to use during the duration of `f`.
/// `with_current_logger` can be used to build it as a child of currently active
/// logger.
///
/// `f` is a code to be executed in the logging scope.
///
/// Note: Thread scopes are thread-local. Each newly spawned thread starts
/// with a global logger, as a current logger.
pub fn scope<SF, R>(logger: slog::Logger, f: SF) -> R
    where SF: FnOnce() -> R
{
    let _guard = ScopeGuard::new(logger);
    f()
}
<commit_msg>Get rid of needless `to_erased`<commit_after>//! Logging scopes for slog-rs
//!
//! Logging scopes are convinience functionality for slog-rs to free user from manually passing
//! `Logger` objects around.
//!
//! Set of macros is also provided as an alternative to original `slog` crate macros, for logging
//! directly to `Logger` of the current logging scope.
//!
//! Note: Part of a `slog` logging philosophy is ability to freely express logging contexts
//! according to logical structure, rather than code structure. By using logging scopes the logging
//! context is tied to code flow again, which is less expressive.
//!
//! It is generally advised **NOT** to use `slog_scope` in libraries. Read more in
//! [slog-rs FAQ](https://github.com/slog-rs/slog/wiki/FAQ#do-i-have-to-pass-logger-around)
//!
//! ```
//! #[macro_use(o, slog_info, slog_log, slog_record, slog_record_static, slog_b)]
//! extern crate slog;
//! #[macro_use]
//! extern crate slog_scope;
//! extern crate slog_term;
//!
//! use slog::Drain;
//!
//! fn foo() {
//!     slog_info!(slog_scope::logger(), "foo");
//!     info!("foo"); // Same as above, but more ergonomic.
//! }
//!
//! fn main() {
//!     let plain = slog_term::PlainSyncDecorator::new(std::io::stdout());
//!     let log = slog::Logger::root(
//!         slog_term::FullFormat::new(plain)
//!         .build().fuse(), o!()
//!     );
//!
//!     slog_scope::set_global_logger(log);
//!     slog_scope::scope(slog_scope::logger().new(o!("scope" => "1")),
//!         || foo()
//!     );
//! }

#![warn(missing_docs)]

#[macro_use(o)]
extern crate slog;
#[macro_use]
extern crate lazy_static;
extern crate crossbeam;

use slog::*;

use std::sync::Arc;
use std::cell::RefCell;
use crossbeam::sync::ArcCell;

/// Log a critical level message using current scope logger
#[macro_export] macro_rules! crit( ($($args:tt)+) => { slog_crit![$crate::logger(), $($args)+]; };);
/// Log a error level message using current scope logger
#[macro_export] macro_rules! error( ($($args:tt)+) => { slog_error![$crate::logger(), $($args)+]; };);
/// Log a warning level message using current scope logger
#[macro_export] macro_rules! warn( ($($args:tt)+) => { slog_warn![$crate::logger(), $($args)+]; };);
/// Log a info level message using current scope logger
#[macro_export] macro_rules! info( ($($args:tt)+) => { slog_info![$crate::logger(), $($args)+]; };);
/// Log a debug level message using current scope logger
#[macro_export] macro_rules! debug( ($($args:tt)+) => { slog_debug![$crate::logger(), $($args)+]; };);
/// Log a trace level message using current scope logger
#[macro_export] macro_rules! trace( ($($args:tt)+) => { slog_trace![$crate::logger(), $($args)+]; };);

thread_local! {
    static TL_SCOPES: RefCell<Vec<slog::Logger>> = RefCell::new(Vec::with_capacity(8))
}

lazy_static! {
    static ref GLOBAL_LOGGER : ArcCell<slog::Logger> = ArcCell::new(
        Arc::new(
            slog::Logger::root(slog::Discard, o!())
        )
    );
}

/// Set global `Logger` that is returned by calls like `logger()` outside of any logging scope.
pub fn set_global_logger(l: slog::Logger) {
    let _ = GLOBAL_LOGGER.set(Arc::new(l));
}

struct ScopeGuard;

impl ScopeGuard {
    fn new(logger: slog::Logger) -> Self {
        TL_SCOPES.with(|s| {
            s.borrow_mut().push(logger);
        });

        ScopeGuard
    }
}

impl Drop for ScopeGuard {
    fn drop(&mut self) {
        TL_SCOPES.with(|s| {
            s.borrow_mut().pop().expect("TL_SCOPES should contain a logger");
        })
    }
}

/// Access the `Logger` for the current logging scope
pub fn logger() -> Logger {
    TL_SCOPES.with(|s| {
        let s = s.borrow();
        match s.last() {
          Some(logger) => logger.clone(),
          None => (*GLOBAL_LOGGER.get()).clone(),
        }
    })
}

/// Execute code in a logging scope
///
/// Logging scopes allow using a `slog::Logger` without explicitly
/// passing it in the code.
///
/// At any time current active `Logger` for a given thread can be retrived
/// with `logger()` call.
///
/// Logging scopes can be nested and are panic safe.
///
/// `logger` is the `Logger` to use during the duration of `f`.
/// `with_current_logger` can be used to build it as a child of currently active
/// logger.
///
/// `f` is a code to be executed in the logging scope.
///
/// Note: Thread scopes are thread-local. Each newly spawned thread starts
/// with a global logger, as a current logger.
pub fn scope<SF, R>(logger: slog::Logger, f: SF) -> R
    where SF: FnOnce() -> R
{
    let _guard = ScopeGuard::new(logger);
    f()
}
<|endoftext|>