<commit_before>/* MT19937 Mersenne Twister RNG
 *
 * Official Mersenne Twister page:
 * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
 *
 * Dmitry Vasiliev <dima@hlabs.org>
 */

extern crate test;

use std::cmp::max;

static N: uint = 624;
static M: uint = 397;

struct MersenneTwister {
    state: Vec<u32>,
    index: uint
}

impl MersenneTwister {
    fn new(init_key: &[u32]) -> MersenneTwister {
        MersenneTwister{state: init_by_vec(init_key), index: N}
    }

    fn rand_u32(&mut self) -> u32 {
        if self.index >= N {
            self.init();
        }
        let mut y = self.state[self.index];
        self.index += 1;
        y ^= y >> 11;
        y ^= (y << 7) & 0x9d2c5680;
        y ^= (y << 15) & 0xefc60000;
        y ^ (y >> 18)
    }

    fn rand_f64(&mut self) -> f64 {
        self.rand_u32() as f64 / 4294967296.0
    }

    #[inline]
    fn init(&mut self) {
        for i in range(0, N) {
            let y = (self.state[i] & 0x80000000)
                    | (self.state[(i + 1) % N] & 0x7fffffff);
            self.state[i] = match y % 2 {
                0 => self.state[(i + M) % N] ^ (y >> 1),
                _ => self.state[(i + M) % N] ^ (y >> 1) ^ 0x9908b0df
            }
        }
        self.index = 0;
    }
}

#[inline]
fn init_state(seed: u32) -> Vec<u32> {
    range(0, N as u32).scan(seed, |state, i| {
        let prev = *state;
        *state = 1812433253 * (*state ^ (*state >> 30)) + i + 1;
        Some(prev)
    }).collect()
}

#[inline]
fn init_by_vec(init_key: &[u32]) -> Vec<u32> {
    let mut state = init_state(19650218);
    let len = init_key.len();
    let limit = N - 1;
    for i in range(0, max(N, len)) {
        let idx = i % limit;
        state[idx + 1] = (state[idx + 1]
            ^ ((state[idx] ^ (state[idx] >> 30)) * 1664525))
            + init_key[i % len] + (i % len) as u32;
        if (i + 1) % limit == 0 {
            state[0] = state[limit];
        }
    }

    for i in range(2, N) {
        state[i] = (state[i]
            ^ ((state[i - 1] ^ (state[i - 1] >> 30)) * 1566083941)) - i as u32;
    }

    state[1] = (state[1]
        ^ ((state[N - 1] ^ (state[N - 1] >> 30)) * 1566083941)) - 1;
    state[0] = 0x80000000;
    state
}

/*
 * Main entry point
 */
#[cfg(not(test))]
fn main() {
    let mut rng = MersenneTwister::new(&[0x123, 0x234, 0x345, 0x456]);
    for i in range(0u, 1000) {
        match i % 5 == 4 {
            false => print!("{:>10} ", rng.rand_u32()),
            true => println!("{:>10}", rng.rand_u32())
        }
    }
    println!("");
    for i in range(0u, 1000) {
        match i % 5 == 4 {
            false => print!("{:>10.8} ", rng.rand_f64()),
            true => println!("{:>10.8}", rng.rand_f64())
        }
    }
}

/*
 * Tests
 *
 * Link to the test data:
 * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/mt19937ar.out
 */
#[cfg(test)]
mod tests {
    use test::Bencher;

    use super::MersenneTwister;

    #[test]
    fn test_rand_u32() {
        let expected: [u32, ..50] = [
            1067595299, 955945823, 477289528, 4107218783, 4228976476,
            3344332714, 3355579695, 227628506, 810200273, 2591290167,
            2560260675, 3242736208, 646746669, 1479517882, 4245472273,
            1143372638, 3863670494, 3221021970, 1773610557, 1138697238,
            1421897700, 1269916527, 2859934041, 1764463362, 3874892047,
            3965319921, 72549643, 2383988930, 2600218693, 3237492380,
            2792901476, 725331109, 605841842, 271258942, 715137098,
            3297999536, 1322965544, 4229579109, 1395091102, 3735697720,
            2101727825, 3730287744, 2950434330, 1661921839, 2895579582,
            2370511479, 1004092106, 2247096681, 2111242379, 3237345263,
        ];
        let mut rng = MersenneTwister::new(&[0x123, 0x234, 0x345, 0x456]);
        for (i, &exp) in expected.iter().enumerate() {
            assert_eq!((i, exp), (i, rng.rand_u32()));
        }
    }

    #[test]
    fn test_rand_f64() {
        let expected: [f64, ..50] = [
            0.76275443, 0.99000644, 0.98670464, 0.10143112, 0.27933125,
            0.69867227, 0.94218740, 0.03427201, 0.78842173, 0.28180608,
            0.92179002, 0.20785655, 0.54534773, 0.69644020, 0.38107718,
            0.23978165, 0.65286910, 0.07514568, 0.22765211, 0.94872929,
            0.74557914, 0.62664415, 0.54708246, 0.90959343, 0.42043116,
            0.86334511, 0.19189126, 0.14718544, 0.70259889, 0.63426346,
            0.77408121, 0.04531601, 0.04605807, 0.88595519, 0.69398270,
            0.05377184, 0.61711170, 0.05565708, 0.10133577, 0.41500776,
            0.91810699, 0.22320679, 0.23353705, 0.92871862, 0.98897234,
            0.19786706, 0.80558809, 0.06961067, 0.55840445, 0.90479405,
        ];
        let mut rng = MersenneTwister::new(&[0x123, 0x234, 0x345, 0x456]);
        // For the test data we use 1000 values should be skipped
        for _ in range(0u, 1000) {
            rng.rand_f64();
        }
        for (i, &exp) in expected.iter().enumerate() {
            assert_eq!((i, true), (i, rng.rand_f64() - exp < 0.00000001f64));
        }
    }

    #[bench]
    fn bench_rand_u32(b: &mut Bencher) {
        let mut rng = MersenneTwister::new(&[0x123, 0x234, 0x345, 0x456]);
        b.iter(|| rng.rand_u32());
    }

    #[bench]
    fn bench_new(b: &mut Bencher) {
        b.iter(|| MersenneTwister::new(&[0x123, 0x234, 0x345, 0x456]));
    }
}
<commit_msg>Use variable for key index<commit_after>/* MT19937 Mersenne Twister RNG
 *
 * Official Mersenne Twister page:
 * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
 *
 * Dmitry Vasiliev <dima@hlabs.org>
 */

extern crate test;

use std::cmp::max;

static N: uint = 624;
static M: uint = 397;

struct MersenneTwister {
    state: Vec<u32>,
    index: uint
}

impl MersenneTwister {
    fn new(init_key: &[u32]) -> MersenneTwister {
        MersenneTwister{state: init_by_vec(init_key), index: N}
    }

    fn rand_u32(&mut self) -> u32 {
        if self.index >= N {
            self.init();
        }
        let mut y = self.state[self.index];
        self.index += 1;
        y ^= y >> 11;
        y ^= (y << 7) & 0x9d2c5680;
        y ^= (y << 15) & 0xefc60000;
        y ^ (y >> 18)
    }

    fn rand_f64(&mut self) -> f64 {
        self.rand_u32() as f64 / 4294967296.0
    }

    #[inline]
    fn init(&mut self) {
        for i in range(0, N) {
            let y = (self.state[i] & 0x80000000)
                    | (self.state[(i + 1) % N] & 0x7fffffff);
            self.state[i] = match y % 2 {
                0 => self.state[(i + M) % N] ^ (y >> 1),
                _ => self.state[(i + M) % N] ^ (y >> 1) ^ 0x9908b0df
            }
        }
        self.index = 0;
    }
}

#[inline]
fn init_state(seed: u32) -> Vec<u32> {
    range(0, N as u32).scan(seed, |state, i| {
        let prev = *state;
        *state = 1812433253 * (*state ^ (*state >> 30)) + i + 1;
        Some(prev)
    }).collect()
}

#[inline]
fn init_by_vec(init_key: &[u32]) -> Vec<u32> {
    let mut state = init_state(19650218);
    let len = init_key.len();
    let limit = N - 1;
    for i in range(0, max(N, len)) {
        let idx = i % limit;
        let k_idx = i % len;
        state[idx + 1] = (state[idx + 1]
            ^ ((state[idx] ^ (state[idx] >> 30)) * 1664525))
            + init_key[k_idx] + k_idx as u32;
        if (i + 1) % limit == 0 {
            state[0] = state[limit];
        }
    }
    for i in range(2, N) {
        state[i] = (state[i]
            ^ ((state[i - 1] ^ (state[i - 1] >> 30)) * 1566083941)) - i as u32;
    }
    state[1] = (state[1]
        ^ ((state[N - 1] ^ (state[N - 1] >> 30)) * 1566083941)) - 1;
    state[0] = 0x80000000;
    state
}

/*
 * Main entry point
 */
#[cfg(not(test))]
fn main() {
    let mut rng = MersenneTwister::new(&[0x123, 0x234, 0x345, 0x456]);
    for i in range(0u, 1000) {
        match i % 5 == 4 {
            false => print!("{:>10} ", rng.rand_u32()),
            true => println!("{:>10}", rng.rand_u32())
        }
    }
    println!("");
    for i in range(0u, 1000) {
        match i % 5 == 4 {
            false => print!("{:>10.8} ", rng.rand_f64()),
            true => println!("{:>10.8}", rng.rand_f64())
        }
    }
}

/*
 * Tests
 *
 * Link to the test data:
 * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/mt19937ar.out
 */
#[cfg(test)]
mod tests {
    use test::Bencher;

    use super::MersenneTwister;

    #[test]
    fn test_rand_u32() {
        let expected: [u32, ..50] = [
            1067595299, 955945823, 477289528, 4107218783, 4228976476,
            3344332714, 3355579695, 227628506, 810200273, 2591290167,
            2560260675, 3242736208, 646746669, 1479517882, 4245472273,
            1143372638, 3863670494, 3221021970, 1773610557, 1138697238,
            1421897700, 1269916527, 2859934041, 1764463362, 3874892047,
            3965319921, 72549643, 2383988930, 2600218693, 3237492380,
            2792901476, 725331109, 605841842, 271258942, 715137098,
            3297999536, 1322965544, 4229579109, 1395091102, 3735697720,
            2101727825, 3730287744, 2950434330, 1661921839, 2895579582,
            2370511479, 1004092106, 2247096681, 2111242379, 3237345263,
        ];
        let mut rng = MersenneTwister::new(&[0x123, 0x234, 0x345, 0x456]);
        for (i, &exp) in expected.iter().enumerate() {
            assert_eq!((i, exp), (i, rng.rand_u32()));
        }
    }

    #[test]
    fn test_rand_f64() {
        let expected: [f64, ..50] = [
            0.76275443, 0.99000644, 0.98670464, 0.10143112, 0.27933125,
            0.69867227, 0.94218740, 0.03427201, 0.78842173, 0.28180608,
            0.92179002, 0.20785655, 0.54534773, 0.69644020, 0.38107718,
            0.23978165, 0.65286910, 0.07514568, 0.22765211, 0.94872929,
            0.74557914, 0.62664415, 0.54708246, 0.90959343, 0.42043116,
            0.86334511, 0.19189126, 0.14718544, 0.70259889, 0.63426346,
            0.77408121, 0.04531601, 0.04605807, 0.88595519, 0.69398270,
            0.05377184, 0.61711170, 0.05565708, 0.10133577, 0.41500776,
            0.91810699, 0.22320679, 0.23353705, 0.92871862, 0.98897234,
            0.19786706, 0.80558809, 0.06961067, 0.55840445, 0.90479405,
        ];
        let mut rng = MersenneTwister::new(&[0x123, 0x234, 0x345, 0x456]);
        // For the test data we use 1000 values should be skipped
        for _ in range(0u, 1000) {
            rng.rand_f64();
        }
        for (i, &exp) in expected.iter().enumerate() {
            assert_eq!((i, true), (i, rng.rand_f64() - exp < 0.00000001f64));
        }
    }

    #[bench]
    fn bench_rand_u32(b: &mut Bencher) {
        let mut rng = MersenneTwister::new(&[0x123, 0x234, 0x345, 0x456]);
        b.iter(|| rng.rand_u32());
    }

