<commit_before>extern crate clap;
extern crate glob;
#[macro_use] extern crate log;
extern crate serde_json;
extern crate semver;
extern crate toml;
#[macro_use] extern crate version;

extern crate task_hookrs;

extern crate libimagrt;
extern crate libimagstore;
extern crate libimagutil;
extern crate libimagtodo;

use std::process::exit;
use std::process::{Command, Stdio};
use std::io::stdin;
use std::io::BufRead;

use task_hookrs::import::{import, import_task, import_tasks};

use libimagrt::runtime::Runtime;
use libimagtodo::task::IntoTask;
use libimagutil::trace::trace_error;

mod ui;

use ui::build_ui;
fn main() {

    let name = "imag-todo";
    let version = &version!()[..];
    let about = "Interface with taskwarrior";
    let ui = build_ui(Runtime::get_default_cli_builder(name, version, about));

    let rt = {
        let rt = Runtime::new(ui);
        if rt.is_ok() {
            rt.unwrap()
        } else {
            println!("Could not set up Runtime");
            println!("{:?}", rt.unwrap_err());
            exit(1);
        }
    };

    let scmd = rt.cli().subcommand_name();
    match scmd {
        Some("tw-hook") => {
            let subcmd = rt.cli().subcommand_matches("tw-hook").unwrap();
            if subcmd.is_present("add") {
                let stdin = stdin();
                let mut stdin = stdin.lock();
                let mut line = String::new();
                match stdin.read_line(&mut line) {
                    Ok(_) => { }
                    Err(e) => {
                        error!("{}", e);
                        return;
                    }
                };
                if let Ok(ttask) = import_task(&line.as_str()) {
                    print!("{}", match serde_json::ser::to_string(&ttask) {
                        Ok(val) => val,
                        Err(e) => {
                            error!("{}", e);
                            return;
                        }
                    });
                    match ttask.into_filelockentry(rt.store()) {
                        Ok(val) => val,
                        Err(e) => {
                            trace_error(&e);
                            error!("{}", e);
                            return;
                        }
                    };
                }
                else {
                    error!("No usable input");
                    return;
                }
            }
            else if subcmd.is_present("delete") {
                // The used hook is "on-modify". This hook gives two json-objects
                // per usage und wants one (the second one) back.
                let mut counter = 0;
                let stdin = stdin();
                for rline in stdin.lock().lines() {
                    let mut line = match rline {
                        Ok(l) => l,
                        Err(e) => {
                            error!("{}", e);
                            return;
                        }
                    };
                    line.insert(0, '[');
                    line.push(']');
                    if counter % 2 == 1 {
                        if let Ok(ttasks) = import(line.as_bytes()) {
                            for ttask in ttasks {
                                // Only every second task is needed, the first one is the
                                // task before the change, and the second one after
                                // the change. The (maybe modified) second one is
                                // expected by taskwarrior.
                                println!("{}", match serde_json::ser::to_string(&ttask) {
                                    Ok(val) => val,
                                    Err(e) => {
                                        error!("{}", e);
                                        return;
                                    }
                                });
                                match ttask.status() {
                                    &task_hookrs::status::TaskStatus::Deleted => {
                                        match libimagtodo::delete::delete(rt.store(), *ttask.uuid()) {
                                            Ok(_) => { }
                                            Err(e) => {
                                                trace_error(&e);
                                                error!("{}", e);
                                                return;
                                            }
                                        }
                                    }
                                    _ => {
                                    }
                                } // end match ttask.status()
                            } // end for
                        }
                        else {
                            error!("No usable input");
                        }
                    }
                    counter += 1;
                }
            }
            else {
                // Should not be possible, as one argument is required via
                // ArgGroup
                unreachable!();
            }
        },
        Some("exec") => {
            let subcmd = rt.cli().subcommand_matches("exec").unwrap();
            let mut args = Vec::new();
            if let Some(exec_string) = subcmd.values_of("command") {
                for e in exec_string {
                    args.push(e);
                }
                let tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn().unwrap_or_else(|e| {
                    panic!("failed to execute taskwarrior: {}", e);
                });

                let output = tw_process.wait_with_output().unwrap_or_else(|e| {
                    panic!("failed to unwrap output: {}", e);
                });
                let outstring = String::from_utf8(output.stdout).unwrap_or_else(|e| {
                    panic!("failed to ececute: {}", e);
                });
                println!("{}", outstring);
            } else {
                panic!("faild to execute: You need to exec --command");
            }
        }
        Some("list") => {
            let subcmd = rt.cli().subcommand_matches("list").unwrap();
            let mut args = Vec::new();
            let verbose = subcmd.is_present("verbose");
            let iter = match libimagtodo::read::get_todo_iterator(rt.store()) {
                //let iter = match rt.store().retrieve_for_module("todo/taskwarrior") {
                Err(e) => {
                    error!("{}", e);
                    return;
                }
                Ok(val) => val,
            };
            for task in iter {
                match task {
                    Ok(val) => {
                        //let val = libimagtodo::task::Task::new(fle);
                        //println!("{:#?}", val.flentry);
                        let uuid = match val.flentry.get_header().read("todo.uuid") {
                            Ok(Some(u)) => u,
                            Ok(None) => continue,
                            Err(e) => {
                                error!("{}", e);
                                continue;
                            }
                        };
                        if verbose {
                            args.clear();
                            args.push(format!("uuid:{}", uuid));
                            args.push(format!("{}", "information"));
                            let tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn()
                                .unwrap_or_else(|e| {
                                    error!("{}", e);
                                    panic!("failed");
                                });
                            let output = tw_process.wait_with_output().unwrap_or_else(|e| {
                                panic!("failed to unwrap output: {}", e);
                            });
                            let outstring = String::from_utf8(output.stdout).unwrap_or_else(|e| {
                                panic!("failed to ececute: {}", e);
                            });
                            println!("{}", outstring);
                        }
                        else {
                            println!("{}", match uuid {
                                toml::Value::String(s) => s,
                                _ => {
                                    error!("Unexpected type for todo.uuid: {}", uuid);
                                    continue;
                                },
                            });
                        }
                    }
                    Err(e) => {
                        error!("{}", e);
                        continue;
                    }
                } // end match task
            } // end for
        }
        _ => unimplemented!(),
    } // end match scmd
} // end main

<commit_msg>delete-hook working<commit_after>extern crate clap;
extern crate glob;
#[macro_use] extern crate log;
extern crate serde_json;
extern crate semver;
extern crate toml;
#[macro_use] extern crate version;

extern crate task_hookrs;

extern crate libimagrt;
extern crate libimagstore;
extern crate libimagutil;
extern crate libimagtodo;

use std::process::exit;
use std::process::{Command, Stdio};
use std::io::stdin;
use std::io::BufRead;

use task_hookrs::import::{import, import_task, import_tasks};

use libimagrt::runtime::Runtime;
use libimagtodo::task::IntoTask;
use libimagutil::trace::trace_error;

mod ui;

use ui::build_ui;
fn main() {

    let name = "imag-todo";
    let version = &version!()[..];
    let about = "Interface with taskwarrior";
    let ui = build_ui(Runtime::get_default_cli_builder(name, version, about));

    let rt = {
        let rt = Runtime::new(ui);
        if rt.is_ok() {
            rt.unwrap()
        } else {
            println!("Could not set up Runtime");
            println!("{:?}", rt.unwrap_err());
            exit(1);
        }
    };

    let scmd = rt.cli().subcommand_name();
    match scmd {
        Some("tw-hook") => {
            let subcmd = rt.cli().subcommand_matches("tw-hook").unwrap();
            if subcmd.is_present("add") {
                let stdin = stdin();
                let mut stdin = stdin.lock();
                let mut line = String::new();
                match stdin.read_line(&mut line) {
                    Ok(_) => { }
                    Err(e) => {
                        error!("{}", e);
                        return;
                    }
                };
                if let Ok(ttask) = import_task(&line.as_str()) {
                    print!("{}", match serde_json::ser::to_string(&ttask) {
                        Ok(val) => val,
                        Err(e) => {
                            error!("{}", e);
                            return;
                        }
                    });
                    match ttask.into_filelockentry(rt.store()) {
                        Ok(val) => val,
                        Err(e) => {
                            trace_error(&e);
                            error!("{}", e);
                            return;
                        }
                    };
                }
                else {
                    error!("No usable input");
                    return;
                }
            }
            else if subcmd.is_present("delete") {
                // The used hook is "on-modify". This hook gives two json-objects
                // per usage und wants one (the second one) back.
                let mut counter = 0;
                let stdin = stdin();
                let mut stdin = stdin.lock();
                if let Ok(ttasks) = import_tasks(stdin) {
                    for ttask in ttasks {
                        if counter % 2 == 1 {
                            // Only every second task is needed, the first one is the
                            // task before the change, and the second one after
                            // the change. The (maybe modified) second one is
                            // expected by taskwarrior.
                            println!("{}", match serde_json::ser::to_string(&ttask) {
                                Ok(val) => val,
                                Err(e) => {
                                    error!("{}", e);
                                    return;
                                }
                            });
                            match ttask.status() {
                                &task_hookrs::status::TaskStatus::Deleted => {
                                    match libimagtodo::delete::delete(rt.store(), *ttask.uuid()) {
                                        Ok(_) => {
                                            println!("Deleted task {}", *ttask.uuid());
                                        }
                                        Err(e) => {
                                            trace_error(&e);
                                            error!("{}", e);
                                            return;
                                        }
                                    }
                                }
                                _ => {
                                }
                            } // end match ttask.status()
                        } // end if c % 2
                        counter += 1;
                    } // end for
                } // end if let
                else {
                    error!("No usable input");
                }
            }
            else {
                // Should not be possible, as one argument is required via
                // ArgGroup
                unreachable!();
            }
        },
        Some("exec") => {
            let subcmd = rt.cli().subcommand_matches("exec").unwrap();
            let mut args = Vec::new();
            if let Some(exec_string) = subcmd.values_of("command") {
                for e in exec_string {
                    args.push(e);
                }
                let tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn().unwrap_or_else(|e| {
                    panic!("failed to execute taskwarrior: {}", e);
                });

                let output = tw_process.wait_with_output().unwrap_or_else(|e| {
                    panic!("failed to unwrap output: {}", e);
                });
                let outstring = String::from_utf8(output.stdout).unwrap_or_else(|e| {
                    panic!("failed to ececute: {}", e);
                });
                println!("{}", outstring);
            } else {
                panic!("faild to execute: You need to exec --command");
            }
        }
        Some("list") => {
            let subcmd = rt.cli().subcommand_matches("list").unwrap();
            let mut args = Vec::new();
            let verbose = subcmd.is_present("verbose");
            let iter = match libimagtodo::read::get_todo_iterator(rt.store()) {
                //let iter = match rt.store().retrieve_for_module("todo/taskwarrior") {
                Err(e) => {
                    error!("{}", e);
                    return;
                }
                Ok(val) => val,
            };
            for task in iter {
                match task {
                    Ok(val) => {
                        //let val = libimagtodo::task::Task::new(fle);
                        //println!("{:#?}", val.flentry);
                        let uuid = match val.flentry.get_header().read("todo.uuid") {
                            Ok(Some(u)) => u,
                            Ok(None) => continue,
                            Err(e) => {
                                error!("{}", e);
                                continue;
                            }
                        };
                        if verbose {
                            args.clear();
                            args.push(format!("uuid:{}", uuid));
                            args.push(format!("{}", "information"));
                            let tw_process = Command::new("task").stdin(Stdio::null()).args(&args).spawn()
                                .unwrap_or_else(|e| {
                                    error!("{}", e);
                                    panic!("failed");
                                });
                            let output = tw_process.wait_with_output().unwrap_or_else(|e| {
                                panic!("failed to unwrap output: {}", e);
                            });
                            let outstring = String::from_utf8(output.stdout).unwrap_or_else(|e| {
                                panic!("failed to ececute: {}", e);
                            });
                            println!("{}", outstring);
                        }
                        else {
                            println!("{}", match uuid {
                                toml::Value::String(s) => s,
                                _ => {
                                    error!("Unexpected type for todo.uuid: {}", uuid);
                                    continue;
                                },
                            });
                        }
                    }
                    Err(e) => {
                        error!("{}", e);
                        continue;
                    }
                } // end match task
            } // end for
        }
        _ => unimplemented!(),
    } // end match scmd
} // end main

