<commit_before>#![allow(dead_code)]
use std::process::{Command, Output};
use std::string::{String, ToString};
use std::ffi::OsString;
use std::io;
use std::fmt;
use image_tools::image_ops::{FileName, FilePath};

//pub type FilePath = String;
//type FileName = String;

enum ImageMagickCommand {
    Identify,
    IdentifyVerbose,
    Mogrify,
    Convert,
    NoOperation,
}

impl fmt::Display for ImageMagickCommand {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ImageMagickCommand::Identify        => write!(f, "Identify"),
            ImageMagickCommand::IdentifyVerbose => write!(f, "IdentifyVerbose"),
            ImageMagickCommand::Mogrify         => write!(f, "Mogrify"),
            ImageMagickCommand::Convert         => write!(f, "Convert"),
            ImageMagickCommand::NoOperation     => write!(f, "NoOperation"),
        }
    }
}

fn imagemagick_command(command_name: ImageMagickCommand,
                       file_path: &FilePath,
                       args: &[String])
    -> io::Result<String> {

    let mut command_args: Vec<OsString> = Vec::new();
    for arg in args {
        command_args.push(OsString::from(arg));
    }

    let output: io::Result<Output> = Command::new(command_name.to_string())
                                            .args(command_args.as_ref())
                                            .arg(file_path)
                                            .output();

    let result: io::Result<String> = match output {
            Ok(output) => Ok(String::from_utf8(output.stdout).unwrap()),
            Err(e)     => Err(e),
        };

    result
}

#[inline]
fn imagemagick_identify(file_path: &FilePath, args: &[String]) -> io::Result<String> {
    imagemagick_command(ImageMagickCommand::Identify, file_path, args)
}

pub fn imagemagick_identify_default(file_path: &FilePath) -> io::Result<String> {
    imagemagick_identify(file_path, &[])
}

pub fn imagemagick_identify_verbose(file_path: &FilePath) -> io::Result<String> {
    let args = ["-verbose".to_string()];

    imagemagick_identify(file_path, &args)
}

pub fn imagemagick_mogrify(file_path: &FilePath, args: &[String]) -> io::Result<String> {
    imagemagick_command(ImageMagickCommand::Mogrify, file_path, args)
}

pub fn imagemagick_convert(file_path: &FilePath, args: &[String]) -> io::Result<String> {
    imagemagick_command(ImageMagickCommand::Convert, file_path, args)
}

pub fn imagemagick_no_operation() -> io::Result<String> {
    Ok(String::from("No Operation"))
}
<commit_msg>Remove redundant type declarations.<commit_after>#![allow(dead_code)]
use std::process::{Command, Output};
use std::string::{String, ToString};
use std::ffi::OsString;
use std::io;
use std::fmt;
use image_tools::image_ops::{FileName, FilePath};

enum ImageMagickCommand {
    Identify,
    IdentifyVerbose,
    Mogrify,
    Convert,
    NoOperation,
}

impl fmt::Display for ImageMagickCommand {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ImageMagickCommand::Identify        => write!(f, "Identify"),
            ImageMagickCommand::IdentifyVerbose => write!(f, "IdentifyVerbose"),
            ImageMagickCommand::Mogrify         => write!(f, "Mogrify"),
            ImageMagickCommand::Convert         => write!(f, "Convert"),
            ImageMagickCommand::NoOperation     => write!(f, "NoOperation"),
        }
    }
}

fn imagemagick_command(command_name: ImageMagickCommand,
                       file_path: &FilePath,
                       args: &[String])
    -> io::Result<String> {

    let mut command_args: Vec<OsString> = Vec::new();
    for arg in args {
        command_args.push(OsString::from(arg));
    }

    let output: io::Result<Output> = Command::new(command_name.to_string())
                                            .args(command_args.as_ref())
                                            .arg(file_path)
                                            .output();

    let result: io::Result<String> = match output {
            Ok(output) => Ok(String::from_utf8(output.stdout).unwrap()),
            Err(e)     => Err(e),
        };

    result
}

#[inline]
fn imagemagick_identify(file_path: &FilePath, args: &[String]) -> io::Result<String> {
    imagemagick_command(ImageMagickCommand::Identify, file_path, args)
}

pub fn imagemagick_identify_default(file_path: &FilePath) -> io::Result<String> {
    imagemagick_identify(file_path, &[])
}

pub fn imagemagick_identify_verbose(file_path: &FilePath) -> io::Result<String> {
    let args = ["-verbose".to_string()];

    imagemagick_identify(file_path, &args)
}

pub fn imagemagick_mogrify(file_path: &FilePath, args: &[String]) -> io::Result<String> {
    imagemagick_command(ImageMagickCommand::Mogrify, file_path, args)
}

pub fn imagemagick_convert(file_path: &FilePath, args: &[String]) -> io::Result<String> {
    imagemagick_command(ImageMagickCommand::Convert, file_path, args)
}

pub fn imagemagick_no_operation() -> io::Result<String> {
    Ok(String::from("No Operation"))
}
<|endoftext|>


<commit_before>use neb::ram::schema::Field;
use neb::ram::types::{TypeId, Id, key_hash, Map, Value};
use neb::ram::cell::{Cell, WriteError};
use neb::client::{Client as NebClient};
use bifrost::rpc::RPCError;

use server::schema::{MorpheusSchema, SchemaType, SchemaContainer, SchemaError};
use graph::vertex::Vertex;

use std::sync::Arc;

pub mod vertex;
pub mod edge;

pub enum NewVertexError {
    SchemaNotFound,
    SchemaNotVertex,
    KeyFieldNotAvailable,
    DataNotMap,
    RPCError(RPCError),
    WriteError(WriteError),
}

lazy_static! {
    pub static ref ID_LINKED_LIST: Vec<Field> = vec![
            Field::new(&String::from("next"), TypeId::Id as u32, true, false, None),
            Field::new(&String::from("list"), TypeId::Id as u32, false, true, None)
        ];
}

pub fn cell_to_vertex (cell: Cell) -> Vertex {
    Vertex {
        id: cell.header.id(),
        schema: cell.header.schema,
        data: cell.data
    }
}

pub struct Graph {
    schema: Arc<SchemaContainer>,
    neb_client: Arc<NebClient>
}

impl Graph {
    pub fn new_vertex_group(&self, schema: &mut MorpheusSchema) -> Result<(), SchemaError> {
        schema.schema_type = SchemaType::Vertex;
        self.schema.new_schema(schema)
    }
    pub fn new_edge_group(&self, schema: &mut MorpheusSchema, edge_type: edge::EdgeType) -> Result<(), SchemaError> {
        if edge_type == edge::EdgeType::Simple {
            return Err(SchemaError::SimpleEdgeShouldNotHaveSchema)
        }
        schema.schema_type = SchemaType::Edge(edge_type);
        self.schema.new_schema(schema)
    }
    pub fn new_vertex(&self, mut vertex: Vertex) -> Result<Vertex, NewVertexError> {
        let schema_id = vertex.schema;
        if let Some(stype) = self.schema.schema_type(schema_id) {
            if stype != SchemaType::Vertex {
                return Err(NewVertexError::SchemaNotVertex)
            }
        } else {
            return Err(NewVertexError::SchemaNotFound)
        }
        let neb_schema = match self.schema.get_neb_schema(schema_id) {
            Some(schema) => schema,
            None => return Err(NewVertexError::SchemaNotFound)
        };
        let mut data = {
            match vertex.data {
                Value::Map(mut map) => map,
                _ => return Err(NewVertexError::DataNotMap)
            }
        };
        let id = {match neb_schema.key_field {
                Some(ref keys) => {
                    let value = data.get_in_by_ids(keys.iter());
                    match value {
                        &Value::Null => return Err(NewVertexError::KeyFieldNotAvailable),
                        _ => Id::from_obj(&(schema_id, value))
                    }
                },
                None => {
                    if vertex.id.is_unit_id() {
                        Id::rand()
                    } else {
                        vertex.id
                    }
                }
            }
        };
        data.insert_key_id(*vertex::INBOUND_KEY_ID, Value::Id(Id::unit_id()));
        data.insert_key_id(*vertex::OUTBOUND_KEY_ID, Value::Id(Id::unit_id()));
        data.insert_key_id(*vertex::INDIRECTED_KEY_ID, Value::Id(Id::unit_id()));
        let mut cell = Cell::new(schema_id, &id, Value::Map(data));
        let header = match self.neb_client.write_cell(&cell) {
            Ok(Ok(header)) => header,
            Ok(Err(e)) => return Err(NewVertexError::WriteError(e)),
            Err(e) => return Err(NewVertexError::RPCError(e))
        };
        cell.header = header;
        Ok(cell_to_vertex(cell))
    }
}<commit_msg>remove and by key<commit_after>use neb::ram::schema::Field;
use neb::ram::types::{TypeId, Id, key_hash, Map, Value};
use neb::ram::cell::{Cell, WriteError};
use neb::client::{Client as NebClient};
use bifrost::rpc::RPCError;

use server::schema::{MorpheusSchema, SchemaType, SchemaContainer, SchemaError};
use graph::vertex::Vertex;

use std::sync::Arc;
use serde::Serialize;

pub mod vertex;
pub mod edge;

pub enum NewVertexError {
    SchemaNotFound,
    SchemaNotVertex,
    KeyFieldNotAvailable,
    DataNotMap,
    RPCError(RPCError),
    WriteError(WriteError),
}
pub enum RemoveVertexError {
    WriteError(WriteError),
    RPCError(RPCError)
}

#[derive(Clone, Copy, Serialize, Deserialize)]
pub enum CellType {
    Vertex,
    Edge(edge::EdgeType)
}

lazy_static! {
    pub static ref ID_LINKED_LIST: Vec<Field> = vec![
            Field::new(&String::from("next"), TypeId::Id as u32, true, false, None),
            Field::new(&String::from("list"), TypeId::Id as u32, false, true, None)
        ];
}

