<commit_before>extern crate chrono;

use self::chrono::{DateTime, Utc, TimeZone};
use std::env;

pub fn read_env_var(var: &str) -> String {
    env::var_os(var)
        .expect(&format!(
            "{} must be specified. \
             Did you forget to add it to your .env file?",
            var
        ))
        .into_string()
        .expect(&format!("{} does not contain a valid UTF8 string", var))
}

pub fn elapsed_ms(from: DateTime<Utc>, to: DateTime<Utc>) -> Result<u64, ()> {
    let ms = to.signed_duration_since(from).num_milliseconds();
    if ms >= 0 { Ok(ms as u64) } else { Err(()) }
}

pub fn timestamp() -> u64 {
    elapsed_ms(Utc.timestamp(0, 0), Utc::now()).expect("Time went backwards")
}

pub fn clamp<T>(val: T, min: T, max: T) -> T
where
    T: Ord,
{
    match (val < min, val > max) {
        (true, _) => min,
        (_, true) => max,
        _ => val,
    }
}

#[macro_export]
macro_rules! newtype {
    (  $name:ident($type:ty)  ) => {
        pub struct $name(pub $type);
        add_impl!($name, $type);
    };
    (  $name:ident($type:ty) : $($derives:meta), + ) => {
        #[derive(
            $($derives,)+
        )]
        pub struct $name(pub $type);
        add_impl!($name, $type);
    };
}

macro_rules! add_impl {
     (  $name:ident, $type:ty ) => {
         impl Deref for $name {
            type Target = $type;

            fn deref(&self) -> &$type {
                &self.0
            }
        }
        impl DerefMut for $name {
            fn deref_mut(&mut self) -> &mut $type {
                &mut self.0
            }
        }
        impl From<$type> for $name {
            fn from(t: $type) -> Self {
                $name(t)
            }
        }
     };
}

#[test]
fn read_string_envvar() {
    env::set_var("TEST", "foo");
    assert_eq!("foo", &read_env_var("TEST"));
}

#[test]
#[should_panic]
fn read_empty_envvar() {
    env::remove_var("EMPTY");
    read_env_var("EMPTY");
}

#[test]
fn one_elapsed_ms() {
    let a = Utc.ymd(1970, 1, 1).and_hms_milli(0, 0, 0, 0);
    let b = Utc.ymd(1970, 1, 1).and_hms_milli(0, 0, 0, 1);
    assert_eq!(1, elapsed_ms(a, b).unwrap());
}

#[test]
fn one_elapsed_second() {
    let a = Utc.ymd(1970, 1, 1).and_hms_milli(0, 0, 0, 0);
    let b = Utc.ymd(1970, 1, 1).and_hms(0, 0, 1);
    assert_eq!(1000, elapsed_ms(a, b).unwrap());
}

#[test]
fn no_elapsed_time() {
    let a = Utc.ymd(1970, 1, 1).and_hms(0, 0, 1);
    assert_eq!(0, elapsed_ms(a, a).unwrap());
}

#[test]
fn negative_elapsed_time() {
    let a = Utc.ymd(1970, 1, 1).and_hms(0, 0, 1);
    let b = Utc.ymd(1970, 1, 1).and_hms(0, 0, 0);
    assert!(elapsed_ms(a, b).is_err());
}

#[test]
fn timestamp_wait() {
    use std::thread;
    use std::time::Duration;

    let a = timestamp();
    let delta = 420;
    thread::sleep(Duration::from_millis(delta));
    let b = timestamp();
    assert!(b - a >= delta)
}

#[test]
fn clamp_in_range() {
    let res = clamp(1, 0, 2);
    assert_eq!(1, res);
}

#[test]
fn clamp_min() {
    let res = clamp(-2, -2, 2);
    assert_eq!(-2, res);
}

#[test]
fn clamp_max() {
    let res = clamp(0, -2, 0);
    assert_eq!(0, res);
}

#[test]
fn clamp_less_than_min() {
    let res = clamp(-1, 0, 2);
    assert_eq!(0, res);
}

#[test]
fn clamp_more_than_max() {
    let res = clamp(999, 9, 10);
    assert_eq!(10, res);
}
<commit_msg>Core: Rewrite timestamp as a result of paranoic distrust of chrono<commit_after>extern crate chrono;

use self::chrono::{DateTime, Utc};
use std::env;
use std::time::{SystemTime, UNIX_EPOCH};

pub fn read_env_var(var: &str) -> String {
    env::var_os(var)
        .expect(&format!(
            "{} must be specified. \
             Did you forget to add it to your .env file?",
            var
        ))
        .into_string()
        .expect(&format!("{} does not contain a valid UTF8 string", var))
}

pub fn elapsed_ms(from: DateTime<Utc>, to: DateTime<Utc>) -> Result<u64, ()> {
    let ms = to.signed_duration_since(from).num_milliseconds();
    if ms >= 0 {
        Ok(ms as u64)
    } else {
        Err(())
    }
}

pub fn timestamp() -> u64 {
    let now = SystemTime::now();
    let elapsed = now.duration_since(UNIX_EPOCH).expect("Time went backwards");
    let in_ms = elapsed.as_secs() * 1000 + elapsed.subsec_nanos() as u64 / 1_000_000;
    in_ms
}

pub fn clamp<T>(val: T, min: T, max: T) -> T
where
    T: Ord,
{
    match (val < min, val > max) {
        (true, _) => min,
        (_, true) => max,
        _ => val,
    }
}

#[macro_export]
macro_rules! newtype {
    (  $name:ident($type:ty)  ) => {
        pub struct $name(pub $type);
        add_impl!($name, $type);
    };
    (  $name:ident($type:ty) : $($derives:meta), + ) => {
        #[derive(
            $($derives,)+
        )]
        pub struct $name(pub $type);
        add_impl!($name, $type);
    };
}

macro_rules! add_impl {
     (  $name:ident, $type:ty ) => {
         impl Deref for $name {
            type Target = $type;

            fn deref(&self) -> &$type {
                &self.0
            }
        }
        impl DerefMut for $name {
            fn deref_mut(&mut self) -> &mut $type {
                &mut self.0
            }
        }
        impl From<$type> for $name {
            fn from(t: $type) -> Self {
                $name(t)
            }
        }
     };
}

#[cfg(test)]
use util::chrono::TimeZone;

#[test]
fn read_string_envvar() {
    env::set_var("TEST", "foo");
    assert_eq!("foo", &read_env_var("TEST"));
}

#[test]
#[should_panic]
fn read_empty_envvar() {
    env::remove_var("EMPTY");
    read_env_var("EMPTY");
}

#[test]
fn one_elapsed_ms() {
    let a = Utc.ymd(1970, 1, 1).and_hms_milli(0, 0, 0, 0);
    let b = Utc.ymd(1970, 1, 1).and_hms_milli(0, 0, 0, 1);
    assert_eq!(1, elapsed_ms(a, b).unwrap());
}

#[test]
fn one_elapsed_second() {
    let a = Utc.ymd(1970, 1, 1).and_hms_milli(0, 0, 0, 0);
    let b = Utc.ymd(1970, 1, 1).and_hms(0, 0, 1);
    assert_eq!(1000, elapsed_ms(a, b).unwrap());
}

#[test]
fn no_elapsed_time() {
    let a = Utc.ymd(1970, 1, 1).and_hms(0, 0, 1);
    assert_eq!(0, elapsed_ms(a, a).unwrap());
}

#[test]
fn negative_elapsed_time() {
    let a = Utc.ymd(1970, 1, 1).and_hms(0, 0, 1);
    let b = Utc.ymd(1970, 1, 1).and_hms(0, 0, 0);
    assert!(elapsed_ms(a, b).is_err());
}

#[test]
fn timestamp_wait() {
    use std::thread;
    use std::time::Duration;

    let a = timestamp();
    let delta = 420;
    thread::sleep(Duration::from_millis(delta));
    let b = timestamp();
    assert!(b - a >= delta)
}

#[test]
fn clamp_in_range() {
    let res = clamp(1, 0, 2);
    assert_eq!(1, res);
}

#[test]
fn clamp_min() {
    let res = clamp(-2, -2, 2);
    assert_eq!(-2, res);
}

#[test]
fn clamp_max() {
    let res = clamp(0, -2, 0);
    assert_eq!(0, res);
}

#[test]
fn clamp_less_than_min() {
    let res = clamp(-1, 0, 2);
    assert_eq!(0, res);
}

#[test]
fn clamp_more_than_max() {
    let res = clamp(999, 9, 10);
    assert_eq!(10, res);
}
<|endoftext|>


<commit_before>// spell-checker:ignore (ToDO) fperm

extern crate libc;
use libc::{mode_t, S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR};

use uucore::mode;

pub fn parse_mode(mode: Option<String>) -> Result<mode_t, String> {
    let fperm = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
    if let Some(mode) = mode {
        let arr: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
        let result = if mode.contains(arr) {
            mode::parse_numeric(fperm as u32, mode.as_str())
        } else {
            mode::parse_symbolic(fperm as u32, mode.as_str(), true)
        };
        result.map(|mode| mode as mode_t)
    } else {
        Ok(fperm)
    }
}

#[test]
fn symbolic_modes() {
    assert_eq!(parse_mode(Some("u+x".to_owned())).unwrap(), 0o766);
    assert_eq!(parse_mode(Some("+x".to_owned())).unwrap(), 0o777);
    assert_eq!(parse_mode(Some("a-w".to_owned())).unwrap(), 0o444);
    assert_eq!(parse_mode(Some("g-r".to_owned())).unwrap(), 0o626);
}

#[test]
fn numeric_modes() {
    assert_eq!(parse_mode(Some("644".to_owned())).unwrap(), 0o644);
    assert_eq!(parse_mode(Some("+100".to_owned())).unwrap(), 0o766);
    assert_eq!(parse_mode(Some("-4".to_owned())).unwrap(), 0o662);
    assert_eq!(parse_mode(None).unwrap(), 0o666);
}
<commit_msg>tests ~ (sub-crate/mknod) fix WSL variation in expected test values<commit_after>// spell-checker:ignore (ToDO) fperm

extern crate libc;
use libc::{mode_t, S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR};

use uucore::mode;

pub fn parse_mode(mode: Option<String>) -> Result<mode_t, String> {
    let fperm = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
    if let Some(mode) = mode {
        let arr: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
        let result = if mode.contains(arr) {
            mode::parse_numeric(fperm as u32, mode.as_str())
        } else {
            mode::parse_symbolic(fperm as u32, mode.as_str(), true)
        };
        result.map(|mode| mode as mode_t)
    } else {
        Ok(fperm)
    }
}

#[cfg(test)]
mod test {
    /// Test if the program is running under WSL
    // ref: <https://github.com/microsoft/WSL/issues/4555> @@ <https://archive.is/dP0bz>
    // ToDO: test on WSL2 which likely doesn't need special handling; plan change to `is_wsl_1()` if WSL2 is less needy
    pub fn is_wsl() -> bool {
        #[cfg(target_os = "linux")]
        {
            if let Ok(b) = std::fs::read("/proc/sys/kernel/osrelease") {
                if let Ok(s) = std::str::from_utf8(&b) {
                    let a = s.to_ascii_lowercase();
                    return a.contains("microsoft") || a.contains("wsl");
                }
            }
        }
        false
    }

    #[test]
    fn symbolic_modes() {
        assert_eq!(super::parse_mode(Some("u+x".to_owned())).unwrap(), 0o766);
        assert_eq!(super::parse_mode(Some("+x".to_owned())).unwrap(), if !is_wsl() { 0o777 } else {0o776});
        assert_eq!(super::parse_mode(Some("a-w".to_owned())).unwrap(), 0o444);
        assert_eq!(super::parse_mode(Some("g-r".to_owned())).unwrap(), 0o626);
    }

