<commit_before>use super::connection::DBusConnection;
use super::error::DBusError;
use super::message::DBusMessage;
use super::value::{DBusSignature, DBusValue};

use std::cell::RefCell;
use std::collections::btree_map::BTreeMap;
use std::rc::Rc;

type DBusMap<T> = BTreeMap<String, T>;

pub struct DBusArgument {
    name: String,
    signature: String,
}

pub struct DBusAnnotation {
    name: String,
    value: String,
}
type DBusAnnotations = Vec<DBusAnnotation>;

pub struct DBusErrorMessage {
    name: String,
    message: String,
}

pub type DBusMethodResult = Result<Vec<DBusValue>, DBusErrorMessage>;
pub type DBusMethodHandler = Box<FnMut(&mut DBusMessage) -> DBusMethodResult>;

pub struct DBusMethod {
    in_args: Vec<DBusArgument>,
    out_args: Vec<DBusArgument>,
    cb: DBusMethodHandler,
    anns: DBusAnnotations,
}

pub type DBusPropertyGetResult = Result<DBusValue, DBusErrorMessage>;
pub type DBusPropertySetResult = Result<(), DBusErrorMessage>;

pub trait DBusPropertyReadHandler {
    fn get(&self) -> DBusPropertyGetResult;
}

pub trait DBusPropertyWriteHandler {
    fn set(&self, &DBusValue) -> DBusPropertySetResult;
}

pub trait DBusPropertyReadWriteHandler {
    fn get(&self) -> DBusPropertyGetResult;
    fn set(&self, &DBusValue) -> DBusPropertySetResult;
}

enum PropertyAccess {
    RO(Box<DBusPropertyReadHandler>),
    RW(Box<DBusPropertyReadWriteHandler>),
    WO(Box<DBusPropertyWriteHandler>),
}

pub struct DBusProperty {
    signature: DBusSignature,
    access: PropertyAccess,
    anns: DBusAnnotations,
}

pub struct DBusSignal {
    args: Vec<DBusArgument>,
    anns: DBusAnnotations,
}

pub struct DBusInterface {
    methods: DBusMap<DBusMethod>,
    properties: DBusMap<DBusProperty>,
    signals: DBusMap<DBusSignal>,
}

type InterfaceMap = Rc<RefCell<DBusMap<DBusInterface>>>;

pub struct DBusInterfaceMap {
    map: InterfaceMap,
}

impl DBusInterfaceMap {
    pub fn finalize(mut self) -> Result<DBusInterfaceMap, DBusError> {
        unimplemented!()
    }

    pub fn handle(&self, conn: &DBusConnection, msg: &mut DBusMessage) -> Option<Result<(), ()>> {
        msg.call_headers().and_then(|hdrs| {
            let iface_name = hdrs.interface;
            let method_name = hdrs.method;
            self.map.borrow_mut().get_mut(&iface_name).and_then(|iface| iface.methods.get_mut(&method_name)).map(|method| {
                // TODO: Verify input argument signature.

                let msg = match (method.cb)(msg) {
                    Ok(vals) => {
                        vals.iter().fold(msg.return_message(), |msg, val| {
                            msg.add_argument(val)
                        })
                    },
                    Err(err) => msg.error_message(&err.name)
                                   .add_argument(&err.message),
                };

                // TODO: Verify that the signature matches the return.

                conn.send(msg)
                    .map(|_| ())
                    .map_err(|_| ())
            })
        })
    }
}
<commit_msg>interface: add infrastructure for finalization<commit_after>use super::connection::DBusConnection;
use super::error::DBusError;
use super::message::DBusMessage;
use super::value::{DBusSignature, DBusValue};

use std::cell::RefCell;
use std::collections::btree_map::BTreeMap;
use std::rc::Rc;

type DBusMap<T> = BTreeMap<String, T>;

pub struct DBusArgument {
    name: String,
    signature: String,
}

pub struct DBusAnnotation {
    name: String,
    value: String,
}
type DBusAnnotations = Vec<DBusAnnotation>;

pub struct DBusErrorMessage {
    name: String,
    message: String,
}

pub type DBusMethodResult = Result<Vec<DBusValue>, DBusErrorMessage>;
pub type DBusMethodHandler = Box<FnMut(&mut DBusMessage) -> DBusMethodResult>;

pub struct DBusMethod {
    in_args: Vec<DBusArgument>,
    out_args: Vec<DBusArgument>,
    cb: DBusMethodHandler,
    anns: DBusAnnotations,
}

pub type DBusPropertyGetResult = Result<DBusValue, DBusErrorMessage>;
pub type DBusPropertySetResult = Result<(), DBusErrorMessage>;

pub trait DBusPropertyReadHandler {
    fn get(&self) -> DBusPropertyGetResult;
}

pub trait DBusPropertyWriteHandler {
    fn set(&self, &DBusValue) -> DBusPropertySetResult;
}

pub trait DBusPropertyReadWriteHandler {
    fn get(&self) -> DBusPropertyGetResult;
    fn set(&self, &DBusValue) -> DBusPropertySetResult;
}

enum PropertyAccess {
    RO(Box<DBusPropertyReadHandler>),
    RW(Box<DBusPropertyReadWriteHandler>),
    WO(Box<DBusPropertyWriteHandler>),
}

pub struct DBusProperty {
    signature: DBusSignature,
    access: PropertyAccess,
    anns: DBusAnnotations,
}

pub struct DBusSignal {
    args: Vec<DBusArgument>,
    anns: DBusAnnotations,
}

pub struct DBusInterface {
    methods: DBusMap<DBusMethod>,
    properties: DBusMap<DBusProperty>,
    signals: DBusMap<DBusSignal>,
}

type InterfaceMap = Rc<RefCell<DBusMap<DBusInterface>>>;

pub struct DBusInterfaceMap {
    map: InterfaceMap,
    finalized: bool,
}

impl DBusInterfaceMap {
    pub fn finalize(mut self) -> Result<DBusInterfaceMap, DBusError> {
        // TODO: Add core interfaces.

        self.finalized = true;
        Ok(self)
    }

    pub fn handle(&self, conn: &DBusConnection, msg: &mut DBusMessage) -> Option<Result<(), ()>> {
        msg.call_headers().and_then(|hdrs| {
            let iface_name = hdrs.interface;
            let method_name = hdrs.method;
            self.map.borrow_mut().get_mut(&iface_name).and_then(|iface| iface.methods.get_mut(&method_name)).map(|method| {
                // TODO: Verify input argument signature.

                let msg = match (method.cb)(msg) {
                    Ok(vals) => {
                        vals.iter().fold(msg.return_message(), |msg, val| {
                            msg.add_argument(val)
                        })
                    },
                    Err(err) => msg.error_message(&err.name)
                                   .add_argument(&err.message),
                };

                // TODO: Verify that the signature matches the return.

                conn.send(msg)
                    .map(|_| ())
                    .map_err(|_| ())
            })
        })
    }
}
<|endoftext|>


<commit_before>use std::error::Error;
use std::fmt;
use std::fmt::{Debug, Display};

use base::source::SourceLocation;
use ir;
use ir::lexer::{Lexer, LexicalError};

// TODO: rename to ParseElement? (or just Element)?
pub struct ParseItem<'a> {
    pub location: SourceLocation,
    pub data: ParseItemData<'a>,
}

impl<'a> ParseItem<'a> {
    pub fn new(location: SourceLocation, data: ParseItemData) -> ParseItem {
        ParseItem { location, data }
    }
}

pub enum ParseItemData<'a> {
    Operation(OperationIterator<'a>),
    Integer,
}

#[derive(Clone, Debug)]
pub enum ParseErrorCause {
    Lexical,
    UnclosedParen,
    ExtraCloseParen,
    MisplacedSymbol,
    MissingOperation,
}

#[derive(Clone, Debug)]
pub struct ParseError {
    location: SourceLocation,
    cause: ParseErrorCause,
}

impl ParseError {
    pub fn new(location: SourceLocation, cause: ParseErrorCause) -> ParseError {
        ParseError { location, cause }
    }
}

impl Display for ParseError {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        self.cause.fmt(formatter)
    }
}

impl Error for ParseError {
    fn description(&self) -> &str {
        "parsing error"
    }
}

/*
 * Helper functions for Parser
 */

fn next_non_white(lexer: &mut Lexer) -> Option<<Lexer as Iterator>::Item> {
    fn is_non_white(t: &Result<ir::Token, LexicalError>) -> bool {
        match t {
            Ok(ref tok) => tok.token_type != ir::TokenType::Whitespace,
            _ => true,
        }
    }

    lexer.find(is_non_white)
}

pub struct Parser {
    lexer: Lexer,
}

impl Parser {
    pub fn new(lexer: Lexer) -> Parser {
        Parser { lexer }
    }

    /**
     * Returns the next element (operation or atom)
     *
     * TODO: make this implement a StreamingIterator interface instead of this ad-hoc solution?
     * (We can't use a regular Iterator due to self-borrowing in the return value.)
     */
    pub fn next_element<'a>(&'a mut self) -> Option<Result<ParseItem<'a>, ParseError>> {
        let next_token = next_non_white(&mut self.lexer);

        match next_token {
            Some(Ok(token)) => Some(match token.token_type {
                ir::TokenType::Whitespace => panic!("Whitespace should be filtered out"),
                ir::TokenType::Open => match OperationIterator::new(&mut self.lexer) {
                    Ok(iter) => Ok(ParseItem::new(
                        token.location,
                        ParseItemData::Operation(iter),
                    )),
                    Err(error) => Err(error),
                },
                ir::TokenType::Close => Err(ParseError::new(
                    token.location,
                    ParseErrorCause::ExtraCloseParen,
                )),
                ir::TokenType::Symbol => Err(ParseError::new(
                    token.location,
                    ParseErrorCause::MisplacedSymbol,
                )),
                ir::TokenType::Integer => {
                    Ok(ParseItem::new(token.location, ParseItemData::Integer))
                }
            }),
            Some(Err(error)) => Some(Err(ParseError::new(
                error.location,
                ParseErrorCause::Lexical,
            ))),
            None => None,
        }
    }
}

pub struct OperationIterator<'a> {
    pub op_text: SourceLocation,
    lexer: &'a mut Lexer,
}

impl<'a> OperationIterator<'a> {
    /**
     * Given a lexer that has just "seen" the opening parenthesis of an
     * operation, returns either an OperationIterator or a syntax error
     */
    fn new(lexer: &'a mut Lexer) -> Result<OperationIterator<'a>, ParseError> {
        let op_token = next_non_white(lexer);
        match op_token {
            Some(Ok(op_t)) => {
                if op_t.token_type == ir::TokenType::Symbol {
                    Ok(OperationIterator {
                        op_text: op_t.location,
                        lexer,
                    })
                } else {
                    Err(ParseError::new(
                        op_t.location,
                        ParseErrorCause::MissingOperation,
                    ))
                }
            }
            Some(Err(error)) => Err(ParseError::new(error.location, ParseErrorCause::Lexical)),
            None => Err(ParseError::new(
                SourceLocation::new(lexer.source(), lexer.offset(), 0),
                ParseErrorCause::UnclosedParen,
            )),
        }
    }

    pub fn next_element<'b>(&'b mut self) -> Option<Result<ParseItem<'b>, ParseError>> {
        let next_token = next_non_white(self.lexer);