pub fn cell_to_vertex (cell: Cell) -> Vertex {
    Vertex {
        id: cell.header.id(),
        schema: cell.header.schema,
        data: cell.data
    }
}

fn encode_cell_key<V>(schema_id: u32, value: &V) -> Id
    where V: Serialize{
    Id::from_obj(&(schema_id, value))
}

pub struct Graph {
    schema: Arc<SchemaContainer>,
    neb_client: Arc<NebClient>
}

impl Graph {
    pub fn new_vertex_group(&self, schema: &mut MorpheusSchema) -> Result<(), SchemaError> {
        schema.schema_type = SchemaType::Vertex;
        self.schema.new_schema(schema)
    }
    pub fn new_edge_group(&self, schema: &mut MorpheusSchema, edge_type: edge::EdgeType) -> Result<(), SchemaError> {
        if edge_type == edge::EdgeType::Simple {
            return Err(SchemaError::SimpleEdgeShouldNotHaveSchema)
        }
        schema.schema_type = SchemaType::Edge(edge_type);
        self.schema.new_schema(schema)
    }
    pub fn new_vertex(&self, mut vertex: Vertex) -> Result<Vertex, NewVertexError> {
        let schema_id = vertex.schema;
        if let Some(stype) = self.schema.schema_type(schema_id) {
            if stype != SchemaType::Vertex {
                return Err(NewVertexError::SchemaNotVertex)
            }
        } else {
            return Err(NewVertexError::SchemaNotFound)
        }
        let neb_schema = match self.schema.get_neb_schema(schema_id) {
            Some(schema) => schema,
            None => return Err(NewVertexError::SchemaNotFound)
        };
        let mut data = {
            match vertex.data {
                Value::Map(mut map) => map,
                _ => return Err(NewVertexError::DataNotMap)
            }
        };
        let id = {match neb_schema.key_field {
                Some(ref keys) => {
                    let value = data.get_in_by_ids(keys.iter());
                    match value {
                        &Value::Null => return Err(NewVertexError::KeyFieldNotAvailable),
                        _ => encode_cell_key(schema_id, value)
                    }
                },
                None => {
                    if vertex.id.is_unit_id() {
                        Id::rand()
                    } else {
                        vertex.id
                    }
                }
            }
        };
        data.insert_key_id(*vertex::INBOUND_KEY_ID, Value::Id(Id::unit_id()));
        data.insert_key_id(*vertex::OUTBOUND_KEY_ID, Value::Id(Id::unit_id()));
        data.insert_key_id(*vertex::INDIRECTED_KEY_ID, Value::Id(Id::unit_id()));
        let mut cell = Cell::new(schema_id, &id, Value::Map(data));
        let header = match self.neb_client.write_cell(&cell) {
            Ok(Ok(header)) => header,
            Ok(Err(e)) => return Err(NewVertexError::WriteError(e)),
            Err(e) => return Err(NewVertexError::RPCError(e))
        };
        cell.header = header;
        Ok(cell_to_vertex(cell))
    }
    pub fn remove_vertex(&self, id: &Id) -> Result<(), RemoveVertexError> {
        match self.neb_client.remove_cell(id) {
            Err(e) => Err(RemoveVertexError::RPCError(e)),
            Ok(Err(e)) => Err(RemoveVertexError::WriteError(e)),
            Ok(Ok(())) => Ok(())
        }
    }
    pub fn remove_vertex_by_key<K>(&self, schema_id: u32, key: &K) -> Result<(), RemoveVertexError>
        where K: Serialize {
        let id = encode_cell_key(schema_id, key);
        self.remove_vertex(&id)
    }
}<|endoftext|>


<commit_before>//! GPIO pin

use core::u16;

use cast::{u16, u32};

use stm32f103xx::{GPIOA, GPIOB, GPIOC, GPIOD, gpioa, Rcc, rcc, adc1, tim2, TIM2, TIM3, TIM4, TIM5};
pub use hal::pin::Pin as halPin;
pub use hal::pin::{State, Mode};
use ::frequency;

/// GPIO pin
pub struct Pin<'a>{
    /// gpio pin
    pub pin: u8,
    /// gpio port
    pub port: &'a gpioa::RegisterBlock,
    adc: Option<&'a adc1::RegisterBlock>,
    timer: Option<&'a tim2::RegisterBlock>,
}

impl<'a> Pin<'a>{
    /// returns a digital pin
    pub fn new(pin: u8, port: &'a gpioa::RegisterBlock) -> Pin {
        Pin{pin, port, adc: None, timer: None}
    }