    #[test]
    fn numeric_modes() {
        assert_eq!(super::parse_mode(Some("644".to_owned())).unwrap(), 0o644);
        assert_eq!(super::parse_mode(Some("+100".to_owned())).unwrap(), 0o766);
        assert_eq!(super::parse_mode(Some("-4".to_owned())).unwrap(), 0o662);
        assert_eq!(super::parse_mode(None).unwrap(), 0o666);
    }
}
<|endoftext|>


<commit_before>extern crate gl;
extern crate glfw;

use gl::types::*;
use glfw::{Context, OpenGlProfileHint, WindowHint, WindowMode};

fn main() {
    let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

    glfw.window_hint(WindowHint::ContextVersion(3, 2));
    glfw.window_hint(WindowHint::OpenGlProfile(OpenGlProfileHint::Core));
    glfw.window_hint(WindowHint::OpenGlForwardCompat(true));
    glfw.window_hint(WindowHint::Resizable(false));

    let (mut window, events) = glfw.create_window(800, 600, "OpenGL", WindowMode::Windowed)
        .expect("Failed to create GLFW window.");

    window.set_key_polling(true);
    window.make_current();

    // Load OpenGL function addresses.
    gl::load_with(|symbol| window.get_proc_address(symbol));

    // Test calling OpenGL.
    let mut vertex_buffer: GLuint = 0;
    unsafe { gl::GenBuffers(1, &mut vertex_buffer); }
    println!("{:?}", vertex_buffer);

    while !window.should_close() {
        glfw.poll_events();

        for (_, event) in glfw::flush_messages(&events) {
            handle_window_event(&mut window, event);
        }

        window.swap_buffers();
    }
}

fn handle_window_event(window: &mut glfw::Window, event: glfw::WindowEvent) {
    use glfw::{Action, Key, WindowEvent};

    match event {
        WindowEvent::Key(Key::Escape, _, Action::Press, _) => {
            window.set_should_close(true);
        },
        _ => {},
    }
}
<commit_msg>Add some comments and a bit more involved GL testing.<commit_after>extern crate gl;
extern crate glfw;

use gl::types::*;
use glfw::{Context, OpenGlProfileHint, WindowHint, WindowMode};

fn main() {
    let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

    glfw.window_hint(WindowHint::ContextVersion(3, 2));
    glfw.window_hint(WindowHint::OpenGlProfile(OpenGlProfileHint::Core));
    glfw.window_hint(WindowHint::OpenGlForwardCompat(true));
    glfw.window_hint(WindowHint::Resizable(false));

    let (mut window, events) = glfw.create_window(800, 600, "OpenGL", WindowMode::Windowed)
        .expect("Failed to create GLFW window.");

    // Listen for keyboard events on this window.
    window.set_key_polling(true);

    // Make this window's OpenGL context the current context. This must be done before calling
    // `gl::load_with`.
    window.make_current();

    // Load OpenGL function pointers.
    gl::load_with(|symbol| window.get_proc_address(symbol));

    static VERTICES: [GLfloat; 6] = [
         0.0,  0.5,
         0.5, -0.5,
        -0.5, -0.5,
    ];

    let mut vbo = 0;

    unsafe {
        gl::GenBuffers(1, &mut vbo);
        gl::BindBuffer(gl::ARRAY_BUFFER, vbo);
        gl::BufferData(gl::ARRAY_BUFFER,
                       (VERTICES.len() * std::mem::size_of::<GLfloat>()) as GLsizeiptr,
                       &VERTICES as *const _ as *const GLvoid,
                       gl::STATIC_DRAW);
    }

    while !window.should_close() {
        glfw.poll_events();

        for (_, event) in glfw::flush_messages(&events) {
            handle_window_event(&mut window, event);
        }

        window.swap_buffers();
    }
}

fn handle_window_event(window: &mut glfw::Window, event: glfw::WindowEvent) {
    use glfw::{Action, Key, WindowEvent};

    match event {
        WindowEvent::Key(Key::Escape, _, Action::Press, _) => {
            window.set_should_close(true);
        },
        _ => {},
    }
}
<|endoftext|>


<commit_before>/*
 * UpdateHub
 * Copyright (C) 2017
 * O.S. Systems Sofware LTDA: contact@ossystems.com.br
 *
 * SPDX-License-Identifier:     GPL-2.0
 */

use serde_ini;

extern crate chrono;
use self::chrono::{DateTime, Utc};

use std::io;
use std::path::Path;
use std::path::PathBuf;

use de_helpers::bool_from_str;
use se_helpers::bool_to_string;

#[derive(Default, Deserialize, PartialEq, Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct RuntimeSettings {
    pub polling: RuntimePolling,
    pub update: RuntimeUpdate,
    #[serde(skip)]
    path: PathBuf,
}

impl RuntimeSettings {
    pub fn new() -> Self {
        RuntimeSettings::default()
    }

    pub fn load(mut self, path: &str) -> Result<Self, RuntimeSettingsError> {
        use std::fs::File;
        use std::io::Read;

        let path = Path::new(path);

        if path.exists() {
            info!(
                "Loading runtime settings from '{}'...",
                path.to_string_lossy()
            );

            let mut content = String::new();
            File::open(path)?.read_to_string(&mut content)?;
            self = self.parse(&content)?;
        } else {
            debug!(
                "Runtime settings file {} does not exists.",
                path.to_string_lossy()
            );
            info!("Using default runtime settings...");
        }

        self.path = path.to_path_buf();
        Ok(self)
    }

    fn parse(self, content: &str) -> Result<Self, RuntimeSettingsError> {
        Ok(serde_ini::from_str::<RuntimeSettings>(content)?)
    }

    pub fn save(&self) -> Result<usize, RuntimeSettingsError> {
        use std::fs::File;
        use std::io::Write;

        debug!(
            "Saving runtime settings from '{}'...",
            &self.path.to_string_lossy()
        );

        Ok(File::create(&self.path)?.write(
            &self.serialize()?.as_bytes(),
        )?)
    }

    fn serialize(&self) -> Result<String, RuntimeSettingsError> {
        Ok(serde_ini::to_string(&self)?)
    }
}

#[derive(Debug)]
pub enum RuntimeSettingsError {
    Io(io::Error),
    IniDeserialize(serde_ini::de::Error),
    IniSerialize(serde_ini::ser::Error),
}

impl From<io::Error> for RuntimeSettingsError {
    fn from(err: io::Error) -> RuntimeSettingsError {
        RuntimeSettingsError::Io(err)
    }
}

impl From<serde_ini::de::Error> for RuntimeSettingsError {
    fn from(err: serde_ini::de::Error) -> RuntimeSettingsError {
        RuntimeSettingsError::IniDeserialize(err)
    }
}

impl From<serde_ini::ser::Error> for RuntimeSettingsError {
    fn from(err: serde_ini::ser::Error) -> RuntimeSettingsError {
        RuntimeSettingsError::IniSerialize(err)
    }
}

#[derive(Deserialize, PartialEq, Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct RuntimePolling {
    #[serde(rename = "LastPoll")]
    pub last: DateTime<Utc>,
    #[serde(rename = "FirstPoll")]
    pub first: DateTime<Utc>,
    pub extra_interval: usize,
    pub retries: usize,
    #[serde(rename = "ProbeASAP")]
    #[serde(deserialize_with = "bool_from_str")]
    #[serde(serialize_with = "bool_to_string")]
    pub now: bool,
}

impl Default for RuntimePolling {
    fn default() -> Self {
        RuntimePolling {
            last: Utc::now(),
            first: Utc::now(),
            extra_interval: 0,
            retries: 0,
            now: false,
        }
    }
}

#[derive(Deserialize, PartialEq, Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct RuntimeUpdate {
    #[serde(rename = "UpgradeToInstallation")]
    pub upgrading_to: i8,
}

impl Default for RuntimeUpdate {
    fn default() -> Self {
        RuntimeUpdate { upgrading_to: -1 }
    }
}

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

    #[test]
    fn ok() {
        let ini = r"
[Polling]
LastPoll=2017-01-01T00:00:00Z
FirstPoll=2017-02-02T00:00:00Z
ExtraInterval=4
Retries=5
ProbeASAP=false

[Update]
UpgradeToInstallation=1
";
        let expected = RuntimeSettings {
            polling: RuntimePolling {
                last: "2017-01-01T00:00:00Z".parse::<DateTime<Utc>>().unwrap(),
                first: "2017-02-02T00:00:00Z".parse::<DateTime<Utc>>().unwrap(),
                extra_interval: 4,
                retries: 5,
                now: false,
            },
            update: RuntimeUpdate { upgrading_to: 1 },
            ..Default::default()
        };

        assert!(
            serde_ini::from_str::<RuntimeSettings>(&ini)
                .map_err(|e| println!("{}", e))
                .as_ref()
                .ok() == Some(&expected)
        );
        assert!(RuntimeSettings::new().parse(&ini).as_ref().ok() == Some(&expected));
    }

    #[test]
    fn default() {
        let settings = RuntimeSettings::new();
        let expected = RuntimeSettings {
            polling: RuntimePolling {
                last: settings.polling.last,
                first: settings.polling.first,
                extra_interval: 0,
                retries: 0,
                now: false,
            },
            update: RuntimeUpdate { upgrading_to: -1 },
            path: PathBuf::new(),
        };

        assert!(Some(settings) == Some(expected));
    }
}

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

    #[test]
    fn ok() {
        let settings = RuntimeSettings {
            polling: RuntimePolling {
                last: "2017-01-01T00:00:00Z".parse::<DateTime<Utc>>().unwrap(),
                first: "2017-02-02T00:00:00Z".parse::<DateTime<Utc>>().unwrap(),
                extra_interval: 4,
                retries: 5,
                now: false,
            },
            update: RuntimeUpdate { upgrading_to: 1 },
            ..Default::default()
        };

        assert!(
            serde_ini::from_str(&settings.serialize().ok().unwrap())
                .map_err(|e| println!("{}", e))
                .ok() == Some(settings)
        );
    }

    #[test]
    fn load_and_save() {
        use mktemp::Temp;

        let settings_file = Temp::new_file().unwrap().to_path_buf();

        let mut settings = RuntimeSettings::new()
            .load(&settings_file.to_str().unwrap())
            .unwrap();

        assert!(settings.polling.now == false);
        settings.polling.now = true;

        assert!(settings.polling.now == true);
        settings.save().expect(
            "Failed to save the runtime settings",
        );

        let new_settings = RuntimeSettings::new()
            .load(&settings_file.to_str().unwrap())
            .unwrap();

        assert!(&settings.update == &new_settings.update);
    }
}
<commit_msg>runtime_settings: Rework unit tests<commit_after>/*
 * UpdateHub
 * Copyright (C) 2017
 * O.S. Systems Sofware LTDA: contact@ossystems.com.br
 *
 * SPDX-License-Identifier:     GPL-2.0
 */

use serde_ini;

extern crate chrono;
use self::chrono::{DateTime, Utc};

use std::io;
use std::path::Path;
use std::path::PathBuf;

use de_helpers::bool_from_str;
use se_helpers::bool_to_string;

#[derive(Default, Deserialize, PartialEq, Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct RuntimeSettings {
    pub polling: RuntimePolling,
    pub update: RuntimeUpdate,
    #[serde(skip)]
    path: PathBuf,
}

impl RuntimeSettings {
    pub fn new() -> Self {
        RuntimeSettings::default()
    }