        match next_token {
            Some(Ok(token)) => match token.token_type {
                ir::TokenType::Whitespace => panic!("Whitespace should be filtered out"),
                ir::TokenType::Open => match OperationIterator::new(self.lexer) {
                    Ok(iter) => Some(Ok(ParseItem::new(
                        token.location,
                        ParseItemData::Operation(iter),
                    ))),
                    Err(error) => Some(Err(error)),
                },
                ir::TokenType::Close => None,
                ir::TokenType::Symbol => Some(Err(ParseError::new(
                    token.location,
                    ParseErrorCause::MisplacedSymbol,
                ))),
                ir::TokenType::Integer => {
                    Some(Ok(ParseItem::new(token.location, ParseItemData::Integer)))
                }
            },
            Some(Err(error)) => Some(Err(ParseError::new(
                error.location,
                ParseErrorCause::Lexical,
            ))),
            None => None,
        }
    }
}
<commit_msg>fix unclosed parenthesis detection<commit_after>use std::error::Error;
use std::fmt;
use std::fmt::{Debug, Display};

use base::source::SourceLocation;
use ir;
use ir::lexer::{Lexer, LexicalError};

// TODO: rename to ParseElement? (or just Element)?
pub struct ParseItem<'a> {
    pub location: SourceLocation,
    pub data: ParseItemData<'a>,
}

impl<'a> ParseItem<'a> {
    pub fn new(location: SourceLocation, data: ParseItemData) -> ParseItem {
        ParseItem { location, data }
    }
}

pub enum ParseItemData<'a> {
    Operation(OperationIterator<'a>),
    Integer,
}

#[derive(Clone, Debug)]
pub enum ParseErrorCause {
    Lexical,
    UnclosedParen,
    ExtraCloseParen,
    MisplacedSymbol,
    MissingOperation,
}

#[derive(Clone, Debug)]
pub struct ParseError {
    location: SourceLocation,
    cause: ParseErrorCause,
}

impl ParseError {
    pub fn new(location: SourceLocation, cause: ParseErrorCause) -> ParseError {
        ParseError { location, cause }
    }
}

impl Display for ParseError {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        self.cause.fmt(formatter)
    }
}

impl Error for ParseError {
    fn description(&self) -> &str {
        "parsing error"
    }
}

/*
 * Helper functions for Parser
 */

fn next_non_white(lexer: &mut Lexer) -> Option<<Lexer as Iterator>::Item> {
    fn is_non_white(t: &Result<ir::Token, LexicalError>) -> bool {
        match t {
            Ok(ref tok) => tok.token_type != ir::TokenType::Whitespace,
            _ => true,
        }
    }

    lexer.find(is_non_white)
}

pub struct Parser {
    lexer: Lexer,
}

impl Parser {
    pub fn new(lexer: Lexer) -> Parser {
        Parser { lexer }
    }

    /**
     * Returns the next element (operation or atom)
     *
     * TODO: make this implement a StreamingIterator interface instead of this ad-hoc solution?
     * (We can't use a regular Iterator due to self-borrowing in the return value.)
     */
    pub fn next_element<'a>(&'a mut self) -> Option<Result<ParseItem<'a>, ParseError>> {
        let next_token = next_non_white(&mut self.lexer);

        match next_token {
            Some(Ok(token)) => Some(match token.token_type {
                ir::TokenType::Whitespace => panic!("Whitespace should be filtered out"),
                ir::TokenType::Open => match OperationIterator::new(&mut self.lexer) {
                    Ok(iter) => Ok(ParseItem::new(
                        token.location,
                        ParseItemData::Operation(iter),
                    )),
                    Err(error) => Err(error),
                },
                ir::TokenType::Close => Err(ParseError::new(
                    token.location,
                    ParseErrorCause::ExtraCloseParen,
                )),
                ir::TokenType::Symbol => Err(ParseError::new(
                    token.location,
                    ParseErrorCause::MisplacedSymbol,
                )),
                ir::TokenType::Integer => {
                    Ok(ParseItem::new(token.location, ParseItemData::Integer))
                }
            }),
            Some(Err(error)) => Some(Err(ParseError::new(
                error.location,
                ParseErrorCause::Lexical,
            ))),
            None => None,
        }
    }
}

pub struct OperationIterator<'a> {
    pub op_text: SourceLocation,
    lexer: &'a mut Lexer,
}

impl<'a> OperationIterator<'a> {
    /**
     * Given a lexer that has just "seen" the opening parenthesis of an
     * operation, returns either an OperationIterator or a syntax error
     */
    fn new(lexer: &'a mut Lexer) -> Result<OperationIterator<'a>, ParseError> {
        let op_token = next_non_white(lexer);
        match op_token {
            Some(Ok(op_t)) => {
                if op_t.token_type == ir::TokenType::Symbol {
                    Ok(OperationIterator {
                        op_text: op_t.location,
                        lexer,
                    })
                } else {
                    Err(ParseError::new(
                        op_t.location,
                        ParseErrorCause::MissingOperation,
                    ))
                }
            }
            Some(Err(error)) => Err(ParseError::new(error.location, ParseErrorCause::Lexical)),
            None => Err(ParseError::new(
                SourceLocation::new(lexer.source(), lexer.offset(), 0),
                ParseErrorCause::UnclosedParen,
            )),
        }
    }

    pub fn next_element<'b>(&'b mut self) -> Option<Result<ParseItem<'b>, ParseError>> {
        let next_token = next_non_white(self.lexer);

