<commit_before>use cgmath::{Vector2, Vector3};
use Color;
use color::*;
use camera::Camera;

pub struct Tunel {
    pub size: Vector3<f64>,
    pub color: Color,
}

impl Tunel {
    pub fn new(size: [f64; 3]) -> Tunel {
        Tunel {
            size: Vector3::from(size),
            color: BLUE,
        }
    }

    pub fn render(&self, camera: &Camera) -> Vec<([Vector2<f64>; 2], Color)> {
        vec![
            camera.render_line(&Vector3::new(0., 0., 0.), &Vector3::new(0., 0., self.size.z)),
            camera.render_line(&Vector3::new(self.size.x, 0., 0.), &Vector3::new(self.size.x, 0., self.size.z)),
            camera.render_line(&Vector3::new(0., self.size.y, 0.), &Vector3::new(0., self.size.y, self.size.z)),
            camera.render_line(&Vector3::new(self.size.x, self.size.y, 0.), &Vector3::new(self.size.x, self.size.y, self.size.z)),
        ].into_iter().filter(|x| x.is_some()).map(|x| (x.unwrap(), self.color)).collect()
    }
}
<commit_msg>Some more refactors<commit_after>use cgmath::{Vector2, Vector3};
use Color;
use color::*;
use camera::Camera;

pub struct Tunel {
    pub size: Vector3<f64>,
    pub color: Color,
}

impl Tunel {
    pub fn new(size: [f64; 3]) -> Tunel {
        Tunel {
            size: Vector3::from(size),
            color: BLUE,
        }
    }

    pub fn render(&self, camera: &Camera) -> Vec<([Vector2<f64>; 2], Color)> {
        vec![
            ((0., 0., 0.), (0., 0., self.size.z)),
            ((self.size.x, 0., 0.), (self.size.x, 0., self.size.z)),
            ((0., self.size.y, 0.), (0., self.size.y, self.size.z)),
            ((self.size.x, self.size.y, 0.), (self.size.x, self.size.y, self.size.z)),
        ].into_iter().map(|(a, b)| camera.render_line(&Vector3::from(a), &Vector3::from(b)))
         .filter(|x| x.is_some()).map(|x| (x.unwrap(), self.color)).collect()
    }
}
<|endoftext|>


<commit_before>#![allow(non_camel_case_types)]
use core::fmt;

pub type c_int = i32;
pub type c_uchar = u8;
pub type c_uint = u32;

/// This might not match C's `c_char` exactly.
/// The way we use it makes it fine either way but this type shouldn't be used outside of the library.
pub type c_char = i8;

/// This is an exact copy of https://doc.rust-lang.org/core/ffi/enum.c_void.html
/// It should be Equivalent to C's void type when used as a pointer.
///
/// We can replace this with `core::ffi::c_void` once we update the rustc version to >=1.30.0.
#[repr(u8)]
pub enum c_void {
    #[doc(hidden)] __variant1,
    #[doc(hidden)] __variant2,
}

impl fmt::Debug for c_void {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad("c_void")
    }
}<commit_msg>Add a test for the types<commit_after>#![allow(non_camel_case_types)]
use core::fmt;

pub type c_int = i32;
pub type c_uchar = u8;
pub type c_uint = u32;

/// This might not match C's `c_char` exactly.
/// The way we use it makes it fine either way but this type shouldn't be used outside of the library.
pub type c_char = i8;

/// This is an exact copy of https://doc.rust-lang.org/core/ffi/enum.c_void.html
/// It should be Equivalent to C's void type when used as a pointer.
///
/// We can replace this with `core::ffi::c_void` once we update the rustc version to >=1.30.0.
#[repr(u8)]
pub enum c_void {
    #[doc(hidden)] __variant1,
    #[doc(hidden)] __variant2,
}

impl fmt::Debug for c_void {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad("c_void")
    }
}

#[cfg(test)]
mod tests {
    use std::os::raw;
    use std::any::TypeId;
    use types;

    #[test]
    fn verify_types() {
        assert_eq!(TypeId::of::<types::c_int>(), TypeId::of::<raw::c_int>());
        assert_eq!(TypeId::of::<types::c_uchar>(), TypeId::of::<raw::c_uchar>());
        assert_eq!(TypeId::of::<types::c_uint>(), TypeId::of::<raw::c_uint>());
        assert_eq!(TypeId::of::<types::c_char>(), TypeId::of::<raw::c_char>());
    }
}<|endoftext|>