    /// returns an analog input pin
    pub fn new_analog_in(pin: u8, port: &'a gpioa::RegisterBlock, adc: &'a adc1::RegisterBlock) -> Pin<'a> {
        Pin{pin, port, adc: Some(adc), timer: None}
    }

    /// returns an analog output pin
    pub fn new_pwm_out(pin: u8, port: &'a gpioa::RegisterBlock, timer: &'a tim2::RegisterBlock) -> Pin<'a> {
        Pin{pin, port, adc: None, timer: Some(timer)}
    }

    /// Initializes the Pin
    pub fn init(&self, rcc: &Rcc, mode: Mode) {
        // Power up peripherals
        // check which memory block this port is pointing to
        match &*self.port as *const _{
            x if x == GPIOA.get() as *const _ => rcc.apb2enr.modify(|_, w| w.iopaen().enabled()),
            x if x == GPIOB.get() as *const _ => rcc.apb2enr.modify(|_, w| w.iopben().enabled()),
            x if x == GPIOC.get() as *const _ => rcc.apb2enr.modify(|_, w| w.iopcen().enabled()),
            x if x == GPIOD.get() as *const _ => rcc.apb2enr.modify(|_, w| w.iopden().enabled()),
            _ => {},
        }

        // Configure pin to input/output
        // still need to handle analog input mode, and possibly setting output frequency
        // defaults to 10Mhz output

        match mode {
            Mode::INPUT =>
                match self.pin {
                    // cnf alt_push mode is actually input pullup/pulldown, since cnf is shared
                    // for output mode the names are confusing
                    0 => self.port.crl.modify(|_,w| w.mode0().input()
                                                    .cnf0().alt_push()),
                    1 => self.port.crl.modify(|_,w| w.mode1().input()
                                                    .cnf1().alt_push()),
                    2 => self.port.crl.modify(|_,w| w.mode2().input()
                                                    .cnf2().alt_push()),
                    3 => self.port.crl.modify(|_,w| w.mode3().input()
                                                    .cnf3().alt_push()),
                    4 => self.port.crl.modify(|_,w| w.mode4().input()
                                                    .cnf4().alt_push()),
                    5 => self.port.crl.modify(|_,w| w.mode5().input()
                                                    .cnf5().alt_push()),
                    6 => self.port.crl.modify(|_,w| w.mode6().input()
                                                    .cnf6().alt_push()),
                    7 => self.port.crl.modify(|_,w| w.mode7().input()
                                                    .cnf7().alt_push()),
                    8 => self.port.crh.modify(|_,w| w.mode8().input()
                                                    .cnf8().alt_push()),
                    9 => self.port.crh.modify(|_,w| w.mode9().input()
                                                    .cnf9().alt_push()),
                    10 => self.port.crh.modify(|_,w| w.mode10().input()
                                                    .cnf10().alt_push()),
                    11 => self.port.crh.modify(|_,w| w.mode11().input()
                                                    .cnf11().alt_push()),
                    12 => self.port.crh.modify(|_,w| w.mode12().input()
                                                    .cnf12().alt_push()),
                    13 => self.port.crh.modify(|_,w| w.mode13().input()
                                                    .cnf13().alt_push()),
                    14 => self.port.crh.modify(|_,w| w.mode14().input()
                                                    .cnf14().alt_push()),
                    15 => self.port.crh.modify(|_,w| w.mode15().input()
                                                    .cnf15().alt_push()),
                    _ => {},
                },
            Mode::ANALOG_INPUT => {},
            Mode::OUTPUT =>
                match self.pin {
                    0 => self.port.crl.modify(|_,w| w.mode0().output()
                                                        .cnf0().push()),
                    1 => self.port.crl.modify(|_,w| w.mode1().output()
                                                        .cnf1().push()),
                    2 => self.port.crl.modify(|_,w| w.mode2().output()
                                                        .cnf2().push()),
                    3 => self.port.crl.modify(|_,w| w.mode3().output()
                                                        .cnf3().push()),
                    4 => self.port.crl.modify(|_,w| w.mode4().output()
                                                        .cnf4().push()),
                    5 => self.port.crl.modify(|_,w| w.mode5().output()
                                                        .cnf5().push()),
                    6 => self.port.crl.modify(|_,w| w.mode6().output()
                                                        .cnf6().push()),
                    7 => self.port.crl.modify(|_,w| w.mode7().output()
                                                        .cnf7().push()),
                    8 => self.port.crh.modify(|_,w| w.mode8().output()
                                                        .cnf8().push()),
                    9 => self.port.crh.modify(|_,w| w.mode9().output()
                                                        .cnf9().push()),
                    10 => self.port.crh.modify(|_,w| w.mode10().output()
                                                        .cnf10().push()),
                    11 => self.port.crh.modify(|_,w| w.mode11().output()
                                                        .cnf11().push()),
                    12 => self.port.crh.modify(|_,w| w.mode12().output()
                                                        .cnf12().push()),
                    13 => self.port.crh.modify(|_,w| w.mode13().output()
                                                        .cnf13().push()),
                    14 => self.port.crh.modify(|_,w| w.mode14().output()
                                                        .cnf14().push()),
                    15 => self.port.crh.modify(|_,w| w.mode15().output()
                                                        .cnf15().push()),
                    _ => {},
                },
            Mode::PWM_OUTPUT => {
                if let Some(timer) = self.timer {
                    match &*timer as *const _{
                        x if x == TIM2.get() as *const _ => rcc.apb1enr.modify(|_, w| w.tim2en().enabled()),
                        x if x == TIM3.get() as *const _ => rcc.apb1enr.modify(|_, w| w.tim3en().enabled()),
                        x if x == TIM4.get() as *const _ => rcc.apb1enr.modify(|_, w| w.tim4en().enabled()),
                        x if x == TIM5.get() as *const _ => rcc.apb1enr.modify(|_, w| w.tim5en().enabled()),
                        _ => {},
                    }

                    // PSC = (CLOCK / FREQ) / u16::MAX
                    // ARR = ((CLOCK / FREQ) + (PSC / 2)) / PSC

                    // if ppre1 is anything other than 1 the timer clock is multiplied by 2
                    let apb1_pre = rcc.cfgr.read().ppre1();
                    let apb1_mult = if apb1_pre == rcc::cfgr::Ppre1R::Div1 { 1 } else { 2 };

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

                    // use 100Khz for default speed
                    let psc = ((speeds.apb1 * apb1_mult) / 100_000) as u16 / u16::MAX + 1;

                    timer.psc.write(|w| w.psc().bits(psc));

                    let arr = ((speeds.apb1 * apb1_mult) / 100_000) as u16 + (psc / 2) / psc;

                    // set frequency
                    timer.arr.write(|w| w.arr().bits(arr));

                    // Valid pins are PA 8, 9, 10, 11  timer 1
                    //                PA 0, 1, 2, 3    timer 2
                    //                PA 6, 7 PB 0, 1  timer 3
                    //                PB 6, 7, 8, 9    timer 4

                    // ocXm = pwm1 mode
                    // ocXpe = preload enable
                    // ccXe = output enable
                    // ccXp = active high
                    match &*self.port as *const _{
                        x if x == GPIOA.get() as *const _ => {
                            match self.pin {
                                0 | 6 | 8 => { timer.ccmr1_output.modify(|_,w| unsafe{ w.oc1m().bits(0b110)
                                                                                .oc1pe().bits(1) });
                                               timer.ccer.modify(|_, w| unsafe{ w.cc1e().bits(1)
                                                                                .cc1p().bits(0) }); },
                                1 | 7 | 9 => { timer.ccmr1_output.modify(|_,w| unsafe{ w.oc2m().bits(0b110)
                                                                                .oc2pe().bits(1) });
                                               timer.ccer.modify(|_, w| unsafe{ w.cc2e().bits(1)
                                                                                .cc2p().bits(0) }); },
                                2 | 10 => {    timer.ccmr2_output.modify(|_,w| unsafe{ w.oc3m().bits(0b110)
                                                                                .oc3pe().bits(1) });
                                               timer.ccer.modify(|_, w| unsafe{ w.cc3e().bits(1)
                                                                                .cc3p().bits(0) }); },
                                3 | 11 => {    timer.ccmr2_output.modify(|_,w| unsafe{ w.oc4m().bits(0b110)
                                                                                .oc4pe().bits(1) });
                                               timer.ccer.modify(|_, w| unsafe{ w.cc4e().bits(1)
                                                                                .cc4p().bits(0) }); },
                                _ => {},
                            }
                        },
                        x if x == GPIOB.get() as *const _ => {
                            match self.pin {
                                6 => {     timer.ccmr1_output.modify(|_,w| unsafe{ w.oc1m().bits(0b110)
                                                                                .oc1pe().bits(1) });
                                           timer.ccer.modify(|_, w| unsafe{ w.cc1e().bits(1)
                                                                             .cc1p().bits(0) }); },
                                7 => {     timer.ccmr1_output.modify(|_,w| unsafe{ w.oc2m().bits(0b110)
                                                                                .oc2pe().bits(1) });
                                           timer.ccer.modify(|_, w| unsafe{ w.cc2e().bits(1)
                                                                             .cc2p().bits(0) }); },
                                0 | 8 => { timer.ccmr2_output.modify(|_,w| unsafe{ w.oc3m().bits(0b110)
                                                                                .oc3pe().bits(1) });
                                           timer.ccer.modify(|_, w| unsafe{ w.cc3e().bits(1)
                                                                             .cc3p().bits(0) }); },
                                1 | 9 => { timer.ccmr2_output.modify(|_,w| unsafe{ w.oc4m().bits(0b110)
                                                                                .oc4pe().bits(1) });
                                           timer.ccer.modify(|_, w| unsafe{ w.cc4e().bits(1)
                                                                             .cc4p().bits(0) }); },
                                _ => {},
                            }
                        },
                        _ => {},
                    }

                    // set update generation bit
                    timer.egr.write(|w| unsafe{ w.ug().bits(1) });

                    //enable timer
                    timer.dier.modify(|_, w| unsafe { w.uie().bits(1) });
                    timer.cr1.modify(|_, w| unsafe { w.opm().continuous()
                                            .cen().enabled()
                                            .arpe().bits(1) });
                }

                match self.pin {
                    0 => self.port.crl.modify(|_,w| w.mode0().output50()
                                                        .cnf0().alt_push()),
                    1 => self.port.crl.modify(|_,w| w.mode1().output50()
                                                        .cnf1().alt_push()),
                    2 => self.port.crl.modify(|_,w| w.mode2().output50()
                                                        .cnf2().alt_push()),
                    3 => self.port.crl.modify(|_,w| w.mode3().output50()
                                                        .cnf3().alt_push()),
                    6 => self.port.crl.modify(|_,w| w.mode6().output50()
                                                        .cnf6().alt_push()),
                    7 => self.port.crl.modify(|_,w| w.mode7().output50()
                                                        .cnf7().alt_push()),
                    8 => self.port.crh.modify(|_,w| w.mode8().output50()
                                                        .cnf8().alt_push()),
                    9 => self.port.crh.modify(|_,w| w.mode9().output50()
                                                        .cnf9().alt_push()),
                    10 => self.port.crh.modify(|_,w| w.mode10().output50()
                                                        .cnf10().alt_push()),
                    11 => self.port.crh.modify(|_,w| w.mode11().output50()
                                                        .cnf11().alt_push()),
                    _ => {},
                }
            },
        };
    }
}

impl<'a> halPin<u16> for Pin<'a>{
    /// Turns off the Pin
    fn off(&self) {
        // NOTE(safe) atomic write
        unsafe { self.port.bsrr.write(|w| w.bits(1 << (self.pin + 16))) }
    }

    /// Turns on the Pin
    fn on(&self) {
        // NOTE(safe) atomic write
        unsafe { self.port.bsrr.write(|w| w.bits(1 << self.pin)) }
    }

    // return state of pin
    fn digital_read(&self) -> State {
        match self.port.idr.read().bits() & (1 << self.pin){
            0 => State::LOW,
            _ => State::HIGH
        }
    }

    fn analog_read(&self) -> u16 {
        1
    }

    fn pwm_write(&self, duty_cycle: u8){
        if let Some(timer) = self.timer {
            let value = if duty_cycle == 0 {
                0
            } else {
                let arr = timer.arr.read().bits();
                let duty_cycle = (u32(duty_cycle) * 100) / 255;
                let tmp = (arr * duty_cycle) / 100;
                u16(tmp).unwrap()
            };
            timer.ccr4.write(|w| unsafe{ w.ccr4().bits(value) });;
        }
    }
}<commit_msg>remove some unneeded deps from pin<commit_after>//! GPIO pin
use stm32f103xx::{GPIOA, GPIOB, GPIOC, GPIOD, gpioa, Rcc, rcc, adc1, tim2, TIM2, TIM3, TIM4, TIM5};
pub use hal::pin::Pin as halPin;
pub use hal::pin::{State, Mode};
use ::frequency;

/// GPIO pin
pub struct Pin<'a>{
    /// gpio pin
    pub pin: u8,
    /// gpio port
    pub port: &'a gpioa::RegisterBlock,
    adc: Option<&'a adc1::RegisterBlock>,
    timer: Option<&'a tim2::RegisterBlock>,
}

impl<'a> Pin<'a>{
    /// returns a digital pin
    pub fn new(pin: u8, port: &'a gpioa::RegisterBlock) -> Pin {
        Pin{pin, port, adc: None, timer: None}
    }