    pub fn load(mut self, path: &str) -> Result<Self, RuntimeSettingsError> {
        use std::fs::File;
        use std::io::Read;

        let path = Path::new(path);

        if path.exists() {
            info!(
                "Loading runtime settings from '{}'...",
                path.to_string_lossy()
            );

            let mut content = String::new();
            File::open(path)?.read_to_string(&mut content)?;
            self = self.parse(&content)?;
        } else {
            debug!(
                "Runtime settings file {} does not exists.",
                path.to_string_lossy()
            );
            info!("Using default runtime settings...");
        }

        self.path = path.to_path_buf();
        Ok(self)
    }

    fn parse(self, content: &str) -> Result<Self, RuntimeSettingsError> {
        Ok(serde_ini::from_str::<RuntimeSettings>(content)?)
    }

    pub fn save(&self) -> Result<usize, RuntimeSettingsError> {
        use std::fs::File;
        use std::io::Write;

        debug!(
            "Saving runtime settings from '{}'...",
            &self.path.to_string_lossy()
        );

        Ok(File::create(&self.path)?.write(
            &self.serialize()?.as_bytes(),
        )?)
    }

    fn serialize(&self) -> Result<String, RuntimeSettingsError> {
        Ok(serde_ini::to_string(&self)?)
    }
}

#[derive(Debug)]
pub enum RuntimeSettingsError {
    Io(io::Error),
    IniDeserialize(serde_ini::de::Error),
    IniSerialize(serde_ini::ser::Error),
}

impl From<io::Error> for RuntimeSettingsError {
    fn from(err: io::Error) -> RuntimeSettingsError {
        RuntimeSettingsError::Io(err)
    }
}

impl From<serde_ini::de::Error> for RuntimeSettingsError {
    fn from(err: serde_ini::de::Error) -> RuntimeSettingsError {
        RuntimeSettingsError::IniDeserialize(err)
    }
}

impl From<serde_ini::ser::Error> for RuntimeSettingsError {
    fn from(err: serde_ini::ser::Error) -> RuntimeSettingsError {
        RuntimeSettingsError::IniSerialize(err)
    }
}

#[derive(Deserialize, PartialEq, Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct RuntimePolling {
    #[serde(rename = "LastPoll")]
    pub last: DateTime<Utc>,
    #[serde(rename = "FirstPoll")]
    pub first: DateTime<Utc>,
    pub extra_interval: usize,
    pub retries: usize,
    #[serde(rename = "ProbeASAP")]
    #[serde(deserialize_with = "bool_from_str")]
    #[serde(serialize_with = "bool_to_string")]
    pub now: bool,
}

impl Default for RuntimePolling {
    fn default() -> Self {
        RuntimePolling {
            last: Utc::now(),
            first: Utc::now(),
            extra_interval: 0,
            retries: 0,
            now: false,
        }
    }
}

#[derive(Deserialize, PartialEq, Serialize)]
#[serde(rename_all = "PascalCase")]
pub struct RuntimeUpdate {
    #[serde(rename = "UpgradeToInstallation")]
    pub upgrading_to: i8,
}

impl Default for RuntimeUpdate {
    fn default() -> Self {
        RuntimeUpdate { upgrading_to: -1 }
    }
}

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

    #[test]
    fn de() {
        let ini = r"
[Polling]
LastPoll=2017-01-01T00:00:00Z
FirstPoll=2017-02-02T00:00:00Z
ExtraInterval=4
Retries=5
ProbeASAP=false

[Update]
UpgradeToInstallation=1
";
        let expected = RuntimeSettings {
            polling: RuntimePolling {
                last: "2017-01-01T00:00:00Z".parse::<DateTime<Utc>>().unwrap(),
                first: "2017-02-02T00:00:00Z".parse::<DateTime<Utc>>().unwrap(),
                extra_interval: 4,
                retries: 5,
                now: false,
            },
            update: RuntimeUpdate { upgrading_to: 1 },
            ..Default::default()
        };

        assert!(
            serde_ini::from_str::<RuntimeSettings>(&ini)
                .map_err(|e| println!("{}", e))
                .as_ref()
                .ok() == Some(&expected)
        );
        assert!(RuntimeSettings::new().parse(&ini).as_ref().ok() == Some(&expected));
    }

    #[test]
    fn default() {
        let settings = RuntimeSettings::new();
        let expected = RuntimeSettings {
            polling: RuntimePolling {
                last: settings.polling.last,
                first: settings.polling.first,
                extra_interval: 0,
                retries: 0,
                now: false,
            },
            update: RuntimeUpdate { upgrading_to: -1 },
            path: PathBuf::new(),
        };

        assert!(Some(settings) == Some(expected));
    }

    #[test]
    fn ser() {
        let settings = RuntimeSettings {
            polling: RuntimePolling {
                last: "2017-01-01T00:00:00Z".parse::<DateTime<Utc>>().unwrap(),
                first: "2017-02-02T00:00:00Z".parse::<DateTime<Utc>>().unwrap(),
                extra_interval: 4,
                retries: 5,
                now: false,
            },
            update: RuntimeUpdate { upgrading_to: 1 },
            ..Default::default()
        };

        assert!(
            serde_ini::from_str(&settings.serialize().ok().unwrap())
                .map_err(|e| println!("{}", e))
                .ok() == Some(settings)
        );
    }

    #[test]
    fn load_and_save() {
        use mktemp::Temp;

        let settings_file = Temp::new_file().unwrap().to_path_buf();

        let mut settings = RuntimeSettings::new()
            .load(&settings_file.to_str().unwrap())
            .unwrap();

        assert!(settings.polling.now == false);
        settings.polling.now = true;

        assert!(settings.polling.now == true);
        settings.save().expect(
            "Failed to save the runtime settings",
        );

        let new_settings = RuntimeSettings::new()
            .load(&settings_file.to_str().unwrap())
            .unwrap();

        assert!(&settings.update == &new_settings.update);
    }
}
<|endoftext|>


<commit_before>//////////// Sprite cache boilerplate ////////////

use std::ops::{Add};
use std::cell::{RefCell};
use calx::backend::{CanvasBuilder, SpriteCache, SpriteKey, Image};

impl SpriteKey for Spr { fn to_usize(self) -> usize { self as usize } }

impl Spr {
    /// Get the sprite image.
    pub fn get(self) -> Image {
        SPRITE_CACHE.with(|c| c.borrow().get(self).expect("Sprite not found"))
    }

    /// Build the actual sprites in a canvas for the enum set.
    pub fn init(builder: &mut CanvasBuilder) {
        SPRITE_CACHE.with(|c| { *c.borrow_mut() = build_sprites(builder); });
    }
}

impl Add<usize> for Spr {
    type Output = Spr;
    fn add(self, rhs: usize) -> Spr {
        // XXX: Assuming enum size is u8. The compiler should complain about this if it changes.
        let idx = self as u8 + rhs as u8;
        if idx >= Spr::MaxSpr as u8 { panic!("Invalid sprite offset"); }
        unsafe { ::std::mem::transmute(idx) }
    }
}

thread_local!(static SPRITE_CACHE: RefCell<SpriteCache<Spr>> = RefCell::new(SpriteCache::new()));

//////////// Custom definitions start here ////////////

#[derive(Copy, Clone, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable)]
pub enum Spr {
    BlockNW,
    BlockN,
    BlockNE,
    BlockRock,
    BlockRock1,
    BlockRock2,

    FloorBlank,
    Floor,
    GrassFloor,
    WaterFloor,

    BrickWallShort,
    BrickWallShort1,
    BrickWall,
    BrickWall1,
    BrickWindowWall,
    BrickWindowWall1,
    BrickOpenWall,
    BrickOpenWall1,
    DoorWallShort,
    DoorWallShort1,
    DoorWall,
    DoorWall1,

    TreeTrunk,
    Foliage,
    Table,
    Avatar,
    Fountain,
    Altar,
    Barrel,
    Stalagmite,
    Pillar,
    Grave,
    Crystal,
    Menhir,
    Grunt,

    EdgeN,
    EdgeNE,
    EdgeSE,
    EdgeS,
    EdgeSW,
    EdgeNW,

    MaxSpr,
}

fn build_sprites(builder: &mut CanvasBuilder) -> SpriteCache<Spr> {
    use image;
    use calx::{V2, IterTiles, color_key, color, Rgba};

    use self::Spr::*;

    fn load(data: &'static [u8]) -> image::ImageBuffer<image::Rgba<u8>, Vec<u8>> {
        color_key(&image::load_from_memory(data).unwrap(), color::CYAN)
    }

    let mut ret = SpriteCache::new();

    ret.batch_add(builder, V2(-16, -22), V2(32, 32), &mut load(include_bytes!("../assets/blocks.png")),
                  vec![
                    BlockNW,
                    BlockN,
                    BlockNE,
                    BlockRock,
                    BlockRock1,
                    BlockRock2,
                  ]);

    ret.batch_add(builder, V2(-16, -22), V2(32, 32), &mut load(include_bytes!("../assets/floors.png")),
                  vec![
                    FloorBlank,
                    Floor,
                    GrassFloor,
                    WaterFloor,
                  ]);

    let walls = vec![
        BrickWallShort,
        BrickWallShort1,
        BrickWall,
        BrickWall1,
        BrickWindowWall,
        BrickWindowWall1,
        BrickOpenWall,
        BrickOpenWall1,
        DoorWallShort,
        DoorWallShort1,
        DoorWall,
        DoorWall1,
    ];

    let mut wall_sheet = load(include_bytes!("../assets/walls.png"));
    // Can't use batch_add for walls because the offsets alternate.
    for (i, rect) in wall_sheet.tiles(V2(16, 32)).take(walls.len()).enumerate() {
        let offset = V2(if i % 2 == 0 { -16 } else { 0 }, -22);
        let image = image::SubImage::new(&mut wall_sheet, rect.mn().0, rect.mn().1, rect.dim().0, rect.dim().1);
        ret.add(builder, walls[i], offset, &image);
    }

    ret.batch_add(builder, V2(-16, -22), V2(32, 32), &mut load(include_bytes!("../assets/props.png")),
                  vec![
                    TreeTrunk,
                    Foliage,
                    Table,
                    Avatar,
                    Fountain,
                    Altar,
                    Barrel,
                    Stalagmite,
                    Pillar,
                    Grave,
                    Crystal,
                    Menhir,
                    Grunt,
                  ]);

    ret.batch_add(builder, V2(-16, -22), V2(32, 32), &mut load(include_bytes!("../assets/segments.png")),
                  vec![
                    EdgeN,
                    EdgeNE,
                    EdgeSE,
                    EdgeS,
                    EdgeSW,
                    EdgeNW,
                  ]);

    ret
}
<commit_msg>Fix sprite offset, inverse projection now matches sprite area<commit_after>//////////// Sprite cache boilerplate ////////////

use std::ops::{Add};
use std::cell::{RefCell};
use calx::backend::{CanvasBuilder, SpriteCache, SpriteKey, Image};

impl SpriteKey for Spr { fn to_usize(self) -> usize { self as usize } }

impl Spr {
    /// Get the sprite image.
    pub fn get(self) -> Image {
        SPRITE_CACHE.with(|c| c.borrow().get(self).expect("Sprite not found"))
    }

    /// Build the actual sprites in a canvas for the enum set.
    pub fn init(builder: &mut CanvasBuilder) {
        SPRITE_CACHE.with(|c| { *c.borrow_mut() = build_sprites(builder); });
    }
}

impl Add<usize> for Spr {
    type Output = Spr;
    fn add(self, rhs: usize) -> Spr {
        // XXX: Assuming enum size is u8. The compiler should complain about this if it changes.
        let idx = self as u8 + rhs as u8;
        if idx >= Spr::MaxSpr as u8 { panic!("Invalid sprite offset"); }
        unsafe { ::std::mem::transmute(idx) }
    }
}