<commit_before>#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct SystemGetSysinfo {
    pub err_code: i64,
    pub sw_ver: String,
    pub hw_ver: String,
    #[serde(rename = "type")]
    pub hwtype: String,
    pub model: String,
    pub mac: String,
    #[serde(rename = "deviceId")]
    pub device_id: String,
    #[serde(rename = "hwId")]
    pub hw_id: String,
    #[serde(rename = "fwId")]
    pub fw_id: String,
    #[serde(rename = "oemId")]
    pub oem_id: String,
    pub alias: String,
    pub dev_name: String,
    pub icon_hash: String,
    pub relay_state: i64,
    pub on_time: i64,
    pub active_mode: String,
    pub feature: String,
    pub updating: i64,
    pub rssi: i64,
    pub led_off: i64,
    pub latitude: f64,
    pub longitude: f64,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct System {
    pub get_sysinfo: SystemGetSysinfo,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct EmeterGetRealtime {
    pub current: f64,
    pub voltage: f64,
    pub power: f64,
    pub total: f64,
    pub err_code: i64,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct EmeterGetVgainIgain {
    pub vgain: i64,
    pub igain: i64,
    pub err_code: i64,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Emeter {
    pub get_realtime: Option<EmeterGetRealtime>,
    pub get_daystat: Option<EmeterGetDaystat>,
    pub get_vgain_igain: Option<EmeterGetVgainIgain>,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct EmeterGetDaystatDayList {
    pub year: i64,
    pub month: i64,
    pub day: i64,
    pub energy: f64,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct EmeterGetDaystat {
    pub day_list: Vec<EmeterGetDaystatDayList>,
    pub err_code: i64,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct PlugInfo {
    pub system: Option<System>,
    pub emeter: Option<Emeter>,
}<commit_msg>fix improper casing<commit_after>#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct SystemGetSysinfo {
    pub err_code: i64,
    pub sw_ver: String,
    pub hw_ver: String,
    #[serde(rename = "type")]
    pub hw_type: String,
    pub model: String,
    pub mac: String,
    #[serde(rename = "deviceId")]
    pub device_id: String,
    #[serde(rename = "hwId")]
    pub hw_id: String,
    #[serde(rename = "fwId")]
    pub fw_id: String,
    #[serde(rename = "oemId")]
    pub oem_id: String,
    pub alias: String,
    pub dev_name: String,
    pub icon_hash: String,
    pub relay_state: i64,
    pub on_time: i64,
    pub active_mode: String,
    pub feature: String,
    pub updating: i64,
    pub rssi: i64,
    pub led_off: i64,
    pub latitude: f64,
    pub longitude: f64,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct System {
    pub get_sysinfo: SystemGetSysinfo,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct EmeterGetRealtime {
    pub current: f64,
    pub voltage: f64,
    pub power: f64,
    pub total: f64,
    pub err_code: i64,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct EmeterGetVgainIgain {
    pub vgain: i64,
    pub igain: i64,
    pub err_code: i64,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct Emeter {
    pub get_realtime: Option<EmeterGetRealtime>,
    pub get_daystat: Option<EmeterGetDaystat>,
    pub get_vgain_igain: Option<EmeterGetVgainIgain>,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct EmeterGetDaystatDayList {
    pub year: i64,
    pub month: i64,
    pub day: i64,
    pub energy: f64,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct EmeterGetDaystat {
    pub day_list: Vec<EmeterGetDaystatDayList>,
    pub err_code: i64,
}

#[derive(Debug, PartialEq, Serialize, Deserialize)]
pub struct PlugInfo {
    pub system: Option<System>,
    pub emeter: Option<Emeter>,
}<|endoftext|>


<commit_before>use std::io::prelude::*;
use std::io::BufReader;
use std::io::Result;
use std::fs::File;
use std::collections::HashMap;

pub fn read_users(path: String) -> Result<HashMap<String, String>> {
    let f = try!(File::open(path));
    let reader = BufReader::new(f);
    let mut users: HashMap<String, String> = HashMap::new();

    for line in reader.lines() {
        let line = try!(line);
        let parts: Vec<&str> = line.split(",").collect();
        users.insert(parts[0].to_string(), parts[1].to_string());
    }
    return Ok(users);
}
<commit_msg>Implemented parse_user function to parse user lines<commit_after>use std::io::prelude::*;
use std::io::BufReader;
use std::io::Result;
use std::fs::File;
use std::option::Option;

#[derive(Debug)]
pub struct User {
    username: String,
    phone_number: Option<String>,
    slack_username: Option<String>
}

pub fn read_users(path: String) -> Result<Vec<User>> {
    let f = try!(File::open(path));
    let reader = BufReader::new(f);
    let mut users: Vec<User> = Vec::new();

    for line in reader.lines() {
        let line = try!(line);
        match parse_user(line) {
            Some(user) => { users.push(user) },
            None => ()
        }
    }
    return Ok(users);
}

fn parse_user(line: String) -> Option<User> {
    let parts: Vec<String> = line.split(",").map( |s| s.to_owned() ).collect();
    let username = parts.get(0);

    if username.is_none() || username.unwrap().is_empty() {
        return None;
    }

    let phone_number = match parts.get(1) {
        Some(number) => Some(number.to_owned()),
        None => None
    };
    let slack_username = match parts.get(2) {
        Some(number) => Some(number.to_owned()),
        None => None
    };
    return Some(User {
        username: username.unwrap().to_owned(),
        phone_number: phone_number,
        slack_username: slack_username
    });
}

#[test]
fn test_parse_user() {
    let good = "patrickod,+16507017829,patrickod".to_string();
    let bad = "".to_string();

    let option_good = parse_user(good);
    assert!(option_good.is_some());
    let parsed_good = option_good.unwrap();
    assert_eq!(parsed_good.username, "patrickod".to_string());
    assert_eq!(parsed_good.phone_number.unwrap(), "+16507017829".to_string());
    assert_eq!(parsed_good.slack_username.unwrap(), "patrickod".to_string());

    assert!(parse_user(bad).is_none());
}
<|endoftext|>


<commit_before>use super::ToTokens;
use std::fmt::{self, Display};

#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Tokens(String);

impl Tokens {
    pub fn new() -> Self {
        Tokens(String::new())
    }

    pub fn append(&mut self, token: &str) {
        if !self.0.is_empty() && !token.is_empty() {
            self.0.push(' ');
        }
        self.0.push_str(token);
    }

    pub fn append_all<T, I>(&mut self, iter: I)
        where T: ToTokens,
              I: IntoIterator<Item = T>
    {
        for token in iter {
            token.to_tokens(self);
        }
    }

    pub fn append_separated<T, I>(&mut self, iter: I, sep: &str)
        where T: ToTokens,
              I: IntoIterator<Item = T>
    {
        for (i, token) in iter.into_iter().enumerate() {
            if i > 0 {
                self.append(sep);
            }
            token.to_tokens(self);
        }
    }

    pub fn append_terminated<T, I>(&mut self, iter: I, term: &str)
        where T: ToTokens,
              I: IntoIterator<Item = T>
    {
        for token in iter {
            token.to_tokens(self);
            self.append(term);
        }
    }

    pub fn as_str(&self) -> &str {
        &self.0
    }
}

impl Default for Tokens {
    fn default() -> Self {
        Tokens::new()
    }
}

impl Display for Tokens {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        self.0.fmt(formatter)
    }
}
<commit_msg>Document Tokens<commit_after>use super::ToTokens;
use std::fmt::{self, Display};

/// Tokens produced by a `quote!(...)` invocation.
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Tokens(String);

impl Tokens {
    /// Empty tokens.
    pub fn new() -> Self {
        Tokens(String::new())
    }

    /// For use by `ToTokens` implementations.
    ///
    /// ```
    /// # #[macro_use] extern crate quote;
    /// # use quote::{Tokens, ToTokens};
    /// # fn main() {
    /// struct X;
    ///
    /// impl ToTokens for X {
    ///     fn to_tokens(&self, tokens: &mut Tokens) {
    ///         tokens.append("a");
    ///         tokens.append("b");
    ///         tokens.append("c");
    ///     }
    /// }
    ///
    /// let x = X;
    /// let tokens = quote!(#x);
    /// assert_eq!(tokens.as_str(), "a b c");
    /// # }
    /// ```
    pub fn append(&mut self, token: &str) {
        if !self.0.is_empty() && !token.is_empty() {
            self.0.push(' ');
        }
        self.0.push_str(token);
    }

    /// For use by `ToTokens` implementations.
    ///
    /// ```
    /// # #[macro_use] extern crate quote;
    /// # use quote::{Tokens, ToTokens};
    /// # fn main() {
    /// struct X;
    ///
    /// impl ToTokens for X {
    ///     fn to_tokens(&self, tokens: &mut Tokens) {
    ///         tokens.append_all(&[true, false]);
    ///     }
    /// }
    ///
    /// let x = X;
    /// let tokens = quote!(#x);
    /// assert_eq!(tokens.as_str(), "true false");
    /// # }
    /// ```
    pub fn append_all<T, I>(&mut self, iter: I)
        where T: ToTokens,
              I: IntoIterator<Item = T>
    {
        for token in iter {
            token.to_tokens(self);
        }
    }

    /// For use by `ToTokens` implementations.
    ///
    /// ```
    /// # #[macro_use] extern crate quote;
    /// # use quote::{Tokens, ToTokens};
    /// # fn main() {
    /// struct X;
    ///
    /// impl ToTokens for X {
    ///     fn to_tokens(&self, tokens: &mut Tokens) {
    ///         tokens.append_separated(&[true, false], ",");
    ///     }
    /// }
    ///
    /// let x = X;
    /// let tokens = quote!(#x);
    /// assert_eq!(tokens.as_str(), "true , false");
    /// # }
    /// ```
    pub fn append_separated<T, I>(&mut self, iter: I, sep: &str)
        where T: ToTokens,
              I: IntoIterator<Item = T>
    {
        for (i, token) in iter.into_iter().enumerate() {
            if i > 0 {
                self.append(sep);
            }
            token.to_tokens(self);
        }
    }

    /// For use by `ToTokens` implementations.
    ///
    /// ```
    /// # #[macro_use] extern crate quote;
    /// # use quote::{Tokens, ToTokens};
    /// # fn main() {
    /// struct X;
    ///
    /// impl ToTokens for X {
    ///     fn to_tokens(&self, tokens: &mut Tokens) {
    ///         tokens.append_terminated(&[true, false], ",");
    ///     }
    /// }
    ///
    /// let x = X;
    /// let tokens = quote!(#x);
    /// assert_eq!(tokens.as_str(), "true , false ,");
    /// # }
    /// ```
    pub fn append_terminated<T, I>(&mut self, iter: I, term: &str)
        where T: ToTokens,
              I: IntoIterator<Item = T>
    {
        for token in iter {
            token.to_tokens(self);
            self.append(term);
        }
    }

    pub fn as_str(&self) -> &str {
        &self.0
    }
}

impl Default for Tokens {
    fn default() -> Self {
        Tokens::new()
    }
}

impl Display for Tokens {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        self.0.fmt(formatter)
    }
}
<|endoftext|>


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

use std::process::Command;
use libc;
use log::{info,warn};

pub fn is_root() -> bool {
    unsafe { libc::geteuid() == 0 }
}

pub fn enable_ipv4_forwarding() -> Result<(), String> {
    let sysctl_arg = if cfg!(target_os = "linux") {
        "net.ipv4.ip_forward=1"
    } else if cfg!(target_os = "macos") {
        "net.inet.ip.forwarding=1"
    } else {
        unimplemented!()
    };
    info!("Enabling IPv4 Forwarding.");
    let status = Command::new("sysctl")
        .arg("-w")
        .arg(sysctl_arg)
        .status()
        .unwrap();
    if status.success() {
        Ok(())
    } else {
        Err(format!("sysctl: {}", status))
    }
}

pub enum RouteType {
    Net,
    Host,
}

pub struct DefaultGateway {
    origin: String,
    remote: String,
}

impl DefaultGateway {
    pub fn create(gateway: &str, remote: &str) -> DefaultGateway {
        let origin = get_default_gateway().unwrap();
        info!("Original default gateway: {}.", origin);
        add_route(RouteType::Host, remote, &origin).unwrap();
        delete_default_gateway().unwrap();
        set_default_gateway(gateway).unwrap();
        DefaultGateway {
            origin: origin,
            remote: String::from(remote),
        }
    }
}

impl Drop for DefaultGateway {
    fn drop(&mut self) {
        delete_default_gateway().unwrap();
        set_default_gateway(&self.origin).unwrap();
        delete_route(RouteType::Host, &self.remote).unwrap();
    }
}

pub fn delete_route(route_type: RouteType, route: &str) -> Result<(), String> {
    let mode = match route_type {
        RouteType::Net => "-net",
        RouteType::Host => "-host",
    };
    info!("Deleting route: {} {}.", mode, route);
    let status = if cfg!(target_os = "linux") {
        Command::new("route")
            .arg("-n")
            .arg("del")
            .arg(mode)
            .arg(route)
            .status()
            .unwrap()
    } else if cfg!(target_os = "macos") {
        Command::new("route")
            .arg("-n")
            .arg("delete")
            .arg(mode)
            .arg(route)
            .status()
            .unwrap()
    } else {
        unimplemented!()
    };
    if status.success() {
        Ok(())
    } else {
        Err(format!("route: {}", status))
    }
}

pub fn add_route(route_type: RouteType, route: &str, gateway: &str) -> Result<(), String> {
    let mode = match route_type {
        RouteType::Net => "-net",
        RouteType::Host => "-host",
    };
    info!("Adding route: {} {} gateway {}.", mode, route, gateway);
    let status = if cfg!(target_os = "linux") {
        Command::new("route")
            .arg("-n")
            .arg("add")
            .arg(mode)
            .arg(route)
            .arg("gw")
            .arg(gateway)
            .status()
            .unwrap()
    } else if cfg!(target_os = "macos") {
        Command::new("route")
            .arg("-n")
            .arg("add")
            .arg(mode)
            .arg(route)
            .arg(gateway)
            .status()
            .unwrap()
    } else {
        unimplemented!()
    };
    if status.success() {
        Ok(())
    } else {
        Err(format!("route: {}", status))
    }
}

pub fn set_default_gateway(gateway: &str) -> Result<(), String> {
    add_route(RouteType::Net, "default", gateway)
}

pub fn delete_default_gateway() -> Result<(), String> {
    delete_route(RouteType::Net, "default")
}

pub fn get_default_gateway() -> Result<String, String> {
    let cmd = if cfg!(target_os = "linux") {
        "ip -4 route list 0/0 | awk '{print $3}'"
    } else if cfg!(target_os = "macos") {
        "route -n get default | grep gateway | awk '{print $2}'"
    } else {
        unimplemented!()
    };
    let output = Command::new("bash")
        .arg("-c")
        .arg(cmd)
        .output()
        .unwrap();
    if output.status.success() {
        Ok(String::from_utf8(output.stdout).unwrap().trim_right().to_string())
    } else {
        Err(String::from_utf8(output.stderr).unwrap())
    }
}

pub fn get_public_ip() -> Result<String, String> {
    let output = Command::new("curl")
        .arg("ipecho.net/plain")
        .output()
        .unwrap();
    if output.status.success() {
        Ok(String::from_utf8(output.stdout).unwrap())
    } else {
        Err(String::from_utf8(output.stderr).unwrap())
    }
}

fn get_route_gateway(route: &str) -> Result<String,String> {
    let cmd = format!("ip -4 route list {}",route);
    let output = Command::new("bash")
        .arg("-c")
        .arg(cmd)
        .output()
        .unwrap();
    if output.status.success() {
        Ok(String::from_utf8(output.stdout).unwrap().trim_right().to_string())
    } else {
        Err(String::from_utf8(output.stderr).unwrap())
    }

}

pub fn set_dns(dns: &str) -> Result<String,String> {
    let cmd = format!("echo nameserver {} > /etc/resolv.conf",dns);
    let output = Command::new("bash")
        .arg("-c")
        .arg(cmd)
        .output()
        .unwrap();
    if output.status.success() {
        Ok(String::from_utf8(output.stdout).unwrap())
    } else {
        Err(String::from_utf8(output.stderr).unwrap())
    }
}

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

    #[test]
    fn enable_ipv4_forwarding_test() {
        enable_ipv4_forwarding().unwrap();
    }
    #[test]
    fn get_default_gateway_test() {
        let a = get_default_gateway().unwrap();
        assert!(get_route_gateway("0/0").unwrap().contains(&*a))
    }

    #[test]
    #[cfg(target_os = "linux")]
    fn route_test() {
        assert!(is_root());
        let gw = get_default_gateway().unwrap();
        add_route(RouteType::Host, "1.1.1.1", &gw).unwrap();
        assert!(get_route_gateway("1.1.1.1").unwrap().contains(&*gw));
        delete_route(RouteType::Host, "1.1.1.1").unwrap();
        assert!(!get_route_gateway("1.1.1.1").unwrap().contains(&*gw));
    }

    #[test]
    fn set_dns_test() {
        assert!(is_root());
        set_dns("8.8.8.8").unwrap();
    }

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

use std::process::Command;
use libc;
use log::{info,warn};

pub fn is_root() -> bool {
    unsafe { libc::geteuid() == 0 }
}

pub fn enable_ipv4_forwarding() -> Result<(), String> {
    let sysctl_arg = if cfg!(target_os = "linux") {
        "net.ipv4.ip_forward=1"
    } else if cfg!(target_os = "macos") {
        "net.inet.ip.forwarding=1"
    } else {
        unimplemented!()
    };
    info!("Enabling IPv4 Forwarding.");
    let status = Command::new("sysctl")
        .arg("-w")
        .arg(sysctl_arg)
        .status()
        .unwrap();
    if status.success() {
        Ok(())
    } else {
        Err(format!("sysctl: {}", status))
    }
}

pub enum RouteType {
    Net,
    Host,
}

pub struct DefaultGateway {
    origin: String,
    remote: String,
}

impl DefaultGateway {
    pub fn create(gateway: &str, remote: &str) -> DefaultGateway {
        let origin = get_default_gateway().unwrap();
        info!("Original default gateway: {}.", origin);
        add_route(RouteType::Host, remote, &origin).unwrap();
        delete_default_gateway().unwrap();
        set_default_gateway(gateway).unwrap();
        DefaultGateway {
            origin: origin,
            remote: String::from(remote),
        }
    }
}

impl Drop for DefaultGateway {
    fn drop(&mut self) {
        delete_default_gateway().unwrap();
        set_default_gateway(&self.origin).unwrap();
        delete_route(RouteType::Host, &self.remote).unwrap();
    }
}

pub fn delete_route(route_type: RouteType, route: &str) -> Result<(), String> {
    let mode = match route_type {
        RouteType::Net => "-net",
        RouteType::Host => "-host",
    };
    info!("Deleting route: {} {}.", mode, route);
    let status = if cfg!(target_os = "linux") {
        Command::new("route")
            .arg("-n")
            .arg("del")
            .arg(mode)
            .arg(route)
            .status()
            .unwrap()
    } else if cfg!(target_os = "macos") {
        Command::new("route")
            .arg("-n")
            .arg("delete")
            .arg(mode)
            .arg(route)
            .status()
            .unwrap()
    } else {
        unimplemented!()
    };
    if status.success() {
        Ok(())
    } else {
        Err(format!("route: {}", status))
    }
}

pub fn add_route(route_type: RouteType, route: &str, gateway: &str) -> Result<(), String> {
    let mode = match route_type {
        RouteType::Net => "-net",
        RouteType::Host => "-host",
    };
    info!("Adding route: {} {} gateway {}.", mode, route, gateway);
    let status = if cfg!(target_os = "linux") {
        Command::new("route")
            .arg("-n")
            .arg("add")
            .arg(mode)
            .arg(route)
            .arg("gw")
            .arg(gateway)
            .status()
            .unwrap()
    } else if cfg!(target_os = "macos") {
        Command::new("route")
            .arg("-n")
            .arg("add")
            .arg(mode)
            .arg(route)
            .arg(gateway)
            .status()
            .unwrap()
    } else {
        unimplemented!()
    };
    if status.success() {
        Ok(())
    } else {
        Err(format!("route: {}", status))
    }
}

pub fn set_default_gateway(gateway: &str) -> Result<(), String> {
    add_route(RouteType::Net, "default", gateway)
}

pub fn delete_default_gateway() -> Result<(), String> {
    delete_route(RouteType::Net, "default")
}

pub fn get_default_gateway() -> Result<String, String> {
    let cmd = if cfg!(target_os = "linux") {
        "ip -4 route list 0/0 | awk '{print $3}'"
    } else if cfg!(target_os = "macos") {
        "route -n get default | grep gateway | awk '{print $2}'"
    } else {
        unimplemented!()
    };
    let output = Command::new("bash")
        .arg("-c")
        .arg(cmd)
        .output()
        .unwrap();
    if output.status.success() {
        Ok(String::from_utf8(output.stdout).unwrap().trim_right().to_string())
    } else {
        Err(String::from_utf8(output.stderr).unwrap())
    }
}

pub fn get_public_ip() -> Result<String, String> {
    let output = Command::new("curl")
        .arg("ipecho.net/plain")
        .output()
        .unwrap();
    if output.status.success() {
        Ok(String::from_utf8(output.stdout).unwrap())
    } else {
        Err(String::from_utf8(output.stderr).unwrap())
    }
}

fn get_route_gateway(route: &str) -> Result<String,String> {
    let cmd = format!("ip -4 route list {}",route);
    let output = Command::new("bash")
        .arg("-c")
        .arg(cmd)
        .output()
        .unwrap();
    if output.status.success() {
        Ok(String::from_utf8(output.stdout).unwrap().trim_right().to_string())
    } else {
        Err(String::from_utf8(output.stderr).unwrap())
    }

}

pub fn set_dns(dns: &str) -> Result<String,String> {
    let cmd = format!("echo nameserver {} > /etc/resolv.conf",dns);
    let output = Command::new("bash")
        .arg("-c")
        .arg(cmd)
        .output()
        .unwrap();
    if output.status.success() {
        Ok(String::from_utf8(output.stdout).unwrap())
    } else {
        Err(String::from_utf8(output.stderr).unwrap())
    }
}

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

    #[test]
    fn enable_ipv4_forwarding_test() {
        enable_ipv4_forwarding().unwrap();
    }
    #[test]
    #[cfg(target_os = "linux")]
    fn get_default_gateway_test() {
        let a = get_default_gateway().unwrap();
        assert!(get_route_gateway("0/0").unwrap().contains(&*a))
    }

    #[test]
    #[cfg(target_os = "linux")]
    fn route_test() {
        assert!(is_root());
        let gw = get_default_gateway().unwrap();
        add_route(RouteType::Host, "1.1.1.1", &gw).unwrap();
        assert!(get_route_gateway("1.1.1.1").unwrap().contains(&*gw));
        delete_route(RouteType::Host, "1.1.1.1").unwrap();
        assert!(!get_route_gateway("1.1.1.1").unwrap().contains(&*gw));
    }

    #[test]
    fn set_dns_test() {
        assert!(is_root());
        set_dns("8.8.8.8").unwrap();
    }

}
<|endoftext|>


<commit_before>// Copyright 2015-2016, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

use ffi;
use translate::*;
use std;
use std::ffi::{OsStr, OsString};
use std::path::{Path, PathBuf};
use error::BoolError;
use Error;
use std::ptr;

/// Same as [`get_prgname()`].
///
/// [`get_prgname()`]: fn.get_prgname.html
pub fn get_program_name() -> Option<String> {
    get_prgname()
}

pub fn get_prgname() -> Option<String> {
    unsafe {
        from_glib_none(ffi::g_get_prgname())
    }
}

/// Same as [`set_prgname()`].
///
/// [`set_prgname()`]: fn.set_prgname.html
pub fn set_program_name(name: Option<&str>) {
    set_prgname(name)
}

pub fn set_prgname(name: Option<&str>) {
    unsafe {
        ffi::g_set_prgname(name.to_glib_none().0)
    }
}

pub fn getenv<K: AsRef<OsStr>>(variable_name: K) -> Option<OsString> {
    #[cfg(windows)]
    use ffi::g_getenv_utf8 as g_getenv;
    #[cfg(not(windows))]
    use ffi::g_getenv;

    unsafe {
        from_glib_none(g_getenv(variable_name.as_ref().to_glib_none().0))
    }
}

pub fn setenv<K: AsRef<OsStr>, V: AsRef<OsStr>>(variable_name: K, value: V, overwrite: bool) -> Result<(), BoolError> {
    #[cfg(windows)]
    use ffi::g_setenv_utf8 as g_setenv;
    #[cfg(not(windows))]
    use ffi::g_setenv;

    unsafe {
        BoolError::from_glib(g_setenv(variable_name.as_ref().to_glib_none().0,
                                value.as_ref().to_glib_none().0,
                                overwrite.to_glib()),
                             "Failed to set environment variable")
    }
}

pub fn unsetenv<K: AsRef<OsStr>>(variable_name: K) {
    #[cfg(windows)]
    use ffi::g_unsetenv_utf8 as g_unsetenv;
    #[cfg(not(windows))]
    use ffi::g_unsetenv;

    unsafe {
        g_unsetenv(variable_name.as_ref().to_glib_none().0)
    }
}

pub fn environ_getenv<K: AsRef<OsStr>>(envp: &[OsString], variable: K) -> Option<OsString> {
    unsafe {
        from_glib_none(ffi::g_environ_getenv(envp.to_glib_none().0, variable.as_ref().to_glib_none().0))
    }
}

pub fn get_user_name() -> Option<String> {
    #[cfg(all(windows,target_arch="x86"))]
    use ffi::g_get_user_name_utf8 as g_get_user_name;
    #[cfg(not(all(windows,target_arch="x86")))]
    use ffi::g_get_user_name;

    unsafe {
        from_glib_none(g_get_user_name())
    }
}

pub fn get_real_name() -> Option<std::path::PathBuf> {
    #[cfg(all(windows,target_arch="x86"))]
    use ffi::g_get_real_name_utf8 as g_get_real_name;
    #[cfg(not(all(windows,target_arch="x86")))]
    use ffi::g_get_real_name;

    unsafe {
        from_glib_none(g_get_real_name())
    }
}

pub fn get_current_dir() -> Option<PathBuf> {
    #[cfg(windows)]
    use ffi::g_get_current_dir_utf8 as g_get_current_dir;
    #[cfg(not(windows))]
    use ffi::g_get_current_dir;

    unsafe {
        from_glib_full(g_get_current_dir())
    }
}

pub fn filename_to_uri<'a, P: AsRef<Path>, Q: Into<Option<&'a str>>>(filename: P, hostname: Q) -> Result<String, Error> {
    #[cfg(windows)]
    use ffi::g_filename_to_uri_utf8 as g_filename_to_uri;
    #[cfg(not(windows))]
    use ffi::g_filename_to_uri;

    let hostname = hostname.into();
    let hostname = hostname.to_glib_none();
    unsafe {
        let mut error = std::ptr::null_mut();
        let ret = g_filename_to_uri(filename.as_ref().to_glib_none().0, hostname.0, &mut error);
        if error.is_null() { Ok(from_glib_full(ret)) } else { Err(from_glib_full(error)) }
    }
}

pub fn filename_from_uri(uri: &str) -> Result<(std::path::PathBuf, Option<String>), Error> {
    #[cfg(windows)]
    use ffi::g_filename_from_uri_utf8 as g_filename_from_uri;
    #[cfg(not(windows))]
    use ffi::g_filename_from_uri;

    unsafe {
        let mut hostname = ptr::null_mut();
        let mut error = ptr::null_mut();
        let ret = g_filename_from_uri(uri.to_glib_none().0, &mut hostname, &mut error);
        if error.is_null() { Ok((from_glib_full(ret), from_glib_full(hostname))) } else { Err(from_glib_full(error)) }
    }
}

pub fn find_program_in_path<P: AsRef<Path>>(program: P) -> Option<PathBuf> {
    #[cfg(all(windows,target_arch="x86"))]
    use ffi::g_find_program_in_path_utf8 as g_find_program_in_path;
    #[cfg(not(all(windows,target_arch="x86")))]
    use ffi::g_find_program_in_path;

    unsafe {
        from_glib_full(g_find_program_in_path(program.as_ref().to_glib_none().0))
    }
}

pub fn get_home_dir() -> Option<std::path::PathBuf> {
    #[cfg(all(windows,target_arch="x86"))]
    use ffi::g_get_home_dir_utf8 as g_get_home_dir;
    #[cfg(not(all(windows,target_arch="x86")))]
    use ffi::g_get_home_dir;

    unsafe {
        from_glib_none(g_get_home_dir())
    }
}

pub fn get_tmp_dir() -> Option<std::path::PathBuf> {
    #[cfg(all(windows,target_arch="x86"))]
    use ffi::g_get_tmp_dir_utf8 as g_get_tmp_dir;
    #[cfg(not(all(windows,target_arch="x86")))]
    use ffi::g_get_tmp_dir;

    unsafe {
        from_glib_none(g_get_tmp_dir())
    }
}

pub fn mkstemp<P: AsRef<std::path::Path>>(tmpl: P) -> i32 {
    #[cfg(windows)]
    use ffi::g_mkstemp_utf8 as g_mkstemp;
    #[cfg(not(windows))]
    use ffi::g_mkstemp;

    unsafe {
        g_mkstemp(tmpl.as_ref().to_glib_none().0)
    }
}

#[cfg(test)]
mod tests {
    use std::env;
    use std::sync::Mutex;

    //Mutex to prevent run environment tests parallel
    lazy_static! { static ref LOCK: Mutex<()> = Mutex::new(()); }

    const VAR_NAME: &str = "function_environment_test";

    fn check_getenv(val: &str) {
        let _data = LOCK.lock().unwrap();

        env::set_var(VAR_NAME, val);
        assert_eq!(env::var_os(VAR_NAME), Some(val.into()));
        assert_eq!(::getenv(VAR_NAME), Some(val.into()));

        let environ = ::get_environ();
        assert_eq!(::environ_getenv(&environ, VAR_NAME), Some(val.into()));
    }

    fn check_setenv(val: &str) {
        let _data = LOCK.lock().unwrap();

        ::setenv(VAR_NAME, val, true).unwrap();
        assert_eq!(env::var_os(VAR_NAME), Some(val.into()));
    }

    #[test]
    fn getenv() {
        check_getenv("Test");
        check_getenv("Тест"); // "Test" in Russian
    }

    #[test]
    fn setenv() {
        check_setenv("Test");
        check_setenv("Тест"); // "Test" in Russian
    }
}
<commit_msg>make get_real_name and get_user_name return OsString<commit_after>// Copyright 2015-2016, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

use ffi;
use translate::*;
use std;
use std::ffi::{OsStr, OsString};
use std::path::{Path, PathBuf};
use error::BoolError;
use Error;
use std::ptr;

/// Same as [`get_prgname()`].
///
/// [`get_prgname()`]: fn.get_prgname.html
pub fn get_program_name() -> Option<String> {
    get_prgname()
}

pub fn get_prgname() -> Option<String> {
    unsafe {
        from_glib_none(ffi::g_get_prgname())
    }
}

/// Same as [`set_prgname()`].
///
/// [`set_prgname()`]: fn.set_prgname.html
pub fn set_program_name(name: Option<&str>) {
    set_prgname(name)
}

pub fn set_prgname(name: Option<&str>) {
    unsafe {
        ffi::g_set_prgname(name.to_glib_none().0)
    }
}

pub fn getenv<K: AsRef<OsStr>>(variable_name: K) -> Option<OsString> {
    #[cfg(windows)]
    use ffi::g_getenv_utf8 as g_getenv;
    #[cfg(not(windows))]
    use ffi::g_getenv;

    unsafe {
        from_glib_none(g_getenv(variable_name.as_ref().to_glib_none().0))
    }
}

pub fn setenv<K: AsRef<OsStr>, V: AsRef<OsStr>>(variable_name: K, value: V, overwrite: bool) -> Result<(), BoolError> {
    #[cfg(windows)]
    use ffi::g_setenv_utf8 as g_setenv;
    #[cfg(not(windows))]
    use ffi::g_setenv;

    unsafe {
        BoolError::from_glib(g_setenv(variable_name.as_ref().to_glib_none().0,
                                value.as_ref().to_glib_none().0,
                                overwrite.to_glib()),
                             "Failed to set environment variable")
    }
}

pub fn unsetenv<K: AsRef<OsStr>>(variable_name: K) {
    #[cfg(windows)]
    use ffi::g_unsetenv_utf8 as g_unsetenv;
    #[cfg(not(windows))]
    use ffi::g_unsetenv;

    unsafe {
        g_unsetenv(variable_name.as_ref().to_glib_none().0)
    }
}

pub fn environ_getenv<K: AsRef<OsStr>>(envp: &[OsString], variable: K) -> Option<OsString> {
    unsafe {
        from_glib_none(ffi::g_environ_getenv(envp.to_glib_none().0, variable.as_ref().to_glib_none().0))
    }
}

pub fn get_user_name() -> Option<OsString> {
    #[cfg(all(windows,target_arch="x86"))]
    use ffi::g_get_user_name_utf8 as g_get_user_name;
    #[cfg(not(all(windows,target_arch="x86")))]
    use ffi::g_get_user_name;

    unsafe {
        from_glib_none(g_get_user_name())
    }
}

pub fn get_real_name() -> Option<OsString> {
    #[cfg(all(windows,target_arch="x86"))]
    use ffi::g_get_real_name_utf8 as g_get_real_name;
    #[cfg(not(all(windows,target_arch="x86")))]
    use ffi::g_get_real_name;

    unsafe {
        from_glib_none(g_get_real_name())
    }
}

pub fn get_current_dir() -> Option<PathBuf> {
    #[cfg(windows)]
    use ffi::g_get_current_dir_utf8 as g_get_current_dir;
    #[cfg(not(windows))]
    use ffi::g_get_current_dir;

    unsafe {
        from_glib_full(g_get_current_dir())
    }
}

pub fn filename_to_uri<'a, P: AsRef<Path>, Q: Into<Option<&'a str>>>(filename: P, hostname: Q) -> Result<String, Error> {
    #[cfg(windows)]
    use ffi::g_filename_to_uri_utf8 as g_filename_to_uri;
    #[cfg(not(windows))]
    use ffi::g_filename_to_uri;

    let hostname = hostname.into();
    let hostname = hostname.to_glib_none();
    unsafe {
        let mut error = std::ptr::null_mut();
        let ret = g_filename_to_uri(filename.as_ref().to_glib_none().0, hostname.0, &mut error);
        if error.is_null() { Ok(from_glib_full(ret)) } else { Err(from_glib_full(error)) }
    }
}

pub fn filename_from_uri(uri: &str) -> Result<(std::path::PathBuf, Option<String>), Error> {
    #[cfg(windows)]
    use ffi::g_filename_from_uri_utf8 as g_filename_from_uri;
    #[cfg(not(windows))]
    use ffi::g_filename_from_uri;

    unsafe {
        let mut hostname = ptr::null_mut();
        let mut error = ptr::null_mut();
        let ret = g_filename_from_uri(uri.to_glib_none().0, &mut hostname, &mut error);
        if error.is_null() { Ok((from_glib_full(ret), from_glib_full(hostname))) } else { Err(from_glib_full(error)) }
    }
}

pub fn find_program_in_path<P: AsRef<Path>>(program: P) -> Option<PathBuf> {
    #[cfg(all(windows,target_arch="x86"))]
    use ffi::g_find_program_in_path_utf8 as g_find_program_in_path;
    #[cfg(not(all(windows,target_arch="x86")))]
    use ffi::g_find_program_in_path;

    unsafe {
        from_glib_full(g_find_program_in_path(program.as_ref().to_glib_none().0))
    }
}

pub fn get_home_dir() -> Option<std::path::PathBuf> {
    #[cfg(all(windows,target_arch="x86"))]
    use ffi::g_get_home_dir_utf8 as g_get_home_dir;
    #[cfg(not(all(windows,target_arch="x86")))]
    use ffi::g_get_home_dir;

    unsafe {
        from_glib_none(g_get_home_dir())
    }
}

pub fn get_tmp_dir() -> Option<std::path::PathBuf> {
    #[cfg(all(windows,target_arch="x86"))]
    use ffi::g_get_tmp_dir_utf8 as g_get_tmp_dir;
    #[cfg(not(all(windows,target_arch="x86")))]
    use ffi::g_get_tmp_dir;

    unsafe {
        from_glib_none(g_get_tmp_dir())
    }
}

pub fn mkstemp<P: AsRef<std::path::Path>>(tmpl: P) -> i32 {
    #[cfg(windows)]
    use ffi::g_mkstemp_utf8 as g_mkstemp;
    #[cfg(not(windows))]
    use ffi::g_mkstemp;

    unsafe {
        g_mkstemp(tmpl.as_ref().to_glib_none().0)
    }
}

#[cfg(test)]
mod tests {
    use std::env;
    use std::sync::Mutex;

    //Mutex to prevent run environment tests parallel
    lazy_static! { static ref LOCK: Mutex<()> = Mutex::new(()); }

    const VAR_NAME: &str = "function_environment_test";

    fn check_getenv(val: &str) {
        let _data = LOCK.lock().unwrap();

        env::set_var(VAR_NAME, val);
        assert_eq!(env::var_os(VAR_NAME), Some(val.into()));
        assert_eq!(::getenv(VAR_NAME), Some(val.into()));

        let environ = ::get_environ();
        assert_eq!(::environ_getenv(&environ, VAR_NAME), Some(val.into()));
    }

    fn check_setenv(val: &str) {
        let _data = LOCK.lock().unwrap();

        ::setenv(VAR_NAME, val, true).unwrap();
        assert_eq!(env::var_os(VAR_NAME), Some(val.into()));
    }

    #[test]
    fn getenv() {
        check_getenv("Test");
        check_getenv("Тест"); // "Test" in Russian
    }

    #[test]
    fn setenv() {
        check_setenv("Test");
        check_setenv("Тест"); // "Test" in Russian
    }
}
<|endoftext|>


<commit_before>
#[derive(Debug, PartialEq, Clone)]
pub enum Value {
    String(String),
    List(Vec<Value>),
    Bool(bool),
    Integer(i64),
    Float(f64),
    Date(String), // TODO
}

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

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

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

impl From<i64> for Value {
    fn from(i: i64) -> Value {
        Value::Integer(i)
    }
}

impl From<f64> for Value {
    fn from(f: f64) -> Value {
        Value::Float(f)
    }
}

impl<T> From<Vec<T>> for Value where Value: From<T> {
    fn from(v: Vec<T>) -> Value {
        Value::List(v.into_iter().map(Value::from).collect())
    }
}

<commit_msg>remove Value::List<commit_after>
#[derive(Debug, PartialEq, Clone)]
pub enum Value {
    String(String),
    Bool(bool),
    Integer(i64),
    Float(f64),
    Date(String), // TODO
}

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

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

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

impl From<i64> for Value {
    fn from(i: i64) -> Value {
        Value::Integer(i)
    }
}

impl From<f64> for Value {
    fn from(f: f64) -> Value {
        Value::Float(f)
    }
}

<|endoftext|>


<commit_before>//! Types representing for data which will be retrieved from the driver.
//! Currently this data is expected to look like a JSON object but this may be
//! changed in the future. Driver authors must cast the data they retrieve from
//! the driver to these types.

use std::collections::BTreeMap;

/// The atomic level of a pointer.
pub type Key = String;

/// Represents a JSON pointer to a document property.
pub type Pointer = Vec<Key>;

/// Various value types. Based on types in the [JSON standard][1] (see section
/// 5).
///
/// [1]: http://ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf
#[derive(PartialEq, Debug)]
pub enum Value {
  /// The abscense of any value.
  Null,
  /// True or false.
  Boolean(bool),
  /// A numeric value, float, integer, whatever.
  Number(f64),
  /// A list of characters.
  String(String),
  /// A list of values.
  Array(Vec<Value>),
  /// A map of key/value pairs.
  Object(BTreeMap<Key, Value>)
}

/// A schema detailing what the data received from the driver (or inserted
/// into the driver) should be. Inspired after [JSON Schema][1]. A reference
/// on JSON Schema type-specific validations used in this enum may be found
/// [here][2].
///
/// [1]: http://json-schema.org
/// [2]: http://spacetelescope.github.io/understanding-json-schema/reference/type.html
pub enum Schema {
  /// There is no schema. No validations should occur.
  None,
  /// Represents the absence of any value.
  Null,
  /// Represents a binary true/false value.
  Boolean,
  /// Represents a numeric type.
  Number {
    /// Forces the number to be a multiple of another. This helps in specifying
    /// integers if this value is `Some(1)` for example.
    multiple_of: Option<f32>,
    /// The minimum value the number can be.
    minimum: Option<f64>,
    /// The maximum value the number can be.
    maximum: Option<f64>
  },
  String {
    /// The mimimum length of characters in the string.
    min_length: Option<u64>,
    /// The maximum length of characters in the string.
    max_length: Option<u64>,
    /// A regular expression pattern to validate the string against.
    // TODO: Use a regex crate.
    pattern: Option<String>
  },
  /// Represents a set of any type.
  Array {
    /// A schema which all items in the array must match.
    items: Box<Schema>
  },
  /// Represents any tuple of values.
  Tuple {
    /// Schemas which each tuple value (in the same place) must comply with.
    items: Vec<Schema>,
    /// Whether or not there can be more items in the tuple.
    additional_items: bool
  },
  /// Represents a set of key/value pairs.
  Object {
    /// Schemas associated to the object properties.
    properties: BTreeMap<Key, Schema>,
    /// Properties that are required to be in the object.
    required: Vec<Key>,
    /// Whether or not there may be extra properties outside of the ones
    /// defined by the properties map.
    additional_properties: bool
  },
  /// Represents a value which *must* be one of the defined values.
  Enum(Vec<Value>)
}
<commit_msg>feat: add reference type to value<commit_after>//! Types representing for data which will be retrieved from the driver.
//! Currently this data is expected to look like a JSON object but this may be
//! changed in the future. Driver authors must cast the data they retrieve from
//! the driver to these types.

use std::collections::BTreeMap;

/// The atomic level of a pointer.
pub type Key = String;

/// Represents a JSON pointer to a document property.
pub type Pointer = Vec<Key>;

/// Various value types. Based on types in the [JSON standard][1] (see section
/// 5).
///
/// [1]: http://ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf
#[derive(PartialEq, Debug)]
pub enum Value {
  /// The abscense of any value.
  Null,
  /// True or false.
  Boolean(bool),
  /// A numeric value, float, integer, whatever.
  Number(f64),
  /// A list of characters.
  String(String),
  /// A list of values.
  Array(Vec<Value>),
  /// A map of key/value pairs.
  Object(BTreeMap<Key, Value>),
  /// References another value somewhere else in the object tree.
  Ref(Pointer)
}

/// A schema detailing what the data received from the driver (or inserted
/// into the driver) should be. Inspired after [JSON Schema][1]. A reference
/// on JSON Schema type-specific validations used in this enum may be found
/// [here][2].
///
/// [1]: http://json-schema.org
/// [2]: http://spacetelescope.github.io/understanding-json-schema/reference/type.html
pub enum Schema {
  /// There is no schema. No validations should occur.
  None,
  /// Represents the absence of any value.
  Null,
  /// Represents a binary true/false value.
  Boolean,
  /// Represents a numeric type.
  Number {
    /// Forces the number to be a multiple of another. This helps in specifying
    /// integers if this value is `Some(1)` for example.
    multiple_of: Option<f32>,
    /// The minimum value the number can be.
    minimum: Option<f64>,
    /// The maximum value the number can be.
    maximum: Option<f64>
  },
  String {
    /// The mimimum length of characters in the string.
    min_length: Option<u64>,
    /// The maximum length of characters in the string.
    max_length: Option<u64>,
    /// A regular expression pattern to validate the string against.
    // TODO: Use a regex crate.
    pattern: Option<String>
  },
  /// Represents a set of any type.
  Array {
    /// A schema which all items in the array must match.
    items: Box<Schema>
  },
  /// Represents any tuple of values.
  Tuple {
    /// Schemas which each tuple value (in the same place) must comply with.
    items: Vec<Schema>,
    /// Whether or not there can be more items in the tuple.
    additional_items: bool
  },
  /// Represents a set of key/value pairs.
  Object {
    /// Schemas associated to the object properties.
    properties: BTreeMap<Key, Schema>,
    /// Properties that are required to be in the object.
    required: Vec<Key>,
    /// Whether or not there may be extra properties outside of the ones
    /// defined by the properties map.
    additional_properties: bool
  },
  /// Represents a value which *must* be one of the defined values.
  Enum(Vec<Value>)
}
<|endoftext|>


<commit_before>//
// Created by Eugene Cherkasov on 03.09.2016.
// Copyright (c) 2014-2016 stage team. All rights reserved.
//

use Number;

#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)]
pub struct Vector2<T: Number> {
    pub x: T,
    pub y: T,
}

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

    const VECTOR_1: Vector2<f32> = Vector2 { x: 10.0, y: 20.0 };
    const VECTOR_2: Vector2<f32> = Vector2 { x: 20.0, y: 20.0 };

    #[test]
    fn test_equal() {
        let vec = VECTOR_1;
        assert_eq!( VECTOR_1 == VECTOR_2, false );
        assert_eq!( VECTOR_1 == vec, true );
    }
}
<commit_msg>Add basic operations for Vector.<commit_after>//
// Created by Eugene Cherkasov on 03.09.2016.
// Copyright (c) 2014-2016 stage team. All rights reserved.
//

//! Math vector with basic operations
//! For now implemented for 2-dimensional space only.

use std::ops::{Add, Sub, Mul};
use Number;

#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)]
pub struct Vector2<T: Number> {
    pub x: T,
    pub y: T,
}

impl<T> Add for Vector2<T> where T: Number, <T as Add>::Output: Number {
    type Output = Vector2<<T as Add>::Output>;

    fn add(self, rhs: Vector2<T>) -> Vector2<<T as Add>::Output> {
        Vector2 { x: self.x + rhs.x, y: self.y + rhs.y }
    }
}

impl<T> Sub for Vector2<T> where T: Number, <T as Sub>::Output: Number {
    type Output = Vector2<<T as Sub>::Output>;

    fn sub(self, rhs: Vector2<T>) -> Vector2<<T as Sub>::Output> {
        Vector2 { x: self.x - rhs.x, y: self.y - rhs.y }
    }
}

impl<T> Mul<T> for Vector2<T> where T: Number, <T as Mul>::Output: Number {
    type Output = Vector2<<T as Mul>::Output>;

    fn mul(self, rhs: T) -> Vector2<<T as Mul>::Output> {
        Vector2 { x: self.x * rhs, y: self.y * rhs }
    }
}

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

    const VECTOR_1: Vector2<f32> = Vector2 { x: 10.0, y: 20.0 };
    const VECTOR_2: Vector2<f32> = Vector2 { x: 20.0, y: 20.0 };

    const SCALE: f32 = 2.0;

    #[test]
    fn test_equal() {
        let vec = VECTOR_1;
        assert_eq!( VECTOR_1 == VECTOR_2, false );
        assert_eq!( VECTOR_1 == vec, true );
    }

    #[test]
    fn test_ops() {
        let v_add = Vector2 { x: VECTOR_1.x + VECTOR_2.x, y: VECTOR_1.y + VECTOR_2.y };
        let v_sub = Vector2 { x: VECTOR_1.x - VECTOR_2.x, y: VECTOR_1.y - VECTOR_2.y };
        let v_mul = Vector2 { x: VECTOR_1.x * SCALE, y: VECTOR_1.y * SCALE };
        assert_eq!(v_add, VECTOR_1 + VECTOR_2);
        assert_eq!(v_sub, VECTOR_1 - VECTOR_2);
        assert_eq!(v_mul, VECTOR_1 * SCALE);
    }
}
<|endoftext|>


<commit_before>//! Graph visitor algorithms.
//!

use std::collections::{
    HashSet,
    VecDeque,
};
use std::hash::Hash;
use fb::FixedBitSet;

use super::{
    graphmap,
    graph,
    EdgeType,
    EdgeDirection,
    Graph,
    GraphMap,
};

use graph::{
    IndexType,
};

/// Base trait for graphs that defines the node identifier.
pub trait Graphlike {
    type NodeId: Clone;
}

/// A graph trait for accessing the neighbors iterator
pub trait NeighborIter<'a> : Graphlike {
    type Iter: Iterator<Item=Self::NodeId>;

    /// Return an iterator that visits all neighbors of the node **n**.
    fn neighbors(&'a self, n: Self::NodeId) -> Self::Iter;
}

impl<'a, N, E, Ty, Ix> NeighborIter<'a> for Graph<N, E, Ty, Ix> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Iter = graph::Neighbors<'a, E, Ix>;
    fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
    {
        Graph::neighbors(self, n)
    }
}

impl<'a, N, E> NeighborIter<'a> for GraphMap<N, E>
where N: Copy + Ord + Hash + Eq
{
    type Iter = graphmap::Neighbors<'a, N>;
    fn neighbors(&'a self, n: N) -> graphmap::Neighbors<'a, N>
    {
        GraphMap::neighbors(self, n)
    }
}

/// Wrapper type for walking the graph as if it is undirected
pub struct AsUndirected<G>(pub G);
/// Wrapper type for walking edges the other way
pub struct Reversed<G>(pub G);

impl<'a, 'b, N, E, Ty, Ix> NeighborIter<'a> for AsUndirected<&'b Graph<N, E, Ty, Ix>> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Iter = graph::Neighbors<'a, E, Ix>;

    fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
    {
        Graph::neighbors_undirected(self.0, n)
    }
}

impl<'a, 'b, N, E, Ty, Ix> NeighborIter<'a> for Reversed<&'b Graph<N, E, Ty, Ix>> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Iter = graph::Neighbors<'a, E, Ix>;
    fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
    {
        Graph::neighbors_directed(self.0, n, EdgeDirection::Incoming)
    }
}

pub trait VisitMap<N> {
    /// Return **true** if the value is not already present.
    fn visit(&mut self, N) -> bool;
    fn is_visited(&self, &N) -> bool;
}

impl<Ix> VisitMap<graph::NodeIndex<Ix>> for FixedBitSet where
    Ix: IndexType,
{
    fn visit(&mut self, x: graph::NodeIndex<Ix>) -> bool {
        let present = self.contains(x.index());
        self.insert(x.index());
        !present
    }
    fn is_visited(&self, x: &graph::NodeIndex<Ix>) -> bool {
        self.contains(x.index())
    }
}

impl<N: Eq + Hash> VisitMap<N> for HashSet<N> {
    fn visit(&mut self, x: N) -> bool {
        self.insert(x)
    }
    fn is_visited(&self, x: &N) -> bool {
        self.contains(x)
    }
}

/// Trait for GraphMap that knows which datastructure is the best for its visitor map
pub trait Visitable : Graphlike {
    type Map: VisitMap<Self::NodeId>;
    fn visit_map(&self) -> Self::Map;
}

impl<N, E, Ty, Ix> Graphlike for Graph<N, E, Ty, Ix> where
    Ix: IndexType,
{
    type NodeId = graph::NodeIndex<Ix>;
}

impl<N, E, Ty, Ix> Visitable for Graph<N, E, Ty, Ix> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Map = FixedBitSet;
    fn visit_map(&self) -> FixedBitSet { FixedBitSet::with_capacity(self.node_count()) }
}

impl<N: Clone, E> Graphlike for GraphMap<N, E>
{
    type NodeId = N;
}

impl<N, E> Visitable for GraphMap<N, E>
    where N: Copy + Ord + Eq + Hash
{
    type Map = HashSet<N>;
    fn visit_map(&self) -> HashSet<N> { HashSet::with_capacity(self.node_count()) }
}

impl<'a, V: Graphlike> Graphlike for AsUndirected<&'a V>
{
    type NodeId = V::NodeId;
}

impl<'a, V: Graphlike> Graphlike for Reversed<&'a V>
{
    type NodeId = V::NodeId;
}

impl<'a, V: Visitable> Visitable for AsUndirected<&'a V>
{
    type Map = V::Map;
    fn visit_map(&self) -> V::Map {
        self.0.visit_map()
    }
}

impl<'a, V: Visitable> Visitable for Reversed<&'a V>
{
    type Map = V::Map;
    fn visit_map(&self) -> V::Map {
        self.0.visit_map()
    }
}

/// Create or access the adjacency matrix of a graph
pub trait GetAdjacencyMatrix : Graphlike {
    type AdjMatrix;
    fn adjacency_matrix(&self) -> Self::AdjMatrix;
    fn is_adjacent(&self, matrix: &Self::AdjMatrix, a: Self::NodeId, b: Self::NodeId) -> bool;
}

/// The **GraphMap** keeps an adjacency matrix internally.
impl<N, E> GetAdjacencyMatrix for GraphMap<N, E>
    where N: Copy + Ord + Eq + Hash
{
    type AdjMatrix = ();
    #[inline]
    fn adjacency_matrix(&self) { }
    #[inline]
    fn is_adjacent(&self, _: &(), a: N, b: N) -> bool {
        self.contains_edge(a, b)
    }
}

/// A depth first search (DFS) of a graph.
///
/// Using a **Dfs** you can run a traversal over a graph while still retaining
/// mutable access to it, if you use it like the following example:
///
/// ```
/// use petgraph::{Graph, Dfs};
///
/// let mut graph = Graph::<_,()>::new();
/// let a = graph.add_node(0);
///
/// let mut dfs = Dfs::new(&graph, a);
/// while let Some(nx) = dfs.next(&graph) {
///     // we can access `graph` mutably here still
///     graph[nx] += 1;
/// }
///
/// assert_eq!(graph[a], 1);
/// ```
///
/// **Note:** The algorithm may not behave correctly if nodes are removed
/// during iteration. It may not necessarily visit added nodes or edges.
#[derive(Clone, Debug)]
pub struct Dfs<N, VM> {
    pub stack: Vec<N>,
    pub discovered: VM,
}

impl<G: Visitable> Dfs<G::NodeId, G::Map>
{
    /// Create a new **Dfs**, using the graph's visitor map, and put **start**
    /// in the stack of nodes to visit.
    pub fn new(graph: &G, start: G::NodeId) -> Self
    {
        let mut dfs = Dfs::empty(graph);
        dfs.move_to(start);
        dfs
    }

    /// Create a new **Dfs** using the graph's visitor map, and no stack.
    pub fn empty(graph: &G) -> Self
    {
        Dfs {
            stack: Vec::new(),
            discovered: graph.visit_map(),
        }
    }
}

impl<N, VM> Dfs<N, VM> where
    N: Clone,
    VM: VisitMap<N>
{
    /// Keep the discovered map, but clear the visit stack and restart
    /// the dfs from a particular node.
    pub fn move_to(&mut self, start: N)
    {
        self.discovered.visit(start.clone());
        self.stack.clear();
        self.stack.push(start);
    }

    /// Return the next node in the dfs, or **None** if the traversal is done.
    pub fn next<G>(&mut self, graph: &G) -> Option<N> where
        G: Graphlike<NodeId=N>,
        G: for<'a> NeighborIter<'a>,
    {
        while let Some(node) = self.stack.pop() {
            for succ in graph.neighbors(node.clone()) {
                if self.discovered.visit(succ.clone()) {
                    self.stack.push(succ);
                }
            }

            return Some(node);
        }
        None
    }
}

/// An iterator for a depth first traversal of a graph.
pub struct DfsIter<'a, G: 'a + Visitable>
{
    graph: &'a G,
    dfs: Dfs<G::NodeId, G::Map>,
}

impl<'a, G: Visitable> DfsIter<'a, G>
{
    pub fn new(graph: &'a G, start: G::NodeId) -> Self
    {
        // Inline the code from Dfs::new to
        // work around rust bug #22841
        let mut dfs = Dfs::empty(graph);
        dfs.move_to(start);
        DfsIter {
            graph: graph,
            dfs: dfs,
        }
    }

    /// Keep the discovered map, but clear the visit stack and restart
    /// the DFS traversal from a particular node.
    pub fn move_to(&mut self, start: G::NodeId)
    {
        self.dfs.move_to(start)
    }
}

impl<'a, G: 'a + Visitable> Iterator for DfsIter<'a, G> where
    G: for<'b> NeighborIter<'b>,
{
    type Item = G::NodeId;

    #[inline]
    fn next(&mut self) -> Option<G::NodeId>
    {
        self.dfs.next(self.graph)
    }

    fn size_hint(&self) -> (usize, Option<usize>)
    {
        // Very vauge info about size of traversal
        (self.dfs.stack.len(), None)
    }
}

impl<'a, G: Visitable> Clone for DfsIter<'a, G> where Dfs<G::NodeId, G::Map>: Clone
{
    fn clone(&self) -> Self {
        DfsIter {
            graph: self.graph,
            dfs: self.dfs.clone(),
        }
    }
}

/// A breadth first search (BFS) of a graph.
///
/// Using a **Bfs** you can run a traversal over a graph while still retaining
/// mutable access to it, if you use it like the following example:
///
/// ```
/// use petgraph::{Graph, Bfs};
///
/// let mut graph = Graph::<_,()>::new();
/// let a = graph.add_node(0);
///
/// let mut bfs = Bfs::new(&graph, a);
/// while let Some(nx) = bfs.next(&graph) {
///     // we can access `graph` mutably here still
///     graph[nx] += 1;
/// }
///
/// assert_eq!(graph[a], 1);
/// ```
///
/// **Note:** The algorithm may not behave correctly if nodes are removed
/// during iteration. It may not necessarily visit added nodes or edges.
#[derive(Clone)]
pub struct Bfs<N, VM> {
    pub stack: VecDeque<N>,
    pub discovered: VM,
}

impl<G: Visitable> Bfs<G::NodeId, G::Map>
{
    /// Create a new **Bfs**, using the graph's visitor map, and put **start**
    /// in the stack of nodes to visit.
    pub fn new(graph: &G, start: G::NodeId) -> Self
    {
        let mut discovered = graph.visit_map();
        discovered.visit(start.clone());
        let mut stack = VecDeque::new();
        stack.push_front(start.clone());
        Bfs {
            stack: stack,
            discovered: discovered,
        }
    }
}

impl<N, VM> Bfs<N, VM> where
    N: Clone,
    VM: VisitMap<N>
{
    /// Return the next node in the dfs, or **None** if the traversal is done.
    pub fn next<G>(&mut self, graph: &G) -> Option<N> where
        G: Graphlike<NodeId=N>,
        G: for<'a> NeighborIter<'a>,
    {
        while let Some(node) = self.stack.pop_front() {
            for succ in graph.neighbors(node.clone()) {
                if self.discovered.visit(succ.clone()) {
                    self.stack.push_back(succ);
                }
            }

            return Some(node);
        }
        None
    }

}

/// An iterator for a breadth first traversal of a graph.
pub struct BfsIter<'a, G: 'a + Visitable>
{
    graph: &'a G,
    bfs: Bfs<G::NodeId, G::Map>,
}

impl<'a, G: Visitable> BfsIter<'a, G> where
    G::NodeId: Clone,
{
    pub fn new(graph: &'a G, start: G::NodeId) -> Self
    {
        // Inline the code from Bfs::new to
        // work around rust bug #22841
        let mut discovered = graph.visit_map();
        discovered.visit(start.clone());
        let mut stack = VecDeque::new();
        stack.push_front(start.clone());
        let bfs = Bfs {
            stack: stack,
            discovered: discovered,
        };
        BfsIter {
            graph: graph,
            bfs: bfs,
        }
    }
}

impl<'a, G: 'a + Visitable> Iterator for BfsIter<'a, G> where
    G::NodeId: Clone,
    G: for<'b> NeighborIter<'b>,
{
    type Item = G::NodeId;
    fn next(&mut self) -> Option<G::NodeId>
    {
        self.bfs.next(self.graph)
    }

    fn size_hint(&self) -> (usize, Option<usize>)
    {
        (self.bfs.stack.len(), None)
    }
}

impl<'a, G: Visitable> Clone for BfsIter<'a, G> where Bfs<G::NodeId, G::Map>: Clone
{
    fn clone(&self) -> Self {
        BfsIter {
            graph: self.graph,
            bfs: self.bfs.clone(),
        }
    }
}
<commit_msg>Edit docs<commit_after>//! Graph visitor algorithms.
//!

use std::collections::{
    HashSet,
    VecDeque,
};
use std::hash::Hash;
use fb::FixedBitSet;

use super::{
    graphmap,
    graph,
    EdgeType,
    EdgeDirection,
    Graph,
    GraphMap,
};

use graph::{
    IndexType,
};

/// Base trait for graphs that defines the node identifier.
pub trait Graphlike {
    type NodeId: Clone;
}

/// A graph trait for accessing the neighbors iterator
pub trait NeighborIter<'a> : Graphlike {
    type Iter: Iterator<Item=Self::NodeId>;

    /// Return an iterator that visits all neighbors of the node **n**.
    fn neighbors(&'a self, n: Self::NodeId) -> Self::Iter;
}

impl<'a, N, E, Ty, Ix> NeighborIter<'a> for Graph<N, E, Ty, Ix> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Iter = graph::Neighbors<'a, E, Ix>;
    fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
    {
        Graph::neighbors(self, n)
    }
}

impl<'a, N, E> NeighborIter<'a> for GraphMap<N, E>
where N: Copy + Ord + Hash + Eq
{
    type Iter = graphmap::Neighbors<'a, N>;
    fn neighbors(&'a self, n: N) -> graphmap::Neighbors<'a, N>
    {
        GraphMap::neighbors(self, n)
    }
}

/// Wrapper type for walking the graph as if it is undirected
pub struct AsUndirected<G>(pub G);
/// Wrapper type for walking edges the other way
pub struct Reversed<G>(pub G);

impl<'a, 'b, N, E, Ty, Ix> NeighborIter<'a> for AsUndirected<&'b Graph<N, E, Ty, Ix>> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Iter = graph::Neighbors<'a, E, Ix>;

    fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
    {
        Graph::neighbors_undirected(self.0, n)
    }
}

impl<'a, 'b, N, E, Ty, Ix> NeighborIter<'a> for Reversed<&'b Graph<N, E, Ty, Ix>> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Iter = graph::Neighbors<'a, E, Ix>;
    fn neighbors(&'a self, n: graph::NodeIndex<Ix>) -> graph::Neighbors<'a, E, Ix>
    {
        Graph::neighbors_directed(self.0, n, EdgeDirection::Incoming)
    }
}

/// A mapping from node → is_visited.
pub trait VisitMap<N> {
    /// Return **true** if the value is not already present.
    fn visit(&mut self, N) -> bool;
    fn is_visited(&self, &N) -> bool;
}

impl<Ix> VisitMap<graph::NodeIndex<Ix>> for FixedBitSet where
    Ix: IndexType,
{
    fn visit(&mut self, x: graph::NodeIndex<Ix>) -> bool {
        let present = self.contains(x.index());
        self.insert(x.index());
        !present
    }
    fn is_visited(&self, x: &graph::NodeIndex<Ix>) -> bool {
        self.contains(x.index())
    }
}

impl<N: Eq + Hash> VisitMap<N> for HashSet<N> {
    fn visit(&mut self, x: N) -> bool {
        self.insert(x)
    }
    fn is_visited(&self, x: &N) -> bool {
        self.contains(x)
    }
}

/// Trait for GraphMap that knows which datastructure is the best for its visitor map
pub trait Visitable : Graphlike {
    type Map: VisitMap<Self::NodeId>;
    fn visit_map(&self) -> Self::Map;
}

impl<N, E, Ty, Ix> Graphlike for Graph<N, E, Ty, Ix> where
    Ix: IndexType,
{
    type NodeId = graph::NodeIndex<Ix>;
}

impl<N, E, Ty, Ix> Visitable for Graph<N, E, Ty, Ix> where
    Ty: EdgeType,
    Ix: IndexType,
{
    type Map = FixedBitSet;
    fn visit_map(&self) -> FixedBitSet { FixedBitSet::with_capacity(self.node_count()) }
}

impl<N: Clone, E> Graphlike for GraphMap<N, E>
{
    type NodeId = N;
}

impl<N, E> Visitable for GraphMap<N, E>
    where N: Copy + Ord + Eq + Hash
{
    type Map = HashSet<N>;
    fn visit_map(&self) -> HashSet<N> { HashSet::with_capacity(self.node_count()) }
}

impl<'a, V: Graphlike> Graphlike for AsUndirected<&'a V>
{
    type NodeId = V::NodeId;
}

impl<'a, V: Graphlike> Graphlike for Reversed<&'a V>
{
    type NodeId = V::NodeId;
}

impl<'a, V: Visitable> Visitable for AsUndirected<&'a V>
{
    type Map = V::Map;
    fn visit_map(&self) -> V::Map {
        self.0.visit_map()
    }
}

impl<'a, V: Visitable> Visitable for Reversed<&'a V>
{
    type Map = V::Map;
    fn visit_map(&self) -> V::Map {
        self.0.visit_map()
    }
}

/// Create or access the adjacency matrix of a graph
pub trait GetAdjacencyMatrix : Graphlike {
    type AdjMatrix;
    fn adjacency_matrix(&self) -> Self::AdjMatrix;
    fn is_adjacent(&self, matrix: &Self::AdjMatrix, a: Self::NodeId, b: Self::NodeId) -> bool;
}

/// The **GraphMap** keeps an adjacency matrix internally.
impl<N, E> GetAdjacencyMatrix for GraphMap<N, E>
    where N: Copy + Ord + Eq + Hash
{
    type AdjMatrix = ();
    #[inline]
    fn adjacency_matrix(&self) { }
    #[inline]
    fn is_adjacent(&self, _: &(), a: N, b: N) -> bool {
        self.contains_edge(a, b)
    }
}

/// A depth first search (DFS) of a graph.
///
/// Using a **Dfs** you can run a traversal over a graph while still retaining
/// mutable access to it, if you use it like the following example:
///
/// ```
/// use petgraph::{Graph, Dfs};
///
/// let mut graph = Graph::<_,()>::new();
/// let a = graph.add_node(0);
///
/// let mut dfs = Dfs::new(&graph, a);
/// while let Some(nx) = dfs.next(&graph) {
///     // we can access `graph` mutably here still
///     graph[nx] += 1;
/// }
///
/// assert_eq!(graph[a], 1);
/// ```
///
/// **Note:** The algorithm may not behave correctly if nodes are removed
/// during iteration. It may not necessarily visit added nodes or edges.
#[derive(Clone, Debug)]
pub struct Dfs<N, VM> {
    /// The stack of nodes to visit
    pub stack: Vec<N>,
    /// The map of discovered nodes
    pub discovered: VM,
}

impl<G: Visitable> Dfs<G::NodeId, G::Map>
{
    /// Create a new **Dfs**, using the graph's visitor map, and put **start**
    /// in the stack of nodes to visit.
    pub fn new(graph: &G, start: G::NodeId) -> Self
    {
        let mut dfs = Dfs::empty(graph);
        dfs.move_to(start);
        dfs
    }

    /// Create a new **Dfs** using the graph's visitor map, and no stack.
    pub fn empty(graph: &G) -> Self
    {
        Dfs {
            stack: Vec::new(),
            discovered: graph.visit_map(),
        }
    }
}

impl<N, VM> Dfs<N, VM> where
    N: Clone,
    VM: VisitMap<N>
{
    /// Keep the discovered map, but clear the visit stack and restart
    /// the dfs from a particular node.
    pub fn move_to(&mut self, start: N)
    {
        self.discovered.visit(start.clone());
        self.stack.clear();
        self.stack.push(start);
    }

    /// Return the next node in the dfs, or **None** if the traversal is done.
    pub fn next<G>(&mut self, graph: &G) -> Option<N> where
        G: Graphlike<NodeId=N>,
        G: for<'a> NeighborIter<'a>,
    {
        while let Some(node) = self.stack.pop() {
            for succ in graph.neighbors(node.clone()) {
                if self.discovered.visit(succ.clone()) {
                    self.stack.push(succ);
                }
            }

            return Some(node);
        }
        None
    }
}

/// An iterator for a depth first traversal of a graph.
pub struct DfsIter<'a, G: 'a + Visitable>
{
    graph: &'a G,
    dfs: Dfs<G::NodeId, G::Map>,
}

impl<'a, G: Visitable> DfsIter<'a, G>
{
    pub fn new(graph: &'a G, start: G::NodeId) -> Self
    {
        // Inline the code from Dfs::new to
        // work around rust bug #22841
        let mut dfs = Dfs::empty(graph);
        dfs.move_to(start);
        DfsIter {
            graph: graph,
            dfs: dfs,
        }
    }

    /// Keep the discovered map, but clear the visit stack and restart
    /// the DFS traversal from a particular node.
    pub fn move_to(&mut self, start: G::NodeId)
    {
        self.dfs.move_to(start)
    }
}

impl<'a, G: 'a + Visitable> Iterator for DfsIter<'a, G> where
    G: for<'b> NeighborIter<'b>,
{
    type Item = G::NodeId;

    #[inline]
    fn next(&mut self) -> Option<G::NodeId>
    {
        self.dfs.next(self.graph)
    }

    fn size_hint(&self) -> (usize, Option<usize>)
    {
        // Very vauge info about size of traversal
        (self.dfs.stack.len(), None)
    }
}

impl<'a, G: Visitable> Clone for DfsIter<'a, G> where Dfs<G::NodeId, G::Map>: Clone
{
    fn clone(&self) -> Self {
        DfsIter {
            graph: self.graph,
            dfs: self.dfs.clone(),
        }
    }
}

/// A breadth first search (BFS) of a graph.
///
/// Using a **Bfs** you can run a traversal over a graph while still retaining
/// mutable access to it, if you use it like the following example:
///
/// ```
/// use petgraph::{Graph, Bfs};
///
/// let mut graph = Graph::<_,()>::new();
/// let a = graph.add_node(0);
///
/// let mut bfs = Bfs::new(&graph, a);
/// while let Some(nx) = bfs.next(&graph) {
///     // we can access `graph` mutably here still
///     graph[nx] += 1;
/// }
///
/// assert_eq!(graph[a], 1);
/// ```
///
/// **Note:** The algorithm may not behave correctly if nodes are removed
/// during iteration. It may not necessarily visit added nodes or edges.
#[derive(Clone)]
pub struct Bfs<N, VM> {
    /// The queue of nodes to visit
    pub stack: VecDeque<N>,
    /// The map of discovered nodes
    pub discovered: VM,
}

impl<G: Visitable> Bfs<G::NodeId, G::Map>
{
    /// Create a new **Bfs**, using the graph's visitor map, and put **start**
    /// in the stack of nodes to visit.
    pub fn new(graph: &G, start: G::NodeId) -> Self
    {
        let mut discovered = graph.visit_map();
        discovered.visit(start.clone());
        let mut stack = VecDeque::new();
        stack.push_front(start.clone());
        Bfs {
            stack: stack,
            discovered: discovered,
        }
    }
}

impl<N, VM> Bfs<N, VM> where
    N: Clone,
    VM: VisitMap<N>
{
    /// Return the next node in the dfs, or **None** if the traversal is done.
    pub fn next<G>(&mut self, graph: &G) -> Option<N> where
        G: Graphlike<NodeId=N>,
        G: for<'a> NeighborIter<'a>,
    {
        while let Some(node) = self.stack.pop_front() {
            for succ in graph.neighbors(node.clone()) {
                if self.discovered.visit(succ.clone()) {
                    self.stack.push_back(succ);
                }
            }

            return Some(node);
        }
        None
    }

}

/// An iterator for a breadth first traversal of a graph.
pub struct BfsIter<'a, G: 'a + Visitable>
{
    graph: &'a G,
    bfs: Bfs<G::NodeId, G::Map>,
}

impl<'a, G: Visitable> BfsIter<'a, G> where
    G::NodeId: Clone,
{
    pub fn new(graph: &'a G, start: G::NodeId) -> Self
    {
        // Inline the code from Bfs::new to
        // work around rust bug #22841
        let mut discovered = graph.visit_map();
        discovered.visit(start.clone());
        let mut stack = VecDeque::new();
        stack.push_front(start.clone());
        let bfs = Bfs {
            stack: stack,
            discovered: discovered,
        };
        BfsIter {
            graph: graph,
            bfs: bfs,
        }
    }
}

impl<'a, G: 'a + Visitable> Iterator for BfsIter<'a, G> where
    G::NodeId: Clone,
    G: for<'b> NeighborIter<'b>,
{
    type Item = G::NodeId;
    fn next(&mut self) -> Option<G::NodeId>
    {
        self.bfs.next(self.graph)
    }

    fn size_hint(&self) -> (usize, Option<usize>)
    {
        (self.bfs.stack.len(), None)
    }
}

impl<'a, G: Visitable> Clone for BfsIter<'a, G> where Bfs<G::NodeId, G::Map>: Clone
{
    fn clone(&self) -> Self {
        BfsIter {
            graph: self.graph,
            bfs: self.bfs.clone(),
        }
    }
}
<|endoftext|>


<commit_before>//! See librustc_codegen_llvm/meth.rs for reference

use crate::prelude::*;

const DROP_FN_INDEX: usize = 0;
const SIZE_INDEX: usize = 1;
const ALIGN_INDEX: usize = 2;

pub fn size_of_obj<'a, 'tcx: 'a>(
    fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
    vtable: Value,
) -> Value {
    let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize;
    fx.bcx.ins().load(
        pointer_ty(fx.tcx),
        MemFlags::new(),
        vtable,
        (SIZE_INDEX * usize_size) as i32,
    )
}

pub fn min_align_of_obj<'a, 'tcx: 'a>(
    fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
    vtable: Value,
) -> Value {
    let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize;
    fx.bcx.ins().load(
        pointer_ty(fx.tcx),
        MemFlags::new(),
        vtable,
        (ALIGN_INDEX * usize_size) as i32,
    )
}

pub fn get_ptr_and_method_ref<'a, 'tcx: 'a>(
    fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
    arg: CValue<'tcx>,
    idx: usize,
) -> (Value, Value) {
    let (ptr, vtable) = arg.load_value_pair(fx);
    let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes();
    let func_ref = fx.bcx.ins().load(
        pointer_ty(fx.tcx),
        MemFlags::new(),
        vtable,
        ((idx + 3) * usize_size as usize) as i32,
    );
    (ptr, func_ref)
}

pub fn get_vtable<'a, 'tcx: 'a>(
    fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
    ty: Ty<'tcx>,
    trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
) -> Value {
    let data_id = if let Some(data_id) = fx.caches.vtables.get(&(ty, trait_ref)) {
        *data_id
    } else {
        let data_id = build_vtable(fx, ty, trait_ref);
        fx.caches.vtables.insert((ty, trait_ref), data_id);
        data_id
    };

    let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
    fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
}

fn build_vtable<'a, 'tcx: 'a>(
    fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
    ty: Ty<'tcx>,
    trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
) -> DataId {
    let tcx = fx.tcx;
    let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize;

    let drop_in_place_fn = import_function(
        tcx,
        fx.module,
        crate::rustc_mir::monomorphize::resolve_drop_in_place(tcx, ty),
    );

    let mut components: Vec<_> = vec![Some(drop_in_place_fn), None, None];

    let methods_root;
    let methods = if let Some(trait_ref) = trait_ref {
        methods_root = tcx.vtable_methods(trait_ref.with_self_ty(tcx, ty));
        methods_root.iter()
    } else {
        (&[]).iter()
    };
    let methods = methods.cloned().map(|opt_mth| {
        opt_mth.map_or(None, |(def_id, substs)| {
            Some(import_function(
                tcx,
                fx.module,
                Instance::resolve(tcx, ParamEnv::reveal_all(), def_id, substs).unwrap(),
            ))
        })
    });
    components.extend(methods);

    let mut data_ctx = DataContext::new();
    let mut data = ::std::iter::repeat(0u8)
        .take(components.len() * usize_size)
        .collect::<Vec<u8>>()
        .into_boxed_slice();

    let layout = tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap();
    write_usize(fx.tcx, &mut data, SIZE_INDEX, layout.size.bytes());
    write_usize(fx.tcx, &mut data, ALIGN_INDEX, layout.align.abi.bytes());
    data_ctx.define(data);

    for (i, component) in components.into_iter().enumerate() {
        if let Some(func_id) = component {
            let func_ref = fx.module.declare_func_in_data(func_id, &mut data_ctx);
            data_ctx.write_function_addr((i * usize_size) as u32, func_ref);
        }
    }

    let data_id = fx
        .module
        .declare_data(
            &format!("vtable.{:?}.for.{:?}", trait_ref, ty),
            Linkage::Local,
            false,
        )
        .unwrap();
    fx.module.define_data(data_id, &data_ctx).unwrap();
    data_id
}

fn write_usize(tcx: TyCtxt, buf: &mut [u8], idx: usize, num: u64) {
    use byteorder::{BigEndian, LittleEndian, WriteBytesExt};

    let usize_size = tcx
        .layout_of(ParamEnv::reveal_all().and(tcx.types.usize))
        .unwrap()
        .size
        .bytes() as usize;
    let mut target = &mut buf[idx * usize_size..(idx + 1) * usize_size];

    match tcx.data_layout.endian {
        layout::Endian::Little => target.write_uint::<LittleEndian>(num, usize_size),
        layout::Endian::Big => target.write_uint::<BigEndian>(num, usize_size),
    }
    .unwrap()
}
<commit_msg>Implement dynamic dispatch for self: Box<T><commit_after>//! See librustc_codegen_llvm/meth.rs for reference

use crate::prelude::*;

const DROP_FN_INDEX: usize = 0;
const SIZE_INDEX: usize = 1;
const ALIGN_INDEX: usize = 2;

pub fn size_of_obj<'a, 'tcx: 'a>(
    fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
    vtable: Value,
) -> Value {
    let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize;
    fx.bcx.ins().load(
        pointer_ty(fx.tcx),
        MemFlags::new(),
        vtable,
        (SIZE_INDEX * usize_size) as i32,
    )
}