    /// returns an analog input pin
    pub fn new_analog_in(pin: u8, port: &'a gpioa::RegisterBlock, adc: &'a adc1::RegisterBlock) -> Pin<'a> {
        Pin{pin, port, adc: Some(adc), timer: None}
    }

    /// returns an analog output pin
    pub fn new_pwm_out(pin: u8, port: &'a gpioa::RegisterBlock, timer: &'a tim2::RegisterBlock) -> Pin<'a> {
        Pin{pin, port, adc: None, timer: Some(timer)}
    }

    /// Initializes the Pin
    pub fn init(&self, rcc: &Rcc, mode: Mode) {
        // Power up peripherals
        // check which memory block this port is pointing to
        match &*self.port as *const _{
            x if x == GPIOA.get() as *const _ => rcc.apb2enr.modify(|_, w| w.iopaen().enabled()),
            x if x == GPIOB.get() as *const _ => rcc.apb2enr.modify(|_, w| w.iopben().enabled()),
            x if x == GPIOC.get() as *const _ => rcc.apb2enr.modify(|_, w| w.iopcen().enabled()),
            x if x == GPIOD.get() as *const _ => rcc.apb2enr.modify(|_, w| w.iopden().enabled()),
            _ => {},
        }

        // Configure pin to input/output
        // still need to handle analog input mode, and possibly setting output frequency
        // defaults to 10Mhz output

        match mode {
            Mode::INPUT =>
                match self.pin {
                    // cnf alt_push mode is actually input pullup/pulldown, since cnf is shared
                    // for output mode the names are confusing
                    0 => self.port.crl.modify(|_,w| w.mode0().input()
                                                    .cnf0().alt_push()),
                    1 => self.port.crl.modify(|_,w| w.mode1().input()
                                                    .cnf1().alt_push()),
                    2 => self.port.crl.modify(|_,w| w.mode2().input()
                                                    .cnf2().alt_push()),
                    3 => self.port.crl.modify(|_,w| w.mode3().input()
                                                    .cnf3().alt_push()),
                    4 => self.port.crl.modify(|_,w| w.mode4().input()
                                                    .cnf4().alt_push()),
                    5 => self.port.crl.modify(|_,w| w.mode5().input()
                                                    .cnf5().alt_push()),
                    6 => self.port.crl.modify(|_,w| w.mode6().input()
                                                    .cnf6().alt_push()),
                    7 => self.port.crl.modify(|_,w| w.mode7().input()
                                                    .cnf7().alt_push()),
                    8 => self.port.crh.modify(|_,w| w.mode8().input()
                                                    .cnf8().alt_push()),
                    9 => self.port.crh.modify(|_,w| w.mode9().input()
                                                    .cnf9().alt_push()),
                    10 => self.port.crh.modify(|_,w| w.mode10().input()
                                                    .cnf10().alt_push()),
                    11 => self.port.crh.modify(|_,w| w.mode11().input()
                                                    .cnf11().alt_push()),
                    12 => self.port.crh.modify(|_,w| w.mode12().input()
                                                    .cnf12().alt_push()),
                    13 => self.port.crh.modify(|_,w| w.mode13().input()
                                                    .cnf13().alt_push()),
                    14 => self.port.crh.modify(|_,w| w.mode14().input()
                                                    .cnf14().alt_push()),
                    15 => self.port.crh.modify(|_,w| w.mode15().input()
                                                    .cnf15().alt_push()),
                    _ => {},
                },
            Mode::ANALOG_INPUT => {},
            Mode::OUTPUT =>
                match self.pin {
                    0 => self.port.crl.modify(|_,w| w.mode0().output()
                                                        .cnf0().push()),
                    1 => self.port.crl.modify(|_,w| w.mode1().output()
                                                        .cnf1().push()),
                    2 => self.port.crl.modify(|_,w| w.mode2().output()
                                                        .cnf2().push()),
                    3 => self.port.crl.modify(|_,w| w.mode3().output()
                                                        .cnf3().push()),
                    4 => self.port.crl.modify(|_,w| w.mode4().output()
                                                        .cnf4().push()),
                    5 => self.port.crl.modify(|_,w| w.mode5().output()
                                                        .cnf5().push()),
                    6 => self.port.crl.modify(|_,w| w.mode6().output()
                                                        .cnf6().push()),
                    7 => self.port.crl.modify(|_,w| w.mode7().output()
                                                        .cnf7().push()),
                    8 => self.port.crh.modify(|_,w| w.mode8().output()
                                                        .cnf8().push()),
                    9 => self.port.crh.modify(|_,w| w.mode9().output()
                                                        .cnf9().push()),
                    10 => self.port.crh.modify(|_,w| w.mode10().output()
                                                        .cnf10().push()),
                    11 => self.port.crh.modify(|_,w| w.mode11().output()
                                                        .cnf11().push()),
                    12 => self.port.crh.modify(|_,w| w.mode12().output()
                                                        .cnf12().push()),
                    13 => self.port.crh.modify(|_,w| w.mode13().output()
                                                        .cnf13().push()),
                    14 => self.port.crh.modify(|_,w| w.mode14().output()
                                                        .cnf14().push()),
                    15 => self.port.crh.modify(|_,w| w.mode15().output()
                                                        .cnf15().push()),
                    _ => {},
                },
            Mode::PWM_OUTPUT => {
                if let Some(timer) = self.timer {
                    match &*timer as *const _{
                        x if x == TIM2.get() as *const _ => rcc.apb1enr.modify(|_, w| w.tim2en().enabled()),
                        x if x == TIM3.get() as *const _ => rcc.apb1enr.modify(|_, w| w.tim3en().enabled()),
                        x if x == TIM4.get() as *const _ => rcc.apb1enr.modify(|_, w| w.tim4en().enabled()),
                        x if x == TIM5.get() as *const _ => rcc.apb1enr.modify(|_, w| w.tim5en().enabled()),
                        _ => {},
                    }

                    // PSC = (CLOCK / FREQ) / u16::MAX
                    // ARR = ((CLOCK / FREQ) + (PSC / 2)) / PSC

                    // if ppre1 is anything other than 1 the timer clock is multiplied by 2
                    let apb1_pre = rcc.cfgr.read().ppre1();
                    let apb1_mult = if apb1_pre == rcc::cfgr::Ppre1R::Div1 { 1 } else { 2 };

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

                    // use 100Khz for default speed
                    let psc = ((speeds.apb1 * apb1_mult) / 100_000) as u16 / 0xFFFF + 1;

                    timer.psc.write(|w| w.psc().bits(psc));

                    let arr = ((speeds.apb1 * apb1_mult) / 100_000) as u16 + (psc / 2) / psc;

                    // set frequency
                    timer.arr.write(|w| w.arr().bits(arr));

                    // Valid pins are PA 8, 9, 10, 11  timer 1
                    //                PA 0, 1, 2, 3    timer 2
                    //                PA 6, 7 PB 0, 1  timer 3
                    //                PB 6, 7, 8, 9    timer 4

                    // ocXm = pwm1 mode
                    // ocXpe = preload enable
                    // ccXe = output enable
                    // ccXp = active high
                    match &*self.port as *const _{
                        x if x == GPIOA.get() as *const _ => {
                            match self.pin {
                                0 | 6 | 8 => { timer.ccmr1_output.modify(|_,w| unsafe{ w.oc1m().bits(0b110)
                                                                                .oc1pe().bits(1) });
                                               timer.ccer.modify(|_, w| unsafe{ w.cc1e().bits(1)
                                                                                .cc1p().bits(0) }); },
                                1 | 7 | 9 => { timer.ccmr1_output.modify(|_,w| unsafe{ w.oc2m().bits(0b110)
                                                                                .oc2pe().bits(1) });
                                               timer.ccer.modify(|_, w| unsafe{ w.cc2e().bits(1)
                                                                                .cc2p().bits(0) }); },
                                2 | 10 => {    timer.ccmr2_output.modify(|_,w| unsafe{ w.oc3m().bits(0b110)
                                                                                .oc3pe().bits(1) });
                                               timer.ccer.modify(|_, w| unsafe{ w.cc3e().bits(1)
                                                                                .cc3p().bits(0) }); },
                                3 | 11 => {    timer.ccmr2_output.modify(|_,w| unsafe{ w.oc4m().bits(0b110)
                                                                                .oc4pe().bits(1) });
                                               timer.ccer.modify(|_, w| unsafe{ w.cc4e().bits(1)
                                                                                .cc4p().bits(0) }); },
                                _ => {},
                            }
                        },
                        x if x == GPIOB.get() as *const _ => {
                            match self.pin {
                                6 => {     timer.ccmr1_output.modify(|_,w| unsafe{ w.oc1m().bits(0b110)
                                                                                .oc1pe().bits(1) });
                                           timer.ccer.modify(|_, w| unsafe{ w.cc1e().bits(1)
                                                                             .cc1p().bits(0) }); },
                                7 => {     timer.ccmr1_output.modify(|_,w| unsafe{ w.oc2m().bits(0b110)
                                                                                .oc2pe().bits(1) });
                                           timer.ccer.modify(|_, w| unsafe{ w.cc2e().bits(1)
                                                                             .cc2p().bits(0) }); },
                                0 | 8 => { timer.ccmr2_output.modify(|_,w| unsafe{ w.oc3m().bits(0b110)
                                                                                .oc3pe().bits(1) });
                                           timer.ccer.modify(|_, w| unsafe{ w.cc3e().bits(1)
                                                                             .cc3p().bits(0) }); },
                                1 | 9 => { timer.ccmr2_output.modify(|_,w| unsafe{ w.oc4m().bits(0b110)
                                                                                .oc4pe().bits(1) });
                                           timer.ccer.modify(|_, w| unsafe{ w.cc4e().bits(1)
                                                                             .cc4p().bits(0) }); },
                                _ => {},
                            }
                        },
                        _ => {},
                    }

                    // set update generation bit
                    timer.egr.write(|w| unsafe{ w.ug().bits(1) });

                    //enable timer
                    timer.dier.modify(|_, w| unsafe { w.uie().bits(1) });
                    timer.cr1.modify(|_, w| unsafe { w.opm().continuous()
                                            .cen().enabled()
                                            .arpe().bits(1) });
                }

                match self.pin {
                    0 => self.port.crl.modify(|_,w| w.mode0().output50()
                                                        .cnf0().alt_push()),
                    1 => self.port.crl.modify(|_,w| w.mode1().output50()
                                                        .cnf1().alt_push()),
                    2 => self.port.crl.modify(|_,w| w.mode2().output50()
                                                        .cnf2().alt_push()),
                    3 => self.port.crl.modify(|_,w| w.mode3().output50()
                                                        .cnf3().alt_push()),
                    6 => self.port.crl.modify(|_,w| w.mode6().output50()
                                                        .cnf6().alt_push()),
                    7 => self.port.crl.modify(|_,w| w.mode7().output50()
                                                        .cnf7().alt_push()),
                    8 => self.port.crh.modify(|_,w| w.mode8().output50()
                                                        .cnf8().alt_push()),
                    9 => self.port.crh.modify(|_,w| w.mode9().output50()
                                                        .cnf9().alt_push()),
                    10 => self.port.crh.modify(|_,w| w.mode10().output50()
                                                        .cnf10().alt_push()),
                    11 => self.port.crh.modify(|_,w| w.mode11().output50()
                                                        .cnf11().alt_push()),
                    _ => {},
                }
            },
        };
    }
}

impl<'a> halPin<u16> for Pin<'a>{
    /// Turns off the Pin
    fn off(&self) {
        // NOTE(safe) atomic write
        unsafe { self.port.bsrr.write(|w| w.bits(1 << (self.pin + 16))) }
    }