        match next_token {
            Some(Ok(token)) => match token.token_type {
                ir::TokenType::Whitespace => panic!("Whitespace should be filtered out"),
                ir::TokenType::Open => match OperationIterator::new(self.lexer) {
                    Ok(iter) => Some(Ok(ParseItem::new(
                        token.location,
                        ParseItemData::Operation(iter),
                    ))),
                    Err(error) => Some(Err(error)),
                },
                ir::TokenType::Close => None,
                ir::TokenType::Symbol => Some(Err(ParseError::new(
                    token.location,
                    ParseErrorCause::MisplacedSymbol,
                ))),
                ir::TokenType::Integer => {
                    Some(Ok(ParseItem::new(token.location, ParseItemData::Integer)))
                }
            },
            Some(Err(error)) => Some(Err(ParseError::new(
                error.location,
                ParseErrorCause::Lexical,
            ))),
            None => Some(Err(ParseError::new(
                SourceLocation::new(self.lexer.source(), self.lexer.offset(), 0),
                ParseErrorCause::UnclosedParen,
            ))),
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2017-2019 Rene van der Meer
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

//! Miscellaneous `embedded-hal` trait implementations.
//!
//! The `hal` module consists of a collection of `embedded-hal` trait
//! implementations for traits that aren't tied to a specific peripheral.
//!
//! This module is only included when either the `hal` or `hal-unproven` feature
//! flag is enabled.

use std::thread;
use std::time::{Duration, Instant};

use embedded_hal::blocking::delay::{DelayMs, DelayUs};
use embedded_hal::timer::CountDown;
use void::Void;

/// Implements the `embedded-hal` `DelayMs` and `DelayUs` traits.
#[derive(Debug, Default)]
pub struct Delay {}

impl Delay {
    /// Constructs a new `Delay`.
    pub fn new() -> Delay {
        Delay {}
    }
}

impl DelayMs<u8> for Delay {
    fn delay_ms(&mut self, ms: u8) {
        thread::sleep(Duration::from_millis(u64::from(ms)));
    }
}

impl DelayMs<u16> for Delay {
    fn delay_ms(&mut self, ms: u16) {
        thread::sleep(Duration::from_millis(u64::from(ms)));
    }
}

impl DelayMs<u32> for Delay {
    fn delay_ms(&mut self, ms: u32) {
        thread::sleep(Duration::from_millis(u64::from(ms)));
    }
}

impl DelayMs<u64> for Delay {
    fn delay_ms(&mut self, ms: u64) {
        thread::sleep(Duration::from_millis(ms));
    }
}

impl DelayUs<u8> for Delay {
    fn delay_us(&mut self, us: u8) {
        thread::sleep(Duration::from_micros(u64::from(us)));
    }
}

impl DelayUs<u16> for Delay {
    fn delay_us(&mut self, us: u16) {
        thread::sleep(Duration::from_micros(u64::from(us)));
    }
}

impl DelayUs<u32> for Delay {
    fn delay_us(&mut self, us: u32) {
        thread::sleep(Duration::from_micros(u64::from(us)));
    }
}

impl DelayUs<u64> for Delay {
    fn delay_us(&mut self, us: u64) {
        thread::sleep(Duration::from_micros(us));
    }
}

/// Implements the `embedded-hal` `CountDown` trait.
#[derive(Debug, Copy, Clone)]
pub struct Timer {
    now: Instant,
    duration: Duration,
}

impl Timer {
    /// Constructs a new `Timer`.
    pub fn new() -> Self {
        Self {
            now: Instant::now(),
            duration: Duration::from_micros(0),
        }
    }
}

pub struct Millisecond(pub u64);
pub struct Microsecond(pub u64);
pub struct Second(pub u64);

impl From<Millisecond> for Microsecond {
    fn from(item: Millisecond) -> Self {
        Microsecond(item.0 * 1_000)
    }
}

impl From<Second> for Microsecond {
    fn from(item: Second) -> Self {
        Microsecond(item.0 * 1_000_000)
    }
}

impl Microsecond {
    fn as_u64(&self) -> u64 {
        let &Microsecond(t) = self;
        t
    }
}

impl CountDown for Timer {
    type Time = Microsecond;

    /// Start the timer with a `timeout`
    fn start<T>(&mut self, timeout: T)
    where
        T: Into<Microsecond>,
    {
        self.duration = Duration::from_micros(timeout.into().as_u64());
        self.now = Instant::now();
    }

    /// Return `Ok` if the timer has wrapped
    /// Automatically clears the flag and restarts the time
    fn wait(&mut self) -> nb::Result<(), Void> {
        if self.now.elapsed() >= self.duration {
            let duration = Duration::from_micros(1);
            thread::sleep(duration);
            Ok(())
        } else {
            Err(nb::Error::WouldBlock)
        }
    }
}
<commit_msg>Implement Default for Timer<commit_after>// Copyright (c) 2017-2019 Rene van der Meer
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

//! Miscellaneous `embedded-hal` trait implementations.
//!
//! The `hal` module consists of a collection of `embedded-hal` trait
//! implementations for traits that aren't tied to a specific peripheral.
//!
//! This module is only included when either the `hal` or `hal-unproven` feature
//! flag is enabled.

use std::thread;
use std::time::{Duration, Instant};

use embedded_hal::blocking::delay::{DelayMs, DelayUs};
use embedded_hal::timer::CountDown;
use void::Void;

/// Implements the `embedded-hal` `DelayMs` and `DelayUs` traits.
#[derive(Debug, Default)]
pub struct Delay {}

impl Delay {
    /// Constructs a new `Delay`.
    pub fn new() -> Delay {
        Delay {}
    }
}

impl DelayMs<u8> for Delay {
    fn delay_ms(&mut self, ms: u8) {
        thread::sleep(Duration::from_millis(u64::from(ms)));
    }
}

impl DelayMs<u16> for Delay {
    fn delay_ms(&mut self, ms: u16) {
        thread::sleep(Duration::from_millis(u64::from(ms)));
    }
}

impl DelayMs<u32> for Delay {
    fn delay_ms(&mut self, ms: u32) {
        thread::sleep(Duration::from_millis(u64::from(ms)));
    }
}

impl DelayMs<u64> for Delay {
    fn delay_ms(&mut self, ms: u64) {
        thread::sleep(Duration::from_millis(ms));
    }
}

impl DelayUs<u8> for Delay {
    fn delay_us(&mut self, us: u8) {
        thread::sleep(Duration::from_micros(u64::from(us)));
    }
}

impl DelayUs<u16> for Delay {
    fn delay_us(&mut self, us: u16) {
        thread::sleep(Duration::from_micros(u64::from(us)));
    }
}

impl DelayUs<u32> for Delay {
    fn delay_us(&mut self, us: u32) {
        thread::sleep(Duration::from_micros(u64::from(us)));
    }
}

impl DelayUs<u64> for Delay {
    fn delay_us(&mut self, us: u64) {
        thread::sleep(Duration::from_micros(us));
    }
}

/// Implements the `embedded-hal` `CountDown` trait.
#[derive(Debug, Default, Copy, Clone)]
pub struct Timer {
    now: Instant,
    duration: Duration,
}

impl Timer {
    /// Constructs a new `Timer`.
    pub fn new() -> Self {
        Self {
            now: Instant::now(),
            duration: Duration::from_micros(0),
        }
    }
}

pub struct Millisecond(pub u64);
pub struct Microsecond(pub u64);
pub struct Second(pub u64);

impl From<Millisecond> for Microsecond {
    fn from(item: Millisecond) -> Self {
        Microsecond(item.0 * 1_000)
    }
}

impl From<Second> for Microsecond {
    fn from(item: Second) -> Self {
        Microsecond(item.0 * 1_000_000)
    }
}

impl Microsecond {
    fn as_u64(&self) -> u64 {
        let &Microsecond(t) = self;
        t
    }
}

impl CountDown for Timer {
    type Time = Microsecond;

    /// Start the timer with a `timeout`
    fn start<T>(&mut self, timeout: T)
    where
        T: Into<Microsecond>,
    {
        self.duration = Duration::from_micros(timeout.into().as_u64());
        self.now = Instant::now();
    }

    /// Return `Ok` if the timer has wrapped
    /// Automatically clears the flag and restarts the time
    fn wait(&mut self) -> nb::Result<(), Void> {
        if self.now.elapsed() >= self.duration {
            let duration = Duration::from_micros(1);
            thread::sleep(duration);
            Ok(())
        } else {
            Err(nb::Error::WouldBlock)
        }
    }
}
<|endoftext|>


<commit_before>// NULL    = 'null'
// BOOLEAN = 'boolean'
// STRING  = 'string'
// BYTES   = 'bytes'
// INT     = 'int'
// LONG    = 'long'
// FLOAT   = 'float'
// DOUBLE  = 'double'
// FIXED   = 'fixed'
// ENUM    = 'enum'
// RECORD  = 'record'
// ERROR   = 'error'
// ARRAY   = 'array'
// MAP     = 'map'
// UNION   = 'union'

mod schema {
  enum Primitive {
    Null,
    Boolean,
    String,
    Bytes,
    Int,
    Long,
    Float,
    Double
  }
  enum Named {
    Fixed,
    Enum,
    Record,
    Error
  }
  enum Complex {
    Array,
    Map,
    Union,
    Request,
    ErrorUnion
  }
  enum Type {
    Primitive(Primitive),
    Named(Named),
    Complex(Complex)
  }
  enum Sort {
    Ascending,
    Descending,
    Ignore
  }

  static SCHEMA_RESERVED_PROPS: [&'static str; 9] = ["type",
  "name",
  "namespace",
  "fields",
  "items",
  "size",
  "symbols",
  "values",
  "doc"];
  static FIELD_RESERVED_PROPS: [&'static str; 5] = [
  "default",
   "name",
   "doc",
   "order",
  "type",];
}

#[test]
#[should_panic]
fn it_works() {
}
<commit_msg>starting to move over old types, will likey generalie properties into traits<commit_after>// NULL    = 'null'
// BOOLEAN = 'boolean'
// STRING  = 'string'
// BYTES   = 'bytes'
// INT     = 'int'
// LONG    = 'long'
// FLOAT   = 'float'
// DOUBLE  = 'double'
// FIXED   = 'fixed'
// ENUM    = 'enum'
// RECORD  = 'record'
// ERROR   = 'error'
// ARRAY   = 'array'
// MAP     = 'map'
// UNION   = 'union'

mod schema {
  enum Primitive {
    Null,
    Boolean,
    String,
    Bytes,
    Int,
    Long,
    Float,
    Double
  }
  enum Named {
    Fixed,
    Enum,
    Record,
    Error
  }
  enum Complex {
    Array,
    Map,
    Union,
    Request,
    ErrorUnion
  }
  enum Type {
    Primitive(Primitive),
    Named(Named),
    Complex(Complex)
  }
  enum Sort {
    Ascending,
    Descending,
    Ignore
  }

  static SCHEMA_RESERVED_PROPS: [&'static str; 9] = ["type",
  "name",
  "namespace",
  "fields",
  "items",
  "size",
  "symbols",
  "values",
  "doc"];
  static FIELD_RESERVED_PROPS: [&'static str; 5] = [
  "default",
   "name",
   "doc",
   "order",
  "type"];
struct Message {
  doc: Option<String>,
  request: Vec<Field>,
  response: Type,
  errors: Option<Vec<Type>>,
  one_way: Option<bool>
}
struct Field {
  name: String,
  doc: Option<String>,
  default: String,
  order: Option<Sort>
}
struct Record {
    name: String,
    namespace: Option<String>,
    doc: Option<String>,
    aliases: Option<Vec<String>>,
    fields: Vec<Field>
}
struct Enum {
    name: String,
    namespace: Option<String>,
    doc: Option<String>,
    aliases: Option<Vec<String>>,
    symbols: Vec<String>
}
struct Array {
  items: Box<Type>
}
struct Fixed {
  name: String,
  namespace: Option<String>,
  aliases: Option<Vec<String>>,
  size: i32
}

}

#[test]
#[should_panic]
fn it_works() {
}
<|endoftext|>


<commit_before>//! Lorem ipsum generator.
//!
//! This crate contains functions for generating pseudo-Latin lorem
//! ipsum placeholder text. The traditional lorem ipsum text start
//! like this:
//!
//! > Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
//! > eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
//! > enim ad minim veniam, quis nostrud exercitation ullamco laboris
//! > nisi ut aliquip ex ea commodo consequat. [...]
//!
//! This text is in the [`LOREM_IPSUM`] constant. Random text looking
//! like the above can be generated using the [`lipsum`] function.
//! This function allows you to generate as much text as desired and
//! each invocation will generate different text. This is done using a
//! [Markov chain] based on both the [`LOREM_IPSUM`] and
//! [`LIBER_PRIMUS`] texts. The latter constant holds the full text of
//! the first book of a work by Cicero, of which the lorem ipsum text
//! is a scrambled subset.
//!
//! The random looking text is generatd using a Markov chain of order
//! two, which simply means that the next word is based on the
//! previous two words in the input texts. The Markov chain can be
//! used with other input texts by creating an instance of
//! [`MarkovChain`] and calling its [`learn`] method.
//!
//! [`LOREM_IPSUM`]: constant.LOREM_IPSUM.html
//! [`LIBER_PRIMUS`]: constant.LIBER_PRIMUS.html
//! [`lipsum`]: fn.lipsum.html
//! [`MarkovChain`]: struct.MarkovChain.html
//! [`learn`]: struct.MarkovChain.html#method.learn
//! [Markov chain]: https://en.wikipedia.org/wiki/Markov_chain

extern crate rand;

#[macro_use]
extern crate lazy_static;

use std::collections::HashMap;
use rand::Rng;

/// A bigram is simply two consecutive words.
pub type Bigram<'a> = (&'a str, &'a str);

/// Simple order two Markov chain implementation.
///
/// The [Markov chain] is a chain of order two, which means that it
/// will use the previous two words (a bigram) when predicting the
/// next word. This is normally enough to generate random text that
/// looks somewhat plausible. The implementation is based on
/// [Generating arbitrary text with Markov chains in Rust][blog post].
///
/// [Markov chain]: https://en.wikipedia.org/wiki/Markov_chain
/// [blog post]: https://blakewilliams.me/posts/generating-arbitrary-text-with-markov-chains-in-rust
#[derive(Default)]
pub struct MarkovChain<'a> {
    pub map: HashMap<Bigram<'a>, Vec<&'a str>>,
}

impl<'a> MarkovChain<'a> {
    /// Create a new Markov chain. It will use a default thread-local
    /// random number generator.
    pub fn new() -> MarkovChain<'a> {
        MarkovChain { map: HashMap::new() }
    }

    /// Add new text to the Markov chain. This can be called several
    /// times to build up the chain.
    ///
    /// # Examples
    ///
    /// ```
    /// use lipsum::MarkovChain;
    ///
    /// let mut chain = MarkovChain::new();
    /// chain.learn("red green blue");
    /// assert_eq!(chain.map[&("red", "green")], vec!["blue"]);
    ///
    /// chain.learn("red green yellow");
    /// assert_eq!(chain.map[&("red", "green")], vec!["blue", "yellow"]);
    /// ```
    pub fn learn(&mut self, sentence: &'a str) {
        let words = sentence.split_whitespace().collect::<Vec<&str>>();
        for window in words.windows(3) {
            let (a, b, c) = (window[0], window[1], window[2]);
            self.map.entry((a, b)).or_insert_with(Vec::new).push(c);
        }
    }

    /// Generate `n` words worth of lorem ipsum text. The text will
    /// start from a random point in the Markov chain.
    ///
    /// See [`generate_from`] if you want to control the starting
    /// point for the generated text.
    ///
    /// # Examples
    ///
    /// Generating the sounds of a grandfather clock:
    ///
    /// ```
    /// use lipsum::MarkovChain;
    ///
    /// let mut chain = MarkovChain::new();
    /// chain.learn("Tick, Tock, Tick, Tock, Ding! Tick, Tock, Ding! Ding!");
    /// println!("{}", chain.generate(15));
    /// ```
    ///
    /// The output looks like this:
    ///
    /// > Ding! Tick, Tock, Tick, Tock, Ding! Ding! Tock, Ding! Tick,
    /// > Tock, Tick, Tock, Tick, Tock
    ///
    /// [`generate_from`]: struct.MarkovChain.html#method.generate_from
    pub fn generate(&self, n: usize) -> String {
        join_words(self.iter().take(n))
    }

    /// Generate `n` words worth of lorem ipsum text. The text will
    /// start from the given bigram.
    ///
    /// Use [`generate`] if the starting point is not important.
    ///
    /// [`generate`]: struct.MarkovChain.html#method.generate
    pub fn generate_from(&self, n: usize, from: Bigram<'a>) -> String {
        join_words(self.iter_from(from).take(n))
    }

    /// Make a never-ending iterator over the words in the Markov
    /// chain. The iterator starts at a random point in the chain.
    pub fn iter(&self) -> Words {
        let keys = self.map.keys().collect::<Vec<&(&str, &str)>>();
        let state = if keys.is_empty() {
            ("", "")
        } else {
            let mut rng = rand::thread_rng();
            **rng.choose(&keys).unwrap()
        };
        Words { map: &self.map, keys: keys, state: state }
    }

    /// Make a never-ending iterator over the words in the Markov
    /// chain. The iterator starts at the given bigram.
    pub fn iter_from(&self, from: Bigram<'a>) -> Words {
        let keys = self.map.keys().collect::<Vec<&(&str, &str)>>();
        Words { map: &self.map, keys: keys, state: from }
    }
}

pub struct Words<'a> {
    map: &'a HashMap<Bigram<'a>, Vec<&'a str>>,
    keys: Vec<&'a Bigram<'a>>,
    state: Bigram<'a>,
}

impl<'a> Iterator for Words<'a> {
    type Item = &'a str;

    fn next(&mut self) -> Option<&'a str> {
        if self.map.is_empty() {
            return None;
        }