thread_local!(static SPRITE_CACHE: RefCell<SpriteCache<Spr>> = RefCell::new(SpriteCache::new()));

//////////// Custom definitions start here ////////////

#[derive(Copy, Clone, PartialEq, Eq, Debug, RustcEncodable, RustcDecodable)]
pub enum Spr {
    BlockNW,
    BlockN,
    BlockNE,
    BlockRock,
    BlockRock1,
    BlockRock2,

    FloorBlank,
    Floor,
    GrassFloor,
    WaterFloor,

    BrickWallShort,
    BrickWallShort1,
    BrickWall,
    BrickWall1,
    BrickWindowWall,
    BrickWindowWall1,
    BrickOpenWall,
    BrickOpenWall1,
    DoorWallShort,
    DoorWallShort1,
    DoorWall,
    DoorWall1,

    TreeTrunk,
    Foliage,
    Table,
    Avatar,
    Fountain,
    Altar,
    Barrel,
    Stalagmite,
    Pillar,
    Grave,
    Crystal,
    Menhir,
    Grunt,

    EdgeN,
    EdgeNE,
    EdgeSE,
    EdgeS,
    EdgeSW,
    EdgeNW,

    MaxSpr,
}

fn build_sprites(builder: &mut CanvasBuilder) -> SpriteCache<Spr> {
    use image;
    use calx::{V2, IterTiles, color_key, color, Rgba};

    use self::Spr::*;

    fn load(data: &'static [u8]) -> image::ImageBuffer<image::Rgba<u8>, Vec<u8>> {
        color_key(&image::load_from_memory(data).unwrap(), color::CYAN)
    }

    let mut ret = SpriteCache::new();

    ret.batch_add(builder, V2(-16, -16), V2(32, 32), &mut load(include_bytes!("../assets/blocks.png")),
                  vec![
                    BlockNW,
                    BlockN,
                    BlockNE,
                    BlockRock,
                    BlockRock1,
                    BlockRock2,
                  ]);

    ret.batch_add(builder, V2(-16, -16), V2(32, 32), &mut load(include_bytes!("../assets/floors.png")),
                  vec![
                    FloorBlank,
                    Floor,
                    GrassFloor,
                    WaterFloor,
                  ]);

    let walls = vec![
        BrickWallShort,
        BrickWallShort1,
        BrickWall,
        BrickWall1,
        BrickWindowWall,
        BrickWindowWall1,
        BrickOpenWall,
        BrickOpenWall1,
        DoorWallShort,
        DoorWallShort1,
        DoorWall,
        DoorWall1,
    ];

    let mut wall_sheet = load(include_bytes!("../assets/walls.png"));
    // Can't use batch_add for walls because the offsets alternate.
    for (i, rect) in wall_sheet.tiles(V2(16, 32)).take(walls.len()).enumerate() {
        let offset = V2(if i % 2 == 0 { -16 } else { 0 }, -16);
        let image = image::SubImage::new(&mut wall_sheet, rect.mn().0, rect.mn().1, rect.dim().0, rect.dim().1);
        ret.add(builder, walls[i], offset, &image);
    }

    ret.batch_add(builder, V2(-16, -16), V2(32, 32), &mut load(include_bytes!("../assets/props.png")),
                  vec![
                    TreeTrunk,
                    Foliage,
                    Table,
                    Avatar,
                    Fountain,
                    Altar,
                    Barrel,
                    Stalagmite,
                    Pillar,
                    Grave,
                    Crystal,
                    Menhir,
                    Grunt,
                  ]);

    ret.batch_add(builder, V2(-16, -16), V2(32, 32), &mut load(include_bytes!("../assets/segments.png")),
                  vec![
                    EdgeN,
                    EdgeNE,
                    EdgeSE,
                    EdgeS,
                    EdgeSW,
                    EdgeNW,
                  ]);

    ret
}
<|endoftext|>


<commit_before>extern crate specs;

use self::specs::{Fetch, Join, WriteStorage, ReadStorage, System};

use model::comp::{Pos, Vel, Bounciness, Bounds, Actor};
use model::game::{Id, Vector};
use collision::World;
use util::angle;
use std::sync::RwLock;

pub struct Bounce;
impl<'a> System<'a> for Bounce {
    #[allow(type_complexity)]
    type SystemData = (WriteStorage<'a, Pos>,
     WriteStorage<'a, Vel>,
     ReadStorage<'a, Actor>,
     ReadStorage<'a, Bounciness>,
     Fetch<'a, Bounds<Pos>>,
     Fetch<'a, RwLock<World<Id>>>);

    fn run(&mut self, (mut pos, mut vel, actor, bounciness, pos_bounds, world): Self::SystemData) {
        let world = world.read().unwrap();
        for (mut pos, mut vel, actor, _) in (&mut pos, &mut vel, &actor, &bounciness).join() {
            handle_movement(actor, &mut pos, &mut vel, &pos_bounds, &world);
        }
    }
}

fn handle_movement(
    actor: &Actor,
    pos: &mut Pos,
    vel: &mut Vel,
    bounds: &Bounds<Pos>,
    world: &World<Id>,
) {
    world.query_intersects_id(&actor.id, |other| {
        let own: Vector = Vector { x: pos.x, y: pos.y };
        let other = Vector {
            x: other.bounds.x,
            y: other.bounds.y,
        };
        if own == other {
            vel.x = -vel.x;
        } else {
            let angle = angle(&own, &other);
            if angle < 270.0 || angle > 90.0 {
                vel.x = -vel.x.abs();
            } else {
                vel.x = vel.x.abs();
            }
        }
    });
    let next_x = pos.x + vel.x;
    let next_y = pos.y + vel.y;
    if next_x > bounds.max.x || next_x < bounds.min.x {
        pos.x = 500;
        pos.y = 500;
    }
    if next_y > bounds.max.y || next_y < bounds.min.y {
        vel.y = -vel.y;
    }
}
<commit_msg>Core: Fix bounce only working for player on the right<commit_after>extern crate specs;

use self::specs::{Fetch, Join, WriteStorage, ReadStorage, System};

use model::comp::{Pos, Vel, Bounciness, Bounds, Actor};
use model::game::{Id, Vector};
use collision::World;
use util::angle;
use std::sync::RwLock;

pub struct Bounce;
impl<'a> System<'a> for Bounce {
    #[allow(type_complexity)]
    type SystemData = (WriteStorage<'a, Pos>,
     WriteStorage<'a, Vel>,
     ReadStorage<'a, Actor>,
     ReadStorage<'a, Bounciness>,
     Fetch<'a, Bounds<Pos>>,
     Fetch<'a, RwLock<World<Id>>>);

    fn run(&mut self, (mut pos, mut vel, actor, bounciness, pos_bounds, world): Self::SystemData) {
        let world = world.read().unwrap();
        for (mut pos, mut vel, actor, _) in (&mut pos, &mut vel, &actor, &bounciness).join() {
            handle_movement(actor, &mut pos, &mut vel, &pos_bounds, &world);
        }
    }
}

fn handle_movement(
    actor: &Actor,
    pos: &mut Pos,
    vel: &mut Vel,
    bounds: &Bounds<Pos>,
    world: &World<Id>,
) {
    world.query_intersects_id(&actor.id, |other| {
        let own: Vector = Vector { x: pos.x, y: pos.y };
        let other = Vector {
            x: other.bounds.x,
            y: other.bounds.y,
        };
        if own == other {
            vel.x = -vel.x;
        } else {
            let angle = angle(&own, &other);
            if angle > 270.0 || angle < 90.0 {
                vel.x = -vel.x.abs();
            } else {
                vel.x = vel.x.abs();
            }
        }
    });
    let next_x = pos.x + vel.x;
    let next_y = pos.y + vel.y;
    if next_x > bounds.max.x || next_x < bounds.min.x {
        pos.x = 500;
        pos.y = 500;
    }
    if next_y > bounds.max.y || next_y < bounds.min.y {
        vel.y = -vel.y;
    }
}
<|endoftext|>


<commit_before>use serde_json::value::Value;
use easter::expr::Expr;
use easter::obj::DotKey;
use easter::id::IdExt;
use easter::punc::{Unop, Binop, Assop, Logop};
use unjson::ty::{Object, TyOf};
use unjson::ExtractField;
use joker::token::RegExpLiteral;

use tag::{Tag, TagOf};
use id::IntoId;
use result::Result;
use error::{Error, string_error, node_type_error, type_error};
use node::ExtractNode;
use fun::IntoFun;
use lit::{IntoStringLiteral, IntoNumberLiteral};

pub trait IntoExpr {
    fn into_expr(self) -> Result<Expr>;
    fn into_lit(self) -> Result<Expr>;
}

impl IntoExpr for Object {
    fn into_expr(mut self) -> Result<Expr> {
        let tag = try!(self.tag());
        Ok(match tag {
            Tag::Identifier => { return Ok(try!(self.into_id()).into_expr()); }
            Tag::Literal => {
                let json = try!(self.extract_field("value").map_err(Error::Json));
                match json {
                    Value::Null => Expr::Null(None),
                    Value::Bool(val) => if val { Expr::True(None) } else { Expr::False(None) },
                    Value::String(value) => Expr::String(None, value.into_string_literal()),
                    Value::I64(val) => Expr::Number(None, val.into_number_literal()),
                    Value::U64(val) => Expr::Number(None, val.into_number_literal()),
                    Value::F64(val) => Expr::Number(None, val.into_number_literal()),
                    Value::Object(_) => {
                        let mut regex = try!(self.extract_object("regex").map_err(Error::Json));
                        let pattern = try!(regex.extract_string("pattern").map_err(Error::Json));
                        let flags = try!(regex.extract_string("flags").map_err(Error::Json));
                        Expr::RegExp(None, RegExpLiteral {
                            pattern: pattern,
                            flags: flags.chars().collect()
                        })
                    }
                    _ => { return type_error("null, number, boolean, string, or object", json.ty()); }
                }
            }
            Tag::BinaryExpression => {
                let str = try!(self.extract_string("operator").map_err(Error::Json));
                let op: Binop = match str.parse() {
                    Ok(op) => op,
                    Err(_) => { return string_error("binary operator", str); }
                };
                let left = try!(self.extract_expr("left"));
                let right = try!(self.extract_expr("right"));
                Expr::Binop(None, op, Box::new(left), Box::new(right))
            }
            Tag::AssignmentExpression => {
                let str = try!(self.extract_string("operator").map_err(Error::Json));
                let right = Box::new(try!(self.extract_expr("right")));
                match &str[..] {
                    "=" => Expr::Assign(None, try!(self.extract_assign_patt("left")), right),
                    _ => {
                        let op: Assop = match str.parse() {
                            Ok(op) => op,
                            Err(_) => { return string_error("assignment operator", str); }
                        };
                        Expr::BinAssign(None, op, try!(self.extract_assign_target("left")), right)
                    }
                }
            }
            Tag::LogicalExpression => {
                let str = try!(self.extract_string("operator").map_err(Error::Json));
                let op: Logop = match str.parse() {
                    Ok(op) => op,
                    Err(_) => { return string_error("logical operator", str); }
                };
                let left = try!(self.extract_expr("left"));
                let right = try!(self.extract_expr("right"));
                Expr::Logop(None, op, Box::new(left), Box::new(right))
            }
            Tag::UnaryExpression => {
                let str = try!(self.extract_string("operator").map_err(Error::Json));
                let op: Unop = match str.parse() {
                    Ok(op) => op,
                    Err(_) => { return string_error("unary operator", str); }
                };
                let arg = try!(self.extract_expr("argument"));
                Expr::Unop(None, op, Box::new(arg))
            }
            Tag::UpdateExpression => {
                let op = try!(self.extract_string("operator").map_err(Error::Json));
                let arg = Box::new(try!(self.extract_assign_target("argument")));
                let prefix = try!(self.extract_bool("prefix").map_err(Error::Json));
                match (&op[..], prefix) {
                    ("++", true)  => Expr::PreInc(None, arg),
                    ("++", false) => Expr::PostInc(None, arg),
                    ("--", true)  => Expr::PreDec(None, arg),
                    ("--", false) => Expr::PostDec(None, arg),
                    _ => { return string_error("'++' or '--'", op); }
                }
            }
            Tag::MemberExpression => {
                let obj = Box::new(try!(self.extract_expr("object")));
                if try!(self.extract_bool("computed").map_err(Error::Json)) {
                    let prop = Box::new(try!(self.extract_expr("property")));
                    Expr::Brack(None, obj, prop)
                } else {
                    let id = try!(try!(self.extract_object("property").map_err(Error::Json)).into_id());
                    let key = DotKey { location: None, value: id.name.into_string() };
                    Expr::Dot(None, obj, key)
                }
            }
            Tag::CallExpression => {
                let callee = Box::new(try!(self.extract_expr("callee")));
                let args = try!(self.extract_expr_list("arguments"));
                Expr::Call(None, callee, args)
            }
            Tag::NewExpression => {
                let callee = Box::new(try!(self.extract_expr("callee")));
                let args = try!(self.extract_expr_list("arguments"));
                Expr::New(None, callee, Some(args))
            }
            Tag::ArrayExpression => {
                let elts = try!(self.extract_expr_opt_list("elements"));
                Expr::Arr(None, elts)
            }
            Tag::FunctionExpression => {
                let fun = try!(self.into_fun());
                Expr::Fun(fun)
            }
            Tag::SequenceExpression => {
                let exprs = try!(self.extract_expr_list("expressions"));
                Expr::Seq(None, exprs)
            }
            Tag::ObjectExpression => {
                let props = try!(self.extract_prop_list("properties"));
                Expr::Obj(None, props)
            }
            Tag::ConditionalExpression => {
                let test = Box::new(try!(self.extract_expr("test")));
                let cons = Box::new(try!(self.extract_expr("consequent")));
                let alt = Box::new(try!(self.extract_expr("alternate")));
                Expr::Cond(None, test, cons, alt)
            }
            Tag::ThisExpression => Expr::This(None),
            _ => { return node_type_error("expression", tag); }
        })
    }