    /// Turns on the Pin
    fn on(&self) {
        // NOTE(safe) atomic write
        unsafe { self.port.bsrr.write(|w| w.bits(1 << self.pin)) }
    }

    // return state of pin
    fn digital_read(&self) -> State {
        match self.port.idr.read().bits() & (1 << self.pin){
            0 => State::LOW,
            _ => State::HIGH
        }
    }

    fn analog_read(&self) -> u16 {
        1
    }

    fn pwm_write(&self, duty_cycle: u8){
        if let Some(timer) = self.timer {
            let value = if duty_cycle == 0 {
                0
            } else {
                let arr = timer.arr.read().bits();
                let duty_cycle = (duty_cycle as u32 * 100) / 255;
                ((arr * duty_cycle) / 100) as u16
            };
            timer.ccr4.write(|w| unsafe{ w.ccr4().bits(value) });;
        }
    }
}<|endoftext|>


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

use std::io::{Read, BufRead, Error as IoError, ErrorKind};
use std::string::{FromUtf8Error};

use num::{Zero};
use num::bigint::{BigInt, ToBigInt, Sign};
use byteorder::{ReadBytesExt, LittleEndian, BigEndian, Error as ByteorderError};
use from_ascii::{FromAscii, ParseIntError, ParseFloatError};

use string::{unescape, Error as UnescapeError};
use value::{Value};

use opcodes::*;

quick_error! {
    #[derive(Debug)]
    pub enum Error {
        EmptyMarker
        StackTooSmall
        EmptyStack
        InvalidValueOnStack
        InvalidGetValue
        InvalidPutValue
        NotImplemented

        Read(err: ByteorderError) {
            from()
        }
        Io(err: IoError) {
            from()
        }
        UnknownOpcode(opcode: u8) {}

        InvalidInt {
            from(ParseIntError)
        }
        InvalidLong
        InvalidFloat {
            from(ParseFloatError)
        }

        InvalidString {
            from(FromUtf8Error)
        }
        UnescapeError(err: UnescapeError) {
            from()
        }

        InvalidProto(proto: u8)
        NegativeLength
    }
}

#[derive(Debug, PartialEq)]
pub enum BooleanOrInt {
    Boolean(bool),
    Int(i64),
}

fn read_exact<R>(rd: &mut R, mut buf: &mut [u8]) -> Result<(), IoError> where R: Read {
    while !buf.is_empty() {
        match rd.read(buf) {
            Ok(0) => break,
            Ok(n) => { let tmp = buf; buf = &mut tmp[n..]; }
            Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
            Err(e) => return Err(e),
        }
    }
    if !buf.is_empty() {
        Err(IoError::new(ErrorKind::Other,
                       "failed to fill whole buffer"))
    } else {
        Ok(())
    }
}

fn read_until_newline<R>(rd: &mut R) -> Result<Vec<u8>, Error> where R: Read + BufRead {
    let mut buf = Vec::new();
    try!(rd.read_until('\n' as u8, &mut buf));

    // Skip last symbol — \n
    match buf.split_last() {
        Some((&b'\n', init)) => Ok(init.to_vec()),
        _ => return Err(Error::InvalidString),
    }
}

fn read_decimal_int<R>(rd: &mut R) -> Result<BooleanOrInt, Error> where R: Read + BufRead {
    let s = try!(read_until_newline(rd));
    let val = match &s[..] {
        b"00" => BooleanOrInt::Boolean(false),
        b"01" => BooleanOrInt::Boolean(true),
        _ => BooleanOrInt::Int(try!(i64::from_ascii(&s)))
    };
    Ok(val)
}

fn read_decimal_long<R>(rd: &mut R) -> Result<BigInt, Error> where R: Read + BufRead {
    let s = try!(read_until_newline(rd));
    let init = match s.split_last() {
        None => return Err(Error::InvalidString),
        Some((&b'L', init)) => init,
        Some(_) => &s[..],
    };

    match BigInt::parse_bytes(&init, 10) {
        Some(i) => Ok(i),
        None => Err(Error::InvalidLong)
    }
}

fn read_long<R>(rd: &mut R, length: usize) -> Result<BigInt, Error> where R: Read + BufRead {
    let mut buf = vec![0; length];
    try!(read_exact(rd, buf.as_mut()));

    let mut n = BigInt::from_bytes_le(Sign::Plus, &buf);

    let last = match buf.last_mut() {
        None => return Err(Error::InvalidLong),
        Some(last) => last,
    };

    if *last > 127 {
        n = n - (1.to_bigint().unwrap() << (length * 8))
    }

    Ok(n)
}

pub struct Machine {
    stack: Vec<Value>,
    memo: Vec<Value>,
    marker: Option<usize>,
}

impl Machine {
    pub fn new() -> Self {
        Machine {
            stack: Vec::new(),
            memo: Vec::with_capacity(8),
            marker: None,
        }
    }

    fn split_off(&mut self) -> Result<Vec<Value>, Error> {
        let at = match self.marker {
            None => return Err(Error::EmptyMarker),
            Some(marker) => marker,
        };

        if at > self.stack.len() {
            return Err(Error::StackTooSmall);
        }

        Ok(self.stack.split_off(at))
    }

    pub fn pop(&mut self) -> Result<Value, Error> {
        match self.stack.pop() {
            None => return Err(Error::EmptyStack),
            Some(value) => Ok(value),
        }
    }

    fn handle_get(&mut self, i: usize) -> Result<(), Error> {
        let value = match self.memo.get(i) {
            None => return Err(Error::InvalidGetValue),
            Some(ref v) => (*v).clone(),
        };
        self.stack.push(value);
        Ok(())
    }

    fn handle_put(&mut self, i: usize) -> Result<(), Error> {
        let value = match self.stack.last() {
            None => return Err(Error::EmptyStack),
            Some(ref v) => (*v).clone(),
        };
        let len = self.memo.len();
        if len != i {
            return Err(Error::InvalidPutValue)
        }
        self.memo.push(value);
        Ok(())
    }

    pub fn execute<R>(&mut self, rd: &mut R) -> Result<bool, Error> where R: Read + BufRead {
        macro_rules! ensure_not_negative {
            ($n: expr) => ({
                if $n < Zero::zero() {
                    return Err(Error::NegativeLength)
                }
            })
        }

        let marker = try!(rd.read_u8());
        match marker {
            PROTO => {
                let version = try!(rd.read_u8());
                if version < 2 {
                    return Err(Error::InvalidProto(version))
                }
            },
            STOP => return Ok(true),

            INT => {
                self.stack.push(match try!(read_decimal_int(rd)) {
                    BooleanOrInt::Boolean(v) => Value::Bool(v),
                    BooleanOrInt::Int(v) => Value::Long(BigInt::from(v)),
                })
            },
            BININT => self.stack.push(Value::Int(try!(rd.read_i32::<LittleEndian>()) as usize)),
            BININT1 => self.stack.push(Value::Int(try!(rd.read_u8()) as usize)),
            BININT2 => self.stack.push(Value::Int(try!(rd.read_u16::<LittleEndian>()) as usize)),
            LONG => self.stack.push(Value::Long(BigInt::from(try!(read_decimal_long(rd))))),
            LONG1 => {
                let length = try!(rd.read_u8());
                self.stack.push(Value::Long(BigInt::from(try!(read_long(rd, length as usize)))))
            }
            LONG4 => {
                let length = try!(rd.read_i32::<LittleEndian>());
                self.stack.push(Value::Long(BigInt::from(try!(read_long(rd, length as usize)))))
            }

            STRING => self.stack.push(Value::String(try!(unescape(&try!(read_until_newline(rd)), false)))),
            BINSTRING => {
                let length = try!(rd.read_i32::<LittleEndian>());
                ensure_not_negative!(length);

                let mut buf = vec![0; length as usize];
                try!(read_exact(rd, &mut buf));
                self.stack.push(Value::String(buf))
            },
            SHORT_BINSTRING => {
                let length = try!(rd.read_u8());
                let mut buf = vec![0; length as usize];
                try!(read_exact(rd, &mut buf));
                self.stack.push(Value::String(buf))
            },

            NONE => self.stack.push(Value::None),
            NEWTRUE => self.stack.push(Value::Bool(true)),
            NEWFALSE => self.stack.push(Value::Bool(false)),

            UNICODE => {
                let buf = try!(unescape(&try!(read_until_newline(rd)), true));
                self.stack.push(Value::Unicode(try!(String::from_utf8(buf))))
            },
            BINUNICODE => {
                let length = try!(rd.read_i32::<LittleEndian>());
                ensure_not_negative!(length);
                let mut buf = vec![0; length as usize];
                try!(read_exact(rd, buf.as_mut()));
                self.stack.push(Value::Unicode(try!(String::from_utf8(buf))))
            },

            FLOAT => {
                let s = try!(read_until_newline(rd));
                self.stack.push(Value::Float(try!(f64::from_ascii(&s))))
            },
            BINFLOAT => {
                self.stack.push(Value::Float(try!(rd.read_f64::<BigEndian>())))
            },

            EMPTY_LIST => {
                self.stack.push(Value::List(Vec::new()))
            },
            APPEND => {
                let v = try!(self.pop());
                match self.stack.last_mut() {
                    None => return Err(Error::EmptyStack),
                    Some(&mut Value::List(ref mut list)) => list.push(v),
                    _ => return Err(Error::InvalidValueOnStack),
                }
            },
            APPENDS => {
                let values = try!(self.split_off());
                match self.stack.last_mut() {
                    None => return Err(Error::EmptyStack),
                    Some(&mut Value::List(ref mut list)) => {
                        list.extend(values);
                    },
                    _ => return Err(Error::InvalidValueOnStack),
                }
            },
            LIST => {
                let values = try!(self.split_off());
                self.stack.push(Value::List(values));
            },

            EMPTY_TUPLE => self.stack.push(Value::Tuple(Vec::new())),
            TUPLE => {
                let values = try!(self.split_off());
                self.stack.push(Value::Tuple(values));
            },
            TUPLE1 => {
                let v1 = try!(self.pop());
                self.stack.push(Value::Tuple(vec![v1]))
            },
            TUPLE2 => {
                let v1 = try!(self.pop());
                let v2 = try!(self.pop());
                self.stack.push(Value::Tuple(vec![v1, v2]))
            },
            TUPLE3 => {
                let v1 = try!(self.pop());
                let v2 = try!(self.pop());
                let v3 = try!(self.pop());
                self.stack.push(Value::Tuple(vec![v1, v2, v3]))
            }

            EMPTY_DICT => self.stack.push(Value::Dict(Vec::new())),
            DICT => {
                let mut values = try!(self.split_off());
                let mut dict = Vec::new();

                for i in 0 .. values.len() / 2 { // TODO: Check panic
                    let key = values.remove(2 * i);
                    let value = values.remove(2 * i + 1);
                    dict.push((key, value));
                }
                self.stack.push(Value::Dict(dict));
            },
            SETITEM => {
                let value = try!(self.pop());
                let key = try!(self.pop());
                match self.stack.last_mut() {
                    None => return Err(Error::EmptyStack),
                    Some(&mut Value::Dict(ref mut dict)) => dict.push((key, value)),
                    _ => return Err(Error::InvalidValueOnStack),
                }
            },
            SETITEMS => {
                let mut values = try!(self.split_off());

                match self.stack.last_mut() {
                    None => return Err(Error::EmptyStack),
                    Some(&mut Value::Dict(ref mut dict)) => {
                        for i in 0 .. values.len() / 2 { // TODO: Check panic
                            let key = values.remove(2 * i);
                            let value = values.remove(2 * i + 1);
                            dict.push((key, value));
                        }
                    },
                    _ => return Err(Error::InvalidValueOnStack),
                }
            },

            POP => {
                try!(self.pop());
            },
            DUP => {
                let value = match self.stack.last() {
                    None => return Err(Error::EmptyStack),
                    Some(ref v) => (*v).clone(),
                };
                self.stack.push(value)
            },
            MARK => {
                self.marker = Some(self.stack.len())
            },
            POP_MARK => {
                try!(self.split_off());
            },

            GET => {
                let n = match try!(read_decimal_int(rd)) {
                    BooleanOrInt::Int(n) => n,
                    BooleanOrInt::Boolean(false) => 0,
                    BooleanOrInt::Boolean(true) => 1,
                };
                ensure_not_negative!(n);
                try!(self.handle_get(n as usize))
            }
            BINGET => {
                try!(self.handle_get(try!(rd.read_u8()) as usize))
            }
            LONG_BINGET => {
                let n = try!(rd.read_i32::<LittleEndian>());
                ensure_not_negative!(n);
                try!(self.handle_get(n as usize))
            }

            PUT => {
                let n = match try!(read_decimal_int(rd)) {
                    BooleanOrInt::Int(n) => n,
                    BooleanOrInt::Boolean(false) => 0,
                    BooleanOrInt::Boolean(true) => 1,
                };
                ensure_not_negative!(n);
                try!(self.handle_put(n as usize))
            }
            BINPUT => {
                try!(self.handle_put(try!(rd.read_u8()) as usize))
            }
            LONG_BINPUT => {
                let n = try!(rd.read_i32::<LittleEndian>());
                ensure_not_negative!(n);
                try!(self.handle_put(n as usize))
            }

            c => return Err(Error::UnknownOpcode(c)),
        }
        Ok(false)
    }
}
<commit_msg>Initialize memo with None<commit_after>// Copyright (c) 2016 Fedor Gogolev <knsd@knsd.net>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::io::{Read, BufRead, Error as IoError, ErrorKind};
use std::string::{FromUtf8Error};