    #[bench]
    fn bench_new(b: &mut Bencher) {
        b.iter(|| MersenneTwister::new(&[0x123, 0x234, 0x345, 0x456]));
    }
}
<|endoftext|>


<commit_before>use std::io::Cursor;
use std::io::prelude::*;
use super::parser::{Parser, ParseEvent, ParseError};
use super::lexer::Lexer;
use super::position::Position;

use super::types::*;

pub struct Figtree {
    parser: Parser,
}

impl Figtree {
    pub fn new<T: Read + 'static>(input: T) -> Self {
        Figtree {
            parser: Parser::parse(Lexer::lex(input))
        }
    }

    pub fn from_string<T>(input: T) -> Figtree where T: Into<String> {
        Figtree::new(Cursor::new(input.into().into_bytes()))
    }

    pub fn parse(&mut self) -> Result<Document, (ParseError, Position)> {
        let mut doc = Document::new();
        match self.parser.next() {
            Some(Ok((ParseEvent::FileStart, _))) => {
                if let Some(err) = self.parse_file(&mut doc) {
                    return Err(err);
                }
            }
            Some(Ok(_)) | None =>
                unreachable!("ParseEvent occurred that cannot happen at this time."),
            Some(Err(error)) =>
                return Err(error),
        }
        Ok(doc)
    }

    fn parse_file(&mut self, doc: &mut Document) -> Option<(ParseError, Position)> {
        loop {
            match self.parser.next() {
                Some(Ok((ParseEvent::NodeStart(name), _))) => {
                    if let Some(err) = self.parse_node(doc.new_node(name)) {
                        return Some(err);
                    }
                },
                Some(Ok((ParseEvent::FileEnd, _))) => {
                    return None;
                },
                Some(Ok(ev)) =>
                    unreachable!("ParseEvent {:?} occured that cannot happen at this time.", ev),
                Some(Err(error)) => { return Some(error) },
                None =>
                    unreachable!("EOF occurred that cannot happen at this time."),
            }
        }
    }

    fn parse_node(&mut self, node: &mut Node) -> Option<(ParseError, Position)> {
        loop {
            match self.parser.next() {
                Some(Ok((ParseEvent::NodeEnd, _))) => { return None; },
                Some(Ok(ev)) =>
                    unreachable!("ParseEvent {:?} occured that cannot happen at this time.", ev),
                Some(Err(error)) => { return Some(error) },
                None =>
                    unreachable!("EOF occurred that cannot happen at this time."),
            }
        }
    }
}

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

    #[test]
    fn construct_empty_file() {
        let mut figgy = Figtree::from_string("");
        let config = figgy.parse().unwrap();
        assert_eq!(config.nodes.len(), 0);
    }

    #[test]
    fn construct_empty_nodes_in_file() {
        let mut figgy = Figtree::from_string("node {} hello {}");
        let config = figgy.parse().unwrap();
        assert_eq!(config.nodes.len(), 2);
    }
}
<commit_msg>Construct nested nodes correctly<commit_after>use std::io::Cursor;
use std::io::prelude::*;
use super::parser::{Parser, ParseEvent, ParseError};
use super::lexer::Lexer;
use super::position::Position;

use super::types::*;

pub struct Figtree {
    parser: Parser,
}

impl Figtree {
    pub fn new<T: Read + 'static>(input: T) -> Self {
        Figtree {
            parser: Parser::parse(Lexer::lex(input))
        }
    }

    pub fn from_string<T>(input: T) -> Figtree where T: Into<String> {
        Figtree::new(Cursor::new(input.into().into_bytes()))
    }

    pub fn parse(&mut self) -> Result<Document, (ParseError, Position)> {
        let mut doc = Document::new();
        match self.parser.next() {
            Some(Ok((ParseEvent::FileStart, _))) => {
                if let Some(err) = self.parse_file(&mut doc) {
                    return Err(err);
                }
            }
            Some(Ok(_)) | None =>
                unreachable!("ParseEvent occurred that cannot happen at this time."),
            Some(Err(error)) =>
                return Err(error),
        }
        Ok(doc)
    }

    fn parse_file(&mut self, doc: &mut Document) -> Option<(ParseError, Position)> {
        loop {
            match self.parser.next() {
                Some(Ok((ParseEvent::NodeStart(name), _))) => {
                    if let Some(err) = self.parse_node(doc.new_node(name)) {
                        return Some(err);
                    }
                },
                Some(Ok((ParseEvent::FileEnd, _))) => {
                    return None;
                },
                Some(Ok(ev)) =>
                    unreachable!("ParseEvent {:?} occured that cannot happen at this time.", ev),
                Some(Err(error)) => { return Some(error) },
                None =>
                    unreachable!("EOF occurred that cannot happen at this time."),
            }
        }
    }

    fn parse_node(&mut self, node: &mut Node) -> Option<(ParseError, Position)> {
        loop {
            match self.parser.next() {
                Some(Ok((ParseEvent::NodeEnd, _))) => { return None; },
                Some(Ok((ParseEvent::NodeStart(name), _))) => {
                    if let Some(err) = self.parse_node(node.new_subnode(name)) {
                        return Some(err);
                    }
                },
                Some(Ok(ev)) =>
                    unreachable!("ParseEvent {:?} occured that cannot happen at this time.", ev),
                Some(Err(error)) => { return Some(error) },
                None =>
                    unreachable!("EOF occurred that cannot happen at this time."),
            }
        }
    }
}

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

    #[test]
    fn construct_empty_file() {
        let mut figgy = Figtree::from_string("");
        let config = figgy.parse().unwrap();
        assert_eq!(config.nodes.len(), 0);
    }

    #[test]
    fn construct_empty_nodes_in_file() {
        let mut figgy = Figtree::from_string("node {} hello { nested {} }");
        let config = figgy.parse().unwrap();
        assert_eq!(config.nodes.len(), 2);
    }
}
<|endoftext|>


<commit_before>//! TODO Fill in

use rustwlc::{Geometry, Point, Size, WlcOutput};
use std::fmt::{self, Display, Formatter};
use std::default::Default;
use std::rc::Rc;
use rlua::{self, Table, Lua, UserData, ToLua, Value, AnyUserData, UserDataMethods,
           MetaMethod};
use super::object::{self, Object, Objectable};
use super::property::Property;
use super::class::{self, Class, ClassBuilder};

pub const SCREENS_HANDLE: &'static str = "__screens";

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Output {
    pub name: String,
    pub mm_width: u32,
    pub mm_height: u32,
    // TODO The XID array?
}

impl From<WlcOutput> for Output {
    fn from(output: WlcOutput) -> Output {
        let resolution = output.get_resolution().unwrap();
        Output {
            name: output.get_name(),
            mm_width: resolution.w,
            mm_height: resolution.h
        }
    }
}

#[derive(Clone, Debug)]
pub struct Screen<'lua>(Object<'lua>);

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ScreenState {
    // Is this screen still valid and may be used
    pub valid: bool,
    // Screen geometry
    pub geometry: Geometry,
    // Screen workarea
    pub workarea: Geometry,
    // The screen outputs information
    pub outputs: Vec<Output>,
    // Some XID indetifying this screen
    pub xid: u32
}

impl_objectable!(Screen, ScreenState);

impl Display for ScreenState {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "Screen: {:p}", self)
    }
}

impl <'lua> ToLua<'lua> for Screen<'lua> {
    fn to_lua(self, lua: &'lua Lua) -> rlua::Result<Value<'lua>> {
        self.0.to_lua(lua)
    }
}

impl Default for ScreenState {
    fn default() -> Self {
        ScreenState {
            valid: true,
            geometry: Geometry::zero(),
            workarea: Geometry::zero(),
            outputs: vec![],
            xid: 0
        }
    }
}

impl UserData for ScreenState {
    fn add_methods(methods: &mut UserDataMethods<Self>) {
        methods.add_meta_function(MetaMethod::Index, index);
        methods.add_meta_function(MetaMethod::NewIndex, object::default_newindex);
    }
}

impl <'lua> Screen<'lua> {
    fn new(lua: &Lua) -> rlua::Result<Object> {
        let class = class::class_setup(lua, "screen")?;
        Ok(Screen::allocate(lua, class)?.build())
    }

    fn init_screens(&mut self, output: WlcOutput, outputs: Vec<Output>) -> rlua::Result<()> {
        let mut state = self.state()?;
        let resolution = output.get_resolution().unwrap();
        state.outputs = outputs;
        state.geometry.size = resolution;
        state.workarea.size = resolution;
        self.set_state(state)
    }

    fn get_geometry(&self, lua: &'lua Lua) -> rlua::Result<Table<'lua>> {
        let state = self.state()?;
        let Point { x, y } = state.geometry.origin;
        let Size { w, h } = state.geometry.size;
        let table = lua.create_table()?;
        table.set("x", x)?;
        table.set("y", y)?;
        table.set("width", w)?;
        table.set("height", h)?;
        Ok(table)
    }

    fn get_workarea(&self, lua: &'lua Lua) -> rlua::Result<Table<'lua>> {
        let state = self.state()?;
        let Point { x, y } = state.workarea.origin;
        let Size { w, h } = state.workarea.size;
        let table = lua.create_table()?;
        table.set("x", x)?;
        table.set("y", y)?;
        table.set("width", w)?;
        table.set("height", h)?;
        Ok(table)
    }
}

pub fn init(lua: &Lua) -> rlua::Result<Class> {
    let builder = Class::builder(lua, "screen", Some(Rc::new(Screen::new)), None, None)?;
    let res = property_setup(lua, method_setup(lua, builder)?)?
        .save_class("screen")?
        .build()?;
    let mut screens: Vec<Screen> = vec![];
    for output in WlcOutput::list() {
        let mut screen = Screen::cast(Screen::new(lua)?)?;
        screen.init_screens(output, vec![output.into()])?;
        // TODO Move to Screen impl like the others
        screens.push(screen);
    }
    lua.globals().set(SCREENS_HANDLE, screens.to_lua(lua)?)?;
    Ok(res)
}

fn method_setup<'lua>(lua: &'lua Lua, builder: ClassBuilder<'lua>)
                      -> rlua::Result<ClassBuilder<'lua>> {
    // TODO Do properly
    use super::dummy;
    builder.method("connect_signal".into(), lua.create_function(dummy)?)?
           .method("__call".into(), lua.create_function(iterate_over_screens)?)
}

fn property_setup<'lua>(lua: &'lua Lua, builder: ClassBuilder<'lua>)
                        -> rlua::Result<ClassBuilder<'lua>> {
    builder
        .property(Property::new("geometry".into(),
                                None,
                                Some(lua.create_function(get_geometry)?),
                                None))?
        .property(Property::new("workarea".into(),
                                None,
                                Some(lua.create_function(get_workarea)?),
                                None))
}

fn get_geometry<'lua>(lua: &'lua Lua, object: AnyUserData<'lua>) -> rlua::Result<Table<'lua>> {
    let screen = Screen::cast(object.into())?;
    screen.get_geometry(lua)
}

fn get_workarea<'lua>(lua: &'lua Lua, object: AnyUserData<'lua>) -> rlua::Result<Table<'lua>> {
    let screen = Screen::cast(object.into())?;
    screen.get_workarea(lua)
}

/// Ok this requires some explanation...
/// Lua gives us the previous value in the loop, with the first one being nil
/// since there was nothing there before.
///
/// To ensure we loop over everything, we take the index of that value in our list,
/// increment it by 1 (starting at 0 if it's the start) and then once it falls outside
/// the bounds it will stop by returning nil.
fn iterate_over_screens<'lua>(lua: &'lua Lua,
                              (_, _, prev): (Value<'lua>, Value<'lua>, Value<'lua>))
                              -> rlua::Result<Value<'lua>> {
    let screens: Vec<Screen> = lua.globals().get::<_, Vec<AnyUserData>>(SCREENS_HANDLE)?
        .into_iter().map(|obj| Screen::cast(obj.into()).unwrap())
        .collect();
    let index = match prev {
        Value::Nil => 0,
        Value::UserData(ref object) => {
            if let Ok(screen) = Screen::cast(object.clone().into()) {
                screens.iter().position(|t| t.state().unwrap() == screen.state().unwrap())
                    .unwrap_or(screens.len()) + 1
            } else {
                panic!("Unexpected non-screen table in loop");
            }
        }
        _ => panic!("Unexpected non-screen or nil value in screens loop")
    };
    if index < screens.len() {
        screens[index].clone().to_lua(lua)
    } else {
        Ok(Value::Nil)
    }

}