    fn into_lit(mut self) -> Result<Expr> {
        let json = try!(self.extract_field("value").map_err(Error::Json));
        Ok(match json {
            Value::Null => Expr::Null(None),
            Value::Bool(val) => if val { Expr::True(None) } else { Expr::False(None) },
            Value::String(value) => Expr::String(None, value.into_string_literal()),
            Value::I64(val) => Expr::Number(None, val.into_number_literal()),
            Value::U64(val) => Expr::Number(None, val.into_number_literal()),
            Value::F64(val) => Expr::Number(None, val.into_number_literal()),
            Value::Object(_) => {
                let mut regex = try!(self.extract_object("regex").map_err(Error::Json));
                let pattern = try!(regex.extract_string("pattern").map_err(Error::Json));
                let flags = try!(regex.extract_string("flags").map_err(Error::Json));
                Expr::RegExp(None, RegExpLiteral {
                    pattern: pattern,
                    flags: flags.chars().collect()
                })
            }
            _ => { return type_error("null, number, boolean, string, or object", json.ty()); }
        })
    }
}
<commit_msg>Avoid duplication of into_lit functionality.<commit_after>use serde_json::value::Value;
use easter::expr::Expr;
use easter::obj::DotKey;
use easter::id::IdExt;
use easter::punc::{Unop, Binop, Assop, Logop};
use unjson::ty::{Object, TyOf};
use unjson::ExtractField;
use joker::token::RegExpLiteral;

use tag::{Tag, TagOf};
use id::IntoId;
use result::Result;
use error::{Error, string_error, node_type_error, type_error};
use node::ExtractNode;
use fun::IntoFun;
use lit::{IntoStringLiteral, IntoNumberLiteral};

pub trait IntoExpr {
    fn into_expr(self) -> Result<Expr>;
    fn into_lit(self) -> Result<Expr>;
}

impl IntoExpr for Object {
    fn into_expr(mut self) -> Result<Expr> {
        let tag = try!(self.tag());
        Ok(match tag {
            Tag::Identifier => { return Ok(try!(self.into_id()).into_expr()); }
            Tag::Literal => try!(IntoExpr::into_lit(self)),
            Tag::BinaryExpression => {
                let str = try!(self.extract_string("operator").map_err(Error::Json));
                let op: Binop = match str.parse() {
                    Ok(op) => op,
                    Err(_) => { return string_error("binary operator", str); }
                };
                let left = try!(self.extract_expr("left"));
                let right = try!(self.extract_expr("right"));
                Expr::Binop(None, op, Box::new(left), Box::new(right))
            }
            Tag::AssignmentExpression => {
                let str = try!(self.extract_string("operator").map_err(Error::Json));
                let right = Box::new(try!(self.extract_expr("right")));
                match &str[..] {
                    "=" => Expr::Assign(None, try!(self.extract_assign_patt("left")), right),
                    _ => {
                        let op: Assop = match str.parse() {
                            Ok(op) => op,
                            Err(_) => { return string_error("assignment operator", str); }
                        };
                        Expr::BinAssign(None, op, try!(self.extract_assign_target("left")), right)
                    }
                }
            }
            Tag::LogicalExpression => {
                let str = try!(self.extract_string("operator").map_err(Error::Json));
                let op: Logop = match str.parse() {
                    Ok(op) => op,
                    Err(_) => { return string_error("logical operator", str); }
                };
                let left = try!(self.extract_expr("left"));
                let right = try!(self.extract_expr("right"));
                Expr::Logop(None, op, Box::new(left), Box::new(right))
            }
            Tag::UnaryExpression => {
                let str = try!(self.extract_string("operator").map_err(Error::Json));
                let op: Unop = match str.parse() {
                    Ok(op) => op,
                    Err(_) => { return string_error("unary operator", str); }
                };
                let arg = try!(self.extract_expr("argument"));
                Expr::Unop(None, op, Box::new(arg))
            }
            Tag::UpdateExpression => {
                let op = try!(self.extract_string("operator").map_err(Error::Json));
                let arg = Box::new(try!(self.extract_assign_target("argument")));
                let prefix = try!(self.extract_bool("prefix").map_err(Error::Json));
                match (&op[..], prefix) {
                    ("++", true)  => Expr::PreInc(None, arg),
                    ("++", false) => Expr::PostInc(None, arg),
                    ("--", true)  => Expr::PreDec(None, arg),
                    ("--", false) => Expr::PostDec(None, arg),
                    _ => { return string_error("'++' or '--'", op); }
                }
            }
            Tag::MemberExpression => {
                let obj = Box::new(try!(self.extract_expr("object")));
                if try!(self.extract_bool("computed").map_err(Error::Json)) {
                    let prop = Box::new(try!(self.extract_expr("property")));
                    Expr::Brack(None, obj, prop)
                } else {
                    let id = try!(try!(self.extract_object("property").map_err(Error::Json)).into_id());
                    let key = DotKey { location: None, value: id.name.into_string() };
                    Expr::Dot(None, obj, key)
                }
            }
            Tag::CallExpression => {
                let callee = Box::new(try!(self.extract_expr("callee")));
                let args = try!(self.extract_expr_list("arguments"));
                Expr::Call(None, callee, args)
            }
            Tag::NewExpression => {
                let callee = Box::new(try!(self.extract_expr("callee")));
                let args = try!(self.extract_expr_list("arguments"));
                Expr::New(None, callee, Some(args))
            }
            Tag::ArrayExpression => {
                let elts = try!(self.extract_expr_opt_list("elements"));
                Expr::Arr(None, elts)
            }
            Tag::FunctionExpression => {
                let fun = try!(self.into_fun());
                Expr::Fun(fun)
            }
            Tag::SequenceExpression => {
                let exprs = try!(self.extract_expr_list("expressions"));
                Expr::Seq(None, exprs)
            }
            Tag::ObjectExpression => {
                let props = try!(self.extract_prop_list("properties"));
                Expr::Obj(None, props)
            }
            Tag::ConditionalExpression => {
                let test = Box::new(try!(self.extract_expr("test")));
                let cons = Box::new(try!(self.extract_expr("consequent")));
                let alt = Box::new(try!(self.extract_expr("alternate")));
                Expr::Cond(None, test, cons, alt)
            }
            Tag::ThisExpression => Expr::This(None),
            _ => { return node_type_error("expression", tag); }
        })
    }

    fn into_lit(mut self) -> Result<Expr> {
        let json = try!(self.extract_field("value").map_err(Error::Json));
        Ok(match json {
            Value::Null => Expr::Null(None),
            Value::Bool(val) => if val { Expr::True(None) } else { Expr::False(None) },
            Value::String(value) => Expr::String(None, value.into_string_literal()),
            Value::I64(val) => Expr::Number(None, val.into_number_literal()),
            Value::U64(val) => Expr::Number(None, val.into_number_literal()),
            Value::F64(val) => Expr::Number(None, val.into_number_literal()),
            Value::Object(_) => {
                let mut regex = try!(self.extract_object("regex").map_err(Error::Json));
                let pattern = try!(regex.extract_string("pattern").map_err(Error::Json));
                let flags = try!(regex.extract_string("flags").map_err(Error::Json));
                Expr::RegExp(None, RegExpLiteral {
                    pattern: pattern,
                    flags: flags.chars().collect()
                })
            }
            _ => { return type_error("null, number, boolean, string, or object", json.ty()); }
        })
    }
}
<|endoftext|>


<commit_before>use core::*;
use walker::*;

macro_rules! unwrap_text {
    ($s:ident, $e:expr) => {{
        match *$e.1 {
            Epiq::Text(ref t) => t,
            _ => {
                let from = $s.printer_printed($e.0);
                panic!("{}からtextは取り出せません", from);
            },
        }
    }}
}

macro_rules! unwrap_nmbr {
    ($s:ident, $e:expr) => {{
        match *$e.1 {
            Epiq::Uit8(n) => n,
            _ => {
                let from = $s.printer_printed($e.0);
                panic!("{}からnmbrは取り出せません", from);
            },
        }
    }}
}

macro_rules! first_nmbr {
    ($s:ident, $e:expr) => {{
        let first = $s.first($e.clone());
        unwrap_nmbr!($s, first)
    }}
}

macro_rules! second_nmbr {
    ($s:ident, $e:expr) => {{
        let first = $s.second($e.clone());
        unwrap_nmbr!($s, first)
    }}
}

impl Walker {
    pub fn eq_nmbr(&self, args: Node<Rc<Epiq>>) -> Node<Rc<Epiq>> {
        let n1 = first_nmbr!(self, args);
        let n2 = second_nmbr!(self, args);

        let new_epiq = if n1 == n2 { Epiq::Tval } else { Epiq::Fval };

        alloc_node!(self, new_epiq)
    }

    pub fn eq_text(&self, args: Node<Rc<Epiq>>) -> Node<Rc<Epiq>> {
        let t1 = self.first(args.clone());
        let text1 = unwrap_text!(self, t1);

        let t2 = self.second(args.clone());
        let text2 = unwrap_text!(self, t2);

        let new_epiq = if text1 == text2 { Epiq::Tval } else { Epiq::Fval };
        alloc_node!(self, new_epiq)
    }