<|endoftext|>


<commit_before>//! Word splitting functionality.
//!
//! To wrap text into lines, long words sometimes need to be split
//! across lines. The [`WordSplitter`] trait defines this
//! functionality. [`HyphenSplitter`] is the default implementation of
//! this treat: it will simply split words on existing hyphens.

#[cfg(feature = "hyphenation")]
use hyphenation::{Hyphenator, Standard};

/// An interface for splitting words.
///
/// When the [`wrap_iter`] method will try to fit text into a line, it
/// will eventually find a word that it too large the current text
/// width. It will then call the currently configured `WordSplitter` to
/// have it attempt to split the word into smaller parts. This trait
/// describes that functionality via the [`split`] method.
///
/// If the `textwrap` crate has been compiled with the `hyphenation`
/// feature enabled, you will find an implementation of `WordSplitter`
/// by the `hyphenation::Standard` struct. Use this struct for
/// language-aware hyphenation. See the [`hyphenation` documentation]
/// for details.
///
/// [`wrap_iter`]: ../struct.Wrapper.html#method.wrap_iter
/// [`split`]: #tymethod.split
/// [`hyphenation` documentation]: https://docs.rs/hyphenation/
pub trait WordSplitter {
    /// Return all possible splits of word. Each split is a triple
    /// with a head, a hyphen, and a tail where `head + &hyphen +
    /// &tail == word`. The hyphen can be empty if there is already a
    /// hyphen in the head.
    ///
    /// The splits should go from smallest to longest and should
    /// include no split at all. So the word "technology" could be
    /// split into
    ///
    /// ```no_run
    /// vec![("tech", "-", "nology"),
    ///      ("technol", "-", "ogy"),
    ///      ("technolo", "-", "gy"),
    ///      ("technology", "", "")];
    /// ```
    fn split<'w>(&self, word: &'w str) -> Vec<(&'w str, &'w str, &'w str)>;
}

/// Use this as a [`Wrapper.splitter`] to avoid any kind of
/// hyphenation:
///
/// ```
/// use textwrap::{Wrapper, NoHyphenation};
///
/// let wrapper = Wrapper::with_splitter(8, NoHyphenation);
/// assert_eq!(wrapper.wrap("foo bar-baz"), vec!["foo", "bar-baz"]);
/// ```
///
/// [`Wrapper.splitter`]: ../struct.Wrapper.html#structfield.splitter
#[derive(Clone, Debug)]
pub struct NoHyphenation;

/// `NoHyphenation` implements `WordSplitter` by not splitting the
/// word at all.
impl WordSplitter for NoHyphenation {
    fn split<'w>(&self, word: &'w str) -> Vec<(&'w str, &'w str, &'w str)> {
        vec![(word, "", "")]
    }
}

/// Simple and default way to split words: splitting on existing
/// hyphens only.
///
/// You probably don't need to use this type since it's already used
/// by default by `Wrapper::new`.
#[derive(Clone, Debug)]
pub struct HyphenSplitter;

/// `HyphenSplitter` is the default `WordSplitter` used by
/// `Wrapper::new`. It will split words on any existing hyphens in the
/// word.
///
/// It will only use hyphens that are surrounded by alphanumeric
/// characters, which prevents a word like "--foo-bar" from being
/// split on the first or second hyphen.
impl WordSplitter for HyphenSplitter {
    fn split<'w>(&self, word: &'w str) -> Vec<(&'w str, &'w str, &'w str)> {
        let mut triples = Vec::new();
        // Split on hyphens, smallest split first. We only use hyphens
        // that are surrounded by alphanumeric characters. This is to
        // avoid splitting on repeated hyphens, such as those found in
        // --foo-bar.
        let mut char_indices = word.char_indices();
        // Early return if the word is empty.
        let mut prev = match char_indices.next() {
            None => return vec![(word, "", "")],
            Some((_, ch)) => ch,
        };

        // Find current word, or return early if the word only has a
        // single character.
        let (mut idx, mut cur) = match char_indices.next() {
            None => return vec![(word, "", "")],
            Some((idx, cur)) => (idx, cur),
        };

        for (i, next) in char_indices {
            if prev.is_alphanumeric() && cur == '-' && next.is_alphanumeric() {
                let (head, tail) = word.split_at(idx + 1);
                triples.push((head, "", tail));
            }
            prev = cur;
            idx = i;
            cur = next;
        }

        // Finally option is no split at all.
        triples.push((word, "", ""));

        triples
    }
}

/// A hyphenation dictionary can be used to do language-specific
/// hyphenation using patterns from the hyphenation crate.
///
/// **Note:** Only available when the `hyphenation` feature is
/// enabled.
#[cfg(feature = "hyphenation")]
impl WordSplitter for Standard {
    fn split<'w>(&self, word: &'w str) -> Vec<(&'w str, &'w str, &'w str)> {
        // Find splits based on language dictionary.
        let mut triples = Vec::new();
        for n in self.hyphenate(word).breaks {
            let (head, tail) = word.split_at(n);
            let hyphen = if head.ends_with('-') { "" } else { "-" };
            triples.push((head, hyphen, tail));
        }
        // Finally option is no split at all.
        triples.push((word, "", ""));

        triples
    }
}
<commit_msg>Simplify use statement<commit_after>//! Word splitting functionality.
//!
//! To wrap text into lines, long words sometimes need to be split
//! across lines. The [`WordSplitter`] trait defines this
//! functionality. [`HyphenSplitter`] is the default implementation of
//! this treat: it will simply split words on existing hyphens.

/// An interface for splitting words.
///
/// When the [`wrap_iter`] method will try to fit text into a line, it
/// will eventually find a word that it too large the current text
/// width. It will then call the currently configured `WordSplitter` to
/// have it attempt to split the word into smaller parts. This trait
/// describes that functionality via the [`split`] method.
///
/// If the `textwrap` crate has been compiled with the `hyphenation`
/// feature enabled, you will find an implementation of `WordSplitter`
/// by the `hyphenation::Standard` struct. Use this struct for
/// language-aware hyphenation. See the [`hyphenation` documentation]
/// for details.
///
/// [`wrap_iter`]: ../struct.Wrapper.html#method.wrap_iter
/// [`split`]: #tymethod.split
/// [`hyphenation` documentation]: https://docs.rs/hyphenation/
pub trait WordSplitter {
    /// Return all possible splits of word. Each split is a triple
    /// with a head, a hyphen, and a tail where `head + &hyphen +
    /// &tail == word`. The hyphen can be empty if there is already a
    /// hyphen in the head.
    ///
    /// The splits should go from smallest to longest and should
    /// include no split at all. So the word "technology" could be
    /// split into
    ///
    /// ```no_run
    /// vec![("tech", "-", "nology"),
    ///      ("technol", "-", "ogy"),
    ///      ("technolo", "-", "gy"),
    ///      ("technology", "", "")];
    /// ```
    fn split<'w>(&self, word: &'w str) -> Vec<(&'w str, &'w str, &'w str)>;
}