fn index<'lua>(lua: &'lua Lua,
               (data, index): (AnyUserData<'lua>, Value<'lua>))
               -> rlua::Result<Value<'lua>> {
    let obj: Object = data.clone().into();
    let screens: Vec<Screen> = lua.globals().get::<_, Vec<AnyUserData>>(SCREENS_HANDLE)?
        .into_iter().map(|obj| Screen::cast(obj.into()).unwrap())
        .collect();
    match index {
        Value::String(ref string) => {
            let string = string.to_str()?;
            if string == "primary" {
                // TODO Emit primary changed signal
                if screens.len() > 0 {
                    return screens[0].clone().to_lua(lua)
                }
            }
            for screen in screens.iter() {
                let screen_state = screen.state()?;
                for output in &screen_state.outputs {
                    if output.name.as_str() == string {
                        return screen.clone().to_lua(lua)
                    }
                }
            }
        },
        // TODO Might need to do Number instead
        Value::Integer(screen_index) => {
            if screen_index < 1 || screen_index as usize > screens.len() {
                return Err(rlua::Error::RuntimeError(
                    format!("invalid screen number: {} (of {} existing)",
                            screen_index, screens.len())))
            }
            return screens[(screen_index - 1) as usize].clone().to_lua(lua)
        },
        Value::UserData(ref obj) => {
            // If this is a screen, just return it
            if let Ok(screen) = Screen::cast(obj.clone().into()) {
                return screen.to_lua(lua)
            }
        },
        // TODO This checke user data like in luaA_toudata in awesome
        _ => {}
    }
    // TODO checkudata
    let table = obj.table()?;
    let meta = table.get_metatable().unwrap();
    meta.get(index.clone()).or_else(|_| super::object::default_index(lua, (data, index)))
}
<commit_msg>Handle indexing in screen properly<commit_after>//! TODO Fill in

use rustwlc::{Geometry, Point, Size, WlcOutput};
use std::fmt::{self, Display, Formatter};
use std::default::Default;
use std::rc::Rc;
use rlua::{self, Table, Lua, UserData, ToLua, Value, AnyUserData, UserDataMethods,
           MetaMethod};
use super::object::{self, Object, Objectable};
use super::property::Property;
use super::class::{self, Class, ClassBuilder};

pub const SCREENS_HANDLE: &'static str = "__screens";

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Output {
    pub name: String,
    pub mm_width: u32,
    pub mm_height: u32,
    // TODO The XID array?
}

impl From<WlcOutput> for Output {
    fn from(output: WlcOutput) -> Output {
        let resolution = output.get_resolution().unwrap();
        Output {
            name: output.get_name(),
            mm_width: resolution.w,
            mm_height: resolution.h
        }
    }
}

#[derive(Clone, Debug)]
pub struct Screen<'lua>(Object<'lua>);

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ScreenState {
    // Is this screen still valid and may be used
    pub valid: bool,
    // Screen geometry
    pub geometry: Geometry,
    // Screen workarea
    pub workarea: Geometry,
    // The screen outputs information
    pub outputs: Vec<Output>,
    // Some XID indetifying this screen
    pub xid: u32
}

impl_objectable!(Screen, ScreenState);

impl Display for ScreenState {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "Screen: {:p}", self)
    }
}

impl <'lua> ToLua<'lua> for Screen<'lua> {
    fn to_lua(self, lua: &'lua Lua) -> rlua::Result<Value<'lua>> {
        self.0.to_lua(lua)
    }
}

impl Default for ScreenState {
    fn default() -> Self {
        ScreenState {
            valid: true,
            geometry: Geometry::zero(),
            workarea: Geometry::zero(),
            outputs: vec![],
            xid: 0
        }
    }
}

impl UserData for ScreenState {
    fn add_methods(methods: &mut UserDataMethods<Self>) {
        methods.add_meta_function(MetaMethod::Index, index);
        methods.add_meta_function(MetaMethod::NewIndex, object::default_newindex);
    }
}

impl <'lua> Screen<'lua> {
    fn new(lua: &Lua) -> rlua::Result<Object> {
        let class = class::class_setup(lua, "screen")?;
        Ok(Screen::allocate(lua, class)?.build())
    }

    fn init_screens(&mut self, output: WlcOutput, outputs: Vec<Output>) -> rlua::Result<()> {
        let mut state = self.state()?;
        let resolution = output.get_resolution().unwrap();
        state.outputs = outputs;
        state.geometry.size = resolution;
        state.workarea.size = resolution;
        self.set_state(state)
    }

    fn get_geometry(&self, lua: &'lua Lua) -> rlua::Result<Table<'lua>> {
        let state = self.state()?;
        let Point { x, y } = state.geometry.origin;
        let Size { w, h } = state.geometry.size;
        let table = lua.create_table()?;
        table.set("x", x)?;
        table.set("y", y)?;
        table.set("width", w)?;
        table.set("height", h)?;
        Ok(table)
    }

    fn get_workarea(&self, lua: &'lua Lua) -> rlua::Result<Table<'lua>> {
        let state = self.state()?;
        let Point { x, y } = state.workarea.origin;
        let Size { w, h } = state.workarea.size;
        let table = lua.create_table()?;
        table.set("x", x)?;
        table.set("y", y)?;
        table.set("width", w)?;
        table.set("height", h)?;
        Ok(table)
    }
}

pub fn init(lua: &Lua) -> rlua::Result<Class> {
    let builder = Class::builder(lua, "screen", Some(Rc::new(Screen::new)), None, None)?;
    let res = property_setup(lua, method_setup(lua, builder)?)?
        .save_class("screen")?
        .build()?;
    let mut screens: Vec<Screen> = vec![];
    for output in WlcOutput::list() {
        let mut screen = Screen::cast(Screen::new(lua)?)?;
        screen.init_screens(output, vec![output.into()])?;
        // TODO Move to Screen impl like the others
        screens.push(screen);
    }
    lua.globals().set(SCREENS_HANDLE, screens.to_lua(lua)?)?;
    Ok(res)
}

fn method_setup<'lua>(lua: &'lua Lua, builder: ClassBuilder<'lua>)
                      -> rlua::Result<ClassBuilder<'lua>> {
    // TODO Do properly
    use super::dummy;
    builder.method("connect_signal".into(), lua.create_function(dummy)?)?
           .method("__call".into(), lua.create_function(iterate_over_screens)?)
}

fn property_setup<'lua>(lua: &'lua Lua, builder: ClassBuilder<'lua>)
                        -> rlua::Result<ClassBuilder<'lua>> {
    builder
        .property(Property::new("geometry".into(),
                                None,
                                Some(lua.create_function(get_geometry)?),
                                None))?
        .property(Property::new("workarea".into(),
                                None,
                                Some(lua.create_function(get_workarea)?),
                                None))
}

fn get_geometry<'lua>(lua: &'lua Lua, object: AnyUserData<'lua>) -> rlua::Result<Table<'lua>> {
    let screen = Screen::cast(object.into())?;
    screen.get_geometry(lua)
}

fn get_workarea<'lua>(lua: &'lua Lua, object: AnyUserData<'lua>) -> rlua::Result<Table<'lua>> {
    let screen = Screen::cast(object.into())?;
    screen.get_workarea(lua)
}

/// Ok this requires some explanation...
/// Lua gives us the previous value in the loop, with the first one being nil
/// since there was nothing there before.
///
/// To ensure we loop over everything, we take the index of that value in our list,
/// increment it by 1 (starting at 0 if it's the start) and then once it falls outside
/// the bounds it will stop by returning nil.
fn iterate_over_screens<'lua>(lua: &'lua Lua,
                              (_, _, prev): (Value<'lua>, Value<'lua>, Value<'lua>))
                              -> rlua::Result<Value<'lua>> {
    let screens: Vec<Screen> = lua.globals().get::<_, Vec<AnyUserData>>(SCREENS_HANDLE)?
        .into_iter().map(|obj| Screen::cast(obj.into()).unwrap())
        .collect();
    let index = match prev {
        Value::Nil => 0,
        Value::UserData(ref object) => {
            if let Ok(screen) = Screen::cast(object.clone().into()) {
                screens.iter().position(|t| t.state().unwrap() == screen.state().unwrap())
                    .unwrap_or(screens.len()) + 1
            } else {
                panic!("Unexpected non-screen table in loop");
            }
        }
        _ => panic!("Unexpected non-screen or nil value in screens loop")
    };
    if index < screens.len() {
        screens[index].clone().to_lua(lua)
    } else {
        Ok(Value::Nil)
    }

}

fn index<'lua>(lua: &'lua Lua,
               (data, index): (AnyUserData<'lua>, Value<'lua>))
               -> rlua::Result<Value<'lua>> {
    let obj: Object = data.clone().into();
    let screens: Vec<Screen> = lua.globals().get::<_, Vec<AnyUserData>>(SCREENS_HANDLE)?
        .into_iter().map(|obj| Screen::cast(obj.into()).unwrap())
        .collect();
    match index {
        Value::String(ref string) => {
            let string = string.to_str()?;
            if string == "primary" {
                // TODO Emit primary changed signal
                if screens.len() > 0 {
                    return screens[0].clone().to_lua(lua)
                }
            }
            for screen in screens.iter() {
                let screen_state = screen.state()?;
                for output in &screen_state.outputs {
                    if output.name.as_str() == string {
                        return screen.clone().to_lua(lua)
                    }
                }
            }
        },
        // TODO Might need to do Number instead
        Value::Integer(screen_index) => {
            if screen_index < 1 || screen_index as usize > screens.len() {
                return Err(rlua::Error::RuntimeError(
                    format!("invalid screen number: {} (of {} existing)",
                            screen_index, screens.len())))
            }
            return screens[(screen_index - 1) as usize].clone().to_lua(lua)
        },
        Value::UserData(ref obj) => {
            // If this is a screen, just return it
            if let Ok(screen) = Screen::cast(obj.clone().into()) {
                return screen.to_lua(lua)
            }
        },
        // TODO This checke user data like in luaA_toudata in awesome
        _ => {}
    }
    // TODO checkudata
    let table = obj.table()?;
    let meta = table.get_metatable().unwrap();
    match meta.get(index.clone()) {
        Err(_) | Ok(Value::Nil) => super::object::default_index(lua, (data, index)),
        Ok(value) => Ok(value)
    }
}
<|endoftext|>


<commit_before>use libc::{self, c_char, c_void, size_t};

use std::mem;
use std::ptr;

use num::{Integer, NumCast};
use num::traits::cast;
use std::ffi::{CStr, CString};

use error::H5Result;

pub fn string_from_cstr(string: *const c_char) -> String {
    unsafe {
        String::from_utf8_unchecked(CStr::from_ptr(string).to_bytes().to_vec())
    }
}

pub fn string_to_cstr(string: String) -> *const c_char {
    unsafe {
        CString::from_vec_unchecked(string.into_bytes()).as_ptr()
    }
}

pub fn get_h5_str<T, F>(func: F) -> H5Result<String>
                 where F: Fn(*mut c_char, size_t) -> T, T: Integer + NumCast {
    unsafe {
        let len: isize = 1 + cast::<T, isize>(func(ptr::null_mut::<c_char>(), 0)).unwrap();
        ensure!(len > 0, "negative string length in get_h5_str()");
        let buf = libc::malloc((len as size_t) * mem::size_of::<c_char>() as size_t) as *mut c_char;
        func(buf, len as size_t);
        let msg = string_from_cstr(buf);
        libc::free(buf as *mut c_void);
        Ok(msg)
    }
}

#[test]
pub fn test_get_h5_str() {
    use ffi::h5e::{H5E_type_t, H5Eget_msg, H5E_CANTOPENOBJ};
    let s = unsafe {
        get_h5_str(|msg, size| {
            H5Eget_msg(*H5E_CANTOPENOBJ, ptr::null_mut::<H5E_type_t>(), msg, size)
        }).ok().unwrap()
    };
    assert_eq!(s, "Can't open object");
}
<commit_msg>Fixed string_to_cstr to not borrow the argument, renamed to str_to_cstr<commit_after>use libc::{self, c_char, c_void, size_t};