        let result = Some(self.state.0);
        let mut rng = rand::thread_rng();

        while !self.map.contains_key(&self.state) {
            self.state = **rng.choose(&self.keys).unwrap();
        }
        let next_words = &self.map[&self.state];
        let next = rng.choose(next_words).unwrap();
        self.state = (self.state.1, next);
        result
    }
}

fn join_words<'a, I: Iterator<Item = &'a str>>(mut words: I) -> String {
    match words.next() {
        None => String::new(),
        Some(word) => {
            let mut sentence = String::from(word);
            for word in words {
                sentence.push(' ');
                sentence.push_str(word);
            }
            sentence
        }
    }
}

/// The traditional lorem ipsum text as given in [Wikipedia]. Using
/// this text alone for a Markov chain of order two doesn't work very
/// well since each bigram (two consequtive words) is followed by just
/// one other word. In other words, the Markov chain will always
/// produce the same output and recreate the lorem ipsum text
/// precisely. However, combining it with the full text in
/// [`LIBER_PRIMUS`] works well.
///
/// [Wikipedia]: https://en.wikipedia.org/wiki/Lorem_ipsum
/// [`LIBER_PRIMUS`]: constant.LIBER_PRIMUS.html
pub const LOREM_IPSUM: &'static str = include_str!("lorem-ipsum.txt");

/// The first book in Cicero's work De finibus bonorum et malorum ("On
/// the ends of good and evil"). The lorem ipsum text in
/// [`LOREM_IPSUM`] is derived from part of this text.
///
/// [`LOREM_IPSUM`]: constant.LOREM_IPSUM.html
pub const LIBER_PRIMUS: &'static str = include_str!("liber-primus.txt");

lazy_static! {
    /// Markov chain generating lorem ipsum text.
    static ref LOREM_IPSUM_CHAIN: MarkovChain<'static> = {
        let mut chain = MarkovChain::new();
        chain.learn(LOREM_IPSUM);
        chain.learn(LIBER_PRIMUS);
        chain
    };
}

/// Generate `n` words of lorem ipsum text. The output starts with
/// "Lorem ipsum" and continues with the standard lorem ipsum text
/// from [`LOREM_IPSUM`]. The text will become random if sufficiently
/// long output is requested.
///
/// [`LOREM_IPSUM`]: constant.LOREM_IPSUM.html
pub fn lipsum(n: usize) -> String {
    LOREM_IPSUM_CHAIN.generate_from(n, ("Lorem", "ipsum"))
}

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

    #[test]
    fn starts_with_lorem_ipsum() {
        assert_eq!(&lipsum(10)[..11], "Lorem ipsum");
    }

    #[test]
    fn generate_zero_words() {
        assert_eq!(lipsum(0).split_whitespace().count(), 0);
    }

    #[test]
    fn generate_one_word() {
        assert_eq!(lipsum(1).split_whitespace().count(), 1);
    }

    #[test]
    fn generate_two_words() {
        assert_eq!(lipsum(2).split_whitespace().count(), 2);
    }

    #[test]
    fn empty_chain() {
        let chain = MarkovChain::new();
        assert_eq!(chain.generate(10), "");
    }

    #[test]
    fn generate_from() {
        let mut chain = MarkovChain::new();
        chain.learn("red orange yellow green blue indigo violet");
        assert_eq!(chain.generate_from(5, ("orange", "yellow")),
                   "orange yellow green blue indigo");
    }

    #[test]
    fn generate_last_bigram() {
        // The bigram "yyy zzz" will not be present in the Markov
        // chain's map, and so we will not generate "xxx yyy zzz" as
        // one would expect. The chain moves from state "xxx yyy" to
        // "yyy zzz", but sees that as invalid state and resets itsel
        // back to "xxx yyy".
        let mut chain = MarkovChain::new();
        chain.learn("xxx yyy zzz");
        // We use assert! instead of assert_ne! to support early
        // versions of Rust.
        assert!(chain.generate_from(3, ("xxx", "yyy")) != "xxx yyy zzz");
    }

    #[test]
    fn generate_from_no_panic() {
        // No panic when asked to generate a chain from a starting
        // point that doesn't exist in the chain.
        let mut chain = MarkovChain::new();
        chain.learn("foo bar baz");
        chain.generate_from(3, ("xxx", "yyy"));
    }

    #[test]
    fn chain_map() {
        let mut chain = MarkovChain::new();
        chain.learn("foo bar baz quuz");
        let map = &chain.map;

        assert_eq!(map.len(), 2);
        assert_eq!(map[&("foo", "bar")], vec!["baz"]);
        assert_eq!(map[&("bar", "baz")], vec!["quuz"]);
    }
}
<commit_msg>MarkovChain: make map private and add words method<commit_after>//! Lorem ipsum generator.
//!
//! This crate contains functions for generating pseudo-Latin lorem
//! ipsum placeholder text. The traditional lorem ipsum text start
//! like this:
//!
//! > Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
//! > eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
//! > enim ad minim veniam, quis nostrud exercitation ullamco laboris
//! > nisi ut aliquip ex ea commodo consequat. [...]
//!
//! This text is in the [`LOREM_IPSUM`] constant. Random text looking
//! like the above can be generated using the [`lipsum`] function.
//! This function allows you to generate as much text as desired and
//! each invocation will generate different text. This is done using a
//! [Markov chain] based on both the [`LOREM_IPSUM`] and
//! [`LIBER_PRIMUS`] texts. The latter constant holds the full text of
//! the first book of a work by Cicero, of which the lorem ipsum text
//! is a scrambled subset.
//!
//! The random looking text is generatd using a Markov chain of order
//! two, which simply means that the next word is based on the
//! previous two words in the input texts. The Markov chain can be
//! used with other input texts by creating an instance of
//! [`MarkovChain`] and calling its [`learn`] method.
//!
//! [`LOREM_IPSUM`]: constant.LOREM_IPSUM.html
//! [`LIBER_PRIMUS`]: constant.LIBER_PRIMUS.html
//! [`lipsum`]: fn.lipsum.html
//! [`MarkovChain`]: struct.MarkovChain.html
//! [`learn`]: struct.MarkovChain.html#method.learn
//! [Markov chain]: https://en.wikipedia.org/wiki/Markov_chain

extern crate rand;

#[macro_use]
extern crate lazy_static;

use std::collections::HashMap;
use rand::Rng;

/// A bigram is simply two consecutive words.
pub type Bigram<'a> = (&'a str, &'a str);

/// Simple order two Markov chain implementation.
///
/// The [Markov chain] is a chain of order two, which means that it
/// will use the previous two words (a bigram) when predicting the
/// next word. This is normally enough to generate random text that
/// looks somewhat plausible. The implementation is based on
/// [Generating arbitrary text with Markov chains in Rust][blog post].
///
/// [Markov chain]: https://en.wikipedia.org/wiki/Markov_chain
/// [blog post]: https://blakewilliams.me/posts/generating-arbitrary-text-with-markov-chains-in-rust
#[derive(Default)]
pub struct MarkovChain<'a> {
    map: HashMap<Bigram<'a>, Vec<&'a str>>,
}

impl<'a> MarkovChain<'a> {
    /// Create a new Markov chain. It will use a default thread-local
    /// random number generator.
    pub fn new() -> MarkovChain<'a> {
        MarkovChain { map: HashMap::new() }
    }

    /// Add new text to the Markov chain. This can be called several
    /// times to build up the chain.
    ///
    /// # Examples
    ///
    /// ```
    /// use lipsum::MarkovChain;
    ///
    /// let mut chain = MarkovChain::new();
    /// chain.learn("red green blue");
    /// assert_eq!(chain.words(("red", "green")), Some(&vec!["blue"]));
    ///
    /// chain.learn("red green yellow");
    /// assert_eq!(chain.words(("red", "green")), Some(&vec!["blue", "yellow"]));
    /// ```
    pub fn learn(&mut self, sentence: &'a str) {
        let words = sentence.split_whitespace().collect::<Vec<&str>>();
        for window in words.windows(3) {
            let (a, b, c) = (window[0], window[1], window[2]);
            self.map.entry((a, b)).or_insert_with(Vec::new).push(c);
        }
    }

    /// Get the possible words following the given bigram, or `None`
    /// if the state is invalid.
    ///
    /// # Examples
    ///
    /// ```
    /// use lipsum::MarkovChain;
    ///
    /// let mut chain = MarkovChain::new();
    /// chain.learn("red green blue");
    /// assert_eq!(chain.words(("red", "green")), Some(&vec!["blue"]));
    /// assert_eq!(chain.words(("foo", "bar")), None);
    /// ```
    pub fn words(&self, state: Bigram<'a>) -> Option<&Vec<&str>> {
        self.map.get(&state)
    }

    /// Generate `n` words worth of lorem ipsum text. The text will
    /// start from a random point in the Markov chain.
    ///
    /// See [`generate_from`] if you want to control the starting
    /// point for the generated text.
    ///
    /// # Examples
    ///
    /// Generating the sounds of a grandfather clock:
    ///
    /// ```
    /// use lipsum::MarkovChain;
    ///
    /// let mut chain = MarkovChain::new();
    /// chain.learn("Tick, Tock, Tick, Tock, Ding! Tick, Tock, Ding! Ding!");
    /// println!("{}", chain.generate(15));
    /// ```
    ///
    /// The output looks like this:
    ///
    /// > Ding! Tick, Tock, Tick, Tock, Ding! Ding! Tock, Ding! Tick,
    /// > Tock, Tick, Tock, Tick, Tock
    ///
    /// [`generate_from`]: struct.MarkovChain.html#method.generate_from
    pub fn generate(&self, n: usize) -> String {
        join_words(self.iter().take(n))
    }

    /// Generate `n` words worth of lorem ipsum text. The text will
    /// start from the given bigram.
    ///
    /// Use [`generate`] if the starting point is not important.
    ///
    /// [`generate`]: struct.MarkovChain.html#method.generate
    pub fn generate_from(&self, n: usize, from: Bigram<'a>) -> String {
        join_words(self.iter_from(from).take(n))
    }

    /// Make a never-ending iterator over the words in the Markov
    /// chain. The iterator starts at a random point in the chain.
    pub fn iter(&self) -> Words {
        let keys = self.map.keys().collect::<Vec<&(&str, &str)>>();
        let state = if keys.is_empty() {
            ("", "")
        } else {
            let mut rng = rand::thread_rng();
            **rng.choose(&keys).unwrap()
        };
        Words { map: &self.map, keys: keys, state: state }
    }

    /// Make a never-ending iterator over the words in the Markov
    /// chain. The iterator starts at the given bigram.
    pub fn iter_from(&self, from: Bigram<'a>) -> Words {
        let keys = self.map.keys().collect::<Vec<&(&str, &str)>>();
        Words { map: &self.map, keys: keys, state: from }
    }
}

pub struct Words<'a> {
    map: &'a HashMap<Bigram<'a>, Vec<&'a str>>,
    keys: Vec<&'a Bigram<'a>>,
    state: Bigram<'a>,
}

impl<'a> Iterator for Words<'a> {
    type Item = &'a str;

    fn next(&mut self) -> Option<&'a str> {
        if self.map.is_empty() {
            return None;
        }

        let result = Some(self.state.0);
        let mut rng = rand::thread_rng();

        while !self.map.contains_key(&self.state) {
            self.state = **rng.choose(&self.keys).unwrap();
        }
        let next_words = &self.map[&self.state];
        let next = rng.choose(next_words).unwrap();
        self.state = (self.state.1, next);
        result
    }
}