/// Use this as a [`Wrapper.splitter`] to avoid any kind of
/// hyphenation:
///
/// ```
/// use textwrap::{Wrapper, NoHyphenation};
///
/// let wrapper = Wrapper::with_splitter(8, NoHyphenation);
/// assert_eq!(wrapper.wrap("foo bar-baz"), vec!["foo", "bar-baz"]);
/// ```
///
/// [`Wrapper.splitter`]: ../struct.Wrapper.html#structfield.splitter
#[derive(Clone, Debug)]
pub struct NoHyphenation;

/// `NoHyphenation` implements `WordSplitter` by not splitting the
/// word at all.
impl WordSplitter for NoHyphenation {
    fn split<'w>(&self, word: &'w str) -> Vec<(&'w str, &'w str, &'w str)> {
        vec![(word, "", "")]
    }
}

/// Simple and default way to split words: splitting on existing
/// hyphens only.
///
/// You probably don't need to use this type since it's already used
/// by default by `Wrapper::new`.
#[derive(Clone, Debug)]
pub struct HyphenSplitter;

/// `HyphenSplitter` is the default `WordSplitter` used by
/// `Wrapper::new`. It will split words on any existing hyphens in the
/// word.
///
/// It will only use hyphens that are surrounded by alphanumeric
/// characters, which prevents a word like "--foo-bar" from being
/// split on the first or second hyphen.
impl WordSplitter for HyphenSplitter {
    fn split<'w>(&self, word: &'w str) -> Vec<(&'w str, &'w str, &'w str)> {
        let mut triples = Vec::new();
        // Split on hyphens, smallest split first. We only use hyphens
        // that are surrounded by alphanumeric characters. This is to
        // avoid splitting on repeated hyphens, such as those found in
        // --foo-bar.
        let mut char_indices = word.char_indices();
        // Early return if the word is empty.
        let mut prev = match char_indices.next() {
            None => return vec![(word, "", "")],
            Some((_, ch)) => ch,
        };

        // Find current word, or return early if the word only has a
        // single character.
        let (mut idx, mut cur) = match char_indices.next() {
            None => return vec![(word, "", "")],
            Some((idx, cur)) => (idx, cur),
        };

        for (i, next) in char_indices {
            if prev.is_alphanumeric() && cur == '-' && next.is_alphanumeric() {
                let (head, tail) = word.split_at(idx + 1);
                triples.push((head, "", tail));
            }
            prev = cur;
            idx = i;
            cur = next;
        }

        // Finally option is no split at all.
        triples.push((word, "", ""));

        triples
    }
}

/// A hyphenation dictionary can be used to do language-specific
/// hyphenation using patterns from the hyphenation crate.
///
/// **Note:** Only available when the `hyphenation` feature is
/// enabled.
#[cfg(feature = "hyphenation")]
impl WordSplitter for hyphenation::Standard {
    fn split<'w>(&self, word: &'w str) -> Vec<(&'w str, &'w str, &'w str)> {
        use hyphenation::Hyphenator;
        // Find splits based on language dictionary.
        let mut triples = Vec::new();
        for n in self.hyphenate(word).breaks {
            let (head, tail) = word.split_at(n);
            let hyphen = if head.ends_with('-') { "" } else { "-" };
            triples.push((head, hyphen, tail));
        }
        // Finally option is no split at all.
        triples.push((word, "", ""));

        triples
    }
}
<|endoftext|>


<commit_before>extern crate clap;
use clap::{Arg, App};

extern crate rusqlite;
use rusqlite::{Connection, Transaction, TransactionBehavior};
use rusqlite::types::{ToSql};

extern crate sqlcmdlutils;
use sqlcmdlutils::dbpath::{DbPath, db_path_help, parse_db_path};

fn main() {
    let arg_matches =
        App::new("sqld - delete SQLite database contents")
            .version(env!("CARGO_PKG_VERSION"))
            .arg(Arg::with_name("path")
                .help(db_path_help())
                .required(true)
                .index(1))
            .arg(Arg::with_name("db_file")
                .help("Absolute or relative path to an SQLite database file.")
                .value_name("database")
                .required(true)
                .index(2))
            .get_matches();

    let db_path = arg_matches.value_of("path").unwrap();

    let db_file = arg_matches.value_of("db_file").unwrap();
    let mut conn = Connection::open(db_file).unwrap();

    match parse_db_path(db_path) {
        DbPath::Error(msg) => println!("{}", msg),

        DbPath::Root => {
            let  tx = Transaction::new(&mut conn, TransactionBehavior::Deferred).unwrap();
            let mut tables: Vec<String> = Vec::new();

            { // prepare available tables
                let query = "SELECT tbl_name FROM sqlite_master WHERE type = 'table' AND length(sql) > 0";
                let mut stmt = tx.prepare(query).unwrap();
                let mut rows = stmt.query(&[]).unwrap();
                while let Some(result_row) = rows.next() {
                    match result_row {
                        Ok(row) => tables.push(row.get::<i32, String>(0)),
                        Err(_) => ()
                    }
                }
            }

            if tables.len() > 0 {
                // TODO Confirmation propmt
                let mut tx_commit = true;
                for t in tables {
                    let delete_query = format!("DELETE FROM {}", t);
                    match tx.execute(delete_query.as_str(), &[]) {
                        Ok(deleted) => println!("Deleted {} row(s) from {}", deleted, t),
                        Err(msg) => {
                            println!("Delete failed at table: {} - doing rollback ...", t);
                            println!("Delete failure message: {}", msg);
                            tx_commit = false;
                            break;
                        }
                    }
                }
                if tx_commit {
                    match tx.commit() {
                        Ok(_) => (),
                        Err(_) => println!("Failed to commit deletes."),
                    };
                } else {
                    match tx.rollback() {
                        Ok(_) => (),
                        Err(_) => println!("Failed to do rollback for deletes."),
                    }
                }
            } else {
                println!("No tables found in the database.");
            }
        }

        DbPath::Table(table) => {
            let query = format!("DELETE FROM {}", table);
            execute_query(&conn, query.as_str(), table.as_str(), &[]);
        }

        DbPath::TableFilter {table, filter} => {
            let query = format!("DELETE FROM {} WHERE {}", table, filter);
            execute_query(&conn, query.as_str(), table.as_str(), &[]);
        }

        _ => println!("Column selection is not supported for DELETE."),
    }
}

fn execute_query(conn: &Connection, query: &str, table: &str, params: &[&ToSql]) -> () {
    match conn.execute(query, params) {
        Ok(deleted) => println!("Deleted {} row(s) from {}", deleted, table),
        Err(msg) => println!("Delete failed: {}", msg),
    }
}
<commit_msg>Add confirmation prompt for sqld for the / (root) case - deletion of all data.<commit_after>extern crate clap;
use clap::{Arg, App};

extern crate rusqlite;
use rusqlite::{Connection, Transaction, TransactionBehavior};
use rusqlite::types::{ToSql};

extern crate sqlcmdlutils;
use sqlcmdlutils::dbpath::{DbPath, db_path_help, parse_db_path};

fn main() {
    let arg_matches =
        App::new("sqld - delete SQLite database contents")
            .version(env!("CARGO_PKG_VERSION"))
            .arg(Arg::with_name("path")
                .help(db_path_help())
                .required(true)
                .index(1))
            .arg(Arg::with_name("db_file")
                .help("Absolute or relative path to an SQLite database file.")
                .value_name("database")
                .required(true)
                .index(2))
            .get_matches();

    let db_path = arg_matches.value_of("path").unwrap();

    let db_file = arg_matches.value_of("db_file").unwrap();
    let mut conn = Connection::open(db_file).unwrap();

    match parse_db_path(db_path) {
        DbPath::Error(msg) => println!("{}", msg),

        DbPath::Root => {
            let  tx = Transaction::new(&mut conn, TransactionBehavior::Deferred).unwrap();
            let mut tables: Vec<String> = Vec::new();

            { // prepare available tables
                let query = "SELECT tbl_name FROM sqlite_master WHERE type = 'table' AND length(sql) > 0";
                let mut stmt = tx.prepare(query).unwrap();
                let mut rows = stmt.query(&[]).unwrap();
                while let Some(result_row) = rows.next() {
                    match result_row {
                        Ok(row) => tables.push(row.get::<i32, String>(0)),
                        Err(_) => ()
                    }
                }
            }

            if tables.len() > 0 {
                println!("Are you sure you'd like to delete data from all tables? S(ure)/H(ell no)");
                let mut user_input = String::new();
                match std::io::stdin() .read_line(&mut user_input) {
                    Ok(_) => {
                        let response = user_input.trim().to_lowercase();
                        if response != "s" && response != "sure" {
                            return ()
                        }
                    }
                    Err(msg) => {
                        println!("Error: {}", msg);
                        return ()
                    }
                }

                let mut tx_commit = true;
                for t in tables {
                    let delete_query = format!("DELETE FROM {}", t);
                    match tx.execute(delete_query.as_str(), &[]) {
                        Ok(deleted) => println!("Deleted {} row(s) from {}", deleted, t),
                        Err(msg) => {
                            println!("Delete failed at table: {} - doing rollback ...", t);
                            println!("Delete failure message: {}", msg);
                            tx_commit = false;
                            break;
                        }
                    }
                }
                if tx_commit {
                    match tx.commit() {
                        Ok(_) => (),
                        Err(_) => println!("Failed to commit deletes."),
                    };
                } else {
                    match tx.rollback() {
                        Ok(_) => (),
                        Err(_) => println!("Failed to do rollback for deletes."),
                    }
                }
            } else {
                println!("No tables found in the database.");
            }
        }

        DbPath::Table(table) => {
            let query = format!("DELETE FROM {}", table);
            execute_query(&conn, query.as_str(), table.as_str(), &[]);
        }

        DbPath::TableFilter {table, filter} => {
            let query = format!("DELETE FROM {} WHERE {}", table, filter);
            execute_query(&conn, query.as_str(), table.as_str(), &[]);
        }

        _ => println!("Column selection is not supported for DELETE."),
    }
}