pub fn min_align_of_obj<'a, 'tcx: 'a>(
    fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
    vtable: Value,
) -> Value {
    let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize;
    fx.bcx.ins().load(
        pointer_ty(fx.tcx),
        MemFlags::new(),
        vtable,
        (ALIGN_INDEX * usize_size) as i32,
    )
}

pub fn get_ptr_and_method_ref<'a, 'tcx: 'a>(
    fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
    arg: CValue<'tcx>,
    idx: usize,
) -> (Value, Value) {
    let arg = if arg.layout().ty.is_box() {
        // Cast `Box<T>` to `*mut T` so `load_value_pair` works
        arg.unchecked_cast_to(fx.layout_of(fx.tcx.mk_mut_ptr(arg.layout().ty.boxed_ty())))
    } else {
        arg
    };

    let (ptr, vtable) = arg.load_value_pair(fx);
    let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes();
    let func_ref = fx.bcx.ins().load(
        pointer_ty(fx.tcx),
        MemFlags::new(),
        vtable,
        ((idx + 3) * usize_size as usize) as i32,
    );
    (ptr, func_ref)
}

pub fn get_vtable<'a, 'tcx: 'a>(
    fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
    ty: Ty<'tcx>,
    trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
) -> Value {
    let data_id = if let Some(data_id) = fx.caches.vtables.get(&(ty, trait_ref)) {
        *data_id
    } else {
        let data_id = build_vtable(fx, ty, trait_ref);
        fx.caches.vtables.insert((ty, trait_ref), data_id);
        data_id
    };

    let local_data_id = fx.module.declare_data_in_func(data_id, &mut fx.bcx.func);
    fx.bcx.ins().global_value(fx.pointer_type, local_data_id)
}