use std::mem;
use std::ptr;

use num::{Integer, NumCast};
use num::traits::cast;
use std::ffi::{CStr, CString};

use error::H5Result;

pub fn string_from_cstr(string: *const c_char) -> String {
    unsafe {
        String::from_utf8_unchecked(CStr::from_ptr(string).to_bytes().to_vec())
    }
}

pub fn str_to_cstr(string: &str) -> *const c_char {
    unsafe {
        CString::from_vec_unchecked(string.to_string().into_bytes()).as_ptr()
    }
}

pub fn get_h5_str<T, F>(func: F) -> H5Result<String>
                 where F: Fn(*mut c_char, size_t) -> T, T: Integer + NumCast {
    unsafe {
        let len: isize = 1 + cast::<T, isize>(func(ptr::null_mut::<c_char>(), 0)).unwrap();
        ensure!(len > 0, "negative string length in get_h5_str()");
        let buf = libc::malloc((len as size_t) * mem::size_of::<c_char>() as size_t) as *mut c_char;
        func(buf, len as size_t);
        let msg = string_from_cstr(buf);
        libc::free(buf as *mut c_void);
        Ok(msg)
    }
}

#[test]
pub fn test_get_h5_str() {
    use ffi::h5e::{H5E_type_t, H5Eget_msg, H5E_CANTOPENOBJ};
    let s = unsafe {
        get_h5_str(|msg, size| {
            H5Eget_msg(*H5E_CANTOPENOBJ, ptr::null_mut::<H5E_type_t>(), msg, size)
        }).ok().unwrap()
    };
    assert_eq!(s, "Can't open object");
}
<|endoftext|>


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

//! An efficient, low-level, bindless graphics API for Rust. See [the
//! blog](http://gfx-rs.github.io/) for explanations and annotated examples.

#![feature(core, libc)]

#[macro_use]
extern crate log;
extern crate libc;

extern crate "gfx_device_gl" as device;

// public re-exports
pub use render::{Renderer, DrawError};
pub use render::batch;
pub use render::device_ext::{DeviceExt, ShaderSource, ProgramError};
pub use render::mesh::{Attribute, Mesh, VertexFormat};
pub use render::mesh::{Slice, ToSlice};
pub use render::mesh::SliceKind;
pub use render::state::{BlendPreset, DrawState};
pub use render::shade;
pub use render::target::{Frame, Plane};
pub use device::Device;
pub use device::{attrib, state, tex};
pub use device::as_byte_slice;
pub use device::{BufferHandle, BufferInfo, RawBufferHandle, ShaderHandle};
pub use device::{ProgramHandle, SurfaceHandle, TextureHandle, SamplerHandle};
pub use device::BufferUsage;
pub use device::{VertexCount, InstanceCount};
pub use device::PrimitiveType;
pub use device::draw::CommandBuffer;
pub use device::shade::{ProgramInfo, UniformValue};
pub use device::target::*;

// TODO: Remove this re-export once `gl_device` becomes a separate crate.
pub use device::gl_device::{GlDevice, GlResources};

#[path = "../render/lib.rs"] pub mod render;

/// A convenient wrapper suitable for single-threaded operation.
pub struct Graphics<D: device::Device> {
    /// Graphics device.
    pub device: D,
    /// Renderer front-end.
    pub renderer: Renderer<D>,
    /// Hidden batch context.
    context: batch::Context,
}

impl<D: device::Device> Graphics<D> {
    /// Create a new graphics wrapper.
    pub fn new(mut device: D) -> Graphics<D> {
        let rend = device.create_renderer();
        Graphics {
            device: device,
            renderer: rend,
            context: batch::Context::new(),
        }
    }

    /// Create a new ref batch.
    pub fn make_batch<T: shade::ShaderParam>(&mut self,
                      program: &ProgramHandle<GlResources>,
                      mesh: &Mesh,
                      slice: Slice,
                      state: &DrawState)
                      -> Result<batch::RefBatch<T>, batch::BatchError> {
        self.context.make_batch(program, mesh, slice, state)
    }

    /// Clear the `Frame` as the `ClearData` specifies.
    pub fn clear(&mut self, data: ClearData, mask: Mask, frame: &Frame) {
        self.renderer.clear(data, mask, frame)
    }

    /// Draw a ref batch.
    pub fn draw<'a, T: shade::ShaderParam>(&'a mut self,
                batch: &'a batch::RefBatch<T>, data: &'a T, frame: &Frame)
                -> Result<(), DrawError<batch::OutOfBounds>> {
        self.renderer.draw(&(batch, data, &self.context), frame)
    }

    /// Submit the internal command buffer and reset for the next frame.
    pub fn end_frame(&mut self) {
        self.device.submit(self.renderer.as_buffer());
        self.renderer.reset();
    }
}
<commit_msg>Reexport `Resources` in `gfx`<commit_after>// Copyright 2014 The Gfx-rs Developers.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! An efficient, low-level, bindless graphics API for Rust. See [the
//! blog](http://gfx-rs.github.io/) for explanations and annotated examples.

#![feature(core, libc)]

#[macro_use]
extern crate log;
extern crate libc;

extern crate "gfx_device_gl" as device;

// public re-exports
pub use render::{Renderer, DrawError};
pub use render::batch;
pub use render::device_ext::{DeviceExt, ShaderSource, ProgramError};
pub use render::mesh::{Attribute, Mesh, VertexFormat};
pub use render::mesh::{Slice, ToSlice};
pub use render::mesh::SliceKind;
pub use render::state::{BlendPreset, DrawState};
pub use render::shade;
pub use render::target::{Frame, Plane};
pub use device::{Device, Resources};
pub use device::{attrib, state, tex};
pub use device::as_byte_slice;
pub use device::{BufferHandle, BufferInfo, RawBufferHandle, ShaderHandle};
pub use device::{ProgramHandle, SurfaceHandle, TextureHandle, SamplerHandle};
pub use device::BufferUsage;
pub use device::{VertexCount, InstanceCount};
pub use device::PrimitiveType;
pub use device::draw::CommandBuffer;
pub use device::shade::{ProgramInfo, UniformValue};
pub use device::target::*;

// TODO: Remove this re-export once `gl_device` becomes a separate crate.
pub use device::gl_device::{GlDevice, GlResources};

#[path = "../render/lib.rs"] pub mod render;

/// A convenient wrapper suitable for single-threaded operation.
pub struct Graphics<D: device::Device> {
    /// Graphics device.
    pub device: D,
    /// Renderer front-end.
    pub renderer: Renderer<D>,
    /// Hidden batch context.
    context: batch::Context,
}

impl<D: device::Device> Graphics<D> {
    /// Create a new graphics wrapper.
    pub fn new(mut device: D) -> Graphics<D> {
        let rend = device.create_renderer();
        Graphics {
            device: device,
            renderer: rend,
            context: batch::Context::new(),
        }
    }

    /// Create a new ref batch.
    pub fn make_batch<T: shade::ShaderParam>(&mut self,
                      program: &ProgramHandle<GlResources>,
                      mesh: &Mesh,
                      slice: Slice,
                      state: &DrawState)
                      -> Result<batch::RefBatch<T>, batch::BatchError> {
        self.context.make_batch(program, mesh, slice, state)
    }

    /// Clear the `Frame` as the `ClearData` specifies.
    pub fn clear(&mut self, data: ClearData, mask: Mask, frame: &Frame) {
        self.renderer.clear(data, mask, frame)
    }

    /// Draw a ref batch.
    pub fn draw<'a, T: shade::ShaderParam>(&'a mut self,
                batch: &'a batch::RefBatch<T>, data: &'a T, frame: &Frame)
                -> Result<(), DrawError<batch::OutOfBounds>> {
        self.renderer.draw(&(batch, data, &self.context), frame)
    }

    /// Submit the internal command buffer and reset for the next frame.
    pub fn end_frame(&mut self) {
        self.device.submit(self.renderer.as_buffer());
        self.renderer.reset();
    }
}
<|endoftext|>


<commit_before>use self::Entry::*;

use std::slice;
use std::mem::swap;

pub struct FlatMap<K, V> {
    v: Vec<(K, V)>,
}

pub enum Entry<'a, K:'a, V:'a> {
    Vacant(VacantEntry<'a, K, V>),
    Occupied(OccupiedEntry<'a, K, V>),
}

pub struct VacantEntry<'a, K:'a, V:'a> {
    v: &'a mut Vec<(K, V)>,
    key: K,
    index: usize,
}

pub struct OccupiedEntry<'a, K:'a, V:'a> {
    v: &'a mut Vec<(K, V)>,
    index: usize,
}

pub struct Iter<'a, K:'a, V:'a> {
    iter: slice::Iter<'a, (K, V)>
}

impl <K: Ord, V> FlatMap<K, V> {
    pub fn new() -> FlatMap<K, V> { FlatMap{ v: vec![] } }

    pub fn with_capacity(capacity: usize) -> FlatMap<K, V> {
        FlatMap { v: Vec::with_capacity(capacity) }
    }

    /// Returns the number of elements the `VecMap` can hold without
    /// reallocating.
    ///
    /// # Examples
    ///
    /// ```
    /// use flat_map::FlatMap;
    /// let map: FlatMap<String, String> = FlatMap::with_capacity(10);
    /// assert!(map.capacity() >= 10);
    /// ```
    pub fn capacity(&self) -> usize {
        self.v.capacity()
    }

    pub fn reserve_len(&mut self, len: usize) {
        let cur_len = self.v.len();
        if len >= cur_len {
            self.v.reserve(len - cur_len);
        }
    }

    pub fn reserve_len_exact(&mut self, len: usize) {
        let cur_len = self.v.len();
        if len >= cur_len {
            self.v.reserve_exact(len - cur_len);
        }
    }

    pub fn len(&self) -> usize { self.v.len() }

    /// Return true if the map contains no elements.
    ///
    /// # Examples
    ///
    /// ```
    /// use flat_map::FlatMap;
    ///
    /// let mut a = FlatMap::new();
    /// assert!(a.is_empty());
    /// a.insert("1", "a");
    /// assert!(!a.is_empty());
    /// ```
    pub fn is_empty(&self) -> bool { self.v.is_empty() }

    pub fn insert(&mut self, key: K, mut v: V) -> Option<V> {
        match self.v[..].binary_search_by(|&(ref k, _)| { k.cmp(&key) }) {
            Err(i) => {
                self.v.insert(i, (key, v));
                None
            }
            Ok(i) => {
                let &mut (_, ref mut value) = &mut self.v[i];
                swap(value, &mut v);
                Some(v)
            }
        }
    }

    pub fn get(&self, key: &K) -> Option<&V> {
        match self.v[..].binary_search_by(|&(ref k, _)| { k.cmp(&key) }) {
            Err(_) => None,
            Ok(idx) => {
                let (_, ref v) = self.v[idx];
                Some(v)
            }
        }
    }

    /// Return Option<&mut V>.
    ///
    /// # Example
    ///
    /// ```
    /// use flat_map::FlatMap;
    ///
    /// let mut m = FlatMap::new();
    /// m.insert(1, "foo".to_string());
    /// m.get_mut(&1).unwrap().push_str("bar");
    /// assert_eq!("foobar", m.get_mut(&1).unwrap());
    /// ```
	pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
		match self.v[..].binary_search_by(|&(ref k, _)| { k.cmp(&key) }) {
			Err(_) => None,
			Ok(idx) => {
				match self.v.get_mut(idx) {
					 Some(&mut (_, ref mut v)) => Some(v),
					 _ => None,
				}
			}
		}
	}

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

    pub fn entry(&mut self, key: K) -> Entry<K, V> {
        match self.v[..].binary_search_by(|&(ref k, _)| { k.cmp(&key) }) {
            Err(i) => Vacant(VacantEntry{v: &mut self.v, key: key, index: i}),
            Ok(i) => Occupied(OccupiedEntry{v: &mut self.v, index: i}),
        }
    }

    pub fn remove(&mut self, key: &K) -> Option<V> {
        match self.v[..].binary_search_by(|&(ref k, _)| { k.cmp(&key) }) {
            Err(_) => None,
            Ok(i) => {
                let (_, value) = self.v.remove(i);
                Some(value)
            }
        }
    }

    pub fn iter<'r>(&'r self) -> Iter<'r, K, V> {
        Iter {
            iter: self.v.iter(),
        }
    }

    pub fn clear(&mut self) {
        self.v.clear()
    }
}