fn execute_query(conn: &Connection, query: &str, table: &str, params: &[&ToSql]) -> () {
    match conn.execute(query, params) {
        Ok(deleted) => println!("Deleted {} row(s) from {}", deleted, table),
        Err(msg) => println!("Delete failed: {}", msg),
    }
}
<|endoftext|>


<commit_before>use std::ffi::{CStr, CString, NulError};
use std::fmt;
use get_error;
use libc::c_char;

use sys::filesystem as ll;

pub fn base_path() -> Result<String, String> {
    let result = unsafe {
        let buf = ll::SDL_GetBasePath();
        CStr::from_ptr(buf as *const _).to_str().unwrap().to_owned()
    };

    if result.len() == 0 {
        Err(get_error())
    } else {
        Ok(result)
    }
}

#[derive(Debug)]
pub enum PrefPathError {
    InvalidOrganizationName(NulError),
    InvalidApplicationName(NulError),
    SdlError(String),
}

impl fmt::Display for PrefPathError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::PrefPathError::*;

        match *self {
            InvalidOrganizationName(ref e) => write!(f, "Invalid organization name: {}", e),
            InvalidApplicationName(ref e) => write!(f, "Invalid application name: {}", e),
            SdlError(ref e) => write!(f, "SDL error: {}", e)
        }
    }
}

// TODO: Change to OsStr or something?
/// Return the preferred directory for the application to write files on this
/// system, based on the given organization and application name.
pub fn pref_path(org_name: &str, app_name: &str)
        -> Result<String, PrefPathError> {
    use self::PrefPathError::*;
    let result = unsafe {
        let org = match CString::new(org_name) {
            Ok(s) => s,
            Err(err) => return Err(InvalidOrganizationName(err)),
        };
        let app = match CString::new(app_name) {
            Ok(s) =>s,
            Err(err) => return Err(InvalidApplicationName(err)),
        };
        let buf = ll::SDL_GetPrefPath(org.as_ptr() as *const c_char, app.as_ptr() as *const c_char);
        CStr::from_ptr(buf as *const _).to_str().unwrap().to_owned()
    };

    if result.len() == 0 {
        Err(SdlError(get_error()))
    } else {
        Ok(result)
    }
}
<commit_msg>Implement Error for PrefPathError.<commit_after>use std::error;
use std::ffi::{CStr, CString, NulError};
use std::fmt;
use get_error;
use libc::c_char;

use sys::filesystem as ll;

pub fn base_path() -> Result<String, String> {
    let result = unsafe {
        let buf = ll::SDL_GetBasePath();
        CStr::from_ptr(buf as *const _).to_str().unwrap().to_owned()
    };

    if result.len() == 0 {
        Err(get_error())
    } else {
        Ok(result)
    }
}

#[derive(Debug)]
pub enum PrefPathError {
    InvalidOrganizationName(NulError),
    InvalidApplicationName(NulError),
    SdlError(String),
}

impl fmt::Display for PrefPathError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::PrefPathError::*;

        match *self {
            InvalidOrganizationName(ref e) => write!(f, "Invalid organization name: {}", e),
            InvalidApplicationName(ref e) => write!(f, "Invalid application name: {}", e),
            SdlError(ref e) => write!(f, "SDL error: {}", e)
        }
    }
}

impl error::Error for PrefPathError {
    fn description(&self) -> &str {
        use self::PrefPathError::*;

        match *self {
            InvalidOrganizationName(_) => "invalid organization name",
            InvalidApplicationName(_) => "invalid application name",
            SdlError(ref e) => e,
        }
    }
}

// TODO: Change to OsStr or something?
/// Return the preferred directory for the application to write files on this
/// system, based on the given organization and application name.
pub fn pref_path(org_name: &str, app_name: &str)
        -> Result<String, PrefPathError> {
    use self::PrefPathError::*;
    let result = unsafe {
        let org = match CString::new(org_name) {
            Ok(s) => s,
            Err(err) => return Err(InvalidOrganizationName(err)),
        };
        let app = match CString::new(app_name) {
            Ok(s) =>s,
            Err(err) => return Err(InvalidApplicationName(err)),
        };
        let buf = ll::SDL_GetPrefPath(org.as_ptr() as *const c_char, app.as_ptr() as *const c_char);
        CStr::from_ptr(buf as *const _).to_str().unwrap().to_owned()
    };

    if result.len() == 0 {
        Err(SdlError(get_error()))
    } else {
        Ok(result)
    }
}
<|endoftext|>


<commit_before>use video::Window;
use get_error;
use SdlResult;

#[allow(non_camel_case_types)]
pub mod ll {
    use libc::{c_int, c_char, uint32_t};
    use video::ll::SDL_Window;

    pub enum SDL_MessageBoxFlags {
        SDL_MESSAGEBOX_ERROR        = 0x00000010,
        SDL_MESSAGEBOX_WARNING      = 0x00000020,
        SDL_MESSAGEBOX_INFORMATION  = 0x00000040
    }

    extern "C" {
        pub fn SDL_ShowSimpleMessageBox(flags: uint32_t, title: *const c_char, message: *const c_char, window: *const SDL_Window) -> c_int;
    }
}

bitflags! {
    flags MessageBoxFlag: u32 {
        const MESSAGEBOX_ERROR = ll::SDL_MessageBoxFlags::SDL_MESSAGEBOX_ERROR as u32,
        const MESSAGEBOX_WARNING = ll::SDL_MessageBoxFlags::SDL_MESSAGEBOX_WARNING as u32,
        const MESSAGEBOX_INFORMATION = ll::SDL_MessageBoxFlags::SDL_MESSAGEBOX_INFORMATION as u32
    }
}

pub fn show_simple_message_box(flags: MessageBoxFlag, title: &str, message: &str, window: Window) -> SdlResult<()> {
    let result = unsafe {
        title.with_c_str(|title_cstr| {
        message.with_c_str(|message_cstr| {
            ll::SDL_ShowSimpleMessageBox(flags.bits(), title_cstr, message_cstr, window.raw())
        })
        })
    } == 0;

    if result {
        Ok(())
    } else {
        Err(get_error())
    }
}
<commit_msg>Replaced ll::SDL_MessageBoxFlags enum with constants.<commit_after>use video::Window;
use get_error;
use SdlResult;

#[allow(non_camel_case_types)]
pub mod ll {
    use libc::{c_int, c_char, uint32_t};
    use video::ll::SDL_Window;

    pub type SDL_MessageBoxFlags = u32;
    pub const SDL_MESSAGEBOX_ERROR : SDL_MessageBoxFlags = 0x00000010;
    pub const SDL_MESSAGEBOX_WARNING : SDL_MessageBoxFlags = 0x00000020;
    pub const SDL_MESSAGEBOX_INFORMATION : SDL_MessageBoxFlags = 0x00000040;

    extern "C" {
        pub fn SDL_ShowSimpleMessageBox(flags: uint32_t, title: *const c_char, message: *const c_char, window: *const SDL_Window) -> c_int;
    }
}

bitflags! {
    flags MessageBoxFlag: u32 {
        const MESSAGEBOX_ERROR = ll::SDL_MESSAGEBOX_ERROR,
        const MESSAGEBOX_WARNING = ll::SDL_MESSAGEBOX_WARNING,
        const MESSAGEBOX_INFORMATION = ll::SDL_MESSAGEBOX_INFORMATION
    }
}

pub fn show_simple_message_box(flags: MessageBoxFlag, title: &str, message: &str, window: Window) -> SdlResult<()> {
    let result = unsafe {
        title.with_c_str(|title_cstr| {
        message.with_c_str(|message_cstr| {
            ll::SDL_ShowSimpleMessageBox(flags.bits(), title_cstr, message_cstr, window.raw())
        })
        })
    } == 0;

    if result {
        Ok(())
    } else {
        Err(get_error())
    }
}
<|endoftext|>


<commit_before>extern crate crypto;

use self::crypto::aesni;
use self::crypto::aes::{KeySize, ecb_decryptor};
use self::crypto::blockmodes;
use self::crypto::buffer::{RefReadBuffer, ReadBuffer, RefWriteBuffer, WriteBuffer, BufferResult};
use self::crypto::symmetriccipher;

use set1::challenge6::base64_to_bytes;
use set1::challenge6::load_file;

fn decrypt_aes_ecb(encrypted_data: &[u8],
                   key: &[u8])
                   -> Result<Vec<u8>, symmetriccipher::SymmetricCipherError> {
    let mut decryptor = ecb_decryptor(KeySize::KeySize128, key, blockmodes::PkcsPadding);
    let mut read_buffer = RefReadBuffer::new(encrypted_data);
    let mut buffer = [0; 4096];
    let mut write_buffer = RefWriteBuffer::new(&mut buffer);
    let mut output = Vec::<u8>::new();
    loop {
        let result = try!(decryptor.decrypt(&mut read_buffer, &mut write_buffer, true));
        output.extend(write_buffer.take_read_buffer().take_remaining().iter().map(|&i| i));
        match result {
            BufferResult::BufferUnderflow => break,
            BufferResult::BufferOverflow => {}
        }
    }
    Ok(output)
}

#[test]
fn test_decrypt_aes_ecb() {
    assert!(String::from_utf8(decrypt_aes_ecb(&base64_to_bytes(&load_file("./files/challenge-7.\
                                                                           txt")),
                                              &"YELLOW SUBMARINE".as_bytes())
            .unwrap())
        .unwrap()
        .starts_with("I\'m back and I\'m ringin"));

}
<commit_msg>set1: Use no padding for aes<commit_after>extern crate crypto;

use self::crypto::aesni;
use self::crypto::aes::{KeySize, ecb_decryptor};
use self::crypto::blockmodes;
use self::crypto::buffer::{RefReadBuffer, ReadBuffer, RefWriteBuffer, WriteBuffer, BufferResult};
use self::crypto::symmetriccipher;