fn build_vtable<'a, 'tcx: 'a>(
    fx: &mut FunctionCx<'a, 'tcx, impl Backend>,
    ty: Ty<'tcx>,
    trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
) -> DataId {
    let tcx = fx.tcx;
    let usize_size = fx.layout_of(fx.tcx.types.usize).size.bytes() as usize;

    let drop_in_place_fn = import_function(
        tcx,
        fx.module,
        crate::rustc_mir::monomorphize::resolve_drop_in_place(tcx, ty),
    );

    let mut components: Vec<_> = vec![Some(drop_in_place_fn), None, None];

    let methods_root;
    let methods = if let Some(trait_ref) = trait_ref {
        methods_root = tcx.vtable_methods(trait_ref.with_self_ty(tcx, ty));
        methods_root.iter()
    } else {
        (&[]).iter()
    };
    let methods = methods.cloned().map(|opt_mth| {
        opt_mth.map_or(None, |(def_id, substs)| {
            Some(import_function(
                tcx,
                fx.module,
                Instance::resolve(tcx, ParamEnv::reveal_all(), def_id, substs).unwrap(),
            ))
        })
    });
    components.extend(methods);

    let mut data_ctx = DataContext::new();
    let mut data = ::std::iter::repeat(0u8)
        .take(components.len() * usize_size)
        .collect::<Vec<u8>>()
        .into_boxed_slice();

    let layout = tcx.layout_of(ParamEnv::reveal_all().and(ty)).unwrap();
    write_usize(fx.tcx, &mut data, SIZE_INDEX, layout.size.bytes());
    write_usize(fx.tcx, &mut data, ALIGN_INDEX, layout.align.abi.bytes());
    data_ctx.define(data);

    for (i, component) in components.into_iter().enumerate() {
        if let Some(func_id) = component {
            let func_ref = fx.module.declare_func_in_data(func_id, &mut data_ctx);
            data_ctx.write_function_addr((i * usize_size) as u32, func_ref);
        }
    }

    let data_id = fx
        .module
        .declare_data(
            &format!("vtable.{:?}.for.{:?}", trait_ref, ty),
            Linkage::Local,
            false,
        )
        .unwrap();
    fx.module.define_data(data_id, &data_ctx).unwrap();
    data_id
}