fn join_words<'a, I: Iterator<Item = &'a str>>(mut words: I) -> String {
    match words.next() {
        None => String::new(),
        Some(word) => {
            let mut sentence = String::from(word);
            for word in words {
                sentence.push(' ');
                sentence.push_str(word);
            }
            sentence
        }
    }
}

/// The traditional lorem ipsum text as given in [Wikipedia]. Using
/// this text alone for a Markov chain of order two doesn't work very
/// well since each bigram (two consequtive words) is followed by just
/// one other word. In other words, the Markov chain will always
/// produce the same output and recreate the lorem ipsum text
/// precisely. However, combining it with the full text in
/// [`LIBER_PRIMUS`] works well.
///
/// [Wikipedia]: https://en.wikipedia.org/wiki/Lorem_ipsum
/// [`LIBER_PRIMUS`]: constant.LIBER_PRIMUS.html
pub const LOREM_IPSUM: &'static str = include_str!("lorem-ipsum.txt");

/// The first book in Cicero's work De finibus bonorum et malorum ("On
/// the ends of good and evil"). The lorem ipsum text in
/// [`LOREM_IPSUM`] is derived from part of this text.
///
/// [`LOREM_IPSUM`]: constant.LOREM_IPSUM.html
pub const LIBER_PRIMUS: &'static str = include_str!("liber-primus.txt");

lazy_static! {
    /// Markov chain generating lorem ipsum text.
    static ref LOREM_IPSUM_CHAIN: MarkovChain<'static> = {
        let mut chain = MarkovChain::new();
        chain.learn(LOREM_IPSUM);
        chain.learn(LIBER_PRIMUS);
        chain
    };
}

/// Generate `n` words of lorem ipsum text. The output starts with
/// "Lorem ipsum" and continues with the standard lorem ipsum text
/// from [`LOREM_IPSUM`]. The text will become random if sufficiently
/// long output is requested.
///
/// [`LOREM_IPSUM`]: constant.LOREM_IPSUM.html
pub fn lipsum(n: usize) -> String {
    LOREM_IPSUM_CHAIN.generate_from(n, ("Lorem", "ipsum"))
}

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

    #[test]
    fn starts_with_lorem_ipsum() {
        assert_eq!(&lipsum(10)[..11], "Lorem ipsum");
    }

    #[test]
    fn generate_zero_words() {
        assert_eq!(lipsum(0).split_whitespace().count(), 0);
    }

    #[test]
    fn generate_one_word() {
        assert_eq!(lipsum(1).split_whitespace().count(), 1);
    }

    #[test]
    fn generate_two_words() {
        assert_eq!(lipsum(2).split_whitespace().count(), 2);
    }

    #[test]
    fn empty_chain() {
        let chain = MarkovChain::new();
        assert_eq!(chain.generate(10), "");
    }

    #[test]
    fn generate_from() {
        let mut chain = MarkovChain::new();
        chain.learn("red orange yellow green blue indigo violet");
        assert_eq!(chain.generate_from(5, ("orange", "yellow")),
                   "orange yellow green blue indigo");
    }

    #[test]
    fn generate_last_bigram() {
        // The bigram "yyy zzz" will not be present in the Markov
        // chain's map, and so we will not generate "xxx yyy zzz" as
        // one would expect. The chain moves from state "xxx yyy" to
        // "yyy zzz", but sees that as invalid state and resets itsel
        // back to "xxx yyy".
        let mut chain = MarkovChain::new();
        chain.learn("xxx yyy zzz");
        // We use assert! instead of assert_ne! to support early
        // versions of Rust.
        assert!(chain.generate_from(3, ("xxx", "yyy")) != "xxx yyy zzz");
    }

    #[test]
    fn generate_from_no_panic() {
        // No panic when asked to generate a chain from a starting
        // point that doesn't exist in the chain.
        let mut chain = MarkovChain::new();
        chain.learn("foo bar baz");
        chain.generate_from(3, ("xxx", "yyy"));
    }

    #[test]
    fn chain_map() {
        let mut chain = MarkovChain::new();
        chain.learn("foo bar baz quuz");
        let map = &chain.map;

        assert_eq!(map.len(), 2);
        assert_eq!(map[&("foo", "bar")], vec!["baz"]);
        assert_eq!(map[&("bar", "baz")], vec!["quuz"]);
    }
}
<|endoftext|>


<commit_before>#![feature(trace_macros)]
#![recursion_limit = "256"]
#[macro_use]
extern crate nom;
#[macro_use]
extern crate cookie_factory;

#[macro_use]
extern crate log;

extern crate av_data;
extern crate av_format;

#[cfg(test)]
#[macro_use]
extern crate quickcheck;

use av_data::rational;

#[macro_use]
pub mod permutation;
#[macro_use]
pub mod ebml;
pub mod elements;
#[macro_use]
pub mod serializer;
pub mod demuxer;
pub mod muxer;

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {}
}
<commit_msg>remove the trace_macros feature<commit_after>#![recursion_limit = "256"]
#[macro_use]
extern crate nom;
#[macro_use]
extern crate cookie_factory;

#[macro_use]
extern crate log;

extern crate av_data;
extern crate av_format;

#[cfg(test)]
#[macro_use]
extern crate quickcheck;

use av_data::rational;

#[macro_use]
pub mod permutation;
#[macro_use]
pub mod ebml;
pub mod elements;
#[macro_use]
pub mod serializer;
pub mod demuxer;
pub mod muxer;

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {}
}
<|endoftext|>


<commit_before>//! Rsure is a set of utilities for capturing information about files, and later verifying it is
//! still true.
//!
//! The easiest way to use Rsure is to build the `rsure` executable contained in this crate.  This
//! program allows you to use most of the functionality of the crate.
//!
//! However, it is also possible to use the crate programmatically.  At the top level of the crate
//! as some utility functions for the most common operations.
//!
//! For example, to scan a directory or do an update use `update`.
//!
//! This example makes use of several of the building blocks necessary to use the store.  First is
//! the store itself.  `parse_store` is able to decode options that are passed to the command line.
//! it is also possible to build a `store::Plain` store directly.
//!
//! Next are the tags for the snapshot.  Generally, this should hold some kind of information about
//! the snapshot itself.  For the `Plain` store, it can be just an empty map.  Other store types
//! may require certain tags to be present.

#![warn(bare_trait_objects)]

use std::path::Path;

pub use crate::surefs::scan_fs;
pub use crate::hashes::SureHash;
pub use crate::suretree::SureTree;
pub use crate::comp::{TreeCompare, TreeUpdate};
pub use crate::compvisit::{CompareVisitor, CompareType, CompareAction, PrintVisitor, stdout_visitor,
                    stderr_visitor};
pub use crate::show::show_tree;
pub use crate::progress::Progress;

pub use crate::errors::{Error, WeaveError, Result};

pub use crate::store::{StoreTags, Store, StoreVersion, Version, parse_store, BkSureFile, BkStore,
                bk_setup};

mod errors;
mod escape;
mod show;
mod suretree;
mod surefs;
mod hashes;
mod comp;
mod compvisit;
mod progress;
mod store;

// Some common operations, abstracted here.

/// Perform an update scan, using the given store.
///
/// If 'update' is true, use the hashes from a previous run, otherwise perform a fresh scan.
/// Depending on the [`Store`] type, the tags may be kept, or ignored.
///
/// [`Store`]: trait.Store.html
///
/// A simple example:
///
/// ```rust
/// # use std::error::Error;
/// #
/// # fn try_main() -> Result<(), Box<Error>> {
/// let mut tags = rsure::StoreTags::new();
/// tags.insert("name".into(), "sample".into());
/// let store = rsure::parse_store("2sure.dat.gz")?;
/// rsure::update(".", &*store, false, &tags)?;
/// #     Ok(())
/// # }
/// #
/// # fn main() {
/// #     try_main().unwrap();
/// # }
/// ```
pub fn update<P: AsRef<Path>>(
    dir: P,
    store: &dyn Store,
    is_update: bool,
    tags: &StoreTags,
) -> Result<()> {
    let dir = dir.as_ref();

    let mut new_tree = scan_fs(dir)?;

    if is_update {
        let old_tree = store.load(Version::Latest)?;
        new_tree.update_from(&old_tree);
    }

    let estimate = new_tree.hash_estimate();
    let mut progress = Progress::new(estimate.files, estimate.bytes);
    new_tree.hash_update(dir, &mut progress);
    progress.flush();

    store.write_new(&new_tree, tags)?;
    Ok(())
}
<commit_msg>Change to Nested imports<commit_after>//! Rsure is a set of utilities for capturing information about files, and later verifying it is
//! still true.
//!
//! The easiest way to use Rsure is to build the `rsure` executable contained in this crate.  This
//! program allows you to use most of the functionality of the crate.
//!
//! However, it is also possible to use the crate programmatically.  At the top level of the crate
//! as some utility functions for the most common operations.
//!
//! For example, to scan a directory or do an update use `update`.
//!
//! This example makes use of several of the building blocks necessary to use the store.  First is
//! the store itself.  `parse_store` is able to decode options that are passed to the command line.
//! it is also possible to build a `store::Plain` store directly.
//!
//! Next are the tags for the snapshot.  Generally, this should hold some kind of information about
//! the snapshot itself.  For the `Plain` store, it can be just an empty map.  Other store types
//! may require certain tags to be present.

#![warn(bare_trait_objects)]

use std::path::Path;

pub use crate::{
    comp::{
        TreeCompare,
        TreeUpdate,
    },
    compvisit::{
        CompareVisitor,
        CompareType,
        CompareAction,
        PrintVisitor,
        stdout_visitor,
        stderr_visitor,
    },
    errors::{
        Error,
        WeaveError,
        Result,
    },
    hashes::SureHash,
    progress::Progress,
    show::show_tree,
    store::{
        StoreTags,
        Store,
        StoreVersion,
        Version,
        parse_store,
        BkSureFile,
        BkStore,
        bk_setup,
    },
    surefs::scan_fs,
    suretree::SureTree,
};

mod errors;
mod escape;
mod show;
mod suretree;
mod surefs;
mod hashes;
mod comp;
mod compvisit;
mod progress;
mod store;

// Some common operations, abstracted here.

/// Perform an update scan, using the given store.
///
/// If 'update' is true, use the hashes from a previous run, otherwise perform a fresh scan.
/// Depending on the [`Store`] type, the tags may be kept, or ignored.
///
/// [`Store`]: trait.Store.html
///
/// A simple example:
///
/// ```rust
/// # use std::error::Error;
/// #
/// # fn try_main() -> Result<(), Box<Error>> {
/// let mut tags = rsure::StoreTags::new();
/// tags.insert("name".into(), "sample".into());
/// let store = rsure::parse_store("2sure.dat.gz")?;
/// rsure::update(".", &*store, false, &tags)?;
/// #     Ok(())
/// # }
/// #
/// # fn main() {
/// #     try_main().unwrap();
/// # }
/// ```
pub fn update<P: AsRef<Path>>(
    dir: P,
    store: &dyn Store,
    is_update: bool,
    tags: &StoreTags,
) -> Result<()> {
    let dir = dir.as_ref();

    let mut new_tree = scan_fs(dir)?;

    if is_update {
        let old_tree = store.load(Version::Latest)?;
        new_tree.update_from(&old_tree);
    }

    let estimate = new_tree.hash_estimate();
    let mut progress = Progress::new(estimate.files, estimate.bytes);
    new_tree.hash_update(dir, &mut progress);
    progress.flush();

    store.write_new(&new_tree, tags)?;
    Ok(())
}
<|endoftext|>


<commit_before>extern crate cards;