impl<'a, K: Ord, V> Entry<'a, K, V> {
    pub fn or_insert(self, default: V) -> &'a mut V {
        match self {
            Occupied(entry) => entry.into_mut(),
            Vacant(entry) => entry.insert(default),
        }
    }

    pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
        match self {
            Occupied(entry) => entry.into_mut(),
            Vacant(entry) => entry.insert(default()),
        }
    }
}

impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
    pub fn insert(mut self, value: V) -> &'a mut V {
        self.v.insert(self.index, (self.key, value));
        let &mut (_, ref mut value) = &mut self.v[self.index];
        value
    }
}

impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
    pub fn get(&self) -> &V {
        let (_, ref value) = self.v[self.index];
        value
    }

    pub fn into_mut(self) -> &'a mut V {
        let &mut (_, ref mut value) = &mut self.v[self.index];
        value
    }

    pub fn remove(self) -> V {
        let (_, value) = self.v.remove(self.index);
        value
    }
}

impl<'a, K, V> Iterator for Iter<'a, K, V> {
    type Item = &'a (K, V);

    #[inline]
    fn next(&mut self) -> Option<&'a (K, V)> {
        self.iter.next()
    }
    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}
<commit_msg>Implement Borrow for key parameters:<commit_after>use self::Entry::*;

use std::slice;
use std::mem::swap;
use std::borrow::Borrow;

pub struct FlatMap<K, V> {
    v: Vec<(K, V)>,
}

pub enum Entry<'a, K:'a, V:'a> {
    Vacant(VacantEntry<'a, K, V>),
    Occupied(OccupiedEntry<'a, K, V>),
}

pub struct VacantEntry<'a, K:'a, V:'a> {
    v: &'a mut Vec<(K, V)>,
    key: K,
    index: usize,
}

pub struct OccupiedEntry<'a, K:'a, V:'a> {
    v: &'a mut Vec<(K, V)>,
    index: usize,
}

pub struct Iter<'a, K:'a, V:'a> {
    iter: slice::Iter<'a, (K, V)>
}

impl <K: Ord, V> FlatMap<K, V> {
    pub fn new() -> FlatMap<K, V> { FlatMap{ v: vec![] } }

    pub fn with_capacity(capacity: usize) -> FlatMap<K, V> {
        FlatMap { v: Vec::with_capacity(capacity) }
    }

    /// Returns the number of elements the `VecMap` can hold without
    /// reallocating.
    ///
    /// # Examples
    ///
    /// ```
    /// use flat_map::FlatMap;
    /// let map: FlatMap<String, String> = FlatMap::with_capacity(10);
    /// assert!(map.capacity() >= 10);
    /// ```
    pub fn capacity(&self) -> usize {
        self.v.capacity()
    }

    pub fn reserve_len(&mut self, len: usize) {
        let cur_len = self.v.len();
        if len >= cur_len {
            self.v.reserve(len - cur_len);
        }
    }

    pub fn reserve_len_exact(&mut self, len: usize) {
        let cur_len = self.v.len();
        if len >= cur_len {
            self.v.reserve_exact(len - cur_len);
        }
    }

    pub fn len(&self) -> usize { self.v.len() }

    /// Return true if the map contains no elements.
    ///
    /// # Examples
    ///
    /// ```
    /// use flat_map::FlatMap;
    ///
    /// let mut a = FlatMap::new();
    /// assert!(a.is_empty());
    /// a.insert("1", "a");
    /// assert!(!a.is_empty());
    /// ```
    pub fn is_empty(&self) -> bool { self.v.is_empty() }

    pub fn insert(&mut self, key: K, mut v: V) -> Option<V> {
        match self.v[..].binary_search_by(|&(ref k, _)| { k.cmp(&key) }) {
            Err(i) => {
                self.v.insert(i, (key, v));
                None
            }
            Ok(i) => {
                let &mut (_, ref mut value) = &mut self.v[i];
                swap(value, &mut v);
                Some(v)
            }
        }
    }

    pub fn get<Q: ?Sized>(&self, q: &Q) -> Option<&V>
        where K: Borrow<Q>, Q: Ord
    {
        match self.v[..].binary_search_by(|&(ref k, _)| { k.borrow().cmp(&q) }) {
            Err(_) => None,
            Ok(idx) => {
                let (_, ref v) = self.v[idx];
                Some(v)
            }
        }
    }

    /// Return Option<&mut V>.
    ///
    /// # Example
    ///
    /// ```
    /// use flat_map::FlatMap;
    ///
    /// let mut m = FlatMap::new();
    /// m.insert(1, "foo".to_string());
    /// m.get_mut(&1).unwrap().push_str("bar");
    /// assert_eq!("foobar", m.get_mut(&1).unwrap());
    /// ```
    pub fn get_mut<Q: ?Sized>(&mut self, q: &Q) -> Option<&mut V>
        where K: Borrow<Q>, Q: Ord
    {
	match self.v[..].binary_search_by(|&(ref k, _)| { k.borrow().cmp(&q) }) {
	    Err(_) => None,
	    Ok(idx) => {
		match self.v.get_mut(idx) {
		    Some(&mut (_, ref mut v)) => Some(v),
		    _ => None,
		}
	    }
	}
    }

    pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
        where K: Borrow<Q>, Q: Ord
    {
        self.get(k).is_some()
    }

    pub fn entry(&mut self, key: K) -> Entry<K, V> {
        match self.v[..].binary_search_by(|&(ref k, _)| { k.cmp(&key) }) {
            Err(i) => Vacant(VacantEntry{v: &mut self.v, key: key, index: i}),
            Ok(i) => Occupied(OccupiedEntry{v: &mut self.v, index: i}),
        }
    }

    pub fn remove<Q: ?Sized>(&mut self, q: &Q) -> Option<V>
        where K: Borrow<Q>, Q: Ord
    {
        match self.v[..].binary_search_by(|&(ref k, _)| { k.borrow().cmp(&q) }) {
            Err(_) => None,
            Ok(i) => {
                let (_, value) = self.v.remove(i);
                Some(value)
            }
        }
    }

    pub fn iter<'r>(&'r self) -> Iter<'r, K, V> {
        Iter {
            iter: self.v.iter(),
        }
    }

    pub fn clear(&mut self) {
        self.v.clear()
    }
}

impl<'a, K: Ord, V> Entry<'a, K, V> {
    pub fn or_insert(self, default: V) -> &'a mut V {
        match self {
            Occupied(entry) => entry.into_mut(),
            Vacant(entry) => entry.insert(default),
        }
    }

    pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
        match self {
            Occupied(entry) => entry.into_mut(),
            Vacant(entry) => entry.insert(default()),
        }
    }
}

impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
    pub fn insert(mut self, value: V) -> &'a mut V {
        self.v.insert(self.index, (self.key, value));
        let &mut (_, ref mut value) = &mut self.v[self.index];
        value
    }
}

impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
    pub fn get(&self) -> &V {
        let (_, ref value) = self.v[self.index];
        value
    }

    pub fn into_mut(self) -> &'a mut V {
        let &mut (_, ref mut value) = &mut self.v[self.index];
        value
    }

    pub fn remove(self) -> V {
        let (_, value) = self.v.remove(self.index);
        value
    }
}

impl<'a, K, V> Iterator for Iter<'a, K, V> {
    type Item = &'a (K, V);

    #[inline]
    fn next(&mut self) -> Option<&'a (K, V)> {
        self.iter.next()
    }
    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}
<|endoftext|>


<commit_before>use ast::*;
use name::*;
use expr::*;

/// Parse a declaration as a statement.
named!(pub statement<&[u8], Statement>,
    alt!(
        map!(declaration, Statement::Declaration) | macro_call | if_else
    )
);

// Parse a list of 0 or more statements.
named!(pub statement_list<&[u8], Vec<Statement>>, many0!(statement));

/// Parse either a block or symbol declaration.
named!(pub declaration<&[u8], Declaration>,
    alt!(
        block_declaration
        | macro_declaration
        | symbol_declaration
    )
);

/// Parse a single named `Symbol` declaration.
named!(pub symbol_declaration<&[u8], Declaration>,
    ws!(do_parse!(
        qualifier: type_specifier >>
        name: identifier >>
        initializer: opt!(preceded!(tag!("="), expr)) >>
        char!(';') >>

        (Declaration::Symbol {qualifier, name, initializer})
    ))
);

/// Parse a `block` or `optional` container, named by an `Identifer` and containing
/// a list of 0 or more `Statement`s.
named!(pub block_declaration<&[u8], Declaration>,
    ws!(do_parse!(
        is_abstract: opt!(tag!("abstract")) >>
        qualifier: type_specifier >>
        name: identifier >>
        char!('{') >>
        statements: many0!(statement) >>
        char!('}') >>

        (Declaration::Block {
            is_abstract: is_abstract.is_some(),
            qualifier,
            name,
            statements
        })
    ))
);

named!(pub macro_declaration<&[u8], Declaration>,
    ws!(do_parse!(
        tag!("macro") >>
        name: identifier >>
        parameters: delimited!(tag!("("), macro_param_list, tag!(")")) >>
        tag!("{") >>
        statements: statement_list >>
        tag!("}") >>

        (Declaration::Macro {
            name,
            parameters,
            statements
        })
    ))
);

named!(pub macro_param_list<&[u8], Vec<MacroParameter>>,
    ws!(do_parse!(
        first_param: macro_param >>
        rest_params: many0!(ws!(do_parse!(char!(',') >> param: macro_param >> (param)))) >>

        ({
            let mut params = rest_params.clone();
            params.insert(0, first_param);

            params
        })
    ))
);

named!(pub macro_param<&[u8], MacroParameter>,
    ws!(do_parse!(
        qualifier: type_specifier >>
        name: identifier >>

        (MacroParameter {
            qualifier, name
        })
    ))
);

named!(pub macro_call<&[u8], Statement>,
    ws!(do_parse!(
        name: identifier >>
        arguments: delimited!(tag!("("), macro_argument_list, tag!(")")) >>
        tag!(";") >>

        (Statement::MacroCall(name, arguments))
    ))
);

named!(pub macro_argument_list<&[u8], Vec<Expr>>,
    ws!(do_parse!(
        first_param: expr >>
        rest_params: many0!(ws!(do_parse!(char!(',') >> param: expr >> (param)))) >>

        ({
            let mut params = rest_params.clone();
            params.insert(0, first_param);

            params
        })
    ))
);

named!(pub if_else<Statement>,
    ws!(do_parse!(
        tag!("if") >>
        condition: expr >>
        then_block: delimited!(char!('{'), statement_list, char!('}')) >>
        else_ifs: many0!(else_if) >>
        else_block: opt!(complete!(do_parse!(tag!("else") >> block: delimited!(char!('{'), statement_list, char!('}')) >> (block)))) >>

        (Statement::IfElse {
            condition,
            then_block,
            else_ifs,
            else_block,
        })
    ))
);

named!(pub else_if<(Expr, Vec<Statement>)>,
    ws!(do_parse!(
        tag!("elseif") >>
        condition: expr >>
        tag!("{") >>
        then_block: statement_list >>
        tag!("}") >>

        (condition, then_block)
    ))
);

#[cfg(test)]
mod tests {

    use super::*;
    use testing::parse;

    #[test]
    pub fn parse_block_decl() {
        let result = parse::<Declaration, _>("abstract block abc {}", block_declaration);

        match result {
            Declaration::Block {
                is_abstract,
                qualifier,
                name,
                ..
            } => {
                assert_eq!(true, is_abstract);
                assert_eq!("abc", name);
                assert_eq!(BlockType::Block, qualifier);
            }
            _ => panic!("Invalid value"),
        }
    }

    #[test]
    pub fn parse_abstract_block_decl() {
        let result = parse::<Declaration, _>("abstract block abc {}", block_declaration);

        match result {
            Declaration::Block { is_abstract, .. } => assert_eq!(true, is_abstract),
            _ => panic!("Invalid value"),
        }
    }