use set1::challenge6::{base64_to_bytes, load_file};

fn decrypt_aes_ecb(encrypted_data: &[u8],
                   key: &[u8])
                   -> Result<Vec<u8>, symmetriccipher::SymmetricCipherError> {
    let mut decryptor = ecb_decryptor(KeySize::KeySize128, key, blockmodes::NoPadding);
    let mut read_buffer = RefReadBuffer::new(encrypted_data);
    let mut buffer = [0; 4096];
    let mut write_buffer = RefWriteBuffer::new(&mut buffer);
    let mut output = Vec::<u8>::new();
    loop {
        let result = try!(decryptor.decrypt(&mut read_buffer, &mut write_buffer, true));
        output.extend(write_buffer.take_read_buffer().take_remaining().iter().map(|&i| i));
        match result {
            BufferResult::BufferUnderflow => break,
            BufferResult::BufferOverflow => {}
        }
    }
    Ok(output)
}

#[test]
fn test_decrypt_aes_ecb() {
    assert!(String::from_utf8(decrypt_aes_ecb(&base64_to_bytes(&load_file("./files/challenge-7.\
                                                                           txt")),
                                              &"YELLOW SUBMARINE".as_bytes())
            .unwrap())
        .unwrap()
        .starts_with("I\'m back and I\'m ringin"));

}
<|endoftext|>


<commit_before>use std::str::FromStr;

use crate::error::{ConfigError, Result};
use crate::map::Map;
use crate::value::{Value, ValueKind};

mod parser;

#[derive(Debug, Eq, PartialEq, Clone, Hash)]
pub enum Expression {
    Identifier(String),
    Child(Box<Self>, String),
    Subscript(Box<Self>, isize),
}

impl FromStr for Expression {
    type Err = ConfigError;

    fn from_str(s: &str) -> Result<Self> {
        parser::from_str(s).map_err(ConfigError::PathParse)
    }
}

fn sindex_to_uindex(index: isize, len: usize) -> usize {
    if index >= 0 {
        index as usize
    } else {
        len - (index.abs() as usize)
    }
}

impl Expression {
    pub fn get(self, root: &Value) -> Option<&Value> {
        match self {
            Self::Identifier(id) => {
                match root.kind {
                    // `x` access on a table is equivalent to: map[x]
                    ValueKind::Table(ref map) => map.get(&id),

                    // all other variants return None
                    _ => None,
                }
            }

            Self::Child(expr, key) => {
                match expr.get(root) {
                    Some(value) => {
                        match value.kind {
                            // Access on a table is identical to Identifier, it just forwards
                            ValueKind::Table(ref map) => map.get(&key),

                            // all other variants return None
                            _ => None,
                        }
                    }

                    _ => None,
                }
            }

            Self::Subscript(expr, index) => match expr.get(root) {
                Some(value) => match value.kind {
                    ValueKind::Array(ref array) => {
                        let index = sindex_to_uindex(index, array.len());

                        if index >= array.len() {
                            None
                        } else {
                            Some(&array[index])
                        }
                    }

                    _ => None,
                },

                _ => None,
            },
        }
    }

    pub fn get_mut<'a>(&self, root: &'a mut Value) -> Option<&'a mut Value> {
        match *self {
            Self::Identifier(ref id) => match root.kind {
                ValueKind::Table(ref mut map) => map.get_mut(id),

                _ => None,
            },

            Self::Child(ref expr, ref key) => match expr.get_mut(root) {
                Some(value) => match value.kind {
                    ValueKind::Table(ref mut map) => map.get_mut(key),

                    _ => None,
                },

                _ => None,
            },

            Self::Subscript(ref expr, index) => match expr.get_mut(root) {
                Some(value) => match value.kind {
                    ValueKind::Array(ref mut array) => {
                        let index = sindex_to_uindex(index, array.len());

                        if index >= array.len() {
                            None
                        } else {
                            Some(&mut array[index])
                        }
                    }

                    _ => None,
                },

                _ => None,
            },
        }
    }

    pub fn get_mut_forcibly<'a>(&self, root: &'a mut Value) -> Option<&'a mut Value> {
        match *self {
            Self::Identifier(ref id) => match root.kind {
                ValueKind::Table(ref mut map) => Some(
                    map.entry(id.clone())
                        .or_insert_with(|| Value::new(None, ValueKind::Nil)),
                ),

                _ => None,
            },

            Self::Child(ref expr, ref key) => match expr.get_mut_forcibly(root) {
                Some(value) => {
                    if let ValueKind::Table(ref mut map) = value.kind {
                        Some(
                            map.entry(key.clone())
                                .or_insert_with(|| Value::new(None, ValueKind::Nil)),
                        )
                    } else {
                        *value = Map::<String, Value>::new().into();

                        if let ValueKind::Table(ref mut map) = value.kind {
                            Some(
                                map.entry(key.clone())
                                    .or_insert_with(|| Value::new(None, ValueKind::Nil)),
                            )
                        } else {
                            unreachable!();
                        }
                    }
                }

                _ => None,
            },

            Self::Subscript(ref expr, index) => match expr.get_mut_forcibly(root) {
                Some(value) => {
                    match value.kind {
                        ValueKind::Array(_) => (),
                        _ => *value = Vec::<Value>::new().into(),
                    }

                    match value.kind {
                        ValueKind::Array(ref mut array) => {
                            let index = sindex_to_uindex(index, array.len());

                            if index >= array.len() {
                                array
                                    .resize((index + 1) as usize, Value::new(None, ValueKind::Nil));
                            }

                            Some(&mut array[index])
                        }

                        _ => None,
                    }
                }
                _ => None,
            },
        }
    }

    pub fn set(&self, root: &mut Value, value: Value) {
        match *self {
            Self::Identifier(ref id) => {
                // Ensure that root is a table
                match root.kind {
                    ValueKind::Table(_) => {}

                    _ => {
                        *root = Map::<String, Value>::new().into();
                    }
                }

                match value.kind {
                    ValueKind::Table(ref incoming_map) => {
                        // Pull out another table
                        let target = if let ValueKind::Table(ref mut map) = root.kind {
                            map.entry(id.clone())
                                .or_insert_with(|| Map::<String, Value>::new().into())
                        } else {
                            unreachable!();
                        };

                        // Continue the deep merge
                        for (key, val) in incoming_map {
                            Self::Identifier(key.clone()).set(target, val.clone());
                        }
                    }

                    _ => {
                        if let ValueKind::Table(ref mut map) = root.kind {
                            // Just do a simple set
                            if let Some(existing) = map.get_mut(id) {
                                *existing = value;
                            } else {
                                map.insert(id.clone(), value);
                            }
                        }
                    }
                }
            }

            Self::Child(ref expr, ref key) => {
                if let Some(parent) = expr.get_mut_forcibly(root) {
                    if let ValueKind::Table(_) = parent.kind {
                        Self::Identifier(key.clone()).set(parent, value);
                    } else {
                        // Didn't find a table. Oh well. Make a table and do this anyway
                        *parent = Map::<String, Value>::new().into();

                        Self::Identifier(key.clone()).set(parent, value);
                    }
                }
            }

            Self::Subscript(ref expr, index) => {
                if let Some(parent) = expr.get_mut_forcibly(root) {
                    match parent.kind {
                        ValueKind::Array(_) => (),
                        _ => *parent = Vec::<Value>::new().into(),
                    }

                    if let ValueKind::Array(ref mut array) = parent.kind {
                        let uindex = sindex_to_uindex(index, array.len());
                        if uindex >= array.len() {
                            array.resize((uindex + 1) as usize, Value::new(None, ValueKind::Nil));
                        }

                        array[uindex] = value;
                    }
                }
            }
        }
    }
}
<commit_msg>simplify some match blocks<commit_after>use std::str::FromStr;

use crate::error::{ConfigError, Result};
use crate::map::Map;
use crate::value::{Value, ValueKind};

mod parser;

#[derive(Debug, Eq, PartialEq, Clone, Hash)]
pub enum Expression {
    Identifier(String),
    Child(Box<Self>, String),
    Subscript(Box<Self>, isize),
}

impl FromStr for Expression {
    type Err = ConfigError;

    fn from_str(s: &str) -> Result<Self> {
        parser::from_str(s).map_err(ConfigError::PathParse)
    }
}

fn sindex_to_uindex(index: isize, len: usize) -> usize {
    if index >= 0 {
        index as usize
    } else {
        len - (index.abs() as usize)
    }
}

impl Expression {
    pub fn get(self, root: &Value) -> Option<&Value> {
        match self {
            Self::Identifier(id) => {
                match root.kind {
                    // `x` access on a table is equivalent to: map[x]
                    ValueKind::Table(ref map) => map.get(&id),

                    // all other variants return None
                    _ => None,
                }
            }

            Self::Child(expr, key) => {
                match expr.get(root) {
                    Some(value) => {
                        match value.kind {
                            // Access on a table is identical to Identifier, it just forwards
                            ValueKind::Table(ref map) => map.get(&key),

                            // all other variants return None
                            _ => None,
                        }
                    }

                    _ => None,
                }
            }

            Self::Subscript(expr, index) => match expr.get(root) {
                Some(value) => match value.kind {
                    ValueKind::Array(ref array) => {
                        let index = sindex_to_uindex(index, array.len());

                        if index >= array.len() {
                            None
                        } else {
                            Some(&array[index])
                        }
                    }

                    _ => None,
                },

                _ => None,
            },
        }
    }