use cards::card::{Card};

pub type CardSlot = Option<Card>;

/*
pub enum CardSlot { //TODO: this could be an option as well?
    Empty,
    Card, //TODO: this is not working as expected
}
*/

/*
impl CardSlot {
    pub fn expect_borrow(&self) -> &Card {
        match self {
            &CardSlot::Empty => panic!("You are trying to borrow a non-dealt card"),
            x @ &CardSlot::Card => x
        }
    }
}
*/

/*
pub fn expectCard<'a>(cs: CardSlot) -> &'a Card {
    match cs {
        None => panic!("You are trying to borrow a non-dealt card"),
        Some(ref x) => x
    }
}
*/

pub enum HandRankClass {
    HighCard,
    OnePair,
    TwoPair,
    ThreeOfAKind,
    Straight,
    Flush,
    FullHouse,
    FourOfAKind,
    StraightFlush,
}

pub struct HandCards(pub CardSlot, pub CardSlot);
pub struct CommunityCards(pub CardSlot, pub CardSlot, pub CardSlot, pub CardSlot, pub CardSlot);
//TODO: unwrap to go from cardSlot to card or panic?
<commit_msg>Deriving Debug.<commit_after>extern crate cards;

use cards::card::{Card};

pub type CardSlot = Option<Card>;

/*
pub enum CardSlot { //TODO: this could be an option as well?
    Empty,
    Card, //TODO: this is not working as expected
}
*/

/*
impl CardSlot {
    pub fn expect_borrow(&self) -> &Card {
        match self {
            &CardSlot::Empty => panic!("You are trying to borrow a non-dealt card"),
            x @ &CardSlot::Card => x
        }
    }
}
*/

/*
pub fn expectCard<'a>(cs: CardSlot) -> &'a Card {
    match cs {
        None => panic!("You are trying to borrow a non-dealt card"),
        Some(ref x) => x
    }
}
*/

#[derive(Debug)]
pub enum HandRankClass {
    HighCard,
    OnePair,
    TwoPair,
    ThreeOfAKind,
    Straight,
    Flush,
    FullHouse,
    FourOfAKind,
    StraightFlush,
}

pub struct HandCards(pub CardSlot, pub CardSlot);
pub struct CommunityCards(pub CardSlot, pub CardSlot, pub CardSlot, pub CardSlot, pub CardSlot);
//TODO: unwrap to go from cardSlot to card or panic?
<|endoftext|>


<commit_before>//!  Linear algebra package for [rust-ndarray](https://github.com/bluss/rust-ndarray) using LAPACK via [stainless-steel/lapack](https://github.com/stainless-steel/lapack)
//!
//!  Linear algebra methods
//!  -----------------------
//!  - [QR decomposition](qr/trait.QR.html)
//!  - [singular value decomposition](svd/trait.SVD.html)
//!  - [solve linear problem](solve/index.html)
//!  - [solve linear problem for triangular matrix](triangular/trait.SolveTriangular.html)
//!  - [inverse matrix](solve/trait.Inverse.html)
//!  - [eigenvalue decomposition for Hermite matrix][eigh]
//!
//!  [eigh]:eigh/trait.Eigh.html
//!
//!  Utilities
//!  -----------
//!  - [assertions for array](index.html#macros)
//!  - [generator functions](generate/index.html)
//!  - [Scalar trait](types/trait.Scalar.html)

pub mod assert;
pub mod cholesky;
pub mod convert;
pub mod diagonal;
pub mod eigh;
pub mod error;
pub mod generate;
pub mod lapack;
pub mod layout;
pub mod norm;
pub mod operator;
pub mod opnorm;
pub mod qr;
pub mod solve;
pub mod solveh;
pub mod svd;
pub mod trace;
pub mod triangular;
pub mod types;

pub use assert::*;
pub use cholesky::*;
pub use convert::*;
pub use diagonal::*;
pub use eigh::*;
pub use generate::*;
pub use layout::*;
pub use norm::*;
pub use operator::*;
pub use opnorm::*;
pub use qr::*;
pub use solve::*;
pub use solveh::*;
pub use svd::*;
pub use trace::*;
pub use triangular::*;
pub use types::*;
<commit_msg>Docs - Landing page (#145)<commit_after>//! The `ndarray-linalg` crate provides linear algebra functionalities for `ArrayBase`, the n-dimensional array data structure provided by [`ndarray`](https://github.com/rust-ndarray/ndarray).
//!
//! `ndarray-linalg` leverages [LAPACK](http://www.netlib.org/lapack/)'s routines using the bindings provided by [blas-lapack-rs/lapack](https://github.com/blas-lapack-rs/lapack).
//!
//! Linear algebra methods
//! -----------------------
//! - Decomposition methods:
//!     - [QR decomposition](qr/index.html)
//!     - [Cholesky/LU decomposition](cholesky/index.html)
//!     - [Eigenvalue decomposition for Hermite matrices](eigh/index.html)
//!     - [**S**ingular **V**alue **D**ecomposition](svd/index.html)
//! - Solution of linear systems:
//!    - [General matrices](solve/index.html)
//!    - [Triangular matrices](triangular/index.html)
//!    - [Hermitian/real symmetric matrices](solveh/index.html)
//! - [Inverse matrix computation](solve/trait.Inverse.html)
//!
//! Naming Convention
//! -----------------------
//! Each routine is usually exposed as a trait, implemented by the relevant types.
//!
//! For each routine there might be multiple "variants": different traits corresponding to the different ownership possibilities of the array you intend to work on.
//!
//! For example, if you are interested in the QR decomposition of a square matrix, you can use:
//! - [QRSquare](qr/trait.QRSquare.html), if you hold an immutable reference (i.e. `&self`) to the matrix you want to decompose;
//! - [QRSquareInplace](qr/trait.QRSquareInplace.html), if you hold a mutable reference (i.e. `&mut self`) to the matrix you want to decompose;
//! - [QRSquareInto](qr/trait.QRSquareInto.html), if you can pass the matrix you want to decompose by value (e.g. `self`).
//!
//! Depending on the algorithm, each variant might require more or less copy operations of the underlying data.
//!
//! Details are provided in the description of each routine.
//!
//!  Utilities
//!  -----------
//!  - [Assertions for array](index.html#macros)
//!  - [Random matrix generators](generate/index.html)
//!  - [Scalar trait](types/trait.Scalar.html)

pub mod assert;
pub mod cholesky;
pub mod convert;
pub mod diagonal;
pub mod eigh;
pub mod error;
pub mod generate;
pub mod lapack;
pub mod layout;
pub mod norm;
pub mod operator;
pub mod opnorm;
pub mod qr;
pub mod solve;
pub mod solveh;
pub mod svd;
pub mod trace;
pub mod triangular;
pub mod types;

pub use assert::*;
pub use cholesky::*;
pub use convert::*;
pub use diagonal::*;
pub use eigh::*;
pub use generate::*;
pub use layout::*;
pub use norm::*;
pub use operator::*;
pub use opnorm::*;
pub use qr::*;
pub use solve::*;
pub use solveh::*;
pub use svd::*;
pub use trace::*;
pub use triangular::*;
pub use types::*;
<|endoftext|>


<commit_before>#[macro_use]
extern crate nom;
use std::ffi::CStr;
use std::os::raw::c_char;

use nom::{le_u64,le_u32,le_i32};
use nom::IResult;

// These are all integer_t, aka int
#[allow(non_camel_case_types)]
pub type cpu_type_t = i32;
#[allow(non_camel_case_types)]
pub type cpu_subtype_t = u32;
#[allow(non_camel_case_types)]
pub type vm_prot_t = i32;

#[derive(Debug)]
pub struct MachHeader {
    pub header: MachHeader_,
    pub segments: Vec<SegmentCommand>,
}

#[derive(Debug)]
pub struct MachHeader_ {
    pub magic: u32,
    pub cputype: cpu_type_t,
    pub cpusubtype: cpu_subtype_t,
    pub filetype: u32,
    pub ncmds: u32,
    pub sizeofcmds: u32,
    pub flags: u32,
    reserved :u32,
}

impl MachHeader {
    pub fn parse(bytes: &[u8]) -> Option<MachHeader> {
        if let IResult::Done(_rest, header) = mach_header(bytes) {
            let mut rest = _rest;
            let mut segments = vec![];
            for _ in 0.. header.ncmds {
                if let IResult::Done(_rest, cmd) = segment_command(rest) {
                    rest = _rest;
                    segments.push(cmd);
                } else {
                    return None
                }
            }

            Some(MachHeader {
                header: header,
                segments: segments,
            })
        } else {
            return None
        }
    }
}

#[derive(Debug)]
pub struct SegmentCommand {
    pub cmd: u32,
    pub cmdsize: u32,
    pub segname: String,
    pub vmaddr: u64,
    pub vmsize: u64,
    pub fileoff: u64,
    pub filesize: u64,
    pub maxprot: vm_prot_t,
    pub initprot: vm_prot_t,
    pub nsects: u32,
    pub flags: u32,
}

named!(mach_header<&[u8], MachHeader_>,
       chain!(
           magic: le_u32 ~
           cputype: le_i32 ~
           cpusubtype: le_u32 ~
           filetype: le_u32 ~
           ncmds: le_u32 ~
           sizeofcmds: le_u32 ~
           flags: le_u32 ~
           reserved: le_u32,

           || {
               assert_eq!(0xfeedfacf, magic);
               MachHeader_ {
                   magic: magic,
                   cputype: cputype,
                   // This value needs to be masked to match otool -h
                   cpusubtype: cpusubtype,
                   filetype: filetype,
                   ncmds: ncmds,
                   sizeofcmds: sizeofcmds,
                   flags: flags,
                   reserved: reserved,
               }
           }
           )
       );

named!(segment_command<&[u8], SegmentCommand>,
       chain!(
           cmd: le_u32 ~
           cmdsize: le_u32 ~
           segname: take!(16) ~
           vmaddr: le_u32 ~
           vmsize: le_u32 ~
           fileoff: le_u32 ~
           filesize: le_u32 ~
           maxprot: le_i32 ~
           initprot: le_i32 ~
           nsects: le_u32 ~
           flags: le_u32 ,

           || {

               let slice = unsafe { CStr::from_ptr(segname.as_ptr() as *const c_char) };
               let name = std::str::from_utf8(slice.to_bytes()).unwrap().to_string();

               SegmentCommand {
                   cmd: cmd,
                   cmdsize: cmdsize,
                   segname: name,
                   vmaddr: vmaddr,
                   vmsize: vmsize,
                   fileoff: fileoff,
                   filesize: filesize,
                   maxprot: maxprot,
                   initprot: initprot,
                   nsects: nsects,
                   flags: flags,
               }
           }
        )
    );

<commit_msg>Pull load commands not segment commands<commit_after>#[macro_use]
extern crate nom;
use std::ffi::CStr;
use std::os::raw::c_char;

use nom::{le_u64,le_u32,le_i32};
use nom::IResult;

// These are all integer_t, aka int
#[allow(non_camel_case_types)]
pub type cpu_type_t = i32;
#[allow(non_camel_case_types)]
pub type cpu_subtype_t = u32;
#[allow(non_camel_case_types)]
pub type vm_prot_t = i32;

#[derive(Debug)]
pub struct MachHeader<'a> {
    pub header: MachHeader_,
    pub commands: Vec<LoadCommand<'a>>,
}

#[derive(Debug)]
pub struct MachHeader_ {
    pub magic: u32,
    pub cputype: cpu_type_t,
    pub cpusubtype: cpu_subtype_t,
    pub filetype: u32,
    pub ncmds: u32,
    pub sizeofcmds: u32,
    pub flags: u32,
    reserved :u32,
}