fn write_usize(tcx: TyCtxt, buf: &mut [u8], idx: usize, num: u64) {
    use byteorder::{BigEndian, LittleEndian, WriteBytesExt};

    let usize_size = tcx
        .layout_of(ParamEnv::reveal_all().and(tcx.types.usize))
        .unwrap()
        .size
        .bytes() as usize;
    let mut target = &mut buf[idx * usize_size..(idx + 1) * usize_size];

    match tcx.data_layout.endian {
        layout::Endian::Little => target.write_uint::<LittleEndian>(num, usize_size),
        layout::Endian::Big => target.write_uint::<BigEndian>(num, usize_size),
    }
    .unwrap()
}
<|endoftext|>


<commit_before>use super::{Event, Renderer};

use std::any::Any;

pub trait Widget : Any {
    fn draw(&self, renderer: &mut Renderer, focused: bool);
    fn event(&self, event: Event, focused: bool, redraw: &mut bool) -> bool;
}
<commit_msg>Implement WidgetCore to share the same fields that each widget uses<commit_after>use super::{Color, Event, Rect, Renderer};

use std::any::Any;
use std::cell::Cell;

pub struct WidgetCore {
    pub rect: Cell<Rect>,
    pub bg: Color,
    pub fg: Color,
}

impl WidgetCore {
    pub fn new(bg: Color, fg: Color) -> Self {
        WidgetCore {
            rect: Cell::new(Rect::default()),
            bg: bg,
            fg: fg,
        }
    }
}

pub trait Widget : Any {
    fn draw(&self, renderer: &mut Renderer, focused: bool);
    fn event(&self, event: Event, focused: bool, redraw: &mut bool) -> bool;
}
<|endoftext|>