    pub fn get_mut<'a>(&self, root: &'a mut Value) -> Option<&'a mut Value> {
        match *self {
            Self::Identifier(ref id) => match root.kind {
                ValueKind::Table(ref mut map) => map.get_mut(id),

                _ => None,
            },

            Self::Child(ref expr, ref key) => match expr.get_mut(root) {
                Some(value) => match value.kind {
                    ValueKind::Table(ref mut map) => map.get_mut(key),

                    _ => None,
                },

                _ => None,
            },

            Self::Subscript(ref expr, index) => match expr.get_mut(root) {
                Some(value) => match value.kind {
                    ValueKind::Array(ref mut array) => {
                        let index = sindex_to_uindex(index, array.len());

                        if index >= array.len() {
                            None
                        } else {
                            Some(&mut array[index])
                        }
                    }

                    _ => None,
                },

                _ => None,
            },
        }
    }

    pub fn get_mut_forcibly<'a>(&self, root: &'a mut Value) -> Option<&'a mut Value> {
        match *self {
            Self::Identifier(ref id) => match root.kind {
                ValueKind::Table(ref mut map) => Some(
                    map.entry(id.clone())
                        .or_insert_with(|| Value::new(None, ValueKind::Nil)),
                ),

                _ => None,
            },

            Self::Child(ref expr, ref key) => match expr.get_mut_forcibly(root) {
                Some(value) => {
                    if let ValueKind::Table(ref mut map) = value.kind {
                        Some(
                            map.entry(key.clone())
                                .or_insert_with(|| Value::new(None, ValueKind::Nil)),
                        )
                    } else {
                        *value = Map::<String, Value>::new().into();

                        if let ValueKind::Table(ref mut map) = value.kind {
                            Some(
                                map.entry(key.clone())
                                    .or_insert_with(|| Value::new(None, ValueKind::Nil)),
                            )
                        } else {
                            unreachable!();
                        }
                    }
                }

                _ => None,
            },

            Self::Subscript(ref expr, index) => match expr.get_mut_forcibly(root) {
                Some(value) => {
                    match value.kind {
                        ValueKind::Array(_) => (),
                        _ => *value = Vec::<Value>::new().into(),
                    }

                    match value.kind {
                        ValueKind::Array(ref mut array) => {
                            let index = sindex_to_uindex(index, array.len());

                            if index >= array.len() {
                                array
                                    .resize((index + 1) as usize, Value::new(None, ValueKind::Nil));
                            }

                            Some(&mut array[index])
                        }

                        _ => None,
                    }
                }
                _ => None,
            },
        }
    }

    pub fn set(&self, root: &mut Value, value: Value) {
        match *self {
            Self::Identifier(ref id) => {
                // Ensure that root is a table
                match root.kind {
                    ValueKind::Table(_) => {}

                    _ => {
                        *root = Map::<String, Value>::new().into();
                    }
                }

                match value.kind {
                    ValueKind::Table(ref incoming_map) => {
                        // Pull out another table
                        let target = if let ValueKind::Table(ref mut map) = root.kind {
                            map.entry(id.clone())
                                .or_insert_with(|| Map::<String, Value>::new().into())
                        } else {
                            unreachable!();
                        };

                        // Continue the deep merge
                        for (key, val) in incoming_map {
                            Self::Identifier(key.clone()).set(target, val.clone());
                        }
                    }

                    _ => {
                        if let ValueKind::Table(ref mut map) = root.kind {
                            // Just do a simple set
                            if let Some(existing) = map.get_mut(id) {
                                *existing = value;
                            } else {
                                map.insert(id.clone(), value);
                            }
                        }
                    }
                }
            }

            Self::Child(ref expr, ref key) => {
                if let Some(parent) = expr.get_mut_forcibly(root) {
                    if !matches!(parent.kind, ValueKind::Table(_)) {
                        // Didn't find a table. Oh well. Make a table and do this anyway
                        *parent = Map::<String, Value>::new().into();
                    }
                    Self::Identifier(key.clone()).set(parent, value);
                }
            }

            Self::Subscript(ref expr, index) => {
                if let Some(parent) = expr.get_mut_forcibly(root) {
                    if !matches!(parent.kind, ValueKind::Array(_)) {
                        *parent = Vec::<Value>::new().into()
                    }

                    if let ValueKind::Array(ref mut array) = parent.kind {
                        let uindex = sindex_to_uindex(index, array.len());
                        if uindex >= array.len() {
                            array.resize((uindex + 1) as usize, Value::new(None, ValueKind::Nil));
                        }

                        array[uindex] = value;
                    }
                }
            }
        }
    }
}
<|endoftext|>


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

use std::sync::Arc;
#[cfg(target_os="linux")]
use libc::c_void;

use glfw::{WindowEvent, Glfw, Context, RenderContext};
use glfw::WindowMode::{Windowed, FullScreen};
use glfw;
use nice_glfw;
use gl;

use collections::TrieMap;

use ovr;

use input;

pub type WindowId = uint;

struct WindowHandle {
    window: glfw::Window,
    forced_event: Option<WindowEvent>,
    receiver: Receiver<(f64, WindowEvent)>,
}

pub struct IOManager {
    glfw: Glfw,
    ovr: Option<ovr::Ovr>,
    windows: TrieMap<WindowHandle>,
    window_id: uint
}

impl IOManager {
    pub fn new(glfw: glfw::Glfw) -> IOManager {
        IOManager {
            glfw: glfw,
            ovr: None,
            windows: TrieMap::new(),
            window_id: 0
        }
    }

    fn add_window(&mut self, window: glfw::Window, recv: Receiver<(f64, WindowEvent)>) -> InputHandle {
        let id = self.window_id;
        self.window_id += 1;

        let (w, h) = window.get_framebuffer_size();

        self.windows.insert(id, {
            WindowHandle {
                window: window,
                forced_event: Some(glfw::WindowEvent::FramebufferSize(w, h)),
                receiver: recv
            }
        });

        InputHandle{ handle: id }
    }

    fn create_window_context(&self, width: u32, height: u32, name: &str, mode: glfw::WindowMode)
            -> Option<(glfw::Window, Receiver<(f64,WindowEvent)>)> {

        nice_glfw::WindowBuilder::new(&self.glfw)
            .try_modern_context_hints()
            .size(width, height)
            .title(name)
            .mode(mode)
            .create()
    }

    pub fn window(&mut self, size: (u32, u32)) -> Option<Window> {
        let (width, height) = size;
        let win_opt = self.create_window_context(width, height, "Snowmew", Windowed);
        let (mut window, events) = match win_opt {
            Some((window, events)) => (window, events),
            None => return None
        };

        window.make_current();
        gl::load_with(|name| self.glfw.get_proc_address_raw(name));
        self.glfw.set_swap_interval(0);
        glfw::make_context_current(None);

        window.set_all_polling(true);
        window.show();
        let version = window.get_context_version();
        let rc = window.render_context();
        let handle = self.add_window(window, events);

        Some(Window {
            handle: handle,
            render: rc,
            version: (version.major, version.minor),
            hmd: None,
            os_spec: WindowOSSpec::new(&self.glfw)
        })
    }

    pub fn primary(&mut self, size: (u32, u32)) -> Option<Window> {
        let screen = {
            self.glfw.with_primary_monitor(|display| {
                let display = display.unwrap();
                let (width, height) = size;
                self.create_window_context(width, height, "Snowmew FullScreen", FullScreen(display))
            })
        };

        match screen {
            None => None,
            Some((mut window, events)) => {
                window.make_current();
                gl::load_with(|name| self.glfw.get_proc_address_raw(name));
                self.glfw.set_swap_interval(0);
                glfw::make_context_current(None);

                window.set_all_polling(true);
                window.show();
                let version = window.get_context_version();
                let rc = window.render_context();
                let handle = self.add_window(window, events);

                Some(Window {
                    handle: handle,
                    render: rc,
                    version: (version.major, version.minor),
                    hmd: None,
                    os_spec: WindowOSSpec::new(&self.glfw)
                })
            }
        }

    }

    pub fn get_primary_resolution(&self) -> (u32, u32) {
        self.glfw.with_primary_monitor(|display| {
            let display = display.expect("Could not get primnay display");
            let vm = display.get_video_mode().expect("Could not get video mode");
            (vm.width, vm.height)
        })
    }

    pub fn get_primary_position(&self) -> (i32, i32) {
        self.glfw.with_primary_monitor(|display| {
            let display = display.expect("Could not get primnay display");
            display.get_pos()
        })
    }

    #[cfg(target_os="linux")]
    fn create_hmd_window(&self, hmd: &ovr::HmdDescription) -> Option<(glfw::Window, Receiver<(f64,WindowEvent)>)> {
        self.glfw.with_connected_monitors(|monitors| {
            for m in monitors.iter() {
                let (x, y) = m.get_pos();
                if x == hmd.window_position.x &&
                   y == hmd.window_position.y {
                    let (width, height) = (hmd.resolution.x, hmd.resolution.y);
                    let win_opt = self.create_window_context(width as u32, height as u32, "Snowmew FullScreen", FullScreen(m));
                    let (window, events) = match win_opt {
                        Some((window, events)) => (window, events),
                        None => return None
                    };

                    return Some((window, events));
                }
            }

            // fallback if we could not guess at the screen
            let (width, height) = (hmd.resolution.x, hmd.resolution.y);
            let win_opt = self.glfw.create_window(width as u32, height as u32, "Snowmew", Windowed);
            let (window, events) = match win_opt {
                Some((window, events)) => (window, events),
                None => return None
            };

            // move viewport
            let (dx, dy) = (hmd.window_position.x, hmd.window_position.y);
            window.set_pos(dx as i32, dy as i32);

            Some((window, events))

        })
    }

    #[cfg(target_os="macos")]
    fn create_hmd_window(&self, hmd: &ovr::HmdDescription) -> Option<(glfw::Window, Receiver<(f64,WindowEvent)>)> {
        self.glfw.with_connected_monitors(|monitors| {
            for m in monitors.iter() {
                if !m.get_name().as_slice().contains("Rift") {
                    continue;
                }

                let (width, height) = (hmd.resolution.x, hmd.resolution.y);
                let win_opt = self.create_window_context(width as u32, height as u32, "Snowmew FullScreen", FullScreen(m));
                let (window, events) = match win_opt {
                    Some((window, events)) => (window, events),
                    None => return None
                };

                return Some((window, events));
            }
            None
        })
    }