    pub fn print(&self, args: Node<Rc<Epiq>>) -> Node<Rc<Epiq>> {
        let t = self.first(args.clone());
        let text = unwrap_text!(self, t);

        print!("{}", text);

        self.get_epiq(UNIT_INDX)
    }

    pub fn decrement(&self, args: Node<Rc<Epiq>>) -> Node<Rc<Epiq>> {
        let n = first_nmbr!(self, args);
        alloc_node!(self, Epiq::Uit8(n - 1))
    }

    pub fn plus(&self, args: Node<Rc<Epiq>>) -> Node<Rc<Epiq>> {
        let n1 = first_nmbr!(self, args);
        let n2 = second_nmbr!(self, args);
        alloc_node!(self, Epiq::Uit8(n1 + n2))
    }

    pub fn minus(&self, args: Node<Rc<Epiq>>) -> Node<Rc<Epiq>> {
        let n1 = first_nmbr!(self, args);
        let n2 = second_nmbr!(self, args);
        alloc_node!(self, Epiq::Uit8(n1 - n2))
    }

    pub fn le_or_eq_nmbr(&self, args: Node<Rc<Epiq>>) -> Node<Rc<Epiq>> {
        let n1 = first_nmbr!(self, args);
        let n2 = second_nmbr!(self, args);

        let new_epiq = if n1 <= n2 { Epiq::Tval } else { Epiq::Fval };

        alloc_node!(self, new_epiq)
    }

    pub fn concat(&self, args: Node<Rc<Epiq>>) -> Node<Rc<Epiq>> {
        self.concat_internal(args, "")
    }

    fn concat_internal(&self, args: Node<Rc<Epiq>>, accum: &str) -> Node<Rc<Epiq>> {
        let t = self.first(args.clone());
        let text = unwrap_text!(self, t);

        let accuming = accum.to_string() + text;
        match *self.qval(args.clone()).1 {
            Epiq::Unit => alloc_node!(self, Epiq::Text(accuming)),
            _ => self.concat_internal(self.qval(args.clone()), &accuming),
        }
    }

    fn first(&self, piq: Node<Rc<Epiq>>) -> Node<Rc<Epiq>> {
        self.pval(piq.clone())
    }

    fn second(&self, piq: Node<Rc<Epiq>>) -> Node<Rc<Epiq>> {
        let second_lpiq = self.qval(piq);
        self.pval(second_lpiq)
    }

}
<commit_msg>add feature to concat func that we can read Name as Text<commit_after>use core::*;
use walker::*;

macro_rules! unwrap_text {
    ($s:ident, $e:expr) => {{
        match *$e.1 {
            Epiq::Text(ref t) => t,
            _ => {
                let from = $s.printer_printed($e.0);
                panic!("{}からtextは取り出せません", from);
            },
        }
    }}
}

macro_rules! unwrap_nmbr {
    ($s:ident, $e:expr) => {{
        match *$e.1 {
            Epiq::Uit8(n) => n,
            _ => {
                let from = $s.printer_printed($e.0);
                panic!("{}からnmbrは取り出せません", from);
            },
        }
    }}
}

macro_rules! first_nmbr {
    ($s:ident, $e:expr) => {{
        let first = $s.first($e.clone());
        unwrap_nmbr!($s, first)
    }}
}

macro_rules! second_nmbr {
    ($s:ident, $e:expr) => {{
        let first = $s.second($e.clone());
        unwrap_nmbr!($s, first)
    }}
}

impl Walker {
    pub fn eq_nmbr(&self, args: Node<Rc<Epiq>>) -> Node<Rc<Epiq>> {
        let n1 = first_nmbr!(self, args);
        let n2 = second_nmbr!(self, args);

        let new_epiq = if n1 == n2 { Epiq::Tval } else { Epiq::Fval };

        alloc_node!(self, new_epiq)
    }

    pub fn eq_text(&self, args: Node<Rc<Epiq>>) -> Node<Rc<Epiq>> {
        let t1 = self.first(args.clone());
        let text1 = unwrap_text!(self, t1);

        let t2 = self.second(args.clone());
        let text2 = unwrap_text!(self, t2);

        let new_epiq = if text1 == text2 { Epiq::Tval } else { Epiq::Fval };
        alloc_node!(self, new_epiq)
    }

    pub fn print(&self, args: Node<Rc<Epiq>>) -> Node<Rc<Epiq>> {
        let t = self.first(args.clone());
        let text = unwrap_text!(self, t);

        print!("{}", text);

        self.get_epiq(UNIT_INDX)
    }

    pub fn decrement(&self, args: Node<Rc<Epiq>>) -> Node<Rc<Epiq>> {
        let n = first_nmbr!(self, args);
        alloc_node!(self, Epiq::Uit8(n - 1))
    }

    pub fn plus(&self, args: Node<Rc<Epiq>>) -> Node<Rc<Epiq>> {
        let n1 = first_nmbr!(self, args);
        let n2 = second_nmbr!(self, args);
        alloc_node!(self, Epiq::Uit8(n1 + n2))
    }

    pub fn minus(&self, args: Node<Rc<Epiq>>) -> Node<Rc<Epiq>> {
        let n1 = first_nmbr!(self, args);
        let n2 = second_nmbr!(self, args);
        alloc_node!(self, Epiq::Uit8(n1 - n2))
    }

    pub fn le_or_eq_nmbr(&self, args: Node<Rc<Epiq>>) -> Node<Rc<Epiq>> {
        let n1 = first_nmbr!(self, args);
        let n2 = second_nmbr!(self, args);

        let new_epiq = if n1 <= n2 { Epiq::Tval } else { Epiq::Fval };

        alloc_node!(self, new_epiq)
    }

    pub fn concat(&self, args: Node<Rc<Epiq>>) -> Node<Rc<Epiq>> {
        self.concat_internal(args, "")
    }

    fn concat_internal(&self, args: Node<Rc<Epiq>>, accum: &str) -> Node<Rc<Epiq>> {
        let t = self.first(args.clone());
        let text = match *t.1 {
            Epiq::Text(ref tt) => tt,
            Epiq::Name(ref tt) => tt,
            _ => {
                let from = self.printer_printed(t.0);
                panic!("{}からtextは取り出せません", from);
            },
        };

        let accuming = accum.to_string() + text;
        match *self.qval(args.clone()).1 {
            Epiq::Unit => alloc_node!(self, Epiq::Text(accuming)),
            _ => self.concat_internal(self.qval(args.clone()), &accuming),
        }
    }

    fn first(&self, piq: Node<Rc<Epiq>>) -> Node<Rc<Epiq>> {
        self.pval(piq.clone())
    }

    fn second(&self, piq: Node<Rc<Epiq>>) -> Node<Rc<Epiq>> {
        let second_lpiq = self.qval(piq);
        self.pval(second_lpiq)
    }

}
<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::{fs::File, io::Read, path::PathBuf};

use libmount;
use nix::mount::{umount2, MntFlags};

use devicemapper::{DevId, DmOptions};

use crate::engine::strat_engine::{
    cmd::udev_settle,
    dm::{get_dm, get_dm_init},
};

mod cleanup_errors {
    use libmount;
    use nix;
    use std;

    error_chain! {
        foreign_links {
            Ioe(std::io::Error);
            Mnt(libmount::mountinfo::ParseError);
            Nix(nix::Error);
        }
    }
}

use self::cleanup_errors::{Error, Result};

/// Attempt to remove all device mapper devices which match the stratis naming convention.
/// FIXME: Current implementation complicated by https://bugzilla.redhat.com/show_bug.cgi?id=1506287
fn dm_stratis_devices_remove() -> Result<()> {
    /// One iteration of removing devicemapper devices
    fn one_iteration() -> Result<(bool, Vec<String>)> {
        let mut progress_made = false;
        let mut remain = Vec::new();

        for n in get_dm()
            .list_devices()
            .map_err(|e| {
                let err_msg = "failed while listing DM devices, giving up";
                Error::with_chain(e, err_msg)
            })?
            .iter()
            .map(|d| &d.0)
            .filter(|n| n.to_string().starts_with("stratis-1"))
        {
            match get_dm().device_remove(&DevId::Name(n), &DmOptions::new()) {
                Ok(_) => progress_made = true,
                Err(_) => remain.push(n.to_string()),
            }
        }
        Ok((progress_made, remain))
    }

    /// Do one iteration of removals until progress stops. Return remaining
    /// dm devices.
    fn do_while_progress() -> Result<Vec<String>> {
        let mut result = one_iteration()?;
        while result.0 {
            result = one_iteration()?;
        }
        Ok(result.1)
    }

    || -> Result<()> {
        udev_settle().unwrap();
        get_dm_init().map_err(|err| Error::with_chain(err, "Unable to initialize DM"))?;
        do_while_progress().and_then(|remain| {
            if !remain.is_empty() {
                Err(format!("Some Stratis DM devices remaining: {:?}", remain).into())
            } else {
                Ok(())
            }
        })
    }()
    .map_err(|e| e.chain_err(|| "Failed to ensure removal of all Stratis DM devices"))
}

/// Try and un-mount any filesystems that have the name stratis in the mount point, returning
/// immediately on the first one we are unable to unmount.
fn stratis_filesystems_unmount() -> Result<()> {
    || -> Result<()> {
        let mut mount_data = String::new();
        File::open("/proc/self/mountinfo")?.read_to_string(&mut mount_data)?;
        let parser = libmount::mountinfo::Parser::new(mount_data.as_bytes());

        for mount_point in parser
            .filter_map(|x| x.ok())
            .filter_map(|m| m.mount_point.into_owned().into_string().ok())
            .filter(|mp| mp.contains("stratis"))
        {
            umount2(&PathBuf::from(mount_point), MntFlags::MNT_DETACH)?;
        }

        Ok(())
    }()
    .map_err(|e| e.chain_err(|| "Failed to ensure all Stratis filesystems were unmounted"))
}

/// When a unit test panics we can leave the system in an inconsistent state.  This function
/// tries to clean up by un-mounting any mounted file systems which contain the string
/// "stratis_testing" and then it tries to remove any device mapper tables which are also stratis
/// created.
pub fn clean_up() -> Result<()> {
    stratis_filesystems_unmount().and_then(|_| dm_stratis_devices_remove())
}
<commit_msg>Allow the use of Error::description() in macro-generated code<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::{fs::File, io::Read, path::PathBuf};

use libmount;
use nix::mount::{umount2, MntFlags};

use devicemapper::{DevId, DmOptions};

use crate::engine::strat_engine::{
    cmd::udev_settle,
    dm::{get_dm, get_dm_init},
};

mod cleanup_errors {
    // FIXME: It should be possible to remove this allow when the next
    // version of error_chain is released.
    #![allow(deprecated)]
    use libmount;
    use nix;
    use std;