    #[test]
    pub fn parse_symbol_decl() {
        let result = parse::<Declaration, _>("type_attribute my_type;", symbol_declaration);

        match result {
            Declaration::Symbol {
                qualifier,
                name,
                initializer,
            } => {
                assert_eq!(SymbolType::TypeAttribute, qualifier);
                assert_eq!("my_type", name);
                assert_eq!(None, initializer)
            }
            _ => panic!("Invalid value parsed"),
        }
    }

    #[test]
    pub fn parse_symbol_decl_with_initializer() {
        let result = parse::<Declaration, _>(
            "context my_context = user:role:type:s0-s1;",
            symbol_declaration,
        );

        match result {
            Declaration::Symbol { qualifier, name, .. } => {
                assert_eq!(SymbolType::Context, qualifier);
                assert_eq!("my_context", name);

                match initializer {
                    Some(Expr::Context {
                             user_id,
                             role_id,
                             type_id,
                             level_range,
                         }) => {}
                    _ => panic!("No initializer found"),
                }
            }
            _ => panic!("Invalid value parsed"),
        }
    }

    #[test]
    pub fn parse_macro_decl() {
        let result = parse::<Declaration, _>(
            "macro my_macro(type v, type v1) {

            }",
            macro_declaration,
        );

        match result {
            Declaration::Macro { name, parameters, .. } => {
                assert_eq!("my_macro", name);
                assert_eq!("v", parameters[0].name);
                assert_eq!("v1", parameters[1].name);
            }
            _ => panic!("Invalid value parsed"),
        }
    }

    #[test]
    pub fn parse_macro_call() {
        let result = parse::<Statement, _>("my_macro(type_name);", macro_call);

        if let Statement::MacroCall(ref name, ref params) = result {
            assert_eq!("my_macro", name);
            assert_eq!(Expr::var("type_name"), params[0])
        } else {
            panic!("Invalid value parsed");
        }
    }

    #[test]
    pub fn parse_if_then_else() {
        let result = parse::<Statement, _>("if my_bool {} else{}", if_else);

        match result {
            Statement::IfElse {
                condition,
                else_block,
                ..
            } => {
                assert_eq!(Expr::var("my_bool"), condition);
                assert_eq!(Some(vec![]), else_block);
            }
            _ => panic!("Invalid value parsed"),
        }
    }

    #[test]
    pub fn parse_if() {
        let result = parse::<Statement, _>("if my_bool {}", if_else);

        match result {
            Statement::IfElse {
                condition,
                else_block,
                ..
            } => {
                assert_eq!(Expr::var("my_bool"), condition);
                assert_eq!(None, else_block);
            }
            _ => panic!("Invalid value parsed"),
        }
    }
}<commit_msg>Fix failing test<commit_after>use ast::*;
use name::*;
use expr::*;

/// Parse a declaration as a statement.
named!(pub statement<&[u8], Statement>,
    alt!(
        map!(declaration, Statement::Declaration) | macro_call | if_else
    )
);

// Parse a list of 0 or more statements.
named!(pub statement_list<&[u8], Vec<Statement>>, many0!(statement));

/// Parse either a block or symbol declaration.
named!(pub declaration<&[u8], Declaration>,
    alt!(
        block_declaration
        | macro_declaration
        | symbol_declaration
    )
);

/// Parse a single named `Symbol` declaration.
named!(pub symbol_declaration<&[u8], Declaration>,
    ws!(do_parse!(
        qualifier: type_specifier >>
        name: identifier >>
        initializer: opt!(preceded!(tag!("="), expr)) >>
        char!(';') >>

        (Declaration::Symbol {qualifier, name, initializer})
    ))
);

/// Parse a `block` or `optional` container, named by an `Identifer` and containing
/// a list of 0 or more `Statement`s.
named!(pub block_declaration<&[u8], Declaration>,
    ws!(do_parse!(
        is_abstract: opt!(tag!("abstract")) >>
        qualifier: type_specifier >>
        name: identifier >>
        char!('{') >>
        statements: many0!(statement) >>
        char!('}') >>

        (Declaration::Block {
            is_abstract: is_abstract.is_some(),
            qualifier,
            name,
            statements
        })
    ))
);

named!(pub macro_declaration<&[u8], Declaration>,
    ws!(do_parse!(
        tag!("macro") >>
        name: identifier >>
        parameters: delimited!(tag!("("), macro_param_list, tag!(")")) >>
        tag!("{") >>
        statements: statement_list >>
        tag!("}") >>

        (Declaration::Macro {
            name,
            parameters,
            statements
        })
    ))
);

named!(pub macro_param_list<&[u8], Vec<MacroParameter>>,
    ws!(do_parse!(
        first_param: macro_param >>
        rest_params: many0!(ws!(do_parse!(char!(',') >> param: macro_param >> (param)))) >>

        ({
            let mut params = rest_params.clone();
            params.insert(0, first_param);

            params
        })
    ))
);

named!(pub macro_param<&[u8], MacroParameter>,
    ws!(do_parse!(
        qualifier: type_specifier >>
        name: identifier >>

        (MacroParameter {
            qualifier, name
        })
    ))
);

named!(pub macro_call<&[u8], Statement>,
    ws!(do_parse!(
        name: identifier >>
        arguments: delimited!(tag!("("), macro_argument_list, tag!(")")) >>
        tag!(";") >>

        (Statement::MacroCall(name, arguments))
    ))
);

named!(pub macro_argument_list<&[u8], Vec<Expr>>,
    ws!(do_parse!(
        first_param: expr >>
        rest_params: many0!(ws!(do_parse!(char!(',') >> param: expr >> (param)))) >>

        ({
            let mut params = rest_params.clone();
            params.insert(0, first_param);

            params
        })
    ))
);

named!(pub if_else<Statement>,
    ws!(do_parse!(
        tag!("if") >>
        condition: expr >>
        then_block: delimited!(char!('{'), statement_list, char!('}')) >>
        else_ifs: many0!(else_if) >>
        else_block: opt!(complete!(do_parse!(tag!("else") >> block: delimited!(char!('{'), statement_list, char!('}')) >> (block)))) >>

        (Statement::IfElse {
            condition,
            then_block,
            else_ifs,
            else_block,
        })
    ))
);

named!(pub else_if<(Expr, Vec<Statement>)>,
    ws!(do_parse!(
        tag!("elseif") >>
        condition: expr >>
        tag!("{") >>
        then_block: statement_list >>
        tag!("}") >>

        (condition, then_block)
    ))
);

#[cfg(test)]
mod tests {

    use super::*;
    use testing::parse;

    #[test]
    pub fn parse_block_decl() {
        let result = parse::<Declaration, _>("abstract block abc {}", block_declaration);

        match result {
            Declaration::Block {
                is_abstract,
                qualifier,
                name,
                ..
            } => {
                assert_eq!(true, is_abstract);
                assert_eq!("abc", name);
                assert_eq!(BlockType::Block, qualifier);
            }
            _ => panic!("Invalid value"),
        }
    }

    #[test]
    pub fn parse_abstract_block_decl() {
        let result = parse::<Declaration, _>("abstract block abc {}", block_declaration);

        match result {
            Declaration::Block { is_abstract, .. } => assert_eq!(true, is_abstract),
            _ => panic!("Invalid value"),
        }
    }

    #[test]
    pub fn parse_symbol_decl() {
        let result = parse::<Declaration, _>("type_attribute my_type;", symbol_declaration);

        match result {
            Declaration::Symbol {
                qualifier,
                name,
                initializer,
            } => {
                assert_eq!(SymbolType::TypeAttribute, qualifier);
                assert_eq!("my_type", name);
                assert_eq!(None, initializer)
            }
            _ => panic!("Invalid value parsed"),
        }
    }

    #[test]
    pub fn parse_symbol_decl_with_initializer() {
        let result = parse::<Declaration, _>(
            "context my_context = user:role:type:s0-s1;",
            symbol_declaration,
        );

        match result {
            Declaration::Symbol {
                qualifier,
                name,
                initializer,
            } => {
                assert_eq!(SymbolType::Context, qualifier);
                assert_eq!("my_context", name);

                match initializer {
                    Some(Expr::Context {
                             user_id,
                             role_id,
                             type_id,
                             level_range,
                         }) => {}
                    _ => panic!("No initializer found"),
                }
            }
            _ => panic!("Invalid value parsed"),
        }
    }

    #[test]
    pub fn parse_macro_decl() {
        let result = parse::<Declaration, _>(
            "macro my_macro(type v, type v1) {

            }",
            macro_declaration,
        );

        match result {
            Declaration::Macro { name, parameters, .. } => {
                assert_eq!("my_macro", name);
                assert_eq!("v", parameters[0].name);
                assert_eq!("v1", parameters[1].name);
            }
            _ => panic!("Invalid value parsed"),
        }
    }

    #[test]
    pub fn parse_macro_call() {
        let result = parse::<Statement, _>("my_macro(type_name);", macro_call);

        if let Statement::MacroCall(ref name, ref params) = result {
            assert_eq!("my_macro", name);
            assert_eq!(Expr::var("type_name"), params[0])
        } else {
            panic!("Invalid value parsed");
        }
    }

    #[test]
    pub fn parse_if_then_else() {
        let result = parse::<Statement, _>("if my_bool {} else{}", if_else);

        match result {
            Statement::IfElse {
                condition,
                else_block,
                ..
            } => {
                assert_eq!(Expr::var("my_bool"), condition);
                assert_eq!(Some(vec![]), else_block);
            }
            _ => panic!("Invalid value parsed"),
        }
    }

    #[test]
    pub fn parse_if() {
        let result = parse::<Statement, _>("if my_bool {}", if_else);

        match result {
            Statement::IfElse {
                condition,
                else_block,
                ..
            } => {
                assert_eq!(Expr::var("my_bool"), condition);
                assert_eq!(None, else_block);
            }
            _ => panic!("Invalid value parsed"),
        }
    }
}<|endoftext|>


<commit_before>use indy_context::IndyContext;
use command_executor::{Command, CommandMetadata, Group as GroupTrait, GroupMetadata};
use commands::{get_opt_bool_param, get_opt_str_param, get_str_param};

use libindy::did::Did;

use serde_json::Value as JSONValue;
use serde_json::Map as JSONMap;

use std::collections::HashMap;
use std::rc::Rc;

pub struct Group {
    metadata: GroupMetadata
}

impl Group {
    pub fn new() -> Group {
        Group {
            metadata: GroupMetadata::new("did", "Identity management commands")
        }
    }
}

impl GroupTrait for Group {
    fn metadata(&self) -> &GroupMetadata {
        &self.metadata
    }
}

#[derive(Debug)]
pub struct NewCommand {
    ctx: Rc<IndyContext>,
    metadata: CommandMetadata,
}

#[derive(Debug)]
pub struct UseCommand {
    ctx: Rc<IndyContext>,
    metadata: CommandMetadata,
}

impl NewCommand {
    pub fn new(ctx: Rc<IndyContext>) -> NewCommand {
        NewCommand {
            ctx,
            metadata: CommandMetadata::build("new", "Create new DID")
                .add_param("did", true, "Known DID for new wallet instance")
                .add_param("seed", true, "Seed for creating DID key-pair")
                .add_param("cid", true, "Create DID as CID (default false)")
                .add_param("metadata", true, "DID metadata")
                .add_param("publish_to_ledger", true, "Send DID to ledger from current DID")
                .finalize()
        }
    }
}