    pub fn hmd(&mut self) -> Option<Window> {
        if !self.setup_ovr() {
            return None;
        }

        let (window, events, rc, hmd) = {
            let hmd = match self.ovr.as_ref().unwrap().first_hmd() {
                Some(hmd) => hmd,
                None => return None
            };
            let hmdinfo = hmd.get_description();

            let (mut window, events) = match self.create_hmd_window(&hmdinfo) {
                Some((window, events)) => (window, events),
                None => return None
            };

            window.make_current();
            gl::load_with(|name| self.glfw.get_proc_address_raw(name));
            self.glfw.set_swap_interval(1);
            glfw::make_context_current(None);

            window.set_all_polling(true);
            window.show();

            let rc = window.render_context();
            (window, events, rc, hmd)
        };

        let version = window.get_context_version();
        let handle = self.add_window(window, events);

        Some(Window {
            handle: handle,
            render: rc,
            version: (version.major, version.minor),
            hmd: Some(Arc::new(hmd)),
            os_spec: WindowOSSpec::new(&self.glfw)
        })
    }

    pub fn wait(&mut self) {
        self.glfw.wait_events();
    }

    pub fn poll(&mut self) {
        self.glfw.poll_events();
    }

    pub fn next_event(&mut self, handle: &InputHandle) -> input::EventGroup {
        let evt = self.windows.get_mut(&handle.handle)
        .map(|rx| {
            // this is a hack to inject the correct size into the event buffer
            match rx.forced_event.take() {
                Some(evt) => return input::Event::from_glfw(evt),
                None => ()
            };
            for (_, evt) in glfw::flush_messages(&rx.receiver) {
                let evt = input::Event::from_glfw(evt);
                if evt != input::EventGroup::Nop {
                    return evt;
                }
            }
            input::EventGroup::Nop
        });

        match evt {
            Some(e) => e,
            _ => input::EventGroup::Nop
        }
    }

    pub fn should_close(&mut self, handle: &InputHandle) -> bool {
        let should_close = self.windows.get_mut(&handle.handle)
        .map(|win| win.window.should_close());

        if let Some(x) = should_close {
            x
        } else {
            true
        }
    }

    fn setup_ovr(&mut self) -> bool {
        if self.ovr.is_some() &&
           self.ovr.as_ref().unwrap().detect() > 0 {
            return true;
        }

        if self.ovr.is_none() {
            self.ovr = ovr::Ovr::init();
        }

        self.ovr.is_some() && self.ovr.as_ref().unwrap().detect() > 0
    }

    pub fn set_window_position(&mut self, window: &Window, pos: (i32, i32)) {
        let (w, h) = pos;
        match self.windows.get_mut(&window.handle.handle) {
            Some(win) => win.window.set_pos(w, h),
            None => ()
        }
    }

    pub fn get_framebuffer_size(&mut self, window: &Window) -> (i32, i32) {
        match self.windows.get_mut(&window.handle.handle) {
            Some(win) => win.window.get_framebuffer_size(),
            None => (0, 0)
        }
    }

    pub fn get_proc_address(&self, name: &str) -> *const ::libc::c_void {
        self.glfw.get_proc_address_raw(name)
    }
}

#[deriving(Clone)]
pub struct InputHandle {
    handle: uint,
}

#[cfg(target_os="macos")]
struct WindowOSSpec;

#[cfg(target_os="macos")]
impl WindowOSSpec {
    fn new(_: &Glfw) -> WindowOSSpec {WindowOSSpec}
}

#[cfg(target_os="linux")]
struct WindowOSSpec {
    display: *mut c_void
}

#[cfg(target_os="linux")]
impl WindowOSSpec {
    fn new(glfw: &Glfw) -> WindowOSSpec {
        WindowOSSpec {
            display: glfw.get_x11_display()
        }
    }
}

pub struct Window {
    handle: InputHandle,
    render: RenderContext,
    version: (uint, uint),
    hmd: Option<Arc<ovr::Hmd>>,
    os_spec: WindowOSSpec
}

impl Window {
    pub fn swap_buffers(&self) {
        self.render.swap_buffers()
    }

    pub fn make_context_current(&self) {
        self.render.make_current()
    }

    pub fn get_context_version(&self) -> (uint, uint) {
        self.version
    }

    pub fn handle(&self) -> InputHandle {
        self.handle.clone()
    }

    pub fn is_hmd(&self) -> bool {
        self.hmd.is_some()
    }

    pub fn get_hmd<'a>(&'a self) -> Arc<ovr::Hmd> {
        self.hmd.as_ref().expect("no hmd device found!").clone()
    }

    /// Wrapper for `glfwGetGLXContext`
    #[cfg(target_os="linux")]
    pub fn get_x11_display(&self) -> *mut c_void {
        self.os_spec.display
    }
}

#[deriving(Clone, Encodable, Decodable)]
pub struct IoState {
    pub render_size: (uint, uint),
    pub size: (uint, uint),
    pub position: (int, int),
    pub show_mouse: bool,
    pub mouse_over: bool
}

impl IoState {
    pub fn new() -> IoState {
        IoState {
            render_size: (1, 1),
            size: (1, 1),
            position: (0, 0),
            show_mouse: true,
            mouse_over: false
        }
    }

    pub fn window_action(&mut self, win: input::WindowEvent) {
        match win {
            input::WindowEvent::Size(x, y) => {
                self.size = (x as uint, y as uint);
            }
            input::WindowEvent::Position(x, y) => {
                self.position = (x, y);
            }
            input::WindowEvent::MouseOver(mouse) => {
                self.mouse_over = mouse;
            }
        }
    }
}<commit_msg>remove swap interval if 0<commit_after>//   Copyright 2014 Colin Sherratt
//
//   Licensed under the Apache License, Version 2.0 (the "License");
//   you may not use this file except in compliance with the License.
//   You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
//   Unless required by applicable law or agreed to in writing, software
//   distributed under the License is distributed on an "AS IS" BASIS,
//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//   See the License for the specific language governing permissions and
//   limitations under the License.

use std::sync::Arc;
#[cfg(target_os="linux")]
use libc::c_void;

use glfw::{WindowEvent, Glfw, Context, RenderContext};
use glfw::WindowMode::{Windowed, FullScreen};
use glfw;
use nice_glfw;
use gl;

use collections::TrieMap;

use ovr;

use input;

pub type WindowId = uint;

struct WindowHandle {
    window: glfw::Window,
    forced_event: Option<WindowEvent>,
    receiver: Receiver<(f64, WindowEvent)>,
}

pub struct IOManager {
    glfw: Glfw,
    ovr: Option<ovr::Ovr>,
    windows: TrieMap<WindowHandle>,
    window_id: uint
}

impl IOManager {
    pub fn new(glfw: glfw::Glfw) -> IOManager {
        IOManager {
            glfw: glfw,
            ovr: None,
            windows: TrieMap::new(),
            window_id: 0
        }
    }

    fn add_window(&mut self, window: glfw::Window, recv: Receiver<(f64, WindowEvent)>) -> InputHandle {
        let id = self.window_id;
        self.window_id += 1;

        let (w, h) = window.get_framebuffer_size();

        self.windows.insert(id, {
            WindowHandle {
                window: window,
                forced_event: Some(glfw::WindowEvent::FramebufferSize(w, h)),
                receiver: recv
            }
        });

        InputHandle{ handle: id }
    }

    fn create_window_context(&self, width: u32, height: u32, name: &str, mode: glfw::WindowMode)
            -> Option<(glfw::Window, Receiver<(f64,WindowEvent)>)> {

        nice_glfw::WindowBuilder::new(&self.glfw)
            .try_modern_context_hints()
            .size(width, height)
            .title(name)
            .mode(mode)
            .create()
    }

    pub fn window(&mut self, size: (u32, u32)) -> Option<Window> {
        let (width, height) = size;
        let win_opt = self.create_window_context(width, height, "Snowmew", Windowed);
        let (mut window, events) = match win_opt {
            Some((window, events)) => (window, events),
            None => return None
        };

        window.make_current();
        gl::load_with(|name| self.glfw.get_proc_address_raw(name));
        self.glfw.set_swap_interval(1);
        glfw::make_context_current(None);

        window.set_all_polling(true);
        window.show();
        let version = window.get_context_version();
        let rc = window.render_context();
        let handle = self.add_window(window, events);

        Some(Window {
            handle: handle,
            render: rc,
            version: (version.major, version.minor),
            hmd: None,
            os_spec: WindowOSSpec::new(&self.glfw)
        })
    }

    pub fn primary(&mut self, size: (u32, u32)) -> Option<Window> {
        let screen = {
            self.glfw.with_primary_monitor(|display| {
                let display = display.unwrap();
                let (width, height) = size;
                self.create_window_context(width, height, "Snowmew FullScreen", FullScreen(display))
            })
        };

        match screen {
            None => None,
            Some((mut window, events)) => {
                window.make_current();
                gl::load_with(|name| self.glfw.get_proc_address_raw(name));
                self.glfw.set_swap_interval(1);
                glfw::make_context_current(None);

                window.set_all_polling(true);
                window.show();
                let version = window.get_context_version();
                let rc = window.render_context();
                let handle = self.add_window(window, events);

                Some(Window {
                    handle: handle,
                    render: rc,
                    version: (version.major, version.minor),
                    hmd: None,
                    os_spec: WindowOSSpec::new(&self.glfw)
                })
            }
        }

    }