    error_chain! {
        foreign_links {
            Ioe(std::io::Error);
            Mnt(libmount::mountinfo::ParseError);
            Nix(nix::Error);
        }
    }
}

use self::cleanup_errors::{Error, Result};

/// Attempt to remove all device mapper devices which match the stratis naming convention.
/// FIXME: Current implementation complicated by https://bugzilla.redhat.com/show_bug.cgi?id=1506287
fn dm_stratis_devices_remove() -> Result<()> {
    /// One iteration of removing devicemapper devices
    fn one_iteration() -> Result<(bool, Vec<String>)> {
        let mut progress_made = false;
        let mut remain = Vec::new();

        for n in get_dm()
            .list_devices()
            .map_err(|e| {
                let err_msg = "failed while listing DM devices, giving up";
                Error::with_chain(e, err_msg)
            })?
            .iter()
            .map(|d| &d.0)
            .filter(|n| n.to_string().starts_with("stratis-1"))
        {
            match get_dm().device_remove(&DevId::Name(n), &DmOptions::new()) {
                Ok(_) => progress_made = true,
                Err(_) => remain.push(n.to_string()),
            }
        }
        Ok((progress_made, remain))
    }

    /// Do one iteration of removals until progress stops. Return remaining
    /// dm devices.
    fn do_while_progress() -> Result<Vec<String>> {
        let mut result = one_iteration()?;
        while result.0 {
            result = one_iteration()?;
        }
        Ok(result.1)
    }

    || -> Result<()> {
        udev_settle().unwrap();
        get_dm_init().map_err(|err| Error::with_chain(err, "Unable to initialize DM"))?;
        do_while_progress().and_then(|remain| {
            if !remain.is_empty() {
                Err(format!("Some Stratis DM devices remaining: {:?}", remain).into())
            } else {
                Ok(())
            }
        })
    }()
    .map_err(|e| e.chain_err(|| "Failed to ensure removal of all Stratis DM devices"))
}

/// Try and un-mount any filesystems that have the name stratis in the mount point, returning
/// immediately on the first one we are unable to unmount.
fn stratis_filesystems_unmount() -> Result<()> {
    || -> Result<()> {
        let mut mount_data = String::new();
        File::open("/proc/self/mountinfo")?.read_to_string(&mut mount_data)?;
        let parser = libmount::mountinfo::Parser::new(mount_data.as_bytes());

        for mount_point in parser
            .filter_map(|x| x.ok())
            .filter_map(|m| m.mount_point.into_owned().into_string().ok())
            .filter(|mp| mp.contains("stratis"))
        {
            umount2(&PathBuf::from(mount_point), MntFlags::MNT_DETACH)?;
        }

        Ok(())
    }()
    .map_err(|e| e.chain_err(|| "Failed to ensure all Stratis filesystems were unmounted"))
}

/// When a unit test panics we can leave the system in an inconsistent state.  This function
/// tries to clean up by un-mounting any mounted file systems which contain the string
/// "stratis_testing" and then it tries to remove any device mapper tables which are also stratis
/// created.
pub fn clean_up() -> Result<()> {
    stratis_filesystems_unmount().and_then(|_| dm_stratis_devices_remove())
}
<|endoftext|>


<commit_before>use std::fs::File;

fn find_package(name: &str) -> String
{

}

fn retrieve_package(url: &str) -> Path
{
    /*
      This function retrieves the package, and
      puts them in a temporary folder.
    */
}

fn verify_package(package: &File, provided: &str)
{
    /*
      This function verifies the package(CRC32 IEEE)
      retrieved by retrieve_package, and returns boolean indicating
      that the file is not corrupted.
    */
}

fn copy_package()
{
    /*
      This function retrieves the package, and put them
      to specified locations accordingly.
    */
}

fn process_package()
{
    /*
      This function finalises the installation of
      the package, such as setting PATH and such.
    */
}

fn install()
{

}<commit_msg>find_package() completed<commit_after>use constants;

use std::error::Error;
use std::fs::File;
use std::io::{BufReader, BufRead};
use std::path::Path;

// TODO: Eliminate hardcoded strings and ints
fn find_package(name: &str) -> String
{
    let mut list = match File::open(constants::PACKAGE_LIST) {
        Err(why) => panic!("An error occured:\n{}", why),
        Ok(file) => file,
    };

    let mut reader = BufReader::new(list);
    let mut buffer = String::new();

    for line in reader.lines() {
        let x = line.unwrap();
        let tokens: Vec<&str> = x.split(' ').collect();

        if tokens.len() < 2 {
            buffer.push_str("NOT FOUND");
        }
        else {
            if tokens[0] == name {
                buffer.push_str(tokens[1]);
            }
            else {
                buffer.push_str("NOT FOUND"); // this is only temporary!
            }
        }
    }

    buffer
}

fn retrieve_package(url: &str) // -> Path
{
    /*
      This function retrieves the package, and
      puts them in a temporary folder.
    */
}

fn verify_package(package: &File, provided: &str)
{
    /*
      This function verifies the package(CRC32 IEEE)
      retrieved by retrieve_package, and returns boolean indicating
      that the file is not corrupted.
    */
}

fn copy_package()
{
    /*
      This function retrieves the package, and put them
      to specified locations accordingly.
    */
}

fn process_package()
{
    /*
      This function finalises the installation of
      the package, such as setting PATH and such.
    */
}

fn install()
{

}<|endoftext|>


<commit_before>use super::util;
use crate::error::Result;
use crate::loader::Loader;
use ansi_term::Color;
use lazy_static::lazy_static;
use serde::ser::SerializeMap;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_json::{json, Value};
use std::collections::HashMap;
use std::fmt::Write;
use std::sync::atomic::AtomicUsize;
use std::time::Instant;
use std::{fs, io, path, str, usize};
use tree_sitter_highlight::{HighlightConfiguration, HighlightEvent, Highlighter, HtmlRenderer};

pub const HTML_HEADER: &'static str = "
<!doctype HTML>