use num::{Zero};
use num::bigint::{BigInt, ToBigInt, Sign};
use byteorder::{ReadBytesExt, LittleEndian, BigEndian, Error as ByteorderError};
use from_ascii::{FromAscii, ParseIntError, ParseFloatError};

use string::{unescape, Error as UnescapeError};
use value::{Value};

use opcodes::*;

quick_error! {
    #[derive(Debug)]
    pub enum Error {
        EmptyMarker
        StackTooSmall
        EmptyStack
        InvalidValueOnStack
        InvalidGetValue
        InvalidPutValue
        NotImplemented

        Read(err: ByteorderError) {
            from()
        }
        Io(err: IoError) {
            from()
        }
        UnknownOpcode(opcode: u8) {}

        InvalidInt {
            from(ParseIntError)
        }
        InvalidLong
        InvalidFloat {
            from(ParseFloatError)
        }

        InvalidString {
            from(FromUtf8Error)
        }
        UnescapeError(err: UnescapeError) {
            from()
        }

        InvalidProto(proto: u8)
        NegativeLength
    }
}

#[derive(Debug, PartialEq)]
pub enum BooleanOrInt {
    Boolean(bool),
    Int(i64),
}

fn read_exact<R>(rd: &mut R, mut buf: &mut [u8]) -> Result<(), IoError> where R: Read {
    while !buf.is_empty() {
        match rd.read(buf) {
            Ok(0) => break,
            Ok(n) => { let tmp = buf; buf = &mut tmp[n..]; }
            Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
            Err(e) => return Err(e),
        }
    }
    if !buf.is_empty() {
        Err(IoError::new(ErrorKind::Other,
                       "failed to fill whole buffer"))
    } else {
        Ok(())
    }
}

fn read_until_newline<R>(rd: &mut R) -> Result<Vec<u8>, Error> where R: Read + BufRead {
    let mut buf = Vec::new();
    try!(rd.read_until('\n' as u8, &mut buf));

    // Skip last symbol — \n
    match buf.split_last() {
        Some((&b'\n', init)) => Ok(init.to_vec()),
        _ => return Err(Error::InvalidString),
    }
}

fn read_decimal_int<R>(rd: &mut R) -> Result<BooleanOrInt, Error> where R: Read + BufRead {
    let s = try!(read_until_newline(rd));
    let val = match &s[..] {
        b"00" => BooleanOrInt::Boolean(false),
        b"01" => BooleanOrInt::Boolean(true),
        _ => BooleanOrInt::Int(try!(i64::from_ascii(&s)))
    };
    Ok(val)
}

fn read_decimal_long<R>(rd: &mut R) -> Result<BigInt, Error> where R: Read + BufRead {
    let s = try!(read_until_newline(rd));
    let init = match s.split_last() {
        None => return Err(Error::InvalidString),
        Some((&b'L', init)) => init,
        Some(_) => &s[..],
    };

    match BigInt::parse_bytes(&init, 10) {
        Some(i) => Ok(i),
        None => Err(Error::InvalidLong)
    }
}

fn read_long<R>(rd: &mut R, length: usize) -> Result<BigInt, Error> where R: Read + BufRead {
    let mut buf = vec![0; length];
    try!(read_exact(rd, buf.as_mut()));

    let mut n = BigInt::from_bytes_le(Sign::Plus, &buf);

    let last = match buf.last_mut() {
        None => return Err(Error::InvalidLong),
        Some(last) => last,
    };

    if *last > 127 {
        n = n - (1.to_bigint().unwrap() << (length * 8))
    }

    Ok(n)
}

pub struct Machine {
    stack: Vec<Value>,
    memo: Vec<Value>,
    marker: Option<usize>,
}

impl Machine {
    pub fn new() -> Self {
        Machine {
            stack: Vec::new(),
            memo: vec![Value::None],
            marker: None,
        }
    }

    fn split_off(&mut self) -> Result<Vec<Value>, Error> {
        let at = match self.marker {
            None => return Err(Error::EmptyMarker),
            Some(marker) => marker,
        };

        if at > self.stack.len() {
            return Err(Error::StackTooSmall);
        }

        Ok(self.stack.split_off(at))
    }

    pub fn pop(&mut self) -> Result<Value, Error> {
        match self.stack.pop() {
            None => return Err(Error::EmptyStack),
            Some(value) => Ok(value),
        }
    }

    fn handle_get(&mut self, i: usize) -> Result<(), Error> {
        let value = match self.memo.get(i) {
            None => return Err(Error::InvalidGetValue),
            Some(ref v) => (*v).clone(),
        };
        self.stack.push(value);
        Ok(())
    }

    fn handle_put(&mut self, i: usize) -> Result<(), Error> {
        let value = match self.stack.last() {
            None => return Err(Error::EmptyStack),
            Some(ref v) => (*v).clone(),
        };
        let len = self.memo.len();
        if len != i {
            return Err(Error::InvalidPutValue)
        }
        self.memo.push(value);
        Ok(())
    }