impl<'a> MachHeader<'a> {
    pub fn parse(bytes: &'a [u8]) -> Option<MachHeader> {
        if let IResult::Done(_rest, header) = mach_header(bytes) {
            let mut rest = _rest;
            let mut commands = vec![];
            for _ in 0.. header.ncmds {
                if let IResult::Done(_rest, cmd) = load_command(rest) {
                    rest = _rest;
                    commands.push(cmd);
                } else {
                    return None
                }
            }

            Some(MachHeader {
                header: header,
                commands: commands,
            })
        } else {
            return None
        }
    }
}

#[derive(Debug)]
pub struct SegmentCommand {
    pub cmd: u32,
    pub cmdsize: u32,
    pub segname: String,
    pub vmaddr: u64,
    pub vmsize: u64,
    pub fileoff: u64,
    pub filesize: u64,
    pub maxprot: vm_prot_t,
    pub initprot: vm_prot_t,
    pub nsects: u32,
    pub flags: u32,
}

#[derive(Debug)]
pub struct LoadCommand<'a> {
    pub cmd: u32,
    pub cmdsize: u32,
    pub data: &'a [u8],
}

named!(load_command<&[u8], LoadCommand>,
       chain!(
           cmd: le_u32 ~
           cmdsize: le_u32 ~
           data: take!(cmdsize - 8),

           || {
               LoadCommand {
                   cmd: cmd,
                   cmdsize: cmdsize,
                   data: data,
               }
           }
           )
       );

named!(mach_header<&[u8], MachHeader_>,
       chain!(
           magic: le_u32 ~
           cputype: le_i32 ~
           cpusubtype: le_u32 ~
           filetype: le_u32 ~
           ncmds: le_u32 ~
           sizeofcmds: le_u32 ~
           flags: le_u32 ~
           reserved: le_u32,

           || {
               assert_eq!(0xfeedfacf, magic);
               MachHeader_ {
                   magic: magic,
                   cputype: cputype,
                   // This value needs to be masked to match otool -h
                   cpusubtype: cpusubtype,
                   filetype: filetype,
                   ncmds: ncmds,
                   sizeofcmds: sizeofcmds,
                   flags: flags,
                   reserved: reserved,
               }
           }
           )
       );

named!(segment_command<&[u8], SegmentCommand>,
       chain!(
           cmd: le_u32 ~
           cmdsize: le_u32 ~
           segname: take!(16) ~
           vmaddr: le_u64 ~
           vmsize: le_u64 ~
           fileoff: le_u64 ~
           filesize: le_u64 ~
           maxprot: le_i32 ~
           initprot: le_i32 ~
           nsects: le_u32 ~
           flags: le_u32 ~
           data: take!(cmdsize - 72) ,

           || {

               let slice = unsafe { CStr::from_ptr(segname.as_ptr() as *const c_char) };
               let name = std::str::from_utf8(slice.to_bytes()).unwrap().to_string();

               SegmentCommand {
                   cmd: cmd,
                   cmdsize: cmdsize,
                   segname: name,
                   vmaddr: vmaddr,
                   vmsize: vmsize,
                   fileoff: fileoff,
                   filesize: filesize,
                   maxprot: maxprot,
                   initprot: initprot,
                   nsects: nsects,
                   flags: flags,
               }
           }
        )
    );

<|endoftext|>


<commit_before>// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.
//! libc - Raw FFI bindings to platforms' system libraries
#![crate_name = "libc"]
#![crate_type = "rlib"]
#![cfg_attr(not(feature = "rustc-dep-of-std"), deny(warnings))]
#![allow(bad_style, overflowing_literals, improper_ctypes, unknown_lints)]
// Attributes needed when building as part of the standard library
#![cfg_attr(
    feature = "rustc-dep-of-std",
    feature(cfg_target_vendor, link_cfg, no_core)
)]
// Enable extra lints:
#![cfg_attr(feature = "extra_traits", deny(missing_debug_implementations))]
#![deny(missing_copy_implementations, safe_packed_borrows)]
// Enable no_std:
#![cfg_attr(
    not(any(
        feature = "use_std",
        feature = "rustc-dep-of-std",
    )),
    no_std
)]

#[cfg(feature = "use_std")]
extern crate std as core;

#[macro_use]
mod macros;

cfg_if! {
    if #[cfg(feature = "rustc-dep-of-std")] {
        extern crate rustc_std_workspace_core as core;
        #[allow(unused_imports)]
        use core::iter;
        #[allow(unused_imports)]
        use core::option;
    }
}

cfg_if! {
    if #[cfg(libc_priv_mod_use)] {
        #[cfg(libc_core_cvoid)]
        #[allow(unused_imports)]
        use core::ffi;
        #[allow(unused_imports)]
        use core::fmt;
        #[allow(unused_imports)]
        use core::hash;
        #[allow(unused_imports)]
        use core::num;
        #[allow(unused_imports)]
        use core::mem;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::clone::Clone;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::marker::Copy;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::option::Option;
    } else {
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::fmt;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::hash;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::num;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::mem;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::clone::Clone;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::marker::Copy;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::option::Option;
    }
}

cfg_if! {
    if #[cfg(windows)] {
        mod windows;
        pub use windows::*;
    } else if #[cfg(target_os = "redox")] {
        mod redox;
        pub use redox::*;
    } else if #[cfg(target_os = "cloudabi")] {
        mod cloudabi;
        pub use cloudabi::*;
    } else if #[cfg(target_os = "fuchsia")] {
        mod fuchsia;
        pub use fuchsia::*;
    } else if #[cfg(target_os = "switch")] {
        mod switch;
        pub use switch::*;
    } else if #[cfg(unix)] {
        mod unix;
        pub use unix::*;
    } else if #[cfg(target_env = "sgx")] {
        mod sgx;
        pub use sgx::*;
    }  else {
        // non-supported targets: empty...
    }
}
<commit_msg>Fix build of `rustc-dep-of-std` feature<commit_after>// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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.
//! libc - Raw FFI bindings to platforms' system libraries
#![crate_name = "libc"]
#![crate_type = "rlib"]
#![cfg_attr(not(feature = "rustc-dep-of-std"), deny(warnings))]
#![allow(bad_style, overflowing_literals, improper_ctypes, unknown_lints)]
// Attributes needed when building as part of the standard library
#![cfg_attr(
    feature = "rustc-dep-of-std",
    feature(cfg_target_vendor, link_cfg, no_core)
)]
// Enable extra lints:
#![cfg_attr(feature = "extra_traits", deny(missing_debug_implementations))]
#![deny(missing_copy_implementations, safe_packed_borrows)]
#![no_std]
#![cfg_attr(feature = "rustc-dep-of-std", no_core)]

#[cfg(feature = "use_std")]
extern crate std;

#[macro_use]
mod macros;

cfg_if! {
    if #[cfg(feature = "rustc-dep-of-std")] {
        extern crate rustc_std_workspace_core as core;
        #[allow(unused_imports)]
        use core::iter;
        #[allow(unused_imports)]
        use core::option;
    }
}

cfg_if! {
    if #[cfg(libc_priv_mod_use)] {
        #[cfg(libc_core_cvoid)]
        #[allow(unused_imports)]
        use core::ffi;
        #[allow(unused_imports)]
        use core::fmt;
        #[allow(unused_imports)]
        use core::hash;
        #[allow(unused_imports)]
        use core::num;
        #[allow(unused_imports)]
        use core::mem;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::clone::Clone;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::marker::Copy;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::option::Option;
    } else {
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::fmt;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::hash;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::num;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::mem;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::clone::Clone;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::marker::Copy;
        #[doc(hidden)]
        #[allow(unused_imports)]
        pub use core::option::Option;
    }
}

cfg_if! {
    if #[cfg(windows)] {
        mod windows;
        pub use windows::*;
    } else if #[cfg(target_os = "redox")] {
        mod redox;
        pub use redox::*;
    } else if #[cfg(target_os = "cloudabi")] {
        mod cloudabi;
        pub use cloudabi::*;
    } else if #[cfg(target_os = "fuchsia")] {
        mod fuchsia;
        pub use fuchsia::*;
    } else if #[cfg(target_os = "switch")] {
        mod switch;
        pub use switch::*;
    } else if #[cfg(unix)] {
        mod unix;
        pub use unix::*;
    } else if #[cfg(target_env = "sgx")] {
        mod sgx;
        pub use sgx::*;
    }  else {
        // non-supported targets: empty...
    }
}
<|endoftext|>


<commit_before>// 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.

//! # Disassemble
//!
//! This crate provides basic functionality for working with
//! disassembled code. It provides (or will provide) functionality
//! for performing:
//!
//! * Working with code that has already been compiled to machine
//!   code for any CPU, bytecode, compiler IR or JIT compiler
//!   output like that of V8 or the JVM. You provide an adapter
//!   to teach [`Instruction`] how to report the correct information
//!   for your generated code.
//! * Reconstructing the [control flow graph] from a body of compiled
//!   code.
//! * **(Future)** Reconstructing loops and higher level control
//!   flow constructs.
//! * **(Future)** Performing [data flow analysis].
//! * **(Future)** Generating HTML and other rich output formats
//!   to assist in visualizing structure and higher level presentations
//!   of the data derived from the generated code.
//! * **(Future)** Writing decompilers that generate C or
//!   other languages from lower level generated code.
//! * **(Future)** Writing tools for reverse engineering. Many tools
//!   for reverse engineering require extracting and inferring higher
//!   level structure from the low level generated code. This crate
//!   provides those capabilities for re-use by anyone.
//! * **(Future)** Writing views that display disassembled code for
//!   debuggers, profilers and other systems level tools.
//!
//! The actual disassembly with the implementation of [`Instruction`]
//! and other elements of the system will be provided by other
//! crates that integrate with other systems, such as the [Capstone
//! Engine]. This crate is written such that it should work with
//! nearly any machine code, VM bytecode or JIT compiler output,
//! given an appropriate implementation of [`Instruction`].
//!
//! It is possible (likely?) that some functionality from within
//! this crate may move in the future to a separate crate for broader
//! re-use. This might impact [`Symbol`] among other things.
//!
//! ## Installation
//!
//! This crate works with Cargo and is on
//! [crates.io](https://crates.io/crates/disassemble).
//! Add it to your `Cargo.toml` like so:
//!
//! ```toml
//! [dependencies]
//! disassemble = "0.0.1"
//! ```
//!
//! Then, let `rustc` know that you're going to use this crate at the
//! top of your own crate:
//!
//! ```
//! extern crate disassemble;
//! # fn main() {}
//! ```
//!
//! ## Future Directions
//!
//! In the future, we want to extend this library to support a number of
//! additional features:
//!
//! * Implement DOT output for the [`ControlFlowGraph`]. This can probably be done with the
//!   help of [`petgraph`].
//! * HTML output modes?
//! * Implement loop finding. (Havlak)
//! * Implement the [Capstone Engine] backend as a separate crate.
//! * Make [`Instruction`] aware of operands, registers
//! * Data flow support. Memory SSA?
//! * Should we deal with mangled symbols at this level?
//! * So much more!
//!
//! ## Contributions
//!
//! Contributions are welcome.
//!
//! [Capstone Engine]: http://www.capstone-engine.org/
//! [`ControlFlowGraph`]: struct.ControlFlowGraph.html
//! [control flow graph]: https://en.wikipedia.org/wiki/Control_flow_graph
//! [data flow analysis]: https://en.wikipedia.org/wiki/Data-flow_analysis
//! [`Function`]: struct.Function.html
//! [`Instruction`]: trait.Instruction.html
//! [`petgraph`]: https://crates.io/crates/petgraph
//! [`Symbol`]: struct.Symbol.html