    pub fn get_primary_resolution(&self) -> (u32, u32) {
        self.glfw.with_primary_monitor(|display| {
            let display = display.expect("Could not get primnay display");
            let vm = display.get_video_mode().expect("Could not get video mode");
            (vm.width, vm.height)
        })
    }

    pub fn get_primary_position(&self) -> (i32, i32) {
        self.glfw.with_primary_monitor(|display| {
            let display = display.expect("Could not get primnay display");
            display.get_pos()
        })
    }

    #[cfg(target_os="linux")]
    fn create_hmd_window(&self, hmd: &ovr::HmdDescription) -> Option<(glfw::Window, Receiver<(f64,WindowEvent)>)> {
        self.glfw.with_connected_monitors(|monitors| {
            for m in monitors.iter() {
                let (x, y) = m.get_pos();
                if x == hmd.window_position.x &&
                   y == hmd.window_position.y {
                    let (width, height) = (hmd.resolution.x, hmd.resolution.y);
                    let win_opt = self.create_window_context(width as u32, height as u32, "Snowmew FullScreen", FullScreen(m));
                    let (window, events) = match win_opt {
                        Some((window, events)) => (window, events),
                        None => return None
                    };

                    return Some((window, events));
                }
            }

            // fallback if we could not guess at the screen
            let (width, height) = (hmd.resolution.x, hmd.resolution.y);
            let win_opt = self.glfw.create_window(width as u32, height as u32, "Snowmew", Windowed);
            let (window, events) = match win_opt {
                Some((window, events)) => (window, events),
                None => return None
            };

            // move viewport
            let (dx, dy) = (hmd.window_position.x, hmd.window_position.y);
            window.set_pos(dx as i32, dy as i32);

            Some((window, events))

        })
    }

    #[cfg(target_os="macos")]
    fn create_hmd_window(&self, hmd: &ovr::HmdDescription) -> Option<(glfw::Window, Receiver<(f64,WindowEvent)>)> {
        self.glfw.with_connected_monitors(|monitors| {
            for m in monitors.iter() {
                if !m.get_name().as_slice().contains("Rift") {
                    continue;
                }

                let (width, height) = (hmd.resolution.x, hmd.resolution.y);
                let win_opt = self.create_window_context(width as u32, height as u32, "Snowmew FullScreen", FullScreen(m));
                let (window, events) = match win_opt {
                    Some((window, events)) => (window, events),
                    None => return None
                };

                return Some((window, events));
            }
            None
        })
    }

    pub fn hmd(&mut self) -> Option<Window> {
        if !self.setup_ovr() {
            return None;
        }

        let (window, events, rc, hmd) = {
            let hmd = match self.ovr.as_ref().unwrap().first_hmd() {
                Some(hmd) => hmd,
                None => return None
            };
            let hmdinfo = hmd.get_description();

            let (mut window, events) = match self.create_hmd_window(&hmdinfo) {
                Some((window, events)) => (window, events),
                None => return None
            };

            window.make_current();
            gl::load_with(|name| self.glfw.get_proc_address_raw(name));
            self.glfw.set_swap_interval(1);
            glfw::make_context_current(None);

            window.set_all_polling(true);
            window.show();

            let rc = window.render_context();
            (window, events, rc, hmd)
        };

        let version = window.get_context_version();
        let handle = self.add_window(window, events);

        Some(Window {
            handle: handle,
            render: rc,
            version: (version.major, version.minor),
            hmd: Some(Arc::new(hmd)),
            os_spec: WindowOSSpec::new(&self.glfw)
        })
    }

    pub fn wait(&mut self) {
        self.glfw.wait_events();
    }

    pub fn poll(&mut self) {
        self.glfw.poll_events();
    }

    pub fn next_event(&mut self, handle: &InputHandle) -> input::EventGroup {
        let evt = self.windows.get_mut(&handle.handle)
        .map(|rx| {
            // this is a hack to inject the correct size into the event buffer
            match rx.forced_event.take() {
                Some(evt) => return input::Event::from_glfw(evt),
                None => ()
            };
            for (_, evt) in glfw::flush_messages(&rx.receiver) {
                let evt = input::Event::from_glfw(evt);
                if evt != input::EventGroup::Nop {
                    return evt;
                }
            }
            input::EventGroup::Nop
        });

        match evt {
            Some(e) => e,
            _ => input::EventGroup::Nop
        }
    }

    pub fn should_close(&mut self, handle: &InputHandle) -> bool {
        let should_close = self.windows.get_mut(&handle.handle)
        .map(|win| win.window.should_close());

        if let Some(x) = should_close {
            x
        } else {
            true
        }
    }

    fn setup_ovr(&mut self) -> bool {
        if self.ovr.is_some() &&
           self.ovr.as_ref().unwrap().detect() > 0 {
            return true;
        }

        if self.ovr.is_none() {
            self.ovr = ovr::Ovr::init();
        }

        self.ovr.is_some() && self.ovr.as_ref().unwrap().detect() > 0
    }

    pub fn set_window_position(&mut self, window: &Window, pos: (i32, i32)) {
        let (w, h) = pos;
        match self.windows.get_mut(&window.handle.handle) {
            Some(win) => win.window.set_pos(w, h),
            None => ()
        }
    }

    pub fn get_framebuffer_size(&mut self, window: &Window) -> (i32, i32) {
        match self.windows.get_mut(&window.handle.handle) {
            Some(win) => win.window.get_framebuffer_size(),
            None => (0, 0)
        }
    }

    pub fn get_proc_address(&self, name: &str) -> *const ::libc::c_void {
        self.glfw.get_proc_address_raw(name)
    }
}

#[deriving(Clone)]
pub struct InputHandle {
    handle: uint,
}

#[cfg(target_os="macos")]
struct WindowOSSpec;

#[cfg(target_os="macos")]
impl WindowOSSpec {
    fn new(_: &Glfw) -> WindowOSSpec {WindowOSSpec}
}

#[cfg(target_os="linux")]
struct WindowOSSpec {
    display: *mut c_void
}

#[cfg(target_os="linux")]
impl WindowOSSpec {
    fn new(glfw: &Glfw) -> WindowOSSpec {
        WindowOSSpec {
            display: glfw.get_x11_display()
        }
    }
}

pub struct Window {
    handle: InputHandle,
    render: RenderContext,
    version: (uint, uint),
    hmd: Option<Arc<ovr::Hmd>>,
    os_spec: WindowOSSpec
}

impl Window {
    pub fn swap_buffers(&self) {
        self.render.swap_buffers()
    }

    pub fn make_context_current(&self) {
        self.render.make_current()
    }

    pub fn get_context_version(&self) -> (uint, uint) {
        self.version
    }

    pub fn handle(&self) -> InputHandle {
        self.handle.clone()
    }

    pub fn is_hmd(&self) -> bool {
        self.hmd.is_some()
    }

    pub fn get_hmd<'a>(&'a self) -> Arc<ovr::Hmd> {
        self.hmd.as_ref().expect("no hmd device found!").clone()
    }

    /// Wrapper for `glfwGetGLXContext`
    #[cfg(target_os="linux")]
    pub fn get_x11_display(&self) -> *mut c_void {
        self.os_spec.display
    }
}

#[deriving(Clone, Encodable, Decodable)]
pub struct IoState {
    pub render_size: (uint, uint),
    pub size: (uint, uint),
    pub position: (int, int),
    pub show_mouse: bool,
    pub mouse_over: bool
}

impl IoState {
    pub fn new() -> IoState {
        IoState {
            render_size: (1, 1),
            size: (1, 1),
            position: (0, 0),
            show_mouse: true,
            mouse_over: false
        }
    }

    pub fn window_action(&mut self, win: input::WindowEvent) {
        match win {
            input::WindowEvent::Size(x, y) => {
                self.size = (x as uint, y as uint);
            }
            input::WindowEvent::Position(x, y) => {
                self.position = (x, y);
            }
            input::WindowEvent::MouseOver(mouse) => {
                self.mouse_over = mouse;
            }
        }
    }
}<|endoftext|>


<commit_before>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern mod extra; // {En,De}codable
mod submod {
    // if any of these are implemented without global calls for any
    // function calls, then being in a submodule will (correctly)
    // cause errors about unrecognised module `std` (or `extra`)
    #[deriving(Eq, Ord, TotalEq, TotalOrd,
               IterBytes,
               Clone, DeepClone,
               ToStr, Rand,
               Encodable, Decodable)]
    enum A { A1(uint), A2(int) }

    #[deriving(Eq, Ord, TotalEq, TotalOrd,
               IterBytes,
               Clone, DeepClone,
               ToStr, Rand,
               Encodable, Decodable)]
    struct B { x: uint, y: int }

    #[deriving(Eq, Ord, TotalEq, TotalOrd,
               IterBytes,
               Clone, DeepClone,
               ToStr, Rand,
               Encodable, Decodable)]
    struct C(uint, int);

}

fn main() {}
<commit_msg>xfail test on windows, because extern mod doesn't work there<commit_after>// xfail-test #7103 `extern mod` does not work on windows

// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern mod extra; // {En,De}codable
mod submod {
    // if any of these are implemented without global calls for any
    // function calls, then being in a submodule will (correctly)
    // cause errors about unrecognised module `std` (or `extra`)
    #[deriving(Eq, Ord, TotalEq, TotalOrd,
               IterBytes,
               Clone, DeepClone,
               ToStr, Rand,
               Encodable, Decodable)]
    enum A { A1(uint), A2(int) }

    #[deriving(Eq, Ord, TotalEq, TotalOrd,
               IterBytes,
               Clone, DeepClone,
               ToStr, Rand,
               Encodable, Decodable)]
    struct B { x: uint, y: int }

    #[deriving(Eq, Ord, TotalEq, TotalOrd,
               IterBytes,
               Clone, DeepClone,
               ToStr, Rand,
               Encodable, Decodable)]
    struct C(uint, int);

}

fn main() {}
<|endoftext|>