    pub fn execute<R>(&mut self, rd: &mut R) -> Result<bool, Error> where R: Read + BufRead {
        macro_rules! ensure_not_negative {
            ($n: expr) => ({
                if $n < Zero::zero() {
                    return Err(Error::NegativeLength)
                }
            })
        }

        let marker = try!(rd.read_u8());
        match marker {
            PROTO => {
                let version = try!(rd.read_u8());
                if version < 2 {
                    return Err(Error::InvalidProto(version))
                }
            },
            STOP => return Ok(true),

            INT => {
                self.stack.push(match try!(read_decimal_int(rd)) {
                    BooleanOrInt::Boolean(v) => Value::Bool(v),
                    BooleanOrInt::Int(v) => Value::Long(BigInt::from(v)),
                })
            },
            BININT => self.stack.push(Value::Int(try!(rd.read_i32::<LittleEndian>()) as usize)),
            BININT1 => self.stack.push(Value::Int(try!(rd.read_u8()) as usize)),
            BININT2 => self.stack.push(Value::Int(try!(rd.read_u16::<LittleEndian>()) as usize)),
            LONG => self.stack.push(Value::Long(BigInt::from(try!(read_decimal_long(rd))))),
            LONG1 => {
                let length = try!(rd.read_u8());
                self.stack.push(Value::Long(BigInt::from(try!(read_long(rd, length as usize)))))
            }
            LONG4 => {
                let length = try!(rd.read_i32::<LittleEndian>());
                self.stack.push(Value::Long(BigInt::from(try!(read_long(rd, length as usize)))))
            }

            STRING => self.stack.push(Value::String(try!(unescape(&try!(read_until_newline(rd)), false)))),
            BINSTRING => {
                let length = try!(rd.read_i32::<LittleEndian>());
                ensure_not_negative!(length);

                let mut buf = vec![0; length as usize];
                try!(read_exact(rd, &mut buf));
                self.stack.push(Value::String(buf))
            },
            SHORT_BINSTRING => {
                let length = try!(rd.read_u8());
                let mut buf = vec![0; length as usize];
                try!(read_exact(rd, &mut buf));
                self.stack.push(Value::String(buf))
            },

            NONE => self.stack.push(Value::None),
            NEWTRUE => self.stack.push(Value::Bool(true)),
            NEWFALSE => self.stack.push(Value::Bool(false)),

            UNICODE => {
                let buf = try!(unescape(&try!(read_until_newline(rd)), true));
                self.stack.push(Value::Unicode(try!(String::from_utf8(buf))))
            },
            BINUNICODE => {
                let length = try!(rd.read_i32::<LittleEndian>());
                ensure_not_negative!(length);
                let mut buf = vec![0; length as usize];
                try!(read_exact(rd, buf.as_mut()));
                self.stack.push(Value::Unicode(try!(String::from_utf8(buf))))
            },

            FLOAT => {
                let s = try!(read_until_newline(rd));
                self.stack.push(Value::Float(try!(f64::from_ascii(&s))))
            },
            BINFLOAT => {
                self.stack.push(Value::Float(try!(rd.read_f64::<BigEndian>())))
            },

            EMPTY_LIST => {
                self.stack.push(Value::List(Vec::new()))
            },
            APPEND => {
                let v = try!(self.pop());
                match self.stack.last_mut() {
                    None => return Err(Error::EmptyStack),
                    Some(&mut Value::List(ref mut list)) => list.push(v),
                    _ => return Err(Error::InvalidValueOnStack),
                }
            },
            APPENDS => {
                let values = try!(self.split_off());
                match self.stack.last_mut() {
                    None => return Err(Error::EmptyStack),
                    Some(&mut Value::List(ref mut list)) => {
                        list.extend(values);
                    },
                    _ => return Err(Error::InvalidValueOnStack),
                }
            },
            LIST => {
                let values = try!(self.split_off());
                self.stack.push(Value::List(values));
            },

            EMPTY_TUPLE => self.stack.push(Value::Tuple(Vec::new())),
            TUPLE => {
                let values = try!(self.split_off());
                self.stack.push(Value::Tuple(values));
            },
            TUPLE1 => {
                let v1 = try!(self.pop());
                self.stack.push(Value::Tuple(vec![v1]))
            },
            TUPLE2 => {
                let v1 = try!(self.pop());
                let v2 = try!(self.pop());
                self.stack.push(Value::Tuple(vec![v1, v2]))
            },
            TUPLE3 => {
                let v1 = try!(self.pop());
                let v2 = try!(self.pop());
                let v3 = try!(self.pop());
                self.stack.push(Value::Tuple(vec![v1, v2, v3]))
            }

            EMPTY_DICT => self.stack.push(Value::Dict(Vec::new())),
            DICT => {
                let mut values = try!(self.split_off());
                let mut dict = Vec::new();

                for i in 0 .. values.len() / 2 { // TODO: Check panic
                    let key = values.remove(2 * i);
                    let value = values.remove(2 * i + 1);
                    dict.push((key, value));
                }
                self.stack.push(Value::Dict(dict));
            },
            SETITEM => {
                let value = try!(self.pop());
                let key = try!(self.pop());
                match self.stack.last_mut() {
                    None => return Err(Error::EmptyStack),
                    Some(&mut Value::Dict(ref mut dict)) => dict.push((key, value)),
                    _ => return Err(Error::InvalidValueOnStack),
                }
            },
            SETITEMS => {
                let mut values = try!(self.split_off());

                match self.stack.last_mut() {
                    None => return Err(Error::EmptyStack),
                    Some(&mut Value::Dict(ref mut dict)) => {
                        for i in 0 .. values.len() / 2 { // TODO: Check panic
                            let key = values.remove(2 * i);
                            let value = values.remove(2 * i + 1);
                            dict.push((key, value));
                        }
                    },
                    _ => return Err(Error::InvalidValueOnStack),
                }
            },

            POP => {
                try!(self.pop());
            },
            DUP => {
                let value = match self.stack.last() {
                    None => return Err(Error::EmptyStack),
                    Some(ref v) => (*v).clone(),
                };
                self.stack.push(value)
            },
            MARK => {
                self.marker = Some(self.stack.len())
            },
            POP_MARK => {
                try!(self.split_off());
            },

            GET => {
                let n = match try!(read_decimal_int(rd)) {
                    BooleanOrInt::Int(n) => n,
                    BooleanOrInt::Boolean(false) => 0,
                    BooleanOrInt::Boolean(true) => 1,
                };
                ensure_not_negative!(n);
                try!(self.handle_get(n as usize))
            }
            BINGET => {
                try!(self.handle_get(try!(rd.read_u8()) as usize))
            }
            LONG_BINGET => {
                let n = try!(rd.read_i32::<LittleEndian>());
                ensure_not_negative!(n);
                try!(self.handle_get(n as usize))
            }

            PUT => {
                let n = match try!(read_decimal_int(rd)) {
                    BooleanOrInt::Int(n) => n,
                    BooleanOrInt::Boolean(false) => 0,
                    BooleanOrInt::Boolean(true) => 1,
                };
                ensure_not_negative!(n);
                try!(self.handle_put(n as usize))
            }
            BINPUT => {
                try!(self.handle_put(try!(rd.read_u8()) as usize))
            }
            LONG_BINPUT => {
                let n = try!(rd.read_i32::<LittleEndian>());
                ensure_not_negative!(n);
                try!(self.handle_put(n as usize))
            }

            c => return Err(Error::UnknownOpcode(c)),
        }
        Ok(false)
    }
}
<|endoftext|>