impl Command for NewCommand {
    fn execute(&self, params: &HashMap<&'static str, &str>) -> Result<(), ()> {
        trace!("NewCommand::execute >> self {:?} params {:?}", self, params);

        let wallet_handle = if let Some(wallet_handle) = self.ctx.get_opened_wallet_handle() {
            wallet_handle
        } else {
            return Err(println_err!("There is no opened wallet"));
        };

        let did = get_opt_str_param("did", params).map_err(error_err!())?;
        let seed = get_opt_str_param("seed", params).map_err(error_err!())?;
        let cid = get_opt_bool_param("cid", params).map_err(error_err!())?;
        let metadata = get_opt_str_param("metadata", params).map_err(error_err!())?;
        let publish_to_ledger = get_opt_bool_param("publish_to_ledger", params).map_err(error_err!())?;

        let config = {
            let mut json = JSONMap::new();
            update_json_map_opt_key!(json, "did", did);
            update_json_map_opt_key!(json, "seed", seed);
            update_json_map_opt_key!(json, "cid", cid);
            update_json_map_opt_key!(json, "metadata", metadata);
            update_json_map_opt_key!(json, "publish_to_ledger", publish_to_ledger);
            JSONValue::from(json).to_string()
        };

        trace!(r#"Did::new try: config {:?}"#, config);

        let res = Did::new(wallet_handle, config.as_str());

        trace!(r#"Did::new return: {:?}"#, res);

        let res = match res {
            Ok((did, vk)) => Ok(println_succ!("Did \"{}\" has been created with \"{}\" verkey", did, vk)),
            Err(err) => Err(println_err!("Did create failed with unexpected Indy SDK error {:?}", err)),
        };

        //TODO implement sending did

        trace!("NewCommand::execute << {:?}", res);
        res
    }

    fn metadata(&self) -> &CommandMetadata {
        &self.metadata
    }
}

impl UseCommand {
    pub fn new(ctx: Rc<IndyContext>) -> UseCommand {
        UseCommand {
            ctx,
            metadata: CommandMetadata::build("use", "Use DID")
                .add_main_param("did", "Did stored in wallet")
                .finalize()
        }
    }
}

impl Command for UseCommand {
    fn execute(&self, params: &HashMap<&'static str, &str>) -> Result<(), ()> {
        trace!("UseCommand::execute >> self {:?} params {:?}", self, params);

        let did = get_str_param("did", params).map_err(error_err!())?;

        self.ctx.set_active_did(did);

        println_succ!("Did \"{}\" has been set as active", did);

        trace!("UseCommand::execute << {:?}", ());
        Ok(())
    }

    fn metadata(&self) -> &CommandMetadata {
        &self.metadata
    }
}<commit_msg>[cli] Remove publish_to_ledger flag for DID new command.<commit_after>use indy_context::IndyContext;
use command_executor::{Command, CommandMetadata, Group as GroupTrait, GroupMetadata};
use commands::{get_opt_bool_param, get_opt_str_param, get_str_param};

use libindy::did::Did;

use serde_json::Value as JSONValue;
use serde_json::Map as JSONMap;

use std::collections::HashMap;
use std::rc::Rc;

pub struct Group {
    metadata: GroupMetadata
}

impl Group {
    pub fn new() -> Group {
        Group {
            metadata: GroupMetadata::new("did", "Identity management commands")
        }
    }
}

impl GroupTrait for Group {
    fn metadata(&self) -> &GroupMetadata {
        &self.metadata
    }
}

#[derive(Debug)]
pub struct NewCommand {
    ctx: Rc<IndyContext>,
    metadata: CommandMetadata,
}

#[derive(Debug)]
pub struct UseCommand {
    ctx: Rc<IndyContext>,
    metadata: CommandMetadata,
}

impl NewCommand {
    pub fn new(ctx: Rc<IndyContext>) -> NewCommand {
        NewCommand {
            ctx,
            metadata: CommandMetadata::build("new", "Create new DID")
                .add_param("did", true, "Known DID for new wallet instance")
                .add_param("seed", true, "Seed for creating DID key-pair")
                .add_param("cid", true, "Create DID as CID (default false)")
                .add_param("metadata", true, "DID metadata")
                .finalize()
        }
    }
}

impl Command for NewCommand {
    fn execute(&self, params: &HashMap<&'static str, &str>) -> Result<(), ()> {
        trace!("NewCommand::execute >> self {:?} params {:?}", self, params);

        let wallet_handle = if let Some(wallet_handle) = self.ctx.get_opened_wallet_handle() {
            wallet_handle
        } else {
            return Err(println_err!("There is no opened wallet"));
        };

        let did = get_opt_str_param("did", params).map_err(error_err!())?;
        let seed = get_opt_str_param("seed", params).map_err(error_err!())?;
        let cid = get_opt_bool_param("cid", params).map_err(error_err!())?;
        let metadata = get_opt_str_param("metadata", params).map_err(error_err!())?;

        let config = {
            let mut json = JSONMap::new();
            update_json_map_opt_key!(json, "did", did);
            update_json_map_opt_key!(json, "seed", seed);
            update_json_map_opt_key!(json, "cid", cid);
            update_json_map_opt_key!(json, "metadata", metadata);
            JSONValue::from(json).to_string()
        };

        trace!(r#"Did::new try: config {:?}"#, config);

        let res = Did::new(wallet_handle, config.as_str());

        trace!(r#"Did::new return: {:?}"#, res);

        let res = match res {
            Ok((did, vk)) => Ok(println_succ!("Did \"{}\" has been created with \"{}\" verkey", did, vk)),
            Err(err) => Err(println_err!("Did create failed with unexpected Indy SDK error {:?}", err)),
        };

        trace!("NewCommand::execute << {:?}", res);
        res
    }

    fn metadata(&self) -> &CommandMetadata {
        &self.metadata
    }
}

impl UseCommand {
    pub fn new(ctx: Rc<IndyContext>) -> UseCommand {
        UseCommand {
            ctx,
            metadata: CommandMetadata::build("use", "Use DID")
                .add_main_param("did", "Did stored in wallet")
                .finalize()
        }
    }
}

impl Command for UseCommand {
    fn execute(&self, params: &HashMap<&'static str, &str>) -> Result<(), ()> {
        trace!("UseCommand::execute >> self {:?} params {:?}", self, params);

        let did = get_str_param("did", params).map_err(error_err!())?;

        self.ctx.set_active_did(did);

        println_succ!("Did \"{}\" has been set as active", did);

        trace!("UseCommand::execute << {:?}", ());
        Ok(())
    }

    fn metadata(&self) -> &CommandMetadata {
        &self.metadata
    }
}<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// Use of this source code is governed by an MIT-style license that can be found
// in the LICENSE file or at https://opensource.org/licenses/MIT.
use std::time::{Duration, SystemTime, UNIX_EPOCH};

use log::error;

pub struct Response {
    boot_time: SystemTime,
}

impl super::Response for Response {

    const RDF_NAME: Option<&'static str> = Some("StartupInfo");

    type Proto = rrg_proto::StartupInfo;

    fn into_proto(self) -> rrg_proto::StartupInfo {
        let boot_time_micros = match rrg_proto::micros(self.boot_time) {
            Ok(boot_time_micros) => boot_time_micros,
            Err(error) => {
                error!("failed to convert boot time: {}", error);
                0
            }
        };

        rrg_proto::StartupInfo {
            client_info: None,
            boot_time: Some(boot_time_micros),
        }
    }
}

pub fn handle(_: ()) -> Result<Response, super::Error> {
    Ok(Response {
        boot_time: boot_time()?,
    })
}

fn boot_time() -> Result<SystemTime, sys_info::Error> {
    let timeval = sys_info::boottime()?;

    let secs = timeval.tv_sec as u64;
    let micros = timeval.tv_usec as u64;

    Ok(UNIX_EPOCH + Duration::from_secs(secs) + Duration::from_micros(micros))
}
<commit_msg>Make startup action provide more metadata.<commit_after>// Copyright 2020 Google LLC
//
// Use of this source code is governed by an MIT-style license that can be found
// in the LICENSE file or at https://opensource.org/licenses/MIT.
use std::time::{Duration, SystemTime, UNIX_EPOCH};

use log::error;

pub struct Response {
    boot_time: SystemTime,
    name: String,
    description: String,
    version: Version,
}

impl super::Response for Response {

    const RDF_NAME: Option<&'static str> = Some("StartupInfo");

    type Proto = rrg_proto::StartupInfo;

    fn into_proto(self) -> rrg_proto::StartupInfo {
        let boot_time_micros = match rrg_proto::micros(self.boot_time) {
            Ok(boot_time_micros) => boot_time_micros,
            Err(error) => {
                error!("failed to convert boot time: {}", error);
                0
            }
        };

        rrg_proto::StartupInfo {
            client_info: Some(rrg_proto::ClientInformation {
                client_name: Some(self.name),
                client_version: Some(self.version.as_numeric()),
                client_description: Some(self.description),
                ..Default::default()
            }),
            boot_time: Some(boot_time_micros),
        }
    }
}

pub fn handle(_: ()) -> Result<Response, super::Error> {
    Ok(Response {
        boot_time: boot_time()?,
        name: String::from(env!("CARGO_PKG_NAME")),
        description: String::from(env!("CARGO_PKG_DESCRIPTION")),
        version: Version::from_crate(),
    })
}

fn boot_time() -> Result<SystemTime, sys_info::Error> {
    let timeval = sys_info::boottime()?;

    let secs = timeval.tv_sec as u64;
    let micros = timeval.tv_usec as u64;

    Ok(UNIX_EPOCH + Duration::from_secs(secs) + Duration::from_micros(micros))
}

pub struct Version {
    pub major: u8,
    pub minor: u8,
    pub patch: u8,
    pub revision: u8,
}

impl Version {

    fn from_crate() -> Version {
        Version {
            major: env!("CARGO_PKG_VERSION_MAJOR").parse().unwrap_or(0),
            minor: env!("CARGO_PKG_VERSION_MINOR").parse().unwrap_or(0),
            patch: env!("CARGO_PKG_VERSION_PATCH").parse().unwrap_or(0),
            revision: env!("CARGO_PKG_VERSION_PRE").parse().unwrap_or(0),
        }
    }

    fn as_numeric(&self) -> u32 {
        let mut result = 0;
        result = 10 * result + self.major as u32;
        result = 10 * result + self.minor as u32;
        result = 10 * result + self.patch as u32;
        result = 10 * result + self.revision as u32;
        result
    }
}
<|endoftext|>


<commit_before>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

/// Error module for the DatePathCompiler type
generate_error_module! {
    generate_error_types!(DatePathCompilerError, DatePathCompilerErrorKind,
        DatePathCompilerError => "Unknown DatePathCompiler error"
    );
}
pub use self::error::DatePathCompilerError;
pub use self::error::DatePathCompilerErrorKind;
pub use self::error::MapErrInto;

<commit_msg>Add error kind<commit_after>//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015, 2016 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//

/// Error module for the DatePathCompiler type
generate_error_module! {
    generate_error_types!(DatePathCompilerError, DatePathCompilerErrorKind,
        UnknownDatePathCompilerError => "Unknown DatePathCompiler error",
        StoreIdBuildFailed           => "Failed building StoreId object"
    );
}
pub use self::error::DatePathCompilerError;
pub use self::error::DatePathCompilerErrorKind;
pub use self::error::MapErrInto;

<|endoftext|>


<commit_before>use serde_json;
use std::collections::{HashSet, HashMap};
use std::f64::consts::PI;
use std::fmt;

const PRECISION: f64 = 10000.0;

/// Point containing latitude and longitude values as integers.
/// Integers are used here due to Rust itself not providing some basic
/// floating point functionality at the moment. All due to the undefined
/// behavior revolving around `NaN` float values. For example, what is the boolean
/// result of `0.0 > NaN` ? Its undefined, so therefore > is not implemented by
/// Rust Proper! Perhaps they'll fix this massive inconvienence in the future.
/// TODO use floats
#[derive(PartialEq, Eq, Clone, Debug, Hash, Copy)]
pub struct Point {
    lat: i64,
    lon: i64,
}

/// Degress to Radians
fn deg2rad(deg : f64) -> f64 {
    ((2.0 * PI)/180.0) * deg
}

impl fmt::Display for Point {
    fn fmt(&self, f : &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({}, {})", self.lat(), self.lon())
    }
}

impl Point {
    /// New integer stored Point from floating point lat/lon coordinates
    pub fn new(lat : f64, lon : f64) -> Point {
        Point {
            lat: (lat*PRECISION).floor() as i64,
            lon: (lon*PRECISION).floor() as i64,
        }
    }

    /// Latitude value
    pub fn lat(&self) -> f64 {
        (self.lat as f64)/PRECISION
    }

    /// Longitude value
    pub fn lon(&self) -> f64 {
        (self.lon as f64)/PRECISION
    }

    /// Spheroid distance calculation given earth coordinates as lat/lon values.
    /// Returns the distance in meters.
    pub fn geo_distance(&self, p : &Point) -> f64 {
        let r = 6371000.0; // metres
        let lat1 = p.lat();
        let lon1 = p.lon();
        let lat2 = self.lat();
        let lon2 = self.lon();
        let sig1 = deg2rad(lat1);
        let sig2 = deg2rad(lat2);
        let deltasig = deg2rad(lat2-lat1);
        let deltalambda = deg2rad(lon2-lon1);
        let a = (deltasig/2.0).sin() * (deltasig/2.0).sin() +
            sig1.cos() * sig2.cos() *
            (deltalambda/2.0).sin() * (deltalambda/2.0).sin();
        let c = 2.0 * a.sqrt().atan2((1.0-a).sqrt());
        r * c
    }

}

/// Path
pub type Path = Vec<Point>;

/// Maintains a sparse routing graph
pub struct RouteGraph {
    vertices: HashSet<Point>,
    edges: HashMap<Point, Vec<Point>>,
    paths: HashMap<(Point, Point), Path>,
}

/// Convert the TFL lineStrings attribute to a simple flat vectory of paths.
/// lineStrings in TFL data is a JSON array of string values, containing
/// either an array of points or an array of arrays of points, we handle both.
pub fn linestrings_to_paths(line_strings : &Vec<String>) -> Vec<Path> {
    let mut paths : Vec<Path> = Vec::new();
    for line_string in line_strings {
        match serde_json::from_str::<Vec<(f64, f64)>>(&line_string) {
            Ok(raw_path) => paths.push(raw_path.iter().map(|&(lon, lat)| Point::new(lat, lon)).collect()),
            Err(err) => {
                match serde_json::from_str::<Vec<Vec<(f64, f64)>>>(&line_string) {
                    Ok(raw_paths) => {
                        for raw_path in raw_paths {
                            paths.push(raw_path.iter().map(|&(lon, lat)| Point::new(lat, lon)).collect());
                        }
                    },
                    Err(err2) => println!("Errors decoding line string, single line {}, multi line {}", err, err2),
                }
            },
        }
    }
    paths
}

impl RouteGraph {
    /// New Route Graph
    pub fn new() -> RouteGraph {
        RouteGraph {
            vertices: HashSet::new(),
            edges: HashMap::new(),
            paths: HashMap::new(),
        }
    }

    /// Add many paths
    pub fn add_paths(&mut self, paths : &Vec<Path>) {
        for path in paths {
            self.add_path(path);
        }
    }

    /// Add single path to the graph
    pub fn add_path(&mut self, path : &Path) {
        // add points
        let first = path.first().unwrap();
        let last = path.last().unwrap();
        self.vertices.insert(first.clone());
        self.vertices.insert(last.clone());

        // add bidirectional edges
        self.edges.entry(first.clone()).or_insert(vec![last.clone()]).push(last.clone());
        self.edges.entry(last.clone()).or_insert(vec![first.clone()]).push(first.clone());

        // add paths
        self.paths.insert((first.clone(), last.clone()), path.clone());
        self.paths.insert((last.clone(), first.clone()), path.iter().rev().cloned().collect());
        assert!(self.paths.contains_key(&(first.clone(), last.clone())));
        assert!(self.paths.contains_key(&(last.clone(), first.clone())));
    }

    /// Find the closest actual point (vertex) in our graph since they are not
    /// going to be exact matches
    fn closest_point(&self, pt : &Point) -> (Point, f64) {
        let far_pt = Point::new(pt.lat()+90.0, pt.lon()+90.0);
        let far_dist = far_pt.geo_distance(pt);
        let (min_pt, min_dist) = self.edges.keys().fold((&far_pt, far_dist), |(min_pt, min_dist), vert| {
            let vert_dist = vert.geo_distance(pt);
            match vert_dist < min_dist {
                true => (vert, vert_dist),
                false => (min_pt, min_dist),
            }
        });
        (min_pt.clone(), min_dist)
    }

    /// Find a path between two points if one exists
    pub fn path(&self, p0 : Point, p1 : Point) -> Option<Path> {
        let (start, start_dist) = self.closest_point(&p0);
        if start_dist > 2000.0 {
            println!("start point {} to closest {} distance is {} > 2000", p0, start, start_dist);
            return None;
        }
        let (end, end_dist) = self.closest_point(&p1);
        if end_dist > 2000.0 {
            println!("end point {} to closest {} distance is {} > 2000", p1, end, end_dist);
            return None;
        }
        let visited : HashSet<Point> = HashSet::new();
        self.find_path(start, end, &visited)
    }

    // Recursively search the path graph from p0 to p1, when a path is found
    // the callstack will inherently build up a single Path containing all the
    // points between the two.
    // Visited is a simple HashSet marking points we've already visited to avoid
    // infinitely recursing in circles.
    fn find_path(&self, p0 : Point, p1 : Point, visited : &HashSet<Point>) -> Option<Path> {
        match self.edges.get(&p0) {
            Some(to_vertices) => match visited.contains(&p0) {
                true => None,
                false => {
                    for next in to_vertices {
                        if next.clone() == p1 {
                            return Some(self.paths.get(&(p0, next.clone())).unwrap().clone());
                        }
                        let mut visited0 = visited.clone();
                        visited0.insert(next.clone());
                        match self.find_path(next.clone(), p1, &visited0) {
                            Some(path) => {
                                return Some(vec![&(self.paths.get(&(p0, next.clone())).unwrap())[..], &path[..]].concat());
                            },
                            None => (),
                        }
                    }
                    None
                },
            },
            None => None,
        }
    }
}
<commit_msg>Clean warnings from geometry<commit_after>use serde_json;
use std::collections::{HashSet, HashMap};
use std::f64::consts::PI;
use std::fmt;

const PRECISION: f64 = 10000.0;

/// Point containing latitude and longitude values as integers.
/// Integers are used here due to Rust itself not providing some basic
/// floating point functionality at the moment. All due to the undefined
/// behavior revolving around `NaN` float values. For example, what is the boolean
/// result of `0.0 > NaN` ? Its undefined, so therefore > is not implemented by
/// Rust Proper! Perhaps they'll fix this massive inconvienence in the future.
/// TODO use floats
#[derive(PartialEq, Eq, Clone, Debug, Hash, Copy)]
pub struct Point {
    lat: i64,
    lon: i64,
}

/// Degress to Radians
fn deg2rad(deg : f64) -> f64 {
    ((2.0 * PI)/180.0) * deg
}

impl fmt::Display for Point {
    fn fmt(&self, f : &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({}, {})", self.lat(), self.lon())
    }
}

impl Point {
    /// New integer stored Point from floating point lat/lon coordinates
    pub fn new(lat : f64, lon : f64) -> Point {
        Point {
            lat: (lat*PRECISION).floor() as i64,
            lon: (lon*PRECISION).floor() as i64,
        }
    }

    /// Latitude value
    pub fn lat(&self) -> f64 {
        (self.lat as f64)/PRECISION
    }

    /// Longitude value
    pub fn lon(&self) -> f64 {
        (self.lon as f64)/PRECISION
    }

    /// Spheroid distance calculation given earth coordinates as lat/lon values.
    /// Returns the distance in meters.
    pub fn geo_distance(&self, p : &Point) -> f64 {
        let r = 6371000.0; // metres
        let lat1 = p.lat();
        let lon1 = p.lon();
        let lat2 = self.lat();
        let lon2 = self.lon();
        let sig1 = deg2rad(lat1);
        let sig2 = deg2rad(lat2);
        let deltasig = deg2rad(lat2-lat1);
        let deltalambda = deg2rad(lon2-lon1);
        let a = (deltasig/2.0).sin() * (deltasig/2.0).sin() +
            sig1.cos() * sig2.cos() *
            (deltalambda/2.0).sin() * (deltalambda/2.0).sin();
        let c = 2.0 * a.sqrt().atan2((1.0-a).sqrt());
        r * c
    }

}

/// Path
pub type Path = Vec<Point>;

/// Maintains a sparse routing graph
pub struct RouteGraph {
    vertices: HashSet<Point>,
    edges: HashMap<Point, Vec<Point>>,
    paths: HashMap<(Point, Point), Path>,
}

/// Convert the TFL lineStrings attribute to a simple flat vectory of paths.
/// lineStrings in TFL data is a JSON array of string values, containing
/// either an array of points or an array of arrays of points, we handle both.
pub fn linestrings_to_paths(line_strings : &Vec<String>) -> Vec<Path> {
    let mut paths : Vec<Path> = Vec::new();
    for line_string in line_strings {
        match serde_json::from_str::<Vec<(f64, f64)>>(&line_string) {
            Ok(raw_path) => paths.push(raw_path.iter().map(|&(lon, lat)| Point::new(lat, lon)).collect()),
            Err(err) => {
                match serde_json::from_str::<Vec<Vec<(f64, f64)>>>(&line_string) {
                    Ok(raw_paths) => {
                        for raw_path in raw_paths {
                            paths.push(raw_path.iter().map(|&(lon, lat)| Point::new(lat, lon)).collect());
                        }
                    },
                    Err(err2) => println!("Errors decoding line string, single line {}, multi line {}", err, err2),
                }
            },
        }
    }
    paths
}

impl RouteGraph {
    /// New Route Graph
    pub fn new() -> RouteGraph {
        RouteGraph {
            vertices: HashSet::new(),
            edges: HashMap::new(),
            paths: HashMap::new(),
        }
    }

    /// Add many paths
    pub fn add_paths(&mut self, paths : &Vec<Path>) {
        for path in paths {
            self.add_path(path);
        }
    }

    /// Add single path to the graph
    pub fn add_path(&mut self, path : &Path) {
        // add points
        let first = path.first().unwrap();
        let last = path.last().unwrap();
        self.vertices.insert(first.clone());
        self.vertices.insert(last.clone());

        // add bidirectional edges
        self.edges.entry(first.clone()).or_insert(vec![last.clone()]).push(last.clone());
        self.edges.entry(last.clone()).or_insert(vec![first.clone()]).push(first.clone());

        // add paths
        self.paths.insert((first.clone(), last.clone()), path.clone());
        self.paths.insert((last.clone(), first.clone()), path.iter().rev().cloned().collect());
        assert!(self.paths.contains_key(&(first.clone(), last.clone())));
        assert!(self.paths.contains_key(&(last.clone(), first.clone())));
    }

    /// Find the closest actual point (vertex) in our graph since they are not
    /// going to be exact matches
    fn closest_point(&self, pt : &Point) -> (Point, f64) {
        let far_pt = Point::new(pt.lat()+90.0, pt.lon()+90.0);
        let far_dist = far_pt.geo_distance(pt);
        let (min_pt, min_dist) = self.edges.keys().fold((&far_pt, far_dist), |(min_pt, min_dist), vert| {
            let vert_dist = vert.geo_distance(pt);
            match vert_dist < min_dist {
                true => (vert, vert_dist),
                false => (min_pt, min_dist),
            }
        });
        (min_pt.clone(), min_dist)
    }

    /// Find a path between two points if one exists
    pub fn path(&self, p0 : Point, p1 : Point) -> Option<Path> {
        let (start, start_dist) = self.closest_point(&p0);
        if start_dist > 2000.0 {
            println!("start point {} to closest {} distance is {} > 2000", p0, start, start_dist);
            return None;
        }
        let (end, end_dist) = self.closest_point(&p1);
        if end_dist > 2000.0 {
            println!("end point {} to closest {} distance is {} > 2000", p1, end, end_dist);
            return None;
        }
        let visited : HashSet<Point> = HashSet::new();
        self.find_path(start, end, &visited)
    }

    // Recursively search the path graph from p0 to p1, when a path is found
    // the callstack will inherently build up a single Path containing all the
    // points between the two.
    // Visited is a simple HashSet marking points we've already visited to avoid
    // infinitely recursing in circles.
    fn find_path(&self, p0 : Point, p1 : Point, visited : &HashSet<Point>) -> Option<Path> {
        match self.edges.get(&p0) {
            Some(to_vertices) => {
                if visited.contains(&p0) {
                    None
                } else {
                    for next in to_vertices {
                        if next.clone() == p1 {
                            return Some(self.paths.get(&(p0, next.clone())).unwrap().clone());
                        }
                        let mut visited0 = visited.clone();
                        visited0.insert(next.clone());

                        if let Some(path) = self.find_path(next.clone(), p1, &visited0) {
                            return Some(vec![&(self.paths.get(&(p0, next.clone())).unwrap())[..], &path[..]].concat());
                        }
                    }

                    None
                }
            },
            None => None,
        }
    }
}
<|endoftext|>