#![warn(missing_docs)]
#![deny(trivial_numeric_casts,
        unsafe_code, unstable_features,
        unused_import_braces, unused_qualifications)]

extern crate petgraph;

#[cfg(feature = "capstone")]
extern crate capstone_rust;

#[cfg(feature = "webassembly")]
extern crate parity_wasm;

mod address;
mod basicblock;
mod callgraphanalysis;
#[cfg(feature = "capstone")]
mod capstone;
mod cfg;
mod disassembler;
mod function;
mod instruction;
mod loops;
mod memory;
mod symbol;
#[cfg(feature = "webassembly")]
mod webassembly;

pub use self::address::Address;
pub use self::basicblock::{BasicBlock, BasicBlockEdge, EdgeType};
pub use self::callgraphanalysis::{CallGraphAnalysis, CallSite, CallSiteTarget};
pub use self::cfg::ControlFlowGraph;
pub use self::function::Function;
pub use self::instruction::Instruction;
pub use self::loops::{find_loops, LoopStructureGraph, SimpleLoop};
pub use self::memory::{Error, Memory, Segment};
pub use self::symbol::Symbol;

#[cfg(test)]
mod tests {
    //! Test Instructions
    //!
    //! This provides some test implementations of `Instruction` for
    //! use in testing out this crate without having to hook up to
    //! a real disassembler.

    use address::Address;
    use instruction::Instruction;
    use disassembler::{Architecture, Disassembler};

    /// Opcodes that we'll use as instructions.
    #[allow(dead_code, missing_docs)]
    #[derive(Debug)]
    pub enum Opcode {
        Add,
        Mul,
        CJmp(Address),
        Jmp(Address),
        Call(Address),
        Ret,
    }

    #[derive(Debug)]
    pub struct TestInstruction {
        address: Address,
        opcode: Opcode,
    }

    impl TestInstruction {
        /// Construct a `TestInstruction`.
        pub fn new(address: u64, opcode: Opcode) -> Self {
            TestInstruction {
                address: Address::new(address),
                opcode: opcode,
            }
        }
    }

    impl Instruction for TestInstruction {
        fn address(&self, _disassembler: &Disassembler) -> Address {
            self.address
        }

        fn comment(&self, _disassembler: &Disassembler) -> Option<String> {
            None
        }

        fn cycle_count(&self, _disassembler: &Disassembler) -> Option<u32> {
            None
        }

        fn is_call(&self, _disassembler: &Disassembler) -> bool {
            match self.opcode {
                Opcode::Call(..) => true,
                _ => false,
            }
        }

        fn is_local_conditional_jump(&self, _disassembler: &Disassembler) -> bool {
            match self.opcode {
                Opcode::CJmp(..) => true,
                _ => false,
            }
        }

        fn is_local_jump(&self, _disassembler: &Disassembler) -> bool {
            match self.opcode {
                Opcode::CJmp(..) => true,
                Opcode::Jmp(..) => true,
                _ => false,
            }
        }

        fn is_return(&self, _disassembler: &Disassembler) -> bool {
            match self.opcode {
                Opcode::Ret => true,
                _ => false,
            }
        }

        fn target_address(&self, _disassembler: &Disassembler) -> Option<Address> {
            match self.opcode {
                Opcode::CJmp(addr) => Some(addr),
                Opcode::Jmp(addr) => Some(addr),
                Opcode::Call(addr) => Some(addr),
                _ => None,
            }
        }
    }

    #[derive(Debug)]
    pub struct TestDisassembler {}

    impl TestDisassembler {
        pub fn new() -> Self {
            TestDisassembler {}
        }
    }

    impl Disassembler for TestDisassembler {
        fn architecture(&self) -> Architecture {
            Architecture::X86
        }
    }
}
<commit_msg>Make some types public<commit_after>// 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.

//! # Disassemble
//!
//! This crate provides basic functionality for working with
//! disassembled code. It provides (or will provide) functionality
//! for performing:
//!
//! * Working with code that has already been compiled to machine
//!   code for any CPU, bytecode, compiler IR or JIT compiler
//!   output like that of V8 or the JVM. You provide an adapter
//!   to teach [`Instruction`] how to report the correct information
//!   for your generated code.
//! * Reconstructing the [control flow graph] from a body of compiled
//!   code.
//! * **(Future)** Reconstructing loops and higher level control
//!   flow constructs.
//! * **(Future)** Performing [data flow analysis].
//! * **(Future)** Generating HTML and other rich output formats
//!   to assist in visualizing structure and higher level presentations
//!   of the data derived from the generated code.
//! * **(Future)** Writing decompilers that generate C or
//!   other languages from lower level generated code.
//! * **(Future)** Writing tools for reverse engineering. Many tools
//!   for reverse engineering require extracting and inferring higher
//!   level structure from the low level generated code. This crate
//!   provides those capabilities for re-use by anyone.
//! * **(Future)** Writing views that display disassembled code for
//!   debuggers, profilers and other systems level tools.
//!
//! The actual disassembly with the implementation of [`Instruction`]
//! and other elements of the system will be provided by other
//! crates that integrate with other systems, such as the [Capstone
//! Engine]. This crate is written such that it should work with
//! nearly any machine code, VM bytecode or JIT compiler output,
//! given an appropriate implementation of [`Instruction`].
//!
//! It is possible (likely?) that some functionality from within
//! this crate may move in the future to a separate crate for broader
//! re-use. This might impact [`Symbol`] among other things.
//!
//! ## Installation
//!
//! This crate works with Cargo and is on
//! [crates.io](https://crates.io/crates/disassemble).
//! Add it to your `Cargo.toml` like so:
//!
//! ```toml
//! [dependencies]
//! disassemble = "0.0.1"
//! ```
//!
//! Then, let `rustc` know that you're going to use this crate at the
//! top of your own crate:
//!
//! ```
//! extern crate disassemble;
//! # fn main() {}
//! ```
//!
//! ## Future Directions
//!
//! In the future, we want to extend this library to support a number of
//! additional features:
//!
//! * Implement DOT output for the [`ControlFlowGraph`]. This can probably be done with the
//!   help of [`petgraph`].
//! * HTML output modes?
//! * Implement loop finding. (Havlak)
//! * Implement the [Capstone Engine] backend as a separate crate.
//! * Make [`Instruction`] aware of operands, registers
//! * Data flow support. Memory SSA?
//! * Should we deal with mangled symbols at this level?
//! * So much more!
//!
//! ## Contributions
//!
//! Contributions are welcome.
//!
//! [Capstone Engine]: http://www.capstone-engine.org/
//! [`ControlFlowGraph`]: struct.ControlFlowGraph.html
//! [control flow graph]: https://en.wikipedia.org/wiki/Control_flow_graph
//! [data flow analysis]: https://en.wikipedia.org/wiki/Data-flow_analysis
//! [`Function`]: struct.Function.html
//! [`Instruction`]: trait.Instruction.html
//! [`petgraph`]: https://crates.io/crates/petgraph
//! [`Symbol`]: struct.Symbol.html

#![warn(missing_docs)]
#![deny(trivial_numeric_casts,
        unsafe_code, unstable_features,
        unused_import_braces, unused_qualifications)]

extern crate petgraph;

#[cfg(feature = "capstone")]
extern crate capstone_rust;

#[cfg(feature = "webassembly")]
extern crate parity_wasm;

mod address;
mod basicblock;
mod callgraphanalysis;
#[cfg(feature = "capstone")]
mod capstone;
mod cfg;
mod disassembler;
mod function;
mod instruction;
mod loops;
mod memory;
mod symbol;
#[cfg(feature = "webassembly")]
mod webassembly;

pub use self::address::Address;
pub use self::basicblock::{BasicBlock, BasicBlockEdge, EdgeType};
pub use self::callgraphanalysis::{CallGraphAnalysis, CallSite, CallSiteTarget};
pub use self::cfg::ControlFlowGraph;
pub use self::function::Function;
pub use self::instruction::Instruction;
pub use self::loops::{find_loops, LoopStructureGraph, SimpleLoop};
pub use self::memory::{Error, Memory, Segment};
pub use self::symbol::Symbol;
pub use self::disassembler::{Disassembler, Architecture};

#[cfg(test)]
mod tests {
    //! Test Instructions
    //!
    //! This provides some test implementations of `Instruction` for
    //! use in testing out this crate without having to hook up to
    //! a real disassembler.

    use address::Address;
    use instruction::Instruction;
    use disassembler::{Architecture, Disassembler};

    /// Opcodes that we'll use as instructions.
    #[allow(dead_code, missing_docs)]
    #[derive(Debug)]
    pub enum Opcode {
        Add,
        Mul,
        CJmp(Address),
        Jmp(Address),
        Call(Address),
        Ret,
    }

    #[derive(Debug)]
    pub struct TestInstruction {
        address: Address,
        opcode: Opcode,
    }

    impl TestInstruction {
        /// Construct a `TestInstruction`.
        pub fn new(address: u64, opcode: Opcode) -> Self {
            TestInstruction {
                address: Address::new(address),
                opcode: opcode,
            }
        }
    }

    impl Instruction for TestInstruction {
        fn address(&self, _disassembler: &Disassembler) -> Address {
            self.address
        }

        fn comment(&self, _disassembler: &Disassembler) -> Option<String> {
            None
        }

        fn cycle_count(&self, _disassembler: &Disassembler) -> Option<u32> {
            None
        }

        fn is_call(&self, _disassembler: &Disassembler) -> bool {
            match self.opcode {
                Opcode::Call(..) => true,
                _ => false,
            }
        }

        fn is_local_conditional_jump(&self, _disassembler: &Disassembler) -> bool {
            match self.opcode {
                Opcode::CJmp(..) => true,
                _ => false,
            }
        }

        fn is_local_jump(&self, _disassembler: &Disassembler) -> bool {
            match self.opcode {
                Opcode::CJmp(..) => true,
                Opcode::Jmp(..) => true,
                _ => false,
            }
        }

        fn is_return(&self, _disassembler: &Disassembler) -> bool {
            match self.opcode {
                Opcode::Ret => true,
                _ => false,
            }
        }

        fn target_address(&self, _disassembler: &Disassembler) -> Option<Address> {
            match self.opcode {
                Opcode::CJmp(addr) => Some(addr),
                Opcode::Jmp(addr) => Some(addr),
                Opcode::Call(addr) => Some(addr),
                _ => None,
            }
        }
    }

    #[derive(Debug)]
    pub struct TestDisassembler {}

    impl TestDisassembler {
        pub fn new() -> Self {
            TestDisassembler {}
        }
    }

    impl Disassembler for TestDisassembler {
        fn architecture(&self) -> Architecture {
            Architecture::X86
        }
    }
}
<|endoftext|>


<commit_before>#![feature(rustc_private)]
#![feature(collections, str_char)]
#![feature(plugin)]
#![plugin(peg_syntax_ext)]

extern crate syntax;

pub mod types;

// TODO Think whether this should really be public
// This is only pub to avoid compiler warnings for now
pub mod parser;
pub mod reader;
pub mod error;

// TODO Implement wrapper methods around parser and expose a nice public API
<commit_msg>Parser module should not be public.<commit_after>#![feature(rustc_private)]
#![feature(collections, str_char)]
#![feature(plugin)]
#![plugin(peg_syntax_ext)]

extern crate syntax;

mod parser;

pub mod types;
pub mod error;
pub mod reader;
<|endoftext|>