<commit_before>//! Rust representations of docker json structures

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct SearchResult {
  pub description: String,
  pub is_official: bool,
  pub is_trusted: bool,
  pub name: String,
  pub star_count: u64
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Image {
  pub Created: u64,
  pub Id: String,
  pub ParentId: String,
  //pub Labels: ???,
  pub RepoTags: Vec<String>,
  pub RepoDigests: Option<Vec<String>>,
  pub Size: u64,
  pub VirtualSize: u64
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct ImageDetails {
  pub Architecture: String,
  pub Author: String,
  pub Comment: String,
  pub Config: Config,
  pub Created: String,
  pub DockerVersion: String,
  pub Id: String,
  pub Os: String,
  pub Parent: String,
  pub Size: u64,
  pub VirtualSize: u64
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Container {
  pub Created: u64,
  pub Command: String,
  pub Id: String,
  pub Image: String,
  //pub Labels: ???,
  pub Names: Vec<String>,
  pub Ports: Vec<Port>,
  pub Status: String,
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct ContainerDetails {
  pub AppArmorProfile: String,
  pub Args: Vec<String>,
  pub Config: Config,
  pub Created: String,
  pub Driver: String,
  pub ExecDriver: String,
  //pub ExecIDs: ??
  pub HostConfig: HostConfig
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct HostConfig {
  pub CgroupParent: Option<String>,
  pub ContainerIDFile: String,
  pub CpuShares: Option<u64>,
  pub CpusetCpus: Option<String>,
  pub Memory: Option<u64>,
  pub MemorySwap: Option<u64>,
  pub NetworkMode: String,
  pub PidMode: Option<String>,
  //pub PortBindings: ???
  pub Privileged: bool,
  pub PublishAllPorts: bool,
  pub ReadonlyRootfs: Option<bool>
  //pub RestartPolicy: ???
  //pub SecurityOpt: Option<???>,
  //pub Ulimits: Option<???>
 // pub VolumesFrom: Option<??/>
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Config {
  AttachStderr: bool,
  AttachStdin: bool,
  AttachStdout: bool,
  Cmd: Vec<String>,
  CpuShares: u64,
  Cpuset: String,
  Domainname: String,
  Entrypoint: Vec<String>,
  Env: Vec<String>,
  //ExposedPorts
  Hostname: String,
  Image: String,
  //Labels:???
  MacAddress: String,
  Memory: u64,
  MemorySwap: u64,
  NetworkDisabled: bool,
  //OnBuild: Option<String>,
  OpenStdin: bool,
  //PortSpecs: ???,
  StdinOnce: bool,
  Tty: bool,
  User: String,
  //Volumes: ??,
  WorkingDir: String
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Port {
  pub IP: Option<String>,
  pub PrivatePort: u64,
  pub PublicPort: Option<u64>,
  pub Type: String
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct Stats {
  pub read: String,
  pub network: Network,
  pub memory_stats: MemoryStats,
  pub cpu_stats: CpuStats
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct Network {
  pub rx_dropped: u64,
  pub rx_bytes: u64,
  pub rx_errors: u64,
  pub tx_packets: u64,
  pub tx_dropped: u64,
  pub rx_packets: u64,
  pub tx_errors: u64,
  pub tx_bytes: u64
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct MemoryStats {
  pub max_usage: u64,
  pub usage: u64,
  pub failcnt: u64,
  pub limit: u64,
  pub stats: MemoryStat
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct MemoryStat {
  pub total_pgmajfault: u64,
  pub cache: u64,
  pub mapped_file: u64,
  pub total_inactive_file: u64,
  pub pgpgout: u64,
  pub rss: u64,
  pub total_mapped_file: u64,
  pub writeback: u64,
  pub unevictable: u64,
  pub pgpgin: u64,
  pub total_unevictable: u64,
  pub pgmajfault: u64,
  pub total_rss: u64,
  pub total_rss_huge: u64,
  pub total_writeback: u64,
  pub total_inactive_anon: u64,
  pub rss_huge: u64,
  pub hierarchical_memory_limit: u64,
  pub hierarchical_memsw_limit: u64,
  pub total_pgfault: u64,
  pub total_active_file: u64,
  pub active_anon: u64,
  pub total_active_anon: u64,
  pub total_pgpgout: u64,
  pub total_cache: u64,
  pub inactive_anon: u64,
  pub active_file: u64,
  pub pgfault: u64,
  pub inactive_file: u64,
  pub total_pgpgin: u64,
  pub swap: u64,
  pub total_swap: u64
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct CpuStats {
  pub cpu_usage: CpuUsage,
  pub system_cpu_usage: u64,
  pub throttling_data: ThrottlingData
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct CpuUsage {
  pub percpu_usage: Vec<u64>,
  pub usage_in_usermode: u64,
  pub total_usage: u64,
  pub usage_in_kernelmode: u64
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct ThrottlingData {
  pub periods: u64,
  pub throttled_periods: u64,
  pub throttled_time: u64
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct BlkioStats {
  pub io_service_bytes_recursive: Vec<BlkioStat>,
  pub io_serviced_recursive: Vec<BlkioStat>,
  pub io_queue_recursive: Vec<BlkioStat>,
  pub io_service_time_recursive: Vec<BlkioStat>,
  pub io_wait_time_recursive: Vec<BlkioStat>,
  pub io_merged_recursive: Vec<BlkioStat>,
  pub io_time_recursive: Vec<BlkioStat>,
  pub sectors_recursive: Vec<BlkioStat>
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct BlkioStat {
  pub major: u64,
  pub minor: u64,
  pub op: String,
  pub value: u64
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Change {
  pub Kind: u64,
  pub Path: String
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Top {
  pub Titles: Vec<String>,
  pub Processes: Vec<Vec<String>>
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Version {
  pub ApiVersion: String,
  pub Version: String,
  pub GitCommit: String,
  pub GoVersion: String
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Info {
  pub Containers: u64,
  pub Images: u64,
  pub Driver: String,
  pub DockerRootDir: String,
  pub DriverStatus: Vec<Vec<String>>,
  pub ExecutionDriver: String,
  pub ID: String,
  pub KernelVersion: String,
  //pub Labels: Option<???>,
  pub MemTotal: u64,
  pub MemoryLimit: u64,
  pub NCPU: u64,
  pub NEventsListener: u64,
  pub NGoroutines: u64,
  pub Name: String,
  pub OperatingSystem: String,
  //pub RegistryConfig:???
  pub SwapLimit: u64,
  pub SystemTime: Option<String>
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct ContainerCreateInfo {
  pub Id: String,
  pub Warnings: Option<Vec<String>>
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct History {
  pub Id: String,
  pub Created: u64,
  pub CreatedBy: String
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Exit {
  pub StatusCode: u64
}
<commit_msg>space<commit_after>//! Rust representations of docker json structures

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct SearchResult {
  pub description: String,
  pub is_official: bool,
  pub is_trusted: bool,
  pub name: String,
  pub star_count: u64
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Image {
  pub Created: u64,
  pub Id: String,
  pub ParentId: String,
  //pub Labels: ???,
  pub RepoTags: Vec<String>,
  pub RepoDigests: Option<Vec<String>>,
  pub Size: u64,
  pub VirtualSize: u64
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct ImageDetails {
  pub Architecture: String,
  pub Author: String,
  pub Comment: String,
  pub Config: Config,
  pub Created: String,
  pub DockerVersion: String,
  pub Id: String,
  pub Os: String,
  pub Parent: String,
  pub Size: u64,
  pub VirtualSize: u64
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Container {
  pub Created: u64,
  pub Command: String,
  pub Id: String,
  pub Image: String,
  //pub Labels: ???,
  pub Names: Vec<String>,
  pub Ports: Vec<Port>,
  pub Status: String,
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct ContainerDetails {
  pub AppArmorProfile: String,
  pub Args: Vec<String>,
  pub Config: Config,
  pub Created: String,
  pub Driver: String,
  pub ExecDriver: String,
  //pub ExecIDs: ??
  pub HostConfig: HostConfig
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct HostConfig {
  pub CgroupParent: Option<String>,
  pub ContainerIDFile: String,
  pub CpuShares: Option<u64>,
  pub CpusetCpus: Option<String>,
  pub Memory: Option<u64>,
  pub MemorySwap: Option<u64>,
  pub NetworkMode: String,
  pub PidMode: Option<String>,
  //pub PortBindings: ???
  pub Privileged: bool,
  pub PublishAllPorts: bool,
  pub ReadonlyRootfs: Option<bool>
  //pub RestartPolicy: ???
  //pub SecurityOpt: Option<???>,
  //pub Ulimits: Option<???>
 // pub VolumesFrom: Option<??/>
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Config {
  AttachStderr: bool,
  AttachStdin: bool,
  AttachStdout: bool,
  Cmd: Vec<String>,
  CpuShares: u64,
  Cpuset: String,
  Domainname: String,
  Entrypoint: Vec<String>,
  Env: Vec<String>,
  //ExposedPorts
  Hostname: String,
  Image: String,
  //Labels:???
  MacAddress: String,
  Memory: u64,
  MemorySwap: u64,
  NetworkDisabled: bool,
  //OnBuild: Option<String>,
  OpenStdin: bool,
  //PortSpecs: ???,
  StdinOnce: bool,
  Tty: bool,
  User: String,
  //Volumes: ??,
  WorkingDir: String
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Port {
  pub IP: Option<String>,
  pub PrivatePort: u64,
  pub PublicPort: Option<u64>,
  pub Type: String
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct Stats {
  pub read: String,
  pub network: Network,
  pub memory_stats: MemoryStats,
  pub cpu_stats: CpuStats
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct Network {
  pub rx_dropped: u64,
  pub rx_bytes: u64,
  pub rx_errors: u64,
  pub tx_packets: u64,
  pub tx_dropped: u64,
  pub rx_packets: u64,
  pub tx_errors: u64,
  pub tx_bytes: u64
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct MemoryStats {
  pub max_usage: u64,
  pub usage: u64,
  pub failcnt: u64,
  pub limit: u64,
  pub stats: MemoryStat
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct MemoryStat {
  pub total_pgmajfault: u64,
  pub cache: u64,
  pub mapped_file: u64,
  pub total_inactive_file: u64,
  pub pgpgout: u64,
  pub rss: u64,
  pub total_mapped_file: u64,
  pub writeback: u64,
  pub unevictable: u64,
  pub pgpgin: u64,
  pub total_unevictable: u64,
  pub pgmajfault: u64,
  pub total_rss: u64,
  pub total_rss_huge: u64,
  pub total_writeback: u64,
  pub total_inactive_anon: u64,
  pub rss_huge: u64,
  pub hierarchical_memory_limit: u64,
  pub hierarchical_memsw_limit: u64,
  pub total_pgfault: u64,
  pub total_active_file: u64,
  pub active_anon: u64,
  pub total_active_anon: u64,
  pub total_pgpgout: u64,
  pub total_cache: u64,
  pub inactive_anon: u64,
  pub active_file: u64,
  pub pgfault: u64,
  pub inactive_file: u64,
  pub total_pgpgin: u64,
  pub swap: u64,
  pub total_swap: u64
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct CpuStats {
  pub cpu_usage: CpuUsage,
  pub system_cpu_usage: u64,
  pub throttling_data: ThrottlingData
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct CpuUsage {
  pub percpu_usage: Vec<u64>,
  pub usage_in_usermode: u64,
  pub total_usage: u64,
  pub usage_in_kernelmode: u64
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct ThrottlingData {
  pub periods: u64,
  pub throttled_periods: u64,
  pub throttled_time: u64
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct BlkioStats {
  pub io_service_bytes_recursive: Vec<BlkioStat>,
  pub io_serviced_recursive: Vec<BlkioStat>,
  pub io_queue_recursive: Vec<BlkioStat>,
  pub io_service_time_recursive: Vec<BlkioStat>,
  pub io_wait_time_recursive: Vec<BlkioStat>,
  pub io_merged_recursive: Vec<BlkioStat>,
  pub io_time_recursive: Vec<BlkioStat>,
  pub sectors_recursive: Vec<BlkioStat>
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct BlkioStat {
  pub major: u64,
  pub minor: u64,
  pub op: String,
  pub value: u64
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Change {
  pub Kind: u64,
  pub Path: String
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Top {
  pub Titles: Vec<String>,
  pub Processes: Vec<Vec<String>>
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Version {
  pub ApiVersion: String,
  pub Version: String,
  pub GitCommit: String,
  pub GoVersion: String
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Info {
  pub Containers: u64,
  pub Images: u64,
  pub Driver: String,
  pub DockerRootDir: String,
  pub DriverStatus: Vec<Vec<String>>,
  pub ExecutionDriver: String,
  pub ID: String,
  pub KernelVersion: String,
  //pub Labels: Option<???>,
  pub MemTotal: u64,
  pub MemoryLimit: u64,
  pub NCPU: u64,
  pub NEventsListener: u64,
  pub NGoroutines: u64,
  pub Name: String,
  pub OperatingSystem: String,
  //pub RegistryConfig:???
  pub SwapLimit: u64,
  pub SystemTime: Option<String>
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct ContainerCreateInfo {
  pub Id: String,
  pub Warnings: Option<Vec<String>>
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct History {
  pub Id: String,
  pub Created: u64,
  pub CreatedBy: String
}

#[derive(Debug, RustcEncodable, RustcDecodable)]
#[allow(non_snake_case)]
pub struct Exit {
  pub StatusCode: u64
}

<|endoftext|>