  <title>Tree-sitter Highlighting</title>

";

pub const HTML_FOOTER: &'static str = "

";

lazy_static! {
    static ref CSS_STYLES_BY_COLOR_ID: Vec<String> =
        serde_json::from_str(include_str!("../vendor/xterm-colors.json")).unwrap();
}

#[derive(Debug, Default)]
pub struct Style {
    pub ansi: ansi_term::Style,
    pub css: Option<String>,
}

#[derive(Debug)]
pub struct Theme {
    pub styles: Vec

";

pub const HTML_FOOTER: &'static str = "

";

lazy_static! {
    static ref CSS_STYLES_BY_COLOR_ID: Vec<String> =
        serde_json::from_str(include_str!("../vendor/xterm-colors.json")).unwrap();
}

#[derive(Debug, Default)]
pub struct Style {
    pub ansi: ansi_term::Style,
    pub css: Option<String>,
}

#[derive(Debug)]
pub struct Theme {
    pub styles: Vec


<commit_before>#[macro_use]
extern crate descriptor;
extern crate expector;

use std::time::Duration;
use std::thread::sleep;

use descriptor::*;
use expector::*;

fn main() {
    describe("example group 1", source_location!(), |eg| {
        eg.it("1", source_location!(), || {
            expect(1).to(eq(2));
        });
        eg.it("2", source_location!(), || {
            expect("abc").to(eq("def"));
        });
        eg.it("3", source_location!(), || {
            expect(None).to(eq(Some(3)));
        });

        eg.it("works", source_location!(), || {
        });
    });

    describe("example group 2", source_location!(), |eg| {
        eg.it("17", source_location!(), || {
        });

        eg.it("does a lot of hard work", source_location!(), || {
            sleep(Duration::new(3, 0));
        });
    });

    descriptor_main();
}
<commit_msg>Update primary example to use the it! macro<commit_after>#[macro_use]
extern crate descriptor;
extern crate expector;

use std::time::Duration;
use std::thread::sleep;

use descriptor::*;
use expector::*;

fn main() {
    describe("example group 1", source_location!(), |eg| {
        it!(eg, "1", || {
            expect(1).to(eq(2));
        });
        it!(eg, "2", || {
            expect("abc").to(eq("def"));
        });
        it!(eg, "3", || {
            expect(None).to(eq(Some(3)));
        });

        it!(eg, "works", || {
        });
    });

    describe("example group 2", source_location!(), |eg| {
        it!(eg, "17", || {
        });

        it!(eg, "does a lot of hard work", || {
            sleep(Duration::new(3, 0));
        });
    });

    descriptor_main();
}
<|endoftext|>


<commit_before>#![feature(std_misc, io)]

extern crate graphics;
extern crate glium;
extern crate glutin;
extern crate glium_graphics;
extern crate image;

fn main() {
    use std::old_io::timer::sleep;
    use std::old_io::BufReader;
    use std::time::duration::Duration;
    use glium::{DisplayBuild, Surface, Texture2d};
    use glium_graphics::{GliumBackendSystem, GliumSurfaceBackEnd, DrawTexture};
    use graphics::{Context, RelativeTransform};

    let display = glutin::WindowBuilder::new()
        .with_dimensions(300, 300)
        .with_title(format!("Image test"))
        .build_glium().unwrap();

    let rust_logo = DrawTexture::new({
        let image =
            image::load(
                BufReader::new(include_bytes!("../assets/rust.png")),
                image::PNG
            ).unwrap();
        Texture2d::new(&display, image)
    });

    let mut system = GliumBackendSystem::new(&display);

    loop {
        let mut target = display.draw();
        {
            let mut backend = GliumSurfaceBackEnd::new(&mut system, &mut target);
            let context = Context::abs(300.0, 300.0);
            graphics::clear([1.0; 4], &mut backend);
            graphics::Rectangle::new([1.0, 0.0, 0.0, 1.0])
                .draw([0.0, 0.0, 100.0, 100.0], &context, &mut backend);
            graphics::Rectangle::new([0.0, 1.0, 0.0, 0.3])
                .draw(
                    [50.0, 50.0, 100.0, 100.0],
                    &context,
                    &mut backend
                );
            graphics::image(&rust_logo, &context.trans(100.0, 100.0), &mut backend);
        }
        target.finish();
        sleep(Duration::milliseconds(15));
    }
}
<commit_msg>Upgraded image_test to use new names<commit_after>#![feature(std_misc, io)]

extern crate graphics;
extern crate glium;
extern crate glutin;
extern crate glium_graphics;
extern crate image;

fn main() {
    use std::old_io::timer::sleep;
    use std::old_io::BufReader;
    use std::time::duration::Duration;
    use glium::{DisplayBuild, Surface, Texture2d};
    use glium_graphics::{Glium2d, GliumGraphics, DrawTexture};
    use graphics::{Context, RelativeTransform};

    let display = glutin::WindowBuilder::new()
        .with_dimensions(300, 300)
        .with_title(format!("Image test"))
        .build_glium().unwrap();

    let rust_logo = DrawTexture::new({
        let image =
            image::load(
                BufReader::new(include_bytes!("../assets/rust.png")),
                image::PNG
            ).unwrap();
        Texture2d::new(&display, image)
    });

    let mut g2d = Glium2d::new(&display);

    loop {
        let mut target = display.draw();
        {
            let mut g = GliumGraphics::new(&mut g2d, &mut target);
            let context = Context::abs(300.0, 300.0);
            graphics::clear([1.0; 4], &mut g);
            graphics::Rectangle::new([1.0, 0.0, 0.0, 1.0])
                .draw([0.0, 0.0, 100.0, 100.0], &context, &mut g);
            graphics::Rectangle::new([0.0, 1.0, 0.0, 0.3])
                .draw(
                    [50.0, 50.0, 100.0, 100.0],
                    &context,
                    &mut g
                );
            graphics::image(&rust_logo, &context.trans(100.0, 100.0), &mut g);
        }
        target.finish();
        sleep(Duration::milliseconds(15));
    }
}
<|endoftext|>


<commit_before>use rand::{SeedableRng, Rng, rngs::SmallRng};

// Having more than 1 test does seem to make a difference
// (i.e., this calls ptr::swap which having just one test does not).
#[test]
fn simple1() {
    assert_eq!(4, 4);
}

#[test]
fn simple2() {
    assert_ne!(42, 24);
}

// A test that won't work on miri (tests disabling tests)
#[cfg(not(miri))]
#[test]
fn does_not_work_on_miri() {
    let x = 0u8;
    assert!(&x as *const _ as usize % 4 < 4);
}

// We also use this to test some external crates, that we cannot depend on in the compiletest suite.

#[test]
fn entropy_rng() {
    // Try seeding with "real" entropy.
    let mut rng = SmallRng::from_entropy();
    let _val = rng.gen::<i32>();
    let _val = rng.gen::<isize>();
    let _val = rng.gen::<i128>();

    // Also try per-thread RNG.
    let mut rng = rand::thread_rng();
    let _val = rng.gen::<i32>();
    let _val = rng.gen::<isize>();
    let _val = rng.gen::<i128>();
}

#[test]
fn num_cpus() {
    assert_eq!(num_cpus::get(), 1);
}

#[test]
#[should_panic]
fn do_panic() { // In large, friendly letters :)
    panic!("Explicit panic from test!");
}
<commit_msg>Disable #[should_panic] test on Windows<commit_after>use rand::{SeedableRng, Rng, rngs::SmallRng};

// Having more than 1 test does seem to make a difference
// (i.e., this calls ptr::swap which having just one test does not).
#[test]
fn simple1() {
    assert_eq!(4, 4);
}

#[test]
fn simple2() {
    assert_ne!(42, 24);
}

// A test that won't work on miri (tests disabling tests)
#[cfg(not(miri))]
#[test]
fn does_not_work_on_miri() {
    let x = 0u8;
    assert!(&x as *const _ as usize % 4 < 4);
}

// We also use this to test some external crates, that we cannot depend on in the compiletest suite.

#[test]
fn entropy_rng() {
    // Try seeding with "real" entropy.
    let mut rng = SmallRng::from_entropy();
    let _val = rng.gen::<i32>();
    let _val = rng.gen::<isize>();
    let _val = rng.gen::<i128>();

    // Also try per-thread RNG.
    let mut rng = rand::thread_rng();
    let _val = rng.gen::<i32>();
    let _val = rng.gen::<isize>();
    let _val = rng.gen::<i128>();
}

#[test]
fn num_cpus() {
    assert_eq!(num_cpus::get(), 1);
}

// FIXME: Remove this `cfg` once we fix https://github.com/rust-lang/miri/issues/1059
// We cfg-gate the `should_panic` attribute and the `panic!` itself, so that the test
// stdout does not depend on the platform
#[test]
#[cfg_attr(not(windows), should_panic)]
fn do_panic() { // In large, friendly letters :)
    #[cfg(not(windows))]
    panic!("Explicit panic from test!");
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::io::{self, Read, Write};
use std::str::from_utf8;

use mio::event::Event;
use mio::net::{TcpListener, TcpStream};
use mio::{Events, Interests, Poll, Token};

// Setup some tokens to allow us to identify which event is for which socket.
const SERVER: Token = Token(0);

// Some data we'll send over the connection.
const DATA: &[u8] = b"Hello world!\n";

fn main() -> io::Result<()> {
    env_logger::init();

    // Create a poll instance.
    let mut poll = Poll::new()?;
    // Create storage for events.
    let mut events = Events::with_capacity(128);

    // Setup the TCP server socket.
    let addr = "127.0.0.1:13265".parse().unwrap();
    let server = TcpListener::bind(addr)?;

    // Register the server with poll we can receive events for it.
    poll.registry()
        .register(&server, SERVER, Interests::READABLE)?;

    // Map of `Token` -> `TcpStream`.
    let mut connections = HashMap::new();
    // Unique token for each incoming connection.
    let mut unique_token = Token(SERVER.0 + 1);

    println!("You can connect to the server using `nc`:");
    println!(" $ nc 127.0.0.1 13265");
    println!("You'll see our welcome message and anything you type we'll be printed here.");

    loop {
        poll.poll(&mut events, None)?;

        for event in events.iter() {
            match event.token() {
                SERVER => {
                    // Received an event for the TCP server socket.
                    // Accept an connection.
                    let (connection, address) = server.accept()?;
                    println!("Accepted connection from: {}", address);

                    let token = next(&mut unique_token);
                    poll.registry().register(
                        &connection,
                        token,
                        Interests::READABLE.add(Interests::WRITABLE),
                    )?;

                    connections.insert(token, connection);
                }
                token => {
                    // (maybe) received an event for a TCP connection.
                    let done = if let Some(connection) = connections.get_mut(&token) {
                        handle_connection_event(&mut poll, connection, event)?
                    } else {
                        // Sporadic events happen.
                        false
                    };
                    if done {
                        connections.remove(&token);
                    }
                }
            }
        }
    }
}

fn next(current: &mut Token) -> Token {
    let next = current.0;
    current.0 += 1;
    Token(next)
}

/// Returns `true` if the connection is done.
fn handle_connection_event(
    poll: &mut Poll,
    connection: &mut TcpStream,
    event: &Event,
) -> io::Result<bool> {
    if event.is_writable() {
        // We can (maybe) write to the connection.
        match connection.write(DATA) {
            // We want to write the entire `DATA` buffer in a single go. If we
            // write less we'll return a short write error (same as
            // `io::Write::write_all` does).
            Ok(n) if n < DATA.len() => return Err(io::ErrorKind::WriteZero.into()),
            Ok(_) => {
                // After we've written something we'll reregister the connection
                // to only respond to readable events.
                poll.registry()
                    .reregister(&connection, event.token(), Interests::READABLE)?
            }
            // Would block "errors" are the OS's way of saying that the
            // connection is not actually ready to perform this I/O operation.
            Err(ref err) if would_block(err) => {}
            // Got interrupted (how rude!), we'll try again.
            Err(ref err) if interrupted(err) => {
                return handle_connection_event(poll, connection, event)
            }
            // Other errors we'll consider fatal.
            Err(err) => return Err(err),
        }
    }

    if event.is_readable() {
        let mut connection_closed = false;
        let mut received_data = Vec::with_capacity(4056);
        // We can (maybe) read from the connection.
        loop {
            let mut buf = [0; 256];
            match connection.read(&mut buf) {
                Ok(0) => {
                    // Reading 0 bytes means the other side has closed the
                    // connection or is done writing, then so are we.
                    connection_closed = true;
                    break;
                }
                Ok(_n) => received_data.extend_from_slice(&buf),
                // Would block "errors" are the OS's way of saying that the
                // connection is not actually ready to perform this I/O operation.
                Err(ref err) if would_block(err) => break,
                // Got interrupted (how rude!), we'll try again.
                // NOTE: that this is not the proper way to this as we'll also redo
                // the writable side above.
                Err(ref err) if interrupted(err) => {
                    return handle_connection_event(poll, connection, event)
                }
                // Other errors we'll consider fatal.
                Err(err) => return Err(err),
            }
        }

        if let Ok(str_buf) = from_utf8(&received_data) {
            println!("Received data: {}", str_buf.trim_end());
        } else {
            println!("Received (none UTF-8) data: {:?}", &received_data);
        }

        if connection_closed {
            println!("Connection closed");
        }
    }

    Ok(false)
}

fn would_block(err: &io::Error) -> bool {
    err.kind() == io::ErrorKind::WouldBlock
}

fn interrupted(err: &io::Error) -> bool {
    err.kind() == io::ErrorKind::Interrupted
}
<commit_msg>Return ok true<commit_after>use std::collections::HashMap;
use std::io::{self, Read, Write};
use std::str::from_utf8;

use mio::event::Event;
use mio::net::{TcpListener, TcpStream};
use mio::{Events, Interests, Poll, Token};

// Setup some tokens to allow us to identify which event is for which socket.
const SERVER: Token = Token(0);

// Some data we'll send over the connection.
const DATA: &[u8] = b"Hello world!\n";

fn main() -> io::Result<()> {
    env_logger::init();

    // Create a poll instance.
    let mut poll = Poll::new()?;
    // Create storage for events.
    let mut events = Events::with_capacity(128);

    // Setup the TCP server socket.
    let addr = "127.0.0.1:13265".parse().unwrap();
    let server = TcpListener::bind(addr)?;

    // Register the server with poll we can receive events for it.
    poll.registry()
        .register(&server, SERVER, Interests::READABLE)?;

    // Map of `Token` -> `TcpStream`.
    let mut connections = HashMap::new();
    // Unique token for each incoming connection.
    let mut unique_token = Token(SERVER.0 + 1);

    println!("You can connect to the server using `nc`:");
    println!(" $ nc 127.0.0.1 13265");
    println!("You'll see our welcome message and anything you type we'll be printed here.");

    loop {
        poll.poll(&mut events, None)?;

        for event in events.iter() {
            match event.token() {
                SERVER => {
                    // Received an event for the TCP server socket.
                    // Accept an connection.
                    let (connection, address) = server.accept()?;
                    println!("Accepted connection from: {}", address);

                    let token = next(&mut unique_token);
                    poll.registry().register(
                        &connection,
                        token,
                        Interests::READABLE.add(Interests::WRITABLE),
                    )?;

                    connections.insert(token, connection);
                }
                token => {
                    // (maybe) received an event for a TCP connection.
                    let done = if let Some(connection) = connections.get_mut(&token) {
                        handle_connection_event(&mut poll, connection, event)?
                    } else {
                        // Sporadic events happen.
                        false
                    };
                    if done {
                        connections.remove(&token);
                    }
                }
            }
        }
    }
}

fn next(current: &mut Token) -> Token {
    let next = current.0;
    current.0 += 1;
    Token(next)
}

/// Returns `true` if the connection is done.
fn handle_connection_event(
    poll: &mut Poll,
    connection: &mut TcpStream,
    event: &Event,
) -> io::Result<bool> {
    if event.is_writable() {
        // We can (maybe) write to the connection.
        match connection.write(DATA) {
            // We want to write the entire `DATA` buffer in a single go. If we
            // write less we'll return a short write error (same as
            // `io::Write::write_all` does).
            Ok(n) if n < DATA.len() => return Err(io::ErrorKind::WriteZero.into()),
            Ok(_) => {
                // After we've written something we'll reregister the connection
                // to only respond to readable events.
                poll.registry()
                    .reregister(&connection, event.token(), Interests::READABLE)?
            }
            // Would block "errors" are the OS's way of saying that the
            // connection is not actually ready to perform this I/O operation.
            Err(ref err) if would_block(err) => {}
            // Got interrupted (how rude!), we'll try again.
            Err(ref err) if interrupted(err) => {
                return handle_connection_event(poll, connection, event)
            }
            // Other errors we'll consider fatal.
            Err(err) => return Err(err),
        }
    }

    if event.is_readable() {
        let mut connection_closed = false;
        let mut received_data = Vec::with_capacity(4056);
        // We can (maybe) read from the connection.
        loop {
            let mut buf = [0; 256];
            match connection.read(&mut buf) {
                Ok(0) => {
                    // Reading 0 bytes means the other side has closed the
                    // connection or is done writing, then so are we.
                    connection_closed = true;
                    break;
                }
                Ok(_n) => received_data.extend_from_slice(&buf),
                // Would block "errors" are the OS's way of saying that the
                // connection is not actually ready to perform this I/O operation.
                Err(ref err) if would_block(err) => break,
                // Got interrupted (how rude!), we'll try again.
                // NOTE: that this is not the proper way to this as we'll also redo
                // the writable side above.
                Err(ref err) if interrupted(err) => {
                    return handle_connection_event(poll, connection, event)
                }
                // Other errors we'll consider fatal.
                Err(err) => return Err(err),
            }
        }

        if let Ok(str_buf) = from_utf8(&received_data) {
            println!("Received data: {}", str_buf.trim_end());
        } else {
            println!("Received (none UTF-8) data: {:?}", &received_data);
        }

        if connection_closed {
            println!("Connection closed");
            return Ok(true);
        }
    }

    Ok(false)
}

fn would_block(err: &io::Error) -> bool {
    err.kind() == io::ErrorKind::WouldBlock
}

fn interrupted(err: &io::Error) -> bool {
    err.kind() == io::ErrorKind::Interrupted
}
<|endoftext|>