<commit_before>// Copyright 2013-2014 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.

// ignore-pretty very bad with line comments

#![feature(unboxed_closures)]

extern crate collections;
extern crate rand;

use std::collections::BitvSet;
use std::collections::HashSet;
use std::collections::TreeSet;
use std::hash::Hash;
use std::os;
use std::time::Duration;
use std::uint;

struct Results {
    sequential_ints: Duration,
    random_ints: Duration,
    delete_ints: Duration,

    sequential_strings: Duration,
    random_strings: Duration,
    delete_strings: Duration,
}

fn timed<F>(result: &mut Duration, op: F) where F: FnOnce() {
    *result = Duration::span(op);
}

trait MutableSet<T> {
    fn insert(&mut self, k: T);
    fn remove(&mut self, k: &T) -> bool;
    fn contains(&self, k: &T) -> bool;
}

impl<T: Hash + Eq> MutableSet<T> for HashSet<T> {
    fn insert(&mut self, k: T) { self.insert(k); }
    fn remove(&mut self, k: &T) -> bool { self.remove(k) }
    fn contains(&self, k: &T) -> bool { self.contains(k) }
}
impl<T: Ord> MutableSet<T> for TreeSet<T> {
    fn insert(&mut self, k: T) { self.insert(k); }
    fn remove(&mut self, k: &T) -> bool { self.remove(k) }
    fn contains(&self, k: &T) -> bool { self.contains(k) }
}
impl MutableSet<uint> for BitvSet {
    fn insert(&mut self, k: uint) { self.insert(k); }
    fn remove(&mut self, k: &uint) -> bool { self.remove(k) }
    fn contains(&self, k: &uint) -> bool { self.contains(k) }
}

impl Results {
    pub fn bench_int<T:MutableSet<uint>,
                     R: rand::Rng>(
                     &mut self,
                     rng: &mut R,
                     num_keys: uint,
                     rand_cap: uint,
                     f: || -> T) { {
            let mut set = f();
            timed(&mut self.sequential_ints, move || {
                for i in range(0u, num_keys) {
                    set.insert(i);
                }

                for i in range(0u, num_keys) {
                    assert!(set.contains(&i));
                }
            })
        }

        {
            let mut set = f();
            timed(&mut self.random_ints, move || {
                for _ in range(0, num_keys) {
                    set.insert(rng.gen::<uint>() % rand_cap);
                }
            })
        }

        {
            let mut set = f();
            for i in range(0u, num_keys) {
                set.insert(i);
            }

            timed(&mut self.delete_ints, move || {
                for i in range(0u, num_keys) {
                    assert!(set.remove(&i));
                }
            })
        }
    }

    pub fn bench_str<T:MutableSet<String>,
                     R:rand::Rng>(
                     &mut self,
                     rng: &mut R,
                     num_keys: uint,
                     f: || -> T) {
        {
            let mut set = f();
            timed(&mut self.sequential_strings, move || {
                for i in range(0u, num_keys) {
                    set.insert(i.to_string());
                }

                for i in range(0u, num_keys) {
                    assert!(set.contains(&i.to_string()));
                }
            })
        }

        {
            let mut set = f();
            timed(&mut self.random_strings, move || {
                for _ in range(0, num_keys) {
                    let s = rng.gen::<uint>().to_string();
                    set.insert(s);
                }
            })
        }

        {
            let mut set = f();
            for i in range(0u, num_keys) {
                set.insert(i.to_string());
            }
            timed(&mut self.delete_strings, move || {
                for i in range(0u, num_keys) {
                    assert!(set.remove(&i.to_string()));
                }
            })
        }
    }
}

fn write_header(header: &str) {
    println!("{}", header);
}

fn write_row(label: &str, value: Duration) {
    println!("{:30} {} s\n", label, value);
}

fn write_results(label: &str, results: &Results) {
    write_header(label);
    write_row("sequential_ints", results.sequential_ints);
    write_row("random_ints", results.random_ints);
    write_row("delete_ints", results.delete_ints);
    write_row("sequential_strings", results.sequential_strings);
    write_row("random_strings", results.random_strings);
    write_row("delete_strings", results.delete_strings);
}

fn empty_results() -> Results {
    Results {
        sequential_ints: Duration::seconds(0),
        random_ints: Duration::seconds(0),
        delete_ints: Duration::seconds(0),

        sequential_strings: Duration::seconds(0),
        random_strings: Duration::seconds(0),
        delete_strings: Duration::seconds(0),
    }
}

fn main() {
    let args = os::args();
    let args = args.as_slice();
    let num_keys = {
        if args.len() == 2 {
            from_str::<uint>(args[1].as_slice()).unwrap()
        } else {
            100 // woefully inadequate for any real measurement
        }
    };

    let seed: &[_] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    let max = 200000;

    {
        let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(seed);
        let mut results = empty_results();
        results.bench_int(&mut rng, num_keys, max, || {
            let s: HashSet<uint> = HashSet::new();
            s
        });
        results.bench_str(&mut rng, num_keys, || {
            let s: HashSet<String> = HashSet::new();
            s
        });
        write_results("collections::HashSet", &results);
    }

    {
        let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(seed);
        let mut results = empty_results();
        results.bench_int(&mut rng, num_keys, max, || {
            let s: TreeSet<uint> = TreeSet::new();
            s
        });
        results.bench_str(&mut rng, num_keys, || {
            let s: TreeSet<String> = TreeSet::new();
            s
        });
        write_results("collections::TreeSet", &results);
    }

    {
        let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(seed);
        let mut results = empty_results();
        results.bench_int(&mut rng, num_keys, max, || BitvSet::new());
        write_results("collections::bitv::BitvSet", &results);
    }
}
<commit_msg>Remove some unnecessary `move` keywords<commit_after>// Copyright 2013-2014 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.

// ignore-pretty very bad with line comments

#![feature(unboxed_closures)]

extern crate collections;
extern crate rand;

use std::collections::BitvSet;
use std::collections::HashSet;
use std::collections::TreeSet;
use std::hash::Hash;
use std::os;
use std::time::Duration;
use std::uint;

struct Results {
    sequential_ints: Duration,
    random_ints: Duration,
    delete_ints: Duration,

    sequential_strings: Duration,
    random_strings: Duration,
    delete_strings: Duration,
}

fn timed<F>(result: &mut Duration, op: F) where F: FnOnce() {
    *result = Duration::span(op);
}

trait MutableSet<T> {
    fn insert(&mut self, k: T);
    fn remove(&mut self, k: &T) -> bool;
    fn contains(&self, k: &T) -> bool;
}

impl<T: Hash + Eq> MutableSet<T> for HashSet<T> {
    fn insert(&mut self, k: T) { self.insert(k); }
    fn remove(&mut self, k: &T) -> bool { self.remove(k) }
    fn contains(&self, k: &T) -> bool { self.contains(k) }
}
impl<T: Ord> MutableSet<T> for TreeSet<T> {
    fn insert(&mut self, k: T) { self.insert(k); }
    fn remove(&mut self, k: &T) -> bool { self.remove(k) }
    fn contains(&self, k: &T) -> bool { self.contains(k) }
}
impl MutableSet<uint> for BitvSet {
    fn insert(&mut self, k: uint) { self.insert(k); }
    fn remove(&mut self, k: &uint) -> bool { self.remove(k) }
    fn contains(&self, k: &uint) -> bool { self.contains(k) }
}

impl Results {
    pub fn bench_int<T:MutableSet<uint>,
                     R: rand::Rng>(
                     &mut self,
                     rng: &mut R,
                     num_keys: uint,
                     rand_cap: uint,
                     f: || -> T) { {
            let mut set = f();
            timed(&mut self.sequential_ints, || {
                for i in range(0u, num_keys) {
                    set.insert(i);
                }

                for i in range(0u, num_keys) {
                    assert!(set.contains(&i));
                }
            })
        }

        {
            let mut set = f();
            timed(&mut self.random_ints, || {
                for _ in range(0, num_keys) {
                    set.insert(rng.gen::<uint>() % rand_cap);
                }
            })
        }

        {
            let mut set = f();
            for i in range(0u, num_keys) {
                set.insert(i);
            }

            timed(&mut self.delete_ints, || {
                for i in range(0u, num_keys) {
                    assert!(set.remove(&i));
                }
            })
        }
    }

    pub fn bench_str<T:MutableSet<String>,
                     R:rand::Rng>(
                     &mut self,
                     rng: &mut R,
                     num_keys: uint,
                     f: || -> T) {
        {
            let mut set = f();
            timed(&mut self.sequential_strings, || {
                for i in range(0u, num_keys) {
                    set.insert(i.to_string());
                }

                for i in range(0u, num_keys) {
                    assert!(set.contains(&i.to_string()));
                }
            })
        }

        {
            let mut set = f();
            timed(&mut self.random_strings, || {
                for _ in range(0, num_keys) {
                    let s = rng.gen::<uint>().to_string();
                    set.insert(s);
                }
            })
        }

        {
            let mut set = f();
            for i in range(0u, num_keys) {
                set.insert(i.to_string());
            }
            timed(&mut self.delete_strings, || {
                for i in range(0u, num_keys) {
                    assert!(set.remove(&i.to_string()));
                }
            })
        }
    }
}

fn write_header(header: &str) {
    println!("{}", header);
}

fn write_row(label: &str, value: Duration) {
    println!("{:30} {} s\n", label, value);
}

fn write_results(label: &str, results: &Results) {
    write_header(label);
    write_row("sequential_ints", results.sequential_ints);
    write_row("random_ints", results.random_ints);
    write_row("delete_ints", results.delete_ints);
    write_row("sequential_strings", results.sequential_strings);
    write_row("random_strings", results.random_strings);
    write_row("delete_strings", results.delete_strings);
}

fn empty_results() -> Results {
    Results {
        sequential_ints: Duration::seconds(0),
        random_ints: Duration::seconds(0),
        delete_ints: Duration::seconds(0),

        sequential_strings: Duration::seconds(0),
        random_strings: Duration::seconds(0),
        delete_strings: Duration::seconds(0),
    }
}

fn main() {
    let args = os::args();
    let args = args.as_slice();
    let num_keys = {
        if args.len() == 2 {
            from_str::<uint>(args[1].as_slice()).unwrap()
        } else {
            100 // woefully inadequate for any real measurement
        }
    };

    let seed: &[_] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    let max = 200000;

    {
        let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(seed);
        let mut results = empty_results();
        results.bench_int(&mut rng, num_keys, max, || {
            let s: HashSet<uint> = HashSet::new();
            s
        });
        results.bench_str(&mut rng, num_keys, || {
            let s: HashSet<String> = HashSet::new();
            s
        });
        write_results("collections::HashSet", &results);
    }

    {
        let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(seed);
        let mut results = empty_results();
        results.bench_int(&mut rng, num_keys, max, || {
            let s: TreeSet<uint> = TreeSet::new();
            s
        });
        results.bench_str(&mut rng, num_keys, || {
            let s: TreeSet<String> = TreeSet::new();
            s
        });
        write_results("collections::TreeSet", &results);
    }

    {
        let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(seed);
        let mut results = empty_results();
        results.bench_int(&mut rng, num_keys, max, || BitvSet::new());
        write_results("collections::bitv::BitvSet", &results);
    }
}
<|endoftext|>


<commit_before>// Copyright 2012 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.

// Microbenchmarks for various functions in std and extra

extern mod extra;

use extra::time::precise_time_s;
use std::io;
use std::os;
use std::rand::RngUtil;
use std::rand;
use std::str;
use std::util;
use std::vec;

macro_rules! bench (
    ($id:ident) => (maybe_run_test(argv, stringify!($id).to_owned(), $id))
)

fn main() {
    let argv = os::args();
    let _tests = argv.slice(1, argv.len());

    bench!(shift_push);
    bench!(read_line);
    bench!(vec_plus);
    bench!(vec_append);
    bench!(vec_push_all);
    bench!(is_utf8_ascii);
    bench!(is_utf8_multibyte);
}

fn maybe_run_test(argv: &[~str], name: ~str, test: &fn()) {
    let mut run_test = false;

    if os::getenv("RUST_BENCH").is_some() {
        run_test = true
    } else if argv.len() > 0 {
        run_test = argv.iter().any(|x| x == &~"all") || argv.iter().any(|x| x == &name)
    }

    if !run_test {
        return
    }

    let start = precise_time_s();
    test();
    let stop = precise_time_s();

    printfln!("%s:\t\t%f ms", name, (stop - start) * 1000f);
}

fn shift_push() {
    let mut v1 = vec::from_elem(30000, 1);
    let mut v2 = ~[];

    while v1.len() > 0 {
        v2.push(v1.shift());
    }
}

fn read_line() {
    let path = Path(env!("CFG_SRC_DIR"))
        .push_rel(&Path("src/test/bench/shootout-k-nucleotide.data"));

    for _ in range(0, 3) {
        let reader = io::file_reader(&path).unwrap();
        while !reader.eof() {
            reader.read_line();
        }
    }
}

fn vec_plus() {
    let mut r = rand::rng();

    let mut v = ~[];
    let mut i = 0;
    while i < 1500 {
        let rv = vec::from_elem(r.gen_uint_range(0, i + 1), i);
        if r.gen() {
            v.push_all_move(rv);
        } else {
            v = rv + v;
        }
        i += 1;
    }
}

fn vec_append() {
    let mut r = rand::rng();

    let mut v = ~[];
    let mut i = 0;
    while i < 1500 {
        let rv = vec::from_elem(r.gen_uint_range(0, i + 1), i);
        if r.gen() {
            v = vec::append(v, rv);
        }
        else {
            v = vec::append(rv, v);
        }
        i += 1;
    }
}

fn vec_push_all() {
    let mut r = rand::rng();

    let mut v = ~[];
    for i in range(0u, 1500) {
        let mut rv = vec::from_elem(r.gen_uint_range(0, i + 1), i);
        if r.gen() {
            v.push_all(rv);
        }
        else {
            util::swap(&mut v, &mut rv);
            v.push_all(rv);
        }
    }
}

fn is_utf8_ascii() {
    let mut v : ~[u8] = ~[];
    for _ in range(0u, 20000) {
        v.push('b' as u8);
        if !str::is_utf8(v) {
            fail!("is_utf8 failed");
        }
    }
}

fn is_utf8_multibyte() {
    let s = "b¢€𤭢";
    let mut v : ~[u8]= ~[];
    for _ in range(0u, 5000) {
        v.push_all(s.as_bytes());
        if !str::is_utf8(v) {
            fail!("is_utf8 failed");
        }
    }
}
<commit_msg>make macro hygienic<commit_after>// Copyright 2012 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.

// Microbenchmarks for various functions in std and extra

extern mod extra;

use extra::time::precise_time_s;
use std::io;
use std::os;
use std::rand::RngUtil;
use std::rand;
use std::str;
use std::util;
use std::vec;

macro_rules! bench (
    ($argv:expr, $id:ident) => (maybe_run_test($argv, stringify!($id).to_owned(), $id))
)

fn main() {
    let argv = os::args();
    let _tests = argv.slice(1, argv.len());

    bench!(argv, shift_push);
    bench!(argv, read_line);
    bench!(argv, vec_plus);
    bench!(argv, vec_append);
    bench!(argv, vec_push_all);
    bench!(argv, is_utf8_ascii);
    bench!(argv, is_utf8_multibyte);
}

fn maybe_run_test(argv: &[~str], name: ~str, test: &fn()) {
    let mut run_test = false;

    if os::getenv("RUST_BENCH").is_some() {
        run_test = true
    } else if argv.len() > 0 {
        run_test = argv.iter().any(|x| x == &~"all") || argv.iter().any(|x| x == &name)
    }

    if !run_test {
        return
    }

    let start = precise_time_s();
    test();
    let stop = precise_time_s();

    printfln!("%s:\t\t%f ms", name, (stop - start) * 1000f);
}

fn shift_push() {
    let mut v1 = vec::from_elem(30000, 1);
    let mut v2 = ~[];

    while v1.len() > 0 {
        v2.push(v1.shift());
    }
}

fn read_line() {
    let path = Path(env!("CFG_SRC_DIR"))
        .push_rel(&Path("src/test/bench/shootout-k-nucleotide.data"));

    for _ in range(0, 3) {
        let reader = io::file_reader(&path).unwrap();
        while !reader.eof() {
            reader.read_line();
        }
    }
}

fn vec_plus() {
    let mut r = rand::rng();

    let mut v = ~[];
    let mut i = 0;
    while i < 1500 {
        let rv = vec::from_elem(r.gen_uint_range(0, i + 1), i);
        if r.gen() {
            v.push_all_move(rv);
        } else {
            v = rv + v;
        }
        i += 1;
    }
}

fn vec_append() {
    let mut r = rand::rng();

    let mut v = ~[];
    let mut i = 0;
    while i < 1500 {
        let rv = vec::from_elem(r.gen_uint_range(0, i + 1), i);
        if r.gen() {
            v = vec::append(v, rv);
        }
        else {
            v = vec::append(rv, v);
        }
        i += 1;
    }
}

fn vec_push_all() {
    let mut r = rand::rng();

    let mut v = ~[];
    for i in range(0u, 1500) {
        let mut rv = vec::from_elem(r.gen_uint_range(0, i + 1), i);
        if r.gen() {
            v.push_all(rv);
        }
        else {
            util::swap(&mut v, &mut rv);
            v.push_all(rv);
        }
    }
}

fn is_utf8_ascii() {
    let mut v : ~[u8] = ~[];
    for _ in range(0u, 20000) {
        v.push('b' as u8);
        if !str::is_utf8(v) {
            fail!("is_utf8 failed");
        }
    }
}

fn is_utf8_multibyte() {
    let s = "b¢€𤭢";
    let mut v : ~[u8]= ~[];
    for _ in range(0u, 5000) {
        v.push_all(s.as_bytes());
        if !str::is_utf8(v) {
            fail!("is_utf8 failed");
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>bench: Add threadring shootout benchmark<commit_after>// Based on threadring.erlang by Jira Isa
use std;

// FIXME: Need a cleaner way to request the runtime to exit
#[nolink]
native mod libc {
    fn exit(status: ctypes::c_int);
}

const n_threads: int = 503;

fn start(+token: int) {
    import iter::*;

    let p = comm::port();
    let ch = iter::foldl(bind int::range(2, n_threads + 1, _),
                         comm::chan(p)) { |ch, i|
        // FIXME: Some twiddling because we don't have a standard
        // reverse range function yet
        let id = n_threads + 2 - i;
        let {to_child, _} = task::spawn_connected::<int, int> {|p, _ch|
            roundtrip(id, p, ch)
        };
        to_child
    };
    comm::send(ch, token);
    roundtrip(1, p, ch);
}

fn roundtrip(id: int, p: comm::port<int>, ch: comm::chan<int>) {
    while (true) {
        alt comm::recv(p) {
          1 {
            std::io::println(#fmt("%d\n", id));
            libc::exit(0i32);
          }
          token {
            #debug("%d %d", id, token);
            comm::send(ch, token - 1);
          }
        }
    }
}

fn main(args: [str]) {
    let token = if vec::len(args) < 2u {
        1000
    } else {
        int::from_str(args[1])
    };

    start(token);
}<|endoftext|>


<commit_before><commit_msg>debuginfo: Added test cases for tuples contained in structs.<commit_after>// 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.

// xfail-win32 Broken because of LLVM bug: http://llvm.org/bugs/show_bug.cgi?id=16249

// compile-flags:-Z extra-debug-info
// debugger:set print pretty off
// debugger:break zzz
// debugger:run
// debugger:finish

// debugger:print noPadding1
// check:$1 = {x = {0, 1}, y = 2, z = {3, 4, 5}}
// debugger:print noPadding2
// check:$2 = {x = {6, 7}, y = {{8, 9}, 10}}

// debugger:print tupleInternalPadding
// check:$3 = {x = {11, 12}, y = {13, 14}}
// debugger:print structInternalPadding
// check:$4 = {x = {15, 16}, y = {17, 18}}
// debugger:print bothInternallyPadded
// check:$5 = {x = {19, 20, 21}, y = {22, 23}}

// debugger:print singleTuple
// check:$6 = {x = {24, 25, 26}}

// debugger:print tuplePaddedAtEnd
// check:$7 = {x = {27, 28}, y = {29, 30}}
// debugger:print structPaddedAtEnd
// check:$8 = {x = {31, 32}, y = {33, 34}}
// debugger:print bothPaddedAtEnd
// check:$9 = {x = {35, 36, 37}, y = {38, 39}}

// debugger:print mixedPadding
// check:$10 = {x = {{40, 41, 42}, {43, 44}}, y = {45, 46, 47, 48}}

struct NoPadding1 {
    x: (i32, i32),
    y: i32,
    z: (i32, i32, i32)
}

struct NoPadding2 {
    x: (i32, i32),
    y: ((i32, i32), i32)
}

struct TupleInternalPadding {
    x: (i16, i32),
    y: (i32, i64)
}

struct StructInternalPadding {
    x: (i16, i16),
    y: (i64, i64)
}

struct BothInternallyPadded {
    x: (i16, i32, i32),
    y: (i32, i64)
}

struct SingleTuple {
    x: (i16, i32, i64)
}

struct TuplePaddedAtEnd {
    x: (i32, i16),
    y: (i64, i32)
}

struct StructPaddedAtEnd {
    x: (i64, i64),
    y: (i16, i16)
}

struct BothPaddedAtEnd {
    x: (i32, i32, i16),
    y: (i64, i32)
}

// Data-layout (padding signified by dots, one column = 2 bytes):
// [a.bbc...ddddee..ffffg.hhi...]
struct MixedPadding {
    x: ((i16, i32, i16), (i64, i32)),
    y: (i64, i16, i32, i16)
}

fn main() {
    let noPadding1 = NoPadding1 {
        x: (0, 1),
        y: 2,
        z: (3, 4, 5)
    };

    let noPadding2 = NoPadding2 {
        x: (6, 7),
        y: ((8, 9), 10)
    };

    let tupleInternalPadding = TupleInternalPadding {
        x: (11, 12),
        y: (13, 14)
    };

    let structInternalPadding = StructInternalPadding {
        x: (15, 16),
        y: (17, 18)
    };

    let bothInternallyPadded = BothInternallyPadded {
        x: (19, 20, 21),
        y: (22, 23)
    };

    let singleTuple = SingleTuple {
        x: (24, 25, 26)
    };

    let tuplePaddedAtEnd = TuplePaddedAtEnd {
        x: (27, 28),
        y: (29, 30)
    };

    let structPaddedAtEnd = StructPaddedAtEnd {
        x: (31, 32),
        y: (33, 34)
    };

    let bothPaddedAtEnd = BothPaddedAtEnd {
        x: (35, 36, 37),
        y: (38, 39)
    };

    let mixedPadding = MixedPadding {
        x: ((40, 41, 42), (43, 44)),
        y: (45, 46, 47, 48)
    };

    zzz();
}

fn zzz() {()}<|endoftext|>


<commit_before><commit_msg>Finish challenge 3<commit_after><|endoftext|>


<commit_before><commit_msg>Rollup merge of #79293 - Havvy:test-eval-order-compound-assign, r=Mark-Simulacrum<commit_after>// Test evaluation order of operands of the compound assignment operators

// run-pass

use std::ops::AddAssign;

enum Side {
    Lhs,
    Rhs,
}

// In the following tests, we place our value into a wrapper type so that we
// can do an element access as the outer place expression. If we just had the
// block expression, it'd be a value expression and not compile.
struct Wrapper<T>(T);

// Evaluation order for `a op= b` where typeof(a) and typeof(b) are primitives
// is first `b` then `a`.
fn primitive_compound() {
    let mut side_order = vec![];
    let mut int = Wrapper(0);

    {
        side_order.push(Side::Lhs);
        int
    }.0 += {
        side_order.push(Side::Rhs);
        0
    };

    assert!(matches!(side_order[..], [Side::Rhs, Side::Lhs]));
}

// Evaluation order for `a op=b` otherwise is first `a` then `b`.
fn generic_compound<T: AddAssign<T> + Default>() {
    let mut side_order = vec![];
    let mut add_assignable: Wrapper<T> = Wrapper(Default::default());

    {
        side_order.push(Side::Lhs);
        add_assignable
    }.0 += {
        side_order.push(Side::Rhs);
        Default::default()
    };

    assert!(matches!(side_order[..], [Side::Lhs, Side::Rhs]));
}

fn custom_compound() {
    struct Custom;

    impl AddAssign<()> for Custom {
        fn add_assign(&mut self, _: ()) {
            // this block purposely left blank
        }
    }

    let mut side_order = vec![];
    let mut custom = Wrapper(Custom);

    {
        side_order.push(Side::Lhs);
        custom
    }.0 += {
        side_order.push(Side::Rhs);
    };

    assert!(matches!(side_order[..], [Side::Lhs, Side::Rhs]));
}

fn main() {
    primitive_compound();
    generic_compound::<i32>();
    custom_compound();
}
<|endoftext|>


<commit_before><commit_msg>Implicit conversion example<commit_after>// Can you guess why this program will fail?
fn main() {
   let x = 10;
   let y = 120.0;

   let z = y - x;
   println!("z = {}",z);
}

<|endoftext|>


<commit_before><commit_msg>When window closed, print window position and size<commit_after><|endoftext|>


<commit_before><commit_msg>Create a new FtpsStream<T> type and revert back to the old FtpStream type for other cases. The new type allows us to retain (and require) information about an Ssl configuration only when the user wants to supply one. Need a way to avoid so much code duplication though<commit_after><|endoftext|>


<commit_before><commit_msg>added first implementation.<commit_after>#![crate_type = "lib"]
#![crate_name = "exbitflags"]

#![feature(macro_rules)]
#[doc(hidden)]

/// Helper! Expands to:
/// ```
/// static $flag = $v
/// ```
#[macro_export]
macro_rules! ebf_flag(
	($flag:ident, $v: expr) => (
		static $flag = $v,
	);
)

/// Helper! Given a list of identifiers,
/// it creates flags for each one according to the series defined by: 2^n.
/// This causes all flags to be exclusive.
#[macro_export]
macro_rules! ebf_flags {
	($flag:ident) => (
		ebf_flag!( $flag, 0x01 );
	);
	($flag:ident, $($tail:expr), +) => (
		ebf_flags!( 0x01, $flag, $($tail), + );
    );
	($val:expr, $flag:ident, $($tail:expr), + ) => (
		ebf_flag!( $flag, $val );
		ebf_flags!( $val << 1, $($tail), + );
	);
}

/// Creates bitfields with $name, with the type $t with a list of flags.
/// Example:
/// ```
/// ebf!( Operations, u32, ADD, DELETE, MODIFY );
#[macro_export]
macro_rules! ebf {
	($name:ident, $t:ty, $flag:ident, $($tail:expr), +) => (
		bitflags!( flags $name: $t ) {
			ebf_flags!( $flag, $($tail:expr), + );
		}
	);
}<|endoftext|>


<commit_before><commit_msg>Typo.<commit_after><|endoftext|>


<commit_before><commit_msg>added update_depot_tools support<commit_after><|endoftext|>


<commit_before><commit_msg>Sort cookies by domain and name (as lowest priority) to stablise output.<commit_after><|endoftext|>


<commit_before><commit_msg>More derived traits.<commit_after><|endoftext|>


<commit_before><commit_msg>Fixed system allocation bug<commit_after><|endoftext|>


<commit_before><commit_msg>Seek parent only on IO errors<commit_after><|endoftext|>


<commit_before><commit_msg>time dilation accounted for<commit_after><|endoftext|>


<commit_before>#![feature(core)]
#![feature(io)]
#![feature(std_misc)]
#![feature(step_by)]
#![feature(test)]

extern crate byteorder;
extern crate flate2;
extern crate nbt;
extern crate "rustc-serialize" as rustc_serialize;
extern crate test;
extern crate time;
extern crate uuid;

pub mod packet;
pub mod proto;
pub mod types;
mod util;
<commit_msg>Update rustc-serialize import to new syntax<commit_after>#![feature(core)]
#![feature(io)]
#![feature(std_misc)]
#![feature(step_by)]
#![feature(test)]

extern crate byteorder;
extern crate flate2;
extern crate nbt;
extern crate rustc_serialize;
extern crate test;
extern crate time;
extern crate uuid;

pub mod packet;
pub mod proto;
pub mod types;
mod util;
<|endoftext|>


<commit_before><commit_msg>Simplify UdpCodec impl for ClientCodec<commit_after><|endoftext|>


<commit_before><commit_msg>Clean up disp9/disp26 logic a bit<commit_after><|endoftext|>


<commit_before><commit_msg>Ray struct<commit_after>use vector::Vector;
#[derive(Debug, Copy)]
pub struct Ray {
	pub origin: Vector,
	pub direction: Vector
}

impl Ray {
	pub fn new(origin: Vector, direction: Vector ) -> Ray {
		Ray { origin: origin, direction: direction }
	}
}<|endoftext|>


<commit_before>// Copyright 2015 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.

use syntax::{ast, attr};
use llvm::LLVMRustHasFeature;
use rustc::session::Session;
use rustc_trans::back::write::create_target_machine;
use syntax::parse::token::InternedString;
use syntax::parse::token::intern_and_get_ident as intern;
use libc::c_char;

/// Add `target_feature = "..."` cfgs for a variety of platform
/// specific features (SSE, NEON etc.).
///
/// This is performed by checking whether a whitelisted set of
/// features is available on the target machine, by querying LLVM.
pub fn add_configuration(cfg: &mut ast::CrateConfig, sess: &Session) {
    let target_machine = create_target_machine(sess);

    let arm_whitelist = [
        "neon\0",
        "vfp\0",
    ];

    let x86_whitelist = [
        "avx\0",
        "avx2\0",
        "sse\0",
        "sse2\0",
        "sse3\0",
        "sse4.1\0",
        "sse4.2\0",
        "ssse3\0",
    ];

    let whitelist = match &*sess.target.target.arch {
        "arm" => &arm_whitelist[..],
        "x86" | "x86_64" => &x86_whitelist[..],
        _ => &[][..],
    };

    let tf = InternedString::new("target_feature");
    for feat in whitelist {
        if unsafe { LLVMRustHasFeature(target_machine, feat.as_ptr() as *const c_char) } {
            cfg.push(attr::mk_name_value_item_str(tf.clone(), intern(&feat[..feat.len()-1])))
        }
    }
}
<commit_msg>Distinguish different `vfp?` features<commit_after>// Copyright 2015 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.

use syntax::{ast, attr};
use llvm::LLVMRustHasFeature;
use rustc::session::Session;
use rustc_trans::back::write::create_target_machine;
use syntax::parse::token::InternedString;
use syntax::parse::token::intern_and_get_ident as intern;
use libc::c_char;

/// Add `target_feature = "..."` cfgs for a variety of platform
/// specific features (SSE, NEON etc.).
///
/// This is performed by checking whether a whitelisted set of
/// features is available on the target machine, by querying LLVM.
pub fn add_configuration(cfg: &mut ast::CrateConfig, sess: &Session) {
    let target_machine = create_target_machine(sess);

    // WARNING: the features must be known to LLVM or the feature
    // detection code will walk past the end of the feature array,
    // leading to crashes.

    let arm_whitelist = [
        "neon\0",
        "vfp2\0",
        "vfp3\0",
        "vfp4\0",
    ];

    let x86_whitelist = [
        "avx\0",
        "avx2\0",
        "sse\0",
        "sse2\0",
        "sse3\0",
        "sse4.1\0",
        "sse4.2\0",
        "ssse3\0",
    ];

    let whitelist = match &*sess.target.target.arch {
        "arm" => &arm_whitelist[..],
        "x86" | "x86_64" => &x86_whitelist[..],
        _ => &[][..],
    };

    let tf = InternedString::new("target_feature");
    for feat in whitelist {
        if unsafe { LLVMRustHasFeature(target_machine, feat.as_ptr() as *const c_char) } {
            cfg.push(attr::mk_name_value_item_str(tf.clone(), intern(&feat[..feat.len()-1])))
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Allocate a vertex scratchpad per thread only once per frame<commit_after><|endoftext|>


<commit_before><commit_msg>Add `unsafe` for transmuting.<commit_after><|endoftext|>


<commit_before><commit_msg>Initial version of crowdcontrol::metrics (tests missing).<commit_after>// XXX(scode): Consider supporting cloning/snapshotting metrics.
// XXX(scode): Consider whether we should expose the current values in the public traits.
// XXX(scode): Missing histograms.
// XXX(scode): Missing meters (questionable).

use std::num::Int;
use std::sync::Arc;
use std::sync::Mutex;

/// A 64 bit signed counter.
pub trait Counter<T: Int> {
    /// Increment the counter by the given delta.
	///
	/// The delta may be negative (for types T where this is possible).
    fn inc(&mut self, delta: T);

    /// Decrement the counter by the given delta.
	///
	/// The delta may be negative (for types T where this is possible).
	///
	/// dec(n) is equivalent of dec(-n)
    fn dec(&mut self, delta: T);
}

/// A gauge has a single value at any given moment in time, and can only be
/// updated by providing an entirely new value to replace the existing one
/// (if any).
pub trait Gauge<T> {
    fn set(&mut self, value: T);
}

pub struct SimpleCounter<T: Int> {
    value: T,
}

impl<T: Int> Counter<T> for SimpleCounter<T> {
    fn inc(&mut self, delta: T) {
		self.value = self.value + delta;
	}

    fn dec(&mut self, delta: T) {
		self.value = self.value - delta;
	}
}

pub struct SharedCounter<T: Int + Send> {
    value: Arc<Mutex<T>>,
}

impl<T: Int + Send> Counter<T> for SharedCounter<T> {
    fn inc(&mut self, delta: T) {
		let mut value = self.value.lock().unwrap();

		*value = *value + delta;
	}

    fn dec(&mut self, delta: T) {
		let mut value = self.value.lock().unwrap();

		*value = *value - delta;
	}
}

pub struct SimpleGauge<T> {
    value: Option<T>,
}

impl<T> Gauge<T> for SimpleGauge<T> {
    fn set(&mut self, new_value: T) {
		self.value = Some(new_value);
	}
}

pub struct SharedGauge<T: Send> {
    value: Arc<Mutex<Option<T>>>,
}

impl<T: Send> Gauge<T> for SharedGauge<T> {
    fn set(&mut self, new_value: T) {
		*self.value.lock().unwrap() = Some(new_value)
	}
}

#[cfg(test)]
mod test {
    // TODO(scode): Add tests.
}

<|endoftext|>


<commit_before><commit_msg>network monitoring<commit_after>extern crate timely;
extern crate differential_dataflow;

use std::sync::{Arc, Mutex};
use std::net::TcpListener;
use std::time::Duration;

use timely::dataflow::operators::Map;
use timely::progress::nested::product::Product;
use timely::progress::timestamp::RootTimestamp;
use timely::logging::TimelyEvent;
use timely::communication::logging::CommunicationEvent;
use timely::dataflow::operators::Filter;
use timely::dataflow::operators::capture::{EventReader, Replay};

use differential_dataflow::AsCollection;
use differential_dataflow::operators::{Consolidate, Join};
// use differential_dataflow::logging::DifferentialEvent;

fn main() {

    let mut args = ::std::env::args();
    args.next().unwrap();

    let source_peers = args.next().expect("Must provide number of source peers").parse::<usize>().expect("Source peers must be an unsigned integer");
    let t_listener = TcpListener::bind("127.0.0.1:8000").unwrap();
    let d_listener = TcpListener::bind("127.0.0.1:9000").unwrap();
    let t_sockets =
    Arc::new(Mutex::new((0..source_peers).map(|_| {
            let socket = t_listener.incoming().next().unwrap().unwrap();
            socket.set_nonblocking(true).expect("failed to set nonblocking");
            Some(socket)
        }).collect::<Vec<_>>()));
    let d_sockets =
    Arc::new(Mutex::new((0..source_peers).map(|_| {
            let socket = d_listener.incoming().next().unwrap().unwrap();
            socket.set_nonblocking(true).expect("failed to set nonblocking");
            Some(socket)
        }).collect::<Vec<_>>()));

    timely::execute_from_args(std::env::args(), move |worker| {

        let index = worker.index();
        let peers = worker.peers();

        let t_streams =
        t_sockets
            .lock()
            .unwrap()
            .iter_mut()
            .enumerate()
            .filter(|(i, _)| *i % peers == index)
            .map(move |(_, s)| s.take().unwrap())
            .map(|r| EventReader::<Product<RootTimestamp, Duration>, (Duration, usize, TimelyEvent),_>::new(r))
            .collect::<Vec<_>>();

        let d_streams =
        d_sockets
            .lock()
            .unwrap()
            .iter_mut()
            .enumerate()
            .filter(|(i, _)| *i % peers == index)
            .map(move |(_, s)| s.take().unwrap())
            .map(|r| EventReader::<Product<RootTimestamp, Duration>, (Duration, usize, CommunicationEvent),_>::new(r))
            .collect::<Vec<_>>();

        worker.dataflow::<_,_,_>(|scope| {

            let t_events = t_streams.replay_into(scope);
            let d_events = d_streams.replay_into(scope);

            let operates =
            t_events
                .filter(|x| x.1 == 0)
                .flat_map(move |(ts, _worker, datum)| {
                    let ts = Duration::from_secs(ts.as_secs() + 1);
                    if let TimelyEvent::Channels(event) = datum {
                        Some(((event.id, event), RootTimestamp::new(ts), 1))
                    }
                    else { None }
                })
                .as_collection()
                // .consolidate()
                .inspect(|x| println!("CHANNEL\t{:?}", x));
                ;

            let memory =
            d_events
                .flat_map(|(ts, _worker, datum)| {
                    let ts = Duration::from_secs(ts.as_secs() + 1);
                    if let CommunicationEvent::Message(x) = datum {
                            Some((x.header.channel, RootTimestamp::new(ts), x.header.length as isize))
                    }
                    else { None }
                })
                .as_collection()
                .consolidate()
                .inspect(|x| println!("MESSAGE\t{:?}", x));
                ;

            // operates
            //     .inspect(|x| println!("OPERATES: {:?}", x))
            //     .semijoin(&memory)
            //     .inspect(|x| println!("{:?}", x));

        });

    }).unwrap(); // asserts error-free execution
}
<|endoftext|>


<commit_before><commit_msg>Add test case for #2869 (xfailed)<commit_after>// xfail-test
enum pat { pat_ident(option<uint>) }

fn f(pat: pat) -> bool { true }

fn num_bindings(pat: pat) -> uint {
    alt pat {
      pat_ident(_) if f(pat) { 0 }
      pat_ident(none) { 1 }
      pat_ident(some(sub)) { sub }
    }
}

fn main() {}<|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.

fn parse_args() -> ~str {
    let args = core::os::args();
    let mut n = 0;

    while n < args.len() {
        match copy args[n] {
            ~"-v" => (),
            s => {
                return s;
            }
        }
        n += 1;
    }

    return ~""
}

fn main() {
    io::println(parse_args());
}
<commit_msg>testsuite: Xfail file that I added by mistake<commit_after>// 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.

// xfail-test
fn parse_args() -> ~str {
    let args = core::os::args();
    let mut n = 0;

    while n < args.len() {
        match copy args[n] {
            ~"-v" => (),
            s => {
                return s;
            }
        }
        n += 1;
    }

    return ~""
}

fn main() {
    io::println(parse_args());
}
<|endoftext|>


<commit_before><commit_msg>implement coreutils' cat as an example<commit_after>use std::io::{Read, Result, copy, stdout};
use std::env::args_os;
use std::process::exit;
use std::ffi::OsString;
use std::fs::File;
use std::path::Path;

extern crate concat;
use concat::concat;

fn main() {
    let mut args = args_os();
    let progname = args.next().unwrap_or_else(|| OsString::from("cat"));

    let mut c = concat(args.map(InputSource::from));
    let res = copy(&mut c, &mut stdout());

    if let Err(e) = res {
        match c.current() {
            None => {
                println!("{}: {}\n",
                         AsRef::<Path>::as_ref(&progname).display(),
                         e);
            },

            Some(ref f) => {
                println!("{}: {}: {}\n",
                         AsRef::<Path>::as_ref(&progname).display(),
                         f.path().display(),
                         e);
            },
        };

        exit(1);
    }
}

struct InputSource {
    path: OsString,
    file: Option<File>,
}

impl InputSource {
    pub fn path(&self) -> &Path {
        self.path.as_ref()
    }
}

impl From<OsString> for InputSource {
    fn from(path: OsString) -> InputSource {
        InputSource {
            path: path,
            file: None,
        }
    }
}

impl Read for InputSource {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        if self.file.is_none() {
            self.file = Some(try!(File::open(&self.path)));
        }

        self.file.as_mut().unwrap().read(buf)
    }
}
<|endoftext|>


<commit_before><commit_msg>string to integer parsing and match comparator added<commit_after><|endoftext|>


<commit_before><commit_msg>benches/geometric_search: add benches between Brute-force and 2d-tree<commit_after>#![feature(test)]

extern crate test;
extern crate rand;

extern crate algs4;

use test::Bencher;
use rand::{thread_rng, Rng};

use algs4::geometric_search::primitive::{Point2D, PointSet, RectHV};
use algs4::symbol_tables::ST;
use algs4::geometric_search::kd_tree::KdTree;

const SIZE: usize = 1000;

#[bench]
fn bench_brute_force_range_search(b: &mut Bencher) {
    let mut pset = PointSet::new();
    let mut rng = thread_rng();
    for _ in 0 .. SIZE {
        pset.insert(rng.gen());
    }
    let rect = RectHV::new(0.4, 0.4, 0.6, 0.6);
    b.iter(|| {
        assert!(pset.range_search(&rect).next().is_some());
    });
}

#[bench]
fn bench_kd_tree_range_search(b: &mut Bencher) {
    let mut kt = KdTree::new();
    let mut rng = thread_rng();
    for _ in 0 .. SIZE {
        kt.insert(rng.gen());
    }
    let rect = RectHV::new(0.4, 0.4, 0.6, 0.6);
    b.iter(|| {
        assert!(kt.range_search(&rect).next().is_some());
    });
}

#[bench]
fn bench_brute_force_nearest(b: &mut Bencher) {
    let mut pset = PointSet::new();
    let mut rng = thread_rng();
    for _ in 0 .. SIZE {
        pset.insert(rng.gen());
    }
    let p = Point2D::new(0.5, 0.5);
    b.iter(|| {
        assert!(pset.nearest(&p).is_some());
    });
}

#[bench]
fn bench_kd_tree_nearest(b: &mut Bencher) {
    let mut kt = KdTree::new();
    let mut rng = thread_rng();
    for _ in 0 .. SIZE {
        kt.insert(rng.gen());
    }
    let p = Point2D::new(0.5, 0.5);
    b.iter(|| {
        assert!(kt.nearest(&p).is_some());
    });
}
<|endoftext|>


<commit_before><commit_msg>Add docstring comments to SphinxDigest methods<commit_after><|endoftext|>


<commit_before><commit_msg>feat(macros): add ability to get mutliple typed values or exit<commit_after><|endoftext|>


<commit_before><commit_msg>Simple dispatch table implementation<commit_after>use hash_map::HashMap;
use core::hash;
use core::cmp;

pub type DispatchFn<T> = fn (&T) -> bool;

pub struct DispatchTable<T: cmp::Eq + hash::Hash> {
    table: HashMap<T, DispatchFn<T>>,
}

impl<T: cmp::Eq + hash::Hash> DispatchTable<T> {

    pub fn new() -> Self{
        DispatchTable{ table: HashMap::new(16) }
    }

    pub fn dispatch(&mut self, event: &T) -> bool {
        match self.table.get(event) {
            Some(func) => func(event),
            None => false,
        }
    }

    pub fn register(&mut self, event: T, func: DispatchFn<T>) {
        self.table.insert(event, func);
    }

    pub fn unregister(&mut self, event: T) {
        self.table.remove(event);
    }

}

#[cfg(test)]
mod test {

    #[derive(Hash, Eq, PartialEq, Debug)]
    enum Event {
        VMExit,
        PageFault,
    }

    fn on_vmexit(_: &Event) -> bool {
        print!("Guest exited!");
        true
    }

    #[test]
    fn test_dispatch_table() {
        let mut dt = DispatchTable::<Event>::new();
        dt.register(Event::VMExit, on_vmexit);
        assert!(dt.dispatch(&Event::VMExit));
        assert!(!dt.dispatch(&Event::PageFault));
    }
}
<|endoftext|>


<commit_before>// This file is part of rgtk.
//
// rgtk is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// rgtk is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with rgtk.  If not, see <http://www.gnu.org/licenses/>.

use gdk;
use libc::c_void;
use std::mem;

pub use self::event_type::EventType;
pub use self::owner_change::OwnerChange;
pub use self::setting_action::SettingAction;
pub use self::window_state::WindowState;
pub use self::property_state::PropertyState;
pub use self::crossing_mode::CrossingMode;
pub use self::notify_type::NotifyType;
pub use self::scroll_direction::ScrollDirection;
pub use self::visibility_state::VisibilityState;

pub mod event_type {
    #[repr(C)]
    #[deriving(Clone, PartialEq, PartialOrd, Show)]
    pub enum EventType {
        Nothing           = -1,
        Delete            = 0,
        Destroy           = 1,
        Expose            = 2,
        MotionNotify      = 3,
        ButtonPress       = 4,
        DoubleButtonPress = 5,
        TripleButtonPress = 6,
        ButtonRelease     = 7,
        KeyPress          = 8,
        KeyRelease        = 9,
        EnterNotify       = 10,
        LeaveNotify       = 11,
        FocusChange       = 12,
        Configure         = 13,
        Map               = 14,
        Unmap             = 15,
        PropertyNotify    = 16,
        SelectionClear    = 17,
        SelectionRequest  = 18,
        SelectionNotify   = 19,
        ProximityIn       = 20,
        ProximityOut      = 21,
        DragEnter         = 22,
        DragLeave         = 23,
        DragMotion        = 24,
        DragStatus        = 25,
        DropStart         = 26,
        DropFinished      = 27,
        ClientEvent       = 28,
        VisibilityNotify  = 29,
        Scroll            = 31,
        WindowState       = 32,
        Setting           = 33,
        OwnerChange       = 34,
        GrabBroken        = 35,
        Damage            = 36,
        TouchBegin        = 37,
        TouchUpdate       = 38,
        TouchEnd          = 39,
        TouchCancel       = 40
    }
}

pub trait Event {
    fn get_send_event(&self) -> bool {
        unsafe {
            let event_any : &EventAny = mem::transmute(self);
            event_any.send_event == 0
        }
    }
}

#[repr(C)]
pub struct EventAny {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,
}

impl Event for EventAny {}

pub struct EventExpose {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub area : gdk::Rectangle,
    pub region : *mut c_void, //TODO cairo_region_t
    pub count : i8 /* If non-zero, how many more events follow. */
}

impl Event for EventExpose {}

pub struct EventVisibility{
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    state : gdk::VisibilityState
}

impl Event for EventVisibility {}

pub struct EventMotion {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    time : u32,
    x : f64,
    y : f64,
    axes : *mut f64,
    state : u32,
    is_hint : i16,
    device : *mut gdk::Device,
    x_root : f64,
    y_root : f64
}

impl Event for EventMotion {}

pub struct EventButton {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    time : u32,
    x : f64,
    y : f64,
    axes : *mut f64,
    state : u32,
    button : u32,
    device : *mut gdk::Device,
    x_root : f64,
    y_root : f64
}

impl Event for EventButton {}

pub struct EventTouch {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub time : u32,
    pub x : f64,
    pub y : f64,
    pub axes : *mut f64,
    pub state : u32,
    pub sequence : *mut c_void, //gdk::EventSequence
    pub emulating_pointer : i32, // boolean
    pub device : *mut gdk::Device,
    pub x_root : f64,
    pub y_root : f64
}

impl Event for EventTouch {}

pub struct EventScroll {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub time : u32,
    pub x : f64,
    pub y : f64,
    pub state : u32,
    pub direction : gdk::ScrollDirection,
    pub device : *mut gdk::Device,
    pub x_root : f64,
    pub y_root : f64,
    pub delta_x : f64,
    pub delta_y : f64
}

impl Event for EventScroll {}

pub struct EventKey {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub time : u32,
    pub state : u32,
    pub keyval : u32,
    pub length : i32,
    pub string : *mut char,
    pub hardware_keycode : u16,
    pub group : u8,
    pub is_modified: u32
}

impl Event for EventKey {}

pub struct EventCrossing {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub subwindow : gdk::Window,
    pub time : u32,
    pub x : f64,
    pub y : f64,
    pub x_root : f64,
    pub y_root : f64,
    pub mode : gdk::CrossingMode,
    pub detail : gdk::NotifyType,
    pub focus : i32, // boolean
    pub state : u32 //FIXME
}

impl Event for EventCrossing {}

pub struct EventFocus {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    _in : i16
}

impl Event for EventFocus {}

pub struct EventConfigure{
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub x : i32,
    pub y : i32,
    pub width : i32,
    pub height : i32
}

impl Event for EventConfigure {}

pub struct EventProperty {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    atom : gdk::Atom,
    time : u32,
    state : u32 //FIXME
}

impl Event for EventProperty {}

pub struct EventSelection {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub selection : gdk::Atom,
    pub target : gdk::Atom,
    pub property : gdk::Atom,
    pub time : u32,
    pub requestor : *mut gdk::Window
}

impl Event for EventSelection {}

pub struct EventOwnerChange {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub owner : *mut gdk::Window,
    pub reason : gdk::OwnerChange,
    pub selection : gdk::Atom,
    pub time : u32,
    pub selection_time : u32
}

impl Event for EventOwnerChange {}

pub struct EventProximity {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub time : u32,
    pub device : *mut gdk::Device
}

impl Event for EventProximity {}

pub struct EventSetting {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub action : gdk::SettingAction,
    pub name : *mut char
}

impl Event for EventSetting {}

pub struct EventWindowState {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub changed_mask : gdk::WindowState,
    pub new_window_state : gdk::WindowState
}

impl Event for EventWindowState {}

pub struct EventGrabBroken {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub keyboard : i32, // boolean
    pub implicit : i32, // boolean
    pub grab_window : *mut gdk::Window
}

impl Event for EventGrabBroken  {}

pub struct EventDND {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub context : *mut c_void, //gdk::DragContext
    pub time : u32,
    pub x_root : i16, //short
    pub y_root : i16  //short
}

impl Event for EventDND  {}

//Supporting types

pub mod visibility_state {
    #[repr(C)]
    #[deriving(Clone, PartialEq, PartialOrd, Show)]
    pub enum VisibilityState{
        VisibilityUnobscured,
        VisibilityPartial,
        VisibilityFullyObscured
    }
}

pub mod scroll_direction {
    #[repr(C)]
    #[deriving(Clone, PartialEq, PartialOrd, Show)]
    pub enum ScrollDirection{
        ScrollUp,
        ScrollDown,
        ScrollLeft,
        ScrollRight,
        ScrollSmooth
    }
}

pub mod notify_type {
    #[repr(C)]
    #[deriving(Clone, PartialEq, PartialOrd, Show)]
    pub enum NotifyType{
        NotifyAncestor   = 0,
        NotifyVirtual    = 1,
        NotifyInferior   = 2,
        NotifyNonlinear  = 3,
        NotifyNonlinearVirtual  = 4,
        NotifyUnknown    = 5
    }
}

pub mod crossing_mode {
    #[repr(C)]
    #[deriving(Clone, PartialEq, PartialOrd, Show)]
    pub enum CrossingMode{
        CrossingNormal,
        CrossingGrab,
        CrossingUngrab,
        CrossingGtkGrab,
        CrossingGtkUngrab,
        CrossingStateChanged,
        CrossingTouchBegin,
        CrossingTouchEnd,
        CrossingDeviceSwitch
    }
}

pub mod property_state {
    #[repr(C)]
    #[deriving(Clone, PartialEq, PartialOrd, Show)]
    pub enum PropertyState{
        PropertyNewValue,
        PropertyDelete
    }
}

pub mod window_state {
    #[repr(C)]
    #[deriving(Clone, PartialEq, PartialOrd, Show)]
    pub enum WindowState{
        WindowStateWithdrawn  = 1 << 0,
        WindowStateIconified  = 1 << 1,
        WindowStateMaximized  = 1 << 2,
        WindowStateSticky     = 1 << 3,
        WindowStateFullscreen = 1 << 4,
        WindowStateAbove      = 1 << 5,
        WindowStateBelow      = 1 << 6,
        WindowStateFocused    = 1 << 7,
        WindowStateTiled      = 1 << 8
    }
}

pub mod setting_action {
    #[repr(C)]
    #[deriving(Clone, PartialEq, PartialOrd, Show)]
    pub enum SettingAction{
        SettingActionNew,
        SettingActionChanged,
        SettingActionDeleted
    }
}

pub mod owner_change {
    #[repr(C)]
    #[deriving(Clone, PartialEq, PartialOrd, Show)]
    pub enum OwnerChange{
        OwnerChangeNewOwner,
        OwnerChangeDestroy,
        OwnerChangeClose
    }
}<commit_msg>Update events.rs<commit_after>// This file is part of rgtk.
//
// rgtk is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// rgtk is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with rgtk.  If not, see <http://www.gnu.org/licenses/>.

use gdk;
use libc::c_void;
use std::mem;

pub use self::event_type::EventType;
pub use self::owner_change::OwnerChange;
pub use self::setting_action::SettingAction;
pub use self::window_state::WindowState;
pub use self::property_state::PropertyState;
pub use self::crossing_mode::CrossingMode;
pub use self::notify_type::NotifyType;
pub use self::scroll_direction::ScrollDirection;
pub use self::visibility_state::VisibilityState;

pub mod event_type {
    #[repr(C)]
    #[deriving(Clone, PartialEq, PartialOrd, Show)]
    pub enum EventType {
        Nothing           = -1,
        Delete            = 0,
        Destroy           = 1,
        Expose            = 2,
        MotionNotify      = 3,
        ButtonPress       = 4,
        DoubleButtonPress = 5,
        TripleButtonPress = 6,
        ButtonRelease     = 7,
        KeyPress          = 8,
        KeyRelease        = 9,
        EnterNotify       = 10,
        LeaveNotify       = 11,
        FocusChange       = 12,
        Configure         = 13,
        Map               = 14,
        Unmap             = 15,
        PropertyNotify    = 16,
        SelectionClear    = 17,
        SelectionRequest  = 18,
        SelectionNotify   = 19,
        ProximityIn       = 20,
        ProximityOut      = 21,
        DragEnter         = 22,
        DragLeave         = 23,
        DragMotion        = 24,
        DragStatus        = 25,
        DropStart         = 26,
        DropFinished      = 27,
        ClientEvent       = 28,
        VisibilityNotify  = 29,
        Scroll            = 31,
        WindowState       = 32,
        Setting           = 33,
        OwnerChange       = 34,
        GrabBroken        = 35,
        Damage            = 36,
        TouchBegin        = 37,
        TouchUpdate       = 38,
        TouchEnd          = 39,
        TouchCancel       = 40
    }
}

pub trait Event {
    fn get_send_event(&self) -> bool {
        unsafe {
            let event_any : &EventAny = mem::transmute(self);
            event_any.send_event == 0
        }
    }
}

#[repr(C)]
pub struct EventAny {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,
}

impl Event for EventAny {}

pub struct EventExpose {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub area : gdk::Rectangle,
    pub region : *mut c_void, //TODO cairo_region_t
    pub count : i8 /* If non-zero, how many more events follow. */
}

impl Event for EventExpose {}

pub struct EventVisibility{
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    state : gdk::VisibilityState
}

impl Event for EventVisibility {}

pub struct EventMotion {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    time : u32,
    x : f64,
    y : f64,
    axes : *mut f64,
    state : u32,
    is_hint : i16,
    device : *mut gdk::Device,
    x_root : f64,
    y_root : f64
}

impl Event for EventMotion {}

pub struct EventButton {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    time : u32,
    x : f64,
    y : f64,
    axes : *mut f64,
    state : u32,
    button : u32,
    device : *mut gdk::Device,
    x_root : f64,
    y_root : f64
}

impl Event for EventButton {}

pub struct EventTouch {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub time : u32,
    pub x : f64,
    pub y : f64,
    pub axes : *mut f64,
    pub state : u32,
    pub sequence : *mut c_void, //gdk::EventSequence
    pub emulating_pointer : i32, // boolean
    pub device : *mut gdk::Device,
    pub x_root : f64,
    pub y_root : f64
}

impl Event for EventTouch {}

pub struct EventScroll {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub time : u32,
    pub x : f64,
    pub y : f64,
    pub state : u32,
    pub direction : gdk::ScrollDirection,
    pub device : *mut gdk::Device,
    pub x_root : f64,
    pub y_root : f64,
    pub delta_x : f64,
    pub delta_y : f64
}

impl Event for EventScroll {}

pub struct EventKey {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub time : u32,
    pub state : u32,
    pub keyval : u32,
    pub length : i32,
    pub string : *mut char,
    pub hardware_keycode : u16,
    pub group : u8,
    pub is_modifier: u32
}

impl Event for EventKey {}

pub struct EventCrossing {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub subwindow : gdk::Window,
    pub time : u32,
    pub x : f64,
    pub y : f64,
    pub x_root : f64,
    pub y_root : f64,
    pub mode : gdk::CrossingMode,
    pub detail : gdk::NotifyType,
    pub focus : i32, // boolean
    pub state : u32 //FIXME
}

impl Event for EventCrossing {}

pub struct EventFocus {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    _in : i16
}

impl Event for EventFocus {}

pub struct EventConfigure{
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub x : i32,
    pub y : i32,
    pub width : i32,
    pub height : i32
}

impl Event for EventConfigure {}

pub struct EventProperty {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    atom : gdk::Atom,
    time : u32,
    state : u32 //FIXME
}

impl Event for EventProperty {}

pub struct EventSelection {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub selection : gdk::Atom,
    pub target : gdk::Atom,
    pub property : gdk::Atom,
    pub time : u32,
    pub requestor : *mut gdk::Window
}

impl Event for EventSelection {}

pub struct EventOwnerChange {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub owner : *mut gdk::Window,
    pub reason : gdk::OwnerChange,
    pub selection : gdk::Atom,
    pub time : u32,
    pub selection_time : u32
}

impl Event for EventOwnerChange {}

pub struct EventProximity {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub time : u32,
    pub device : *mut gdk::Device
}

impl Event for EventProximity {}

pub struct EventSetting {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub action : gdk::SettingAction,
    pub name : *mut char
}

impl Event for EventSetting {}

pub struct EventWindowState {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub changed_mask : gdk::WindowState,
    pub new_window_state : gdk::WindowState
}

impl Event for EventWindowState {}

pub struct EventGrabBroken {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub keyboard : i32, // boolean
    pub implicit : i32, // boolean
    pub grab_window : *mut gdk::Window
}

impl Event for EventGrabBroken  {}

pub struct EventDND {
    pub _type : gdk::EventType,
    pub window : *mut gdk::Window,
    send_event : i8,

    pub context : *mut c_void, //gdk::DragContext
    pub time : u32,
    pub x_root : i16, //short
    pub y_root : i16  //short
}

impl Event for EventDND  {}

//Supporting types

pub mod visibility_state {
    #[repr(C)]
    #[deriving(Clone, PartialEq, PartialOrd, Show)]
    pub enum VisibilityState{
        VisibilityUnobscured,
        VisibilityPartial,
        VisibilityFullyObscured
    }
}

pub mod scroll_direction {
    #[repr(C)]
    #[deriving(Clone, PartialEq, PartialOrd, Show)]
    pub enum ScrollDirection{
        ScrollUp,
        ScrollDown,
        ScrollLeft,
        ScrollRight,
        ScrollSmooth
    }
}

pub mod notify_type {
    #[repr(C)]
    #[deriving(Clone, PartialEq, PartialOrd, Show)]
    pub enum NotifyType{
        NotifyAncestor   = 0,
        NotifyVirtual    = 1,
        NotifyInferior   = 2,
        NotifyNonlinear  = 3,
        NotifyNonlinearVirtual  = 4,
        NotifyUnknown    = 5
    }
}

pub mod crossing_mode {
    #[repr(C)]
    #[deriving(Clone, PartialEq, PartialOrd, Show)]
    pub enum CrossingMode{
        CrossingNormal,
        CrossingGrab,
        CrossingUngrab,
        CrossingGtkGrab,
        CrossingGtkUngrab,
        CrossingStateChanged,
        CrossingTouchBegin,
        CrossingTouchEnd,
        CrossingDeviceSwitch
    }
}

pub mod property_state {
    #[repr(C)]
    #[deriving(Clone, PartialEq, PartialOrd, Show)]
    pub enum PropertyState{
        PropertyNewValue,
        PropertyDelete
    }
}

pub mod window_state {
    #[repr(C)]
    #[deriving(Clone, PartialEq, PartialOrd, Show)]
    pub enum WindowState{
        WindowStateWithdrawn  = 1 << 0,
        WindowStateIconified  = 1 << 1,
        WindowStateMaximized  = 1 << 2,
        WindowStateSticky     = 1 << 3,
        WindowStateFullscreen = 1 << 4,
        WindowStateAbove      = 1 << 5,
        WindowStateBelow      = 1 << 6,
        WindowStateFocused    = 1 << 7,
        WindowStateTiled      = 1 << 8
    }
}

pub mod setting_action {
    #[repr(C)]
    #[deriving(Clone, PartialEq, PartialOrd, Show)]
    pub enum SettingAction{
        SettingActionNew,
        SettingActionChanged,
        SettingActionDeleted
    }
}

pub mod owner_change {
    #[repr(C)]
    #[deriving(Clone, PartialEq, PartialOrd, Show)]
    pub enum OwnerChange{
        OwnerChangeNewOwner,
        OwnerChangeDestroy,
        OwnerChangeClose
    }
}
<|endoftext|>


<commit_before><commit_msg>Comment on binary expression parsing<commit_after><|endoftext|>


<commit_before><commit_msg>permissions and output type fix for status api<commit_after><|endoftext|>


<commit_before><commit_msg>Trivial cleanup<commit_after><|endoftext|>


<commit_before><commit_msg>Impl ty parsing.<commit_after><|endoftext|>


<commit_before><commit_msg>Improve can_trash() check, fix non-linux build<commit_after><|endoftext|>


<commit_before><commit_msg>Missing units.rs<commit_after>#[derive(Eq, PartialEq, Copy, Clone, Debug)]
pub struct RowsCount(pub usize);
#[derive(Eq, PartialEq, Copy, Clone, Debug)]
pub struct ColumnsCount(pub usize);

#[derive(Eq, PartialEq, Copy, Clone, Debug)]
pub struct RowLength(pub usize);
#[derive(Eq, PartialEq, Copy, Clone, Debug)]
pub struct ColumnLength(pub usize);

#[derive(Eq, PartialEq, Copy, Clone, Debug)]
pub struct RowIndex(pub usize);
#[derive(Eq, PartialEq, Copy, Clone, Debug)]
pub struct ColumnIndex(pub usize);

#[derive(Eq, PartialEq, Copy, Clone, Debug)]
pub struct Width(pub usize);
#[derive(Eq, PartialEq, Copy, Clone, Debug)]
pub struct Height(pub usize);
<|endoftext|>


<commit_before>use gtk::widgets;
use rustc_serialize::{Encodable, json};
use std::cell::Cell;
use std::env;
use std::collections::{HashMap, HashSet};
use std::io::{Read, Write};
use std::fs::{self, PathExt};
use std::ops::Deref;
use std::path::{Path, PathBuf};

pub static WINDOW_WIDTH : i32 = 1242;
pub static WINDOW_HEIGHT : i32 = 768;
pub static EDITOR_HEIGHT_PCT : f32 = 0.70;
pub static MIN_FONT_SIZE : i32 = 0;
pub static MAX_FONT_SIZE : i32 = 50;

#[cfg(target_os = "macos")]
pub static META_KEY : u32 = 1 << 28;
#[cfg(not(target_os = "macos"))]
pub static META_KEY : u32 = 1 << 2;

pub static DATA_DIR : &'static str = ".soak";
pub static CONFIG_FILE : &'static str = ".soakrc";
pub static CONFIG_CONTENT : &'static str = include_str!("../resources/soakrc");
pub static PREFS_FILE : &'static str = "prefs.json";
pub static SETTINGS_FILE : &'static str = "settings.json";
pub static NO_WINDOW_FLAG : &'static str = "-nw";

pub struct Resource {
    pub path: &'static [&'static str],
    pub data: &'static str,
    pub always_copy: bool
}
pub static DATA_CONTENT : &'static [Resource] = &[
    Resource{path: &["after", "syntax", "rust.vim"],
             data: include_str!("../resources/soak/after/syntax/rust.vim"),
             always_copy: true},

    Resource{path: &["autoload", "paste.vim"],
             data: include_str!("../resources/soak/autoload/paste.vim"),
             always_copy: false},
    Resource{path: &["autoload", "rust.vim"],
             data: include_str!("../resources/soak/autoload/rust.vim"),
             always_copy: true},

    Resource{path: &["compiler", "rustc.vim"],
             data: include_str!("../resources/soak/compiler/rustc.vim"),
             always_copy: true},
    Resource{path: &["compiler", "cargo.vim"],
             data: include_str!("../resources/soak/compiler/cargo.vim"),
             always_copy: true},

    Resource{path: &["doc", "rust.txt"],
             data: include_str!("../resources/soak/doc/rust.txt"),
             always_copy: true},

    Resource{path: &["ftdetect", "rust.vim"],
             data: include_str!("../resources/soak/ftdetect/rust.vim"),
             always_copy: true},

    Resource{path: &["ftplugin", "rust.vim"],
             data: include_str!("../resources/soak/ftplugin/rust.vim"),
             always_copy: true},
    Resource{path: &["ftplugin", "c.vim"],
             data: include_str!("../resources/soak/ftplugin/c.vim"),
             always_copy: false},

    Resource{path: &["indent", "rust.vim"],
             data: include_str!("../resources/soak/indent/rust.vim"),
             always_copy: true},
    Resource{path: &["indent", "c.vim"],
             data: include_str!("../resources/soak/indent/c.vim"),
             always_copy: false},

    Resource{path: &["plugin", "eunuch.vim"],
             data: include_str!("../resources/soak/plugin/eunuch.vim"),
             always_copy: false},
    Resource{path: &["plugin", "racer.vim"],
             data: include_str!("../resources/soak/plugin/racer.vim"),
             always_copy: true},
    Resource{path: &["plugin", "rust.vim"],
             data: include_str!("../resources/soak/plugin/rust.vim"),
             always_copy: true},

    Resource{path: &["syntax", "c.vim"],
             data: include_str!("../resources/soak/syntax/c.vim"),
             always_copy: false},
    Resource{path: &["syntax", "nosyntax.vim"],
             data: include_str!("../resources/soak/syntax/nosyntax.vim"),
             always_copy: false},
    Resource{path: &["syntax", "rust.vim"],
             data: include_str!("../resources/soak/syntax/rust.vim"),
             always_copy: true},
    Resource{path: &["syntax", "syncolor.vim"],
             data: include_str!("../resources/soak/syntax/syncolor.vim"),
             always_copy: false},
    Resource{path: &["syntax", "synload.vim"],
             data: include_str!("../resources/soak/syntax/synload.vim"),
             always_copy: false},
    Resource{path: &["syntax", "syntax.vim"],
             data: include_str!("../resources/soak/syntax/syntax.vim"),
             always_copy: false},

    Resource{path: &["syntax_checkers", "rust", "rustc.vim"],
             data: include_str!("../resources/soak/syntax_checkers/rust/rustc.vim"),
             always_copy: true},

    Resource{path: &["filetype.vim"],
             data: include_str!("../resources/soak/filetype.vim"),
             always_copy: false}
];

pub struct State<'a> {
    pub projects: HashSet<String>,
    pub expansions: HashSet<String>,
    pub selection: Option<String>,
    pub easy_mode: bool,
    pub font_size: i32,
    pub builders: HashMap<PathBuf, (widgets::VteTerminal, Cell<i32>)>,
    pub window: &'a widgets::Window,
    pub tree_store: &'a widgets::TreeStore,
    pub tree_model: &'a widgets::TreeModel,
    pub tree_selection: &'a widgets::TreeSelection,
    pub rename_button: &'a widgets::Button,
    pub remove_button: &'a widgets::Button,
    pub is_refreshing_tree: bool
}

#[derive(RustcDecodable, RustcEncodable)]
struct Prefs {
    projects: Vec<String>,
    expansions: Vec<String>,
    selection: Option<String>,
    easy_mode: bool,
    font_size: i32
}

#[derive(RustcDecodable, RustcEncodable)]
pub struct KeySettings {
    pub new_project: Option<String>,
    pub import: Option<String>,
    pub rename: Option<String>,
    pub remove: Option<String>,

    pub run: Option<String>,
    pub build: Option<String>,
    pub test: Option<String>,
    pub clean: Option<String>,
    pub stop: Option<String>,

    pub save: Option<String>,
    pub undo: Option<String>,
    pub redo: Option<String>,
    pub font_dec: Option<String>,
    pub font_inc: Option<String>,
    pub close: Option<String>
}

#[derive(RustcDecodable, RustcEncodable)]
pub struct Settings {
    pub keys: KeySettings
}

pub fn get_home_dir() -> PathBuf {
    if let Some(path) = env::home_dir() {
        path
    } else {
        PathBuf::from(".")
    }
}

fn get_prefs(state: &State) -> Prefs {
    Prefs {
        projects: state.projects.clone().into_iter().collect(),
        expansions: state.expansions.clone().into_iter().collect(),
        selection: state.selection.clone(),
        easy_mode: state.easy_mode,
        font_size: state.font_size
    }
}

pub fn is_parent_path(parent_str: &String, child_str: &String) -> bool {
    let parent_ref: &str = parent_str.as_ref();
    child_str.starts_with(parent_ref) &&
    Path::new(parent_str).parent() != Path::new(child_str).parent()
}

pub fn get_selected_path(state: &State) -> Option<String> {
    let mut iter = widgets::TreeIter::new().unwrap();

    if state.tree_selection.get_selected(state.tree_model, &mut iter) {
        state.tree_model.get_value(&iter, 1).get_string()
    } else {
        None
    }
}

fn is_project_path(path: &Path) -> bool {
    path.join("Cargo.toml").exists()
}

fn is_project_root(state: &State, path: &Path) -> bool {
    if let Some(path_str) = path.to_str() {
        state.projects.contains(&path_str.to_string())
    } else {
        false
    }
}

pub fn get_project_path(state: &State, path: &Path) -> Option<PathBuf> {
    if is_project_path(path) || is_project_root(state, path) {
        Some(PathBuf::from(path))
    } else {
        if let Some(parent_path) = path.parent() {
            get_project_path(state, parent_path.deref())
        } else {
            None
        }
    }
}

pub fn get_selected_project_path(state: &State) -> Option<PathBuf> {
    if let Some(path_str) = get_selected_path(state) {
        get_project_path(state, Path::new(&path_str))
    } else {
        None
    }
}

pub fn write_prefs(state: &State) {
    let prefs = get_prefs(state);

    let mut json_str = String::new();
    {
        let mut encoder = json::Encoder::new_pretty(&mut json_str);
        prefs.encode(&mut encoder).ok().expect("Error encoding prefs.");
    }

    let prefs_path = get_home_dir().deref().join(DATA_DIR).join(PREFS_FILE);
    if let Some(mut f) = fs::File::create(&prefs_path).ok() {
        match f.write(json_str.as_bytes()) {
            Ok(_) => {},
            Err(e) => println!("Error writing prefs: {}", e)
        };
    }
}

pub fn read_prefs(state: &mut State) {
    let prefs_path = get_home_dir().deref().join(DATA_DIR).join(PREFS_FILE);
    if let Some(mut f) = fs::File::open(&prefs_path).ok() {
        let mut json_str = String::new();
        let prefs_option : Option<Prefs> = match f.read_to_string(&mut json_str) {
            Ok(_) => {
                match json::decode(json_str.as_ref()) {
                    Ok(object) => Some(object),
                    Err(e) => {
                        println!("Error decoding prefs: {}", e);
                        None
                    }
                }
            },
            Err(_) => None
        };

        if let Some(prefs) = prefs_option {
            state.projects.clear();
            for path_str in prefs.projects.iter() {
                state.projects.insert(path_str.clone());
            }

            state.expansions.clear();
            for path_str in prefs.expansions.iter() {
                state.expansions.insert(path_str.clone());
            }

            state.selection = prefs.selection;
            state.easy_mode = prefs.easy_mode;

            if (prefs.font_size >= MIN_FONT_SIZE) && (prefs.font_size <= MAX_FONT_SIZE) {
                state.font_size = prefs.font_size;
            }
        }
    }
}

fn get_settings() -> Settings {
    Settings {
        keys: ::utils::KeySettings {
            new_project: Some("p".to_string()),
            import: Some("o".to_string()),
            rename: Some("n".to_string()),
            remove: Some("x".to_string()),

            run: Some("a".to_string()),
            build: Some("k".to_string()),
            test: Some("v".to_string()),
            clean: Some("l".to_string()),
            stop: Some("i".to_string()),

            save: Some("s".to_string()),
            undo: Some("z".to_string()),
            redo: Some("r".to_string()),
            font_dec: Some("minus".to_string()),
            font_inc: Some("equal".to_string()),
            close: Some("w".to_string())
        }
    }
}

pub fn write_settings() {
    let settings_path = get_home_dir().deref().join(DATA_DIR).join(SETTINGS_FILE);
    if settings_path.exists() { // don't overwrite existing file, so user can modify it
        return;
    }

    let default_settings = get_settings();

    let mut json_str = String::new();
    {
        let mut encoder = json::Encoder::new_pretty(&mut json_str);
        default_settings.encode(&mut encoder).ok().expect("Error encoding settings.");
    }

    if let Some(mut f) = fs::File::create(&settings_path).ok() {
        match f.write(json_str.as_bytes()) {
            Ok(_) => {},
            Err(e) => println!("Error writing settings: {}", e)
        };
    }
}

pub fn read_settings() -> Settings {
    let default_settings = get_settings();
    let settings_path = get_home_dir().deref().join(DATA_DIR).join(SETTINGS_FILE);

    if let Some(mut f) = fs::File::open(&settings_path).ok() {
        let mut json_str = String::new();
        let settings_opt : Option<Settings> = match f.read_to_string(&mut json_str) {
            Ok(_) => {
                match json::decode(json_str.as_ref()) {
                    Ok(object) => Some(object),
                    Err(e) => {
                        println!("Error decoding settings: {}", e);
                        None
                    }
                }
            },
            Err(_) => None
        };

        if let Some(mut settings) = settings_opt {
            let keys = default_settings.keys;

            if let Some(key) = keys.new_project {
                settings.keys.new_project = Some(settings.keys.new_project.unwrap_or(key));
            }
            if let Some(key) = keys.import {
                settings.keys.import = Some(settings.keys.import.unwrap_or(key));
            }
            if let Some(key) = keys.rename {
                settings.keys.rename = Some(settings.keys.rename.unwrap_or(key));
            }
            if let Some(key) = keys.remove {
                settings.keys.remove = Some(settings.keys.remove.unwrap_or(key));
            }

            if let Some(key) = keys.run {
                settings.keys.run = Some(settings.keys.run.unwrap_or(key));
            }
            if let Some(key) = keys.build {
                settings.keys.build = Some(settings.keys.build.unwrap_or(key));
            }
            if let Some(key) = keys.test {
                settings.keys.test = Some(settings.keys.test.unwrap_or(key));
            }
            if let Some(key) = keys.clean {
                settings.keys.clean = Some(settings.keys.clean.unwrap_or(key));
            }
            if let Some(key) = keys.stop {
                settings.keys.stop = Some(settings.keys.stop.unwrap_or(key))
            }

            if let Some(key) = keys.save {
                settings.keys.save = Some(settings.keys.save.unwrap_or(key));
            }
            if let Some(key) = keys.undo {
                settings.keys.undo = Some(settings.keys.undo.unwrap_or(key));
            }
            if let Some(key) = keys.redo {
                settings.keys.redo = Some(settings.keys.redo.unwrap_or(key));
            }
            if let Some(key) = keys.font_dec {
                settings.keys.font_dec = Some(settings.keys.font_dec.unwrap_or(key));
            }
            if let Some(key) = keys.font_inc {
                settings.keys.font_inc = Some(settings.keys.font_inc.unwrap_or(key));
            }
            if let Some(key) = keys.close {
                settings.keys.close = Some(settings.keys.close.unwrap_or(key));
            }

            return settings;
        }
    }

    default_settings
}
<commit_msg>Change shortcuts again<commit_after>use gtk::widgets;
use rustc_serialize::{Encodable, json};
use std::cell::Cell;
use std::env;
use std::collections::{HashMap, HashSet};
use std::io::{Read, Write};
use std::fs::{self, PathExt};
use std::ops::Deref;
use std::path::{Path, PathBuf};

pub static WINDOW_WIDTH : i32 = 1242;
pub static WINDOW_HEIGHT : i32 = 768;
pub static EDITOR_HEIGHT_PCT : f32 = 0.70;
pub static MIN_FONT_SIZE : i32 = 0;
pub static MAX_FONT_SIZE : i32 = 50;

#[cfg(target_os = "macos")]
pub static META_KEY : u32 = 1 << 28;
#[cfg(not(target_os = "macos"))]
pub static META_KEY : u32 = 1 << 2;

pub static DATA_DIR : &'static str = ".soak";
pub static CONFIG_FILE : &'static str = ".soakrc";
pub static CONFIG_CONTENT : &'static str = include_str!("../resources/soakrc");
pub static PREFS_FILE : &'static str = "prefs.json";
pub static SETTINGS_FILE : &'static str = "settings.json";
pub static NO_WINDOW_FLAG : &'static str = "-nw";

pub struct Resource {
    pub path: &'static [&'static str],
    pub data: &'static str,
    pub always_copy: bool
}
pub static DATA_CONTENT : &'static [Resource] = &[
    Resource{path: &["after", "syntax", "rust.vim"],
             data: include_str!("../resources/soak/after/syntax/rust.vim"),
             always_copy: true},

    Resource{path: &["autoload", "paste.vim"],
             data: include_str!("../resources/soak/autoload/paste.vim"),
             always_copy: false},
    Resource{path: &["autoload", "rust.vim"],
             data: include_str!("../resources/soak/autoload/rust.vim"),
             always_copy: true},

    Resource{path: &["compiler", "rustc.vim"],
             data: include_str!("../resources/soak/compiler/rustc.vim"),
             always_copy: true},
    Resource{path: &["compiler", "cargo.vim"],
             data: include_str!("../resources/soak/compiler/cargo.vim"),
             always_copy: true},

    Resource{path: &["doc", "rust.txt"],
             data: include_str!("../resources/soak/doc/rust.txt"),
             always_copy: true},

    Resource{path: &["ftdetect", "rust.vim"],
             data: include_str!("../resources/soak/ftdetect/rust.vim"),
             always_copy: true},

    Resource{path: &["ftplugin", "rust.vim"],
             data: include_str!("../resources/soak/ftplugin/rust.vim"),
             always_copy: true},
    Resource{path: &["ftplugin", "c.vim"],
             data: include_str!("../resources/soak/ftplugin/c.vim"),
             always_copy: false},

    Resource{path: &["indent", "rust.vim"],
             data: include_str!("../resources/soak/indent/rust.vim"),
             always_copy: true},
    Resource{path: &["indent", "c.vim"],
             data: include_str!("../resources/soak/indent/c.vim"),
             always_copy: false},

    Resource{path: &["plugin", "eunuch.vim"],
             data: include_str!("../resources/soak/plugin/eunuch.vim"),
             always_copy: false},
    Resource{path: &["plugin", "racer.vim"],
             data: include_str!("../resources/soak/plugin/racer.vim"),
             always_copy: true},
    Resource{path: &["plugin", "rust.vim"],
             data: include_str!("../resources/soak/plugin/rust.vim"),
             always_copy: true},

    Resource{path: &["syntax", "c.vim"],
             data: include_str!("../resources/soak/syntax/c.vim"),
             always_copy: false},
    Resource{path: &["syntax", "nosyntax.vim"],
             data: include_str!("../resources/soak/syntax/nosyntax.vim"),
             always_copy: false},
    Resource{path: &["syntax", "rust.vim"],
             data: include_str!("../resources/soak/syntax/rust.vim"),
             always_copy: true},
    Resource{path: &["syntax", "syncolor.vim"],
             data: include_str!("../resources/soak/syntax/syncolor.vim"),
             always_copy: false},
    Resource{path: &["syntax", "synload.vim"],
             data: include_str!("../resources/soak/syntax/synload.vim"),
             always_copy: false},
    Resource{path: &["syntax", "syntax.vim"],
             data: include_str!("../resources/soak/syntax/syntax.vim"),
             always_copy: false},

    Resource{path: &["syntax_checkers", "rust", "rustc.vim"],
             data: include_str!("../resources/soak/syntax_checkers/rust/rustc.vim"),
             always_copy: true},

    Resource{path: &["filetype.vim"],
             data: include_str!("../resources/soak/filetype.vim"),
             always_copy: false}
];

pub struct State<'a> {
    pub projects: HashSet<String>,
    pub expansions: HashSet<String>,
    pub selection: Option<String>,
    pub easy_mode: bool,
    pub font_size: i32,
    pub builders: HashMap<PathBuf, (widgets::VteTerminal, Cell<i32>)>,
    pub window: &'a widgets::Window,
    pub tree_store: &'a widgets::TreeStore,
    pub tree_model: &'a widgets::TreeModel,
    pub tree_selection: &'a widgets::TreeSelection,
    pub rename_button: &'a widgets::Button,
    pub remove_button: &'a widgets::Button,
    pub is_refreshing_tree: bool
}

#[derive(RustcDecodable, RustcEncodable)]
struct Prefs {
    projects: Vec<String>,
    expansions: Vec<String>,
    selection: Option<String>,
    easy_mode: bool,
    font_size: i32
}

#[derive(RustcDecodable, RustcEncodable)]
pub struct KeySettings {
    pub new_project: Option<String>,
    pub import: Option<String>,
    pub rename: Option<String>,
    pub remove: Option<String>,

    pub run: Option<String>,
    pub build: Option<String>,
    pub test: Option<String>,
    pub clean: Option<String>,
    pub stop: Option<String>,

    pub save: Option<String>,
    pub undo: Option<String>,
    pub redo: Option<String>,
    pub font_dec: Option<String>,
    pub font_inc: Option<String>,
    pub close: Option<String>
}

#[derive(RustcDecodable, RustcEncodable)]
pub struct Settings {
    pub keys: KeySettings
}

pub fn get_home_dir() -> PathBuf {
    if let Some(path) = env::home_dir() {
        path
    } else {
        PathBuf::from(".")
    }
}

fn get_prefs(state: &State) -> Prefs {
    Prefs {
        projects: state.projects.clone().into_iter().collect(),
        expansions: state.expansions.clone().into_iter().collect(),
        selection: state.selection.clone(),
        easy_mode: state.easy_mode,
        font_size: state.font_size
    }
}

pub fn is_parent_path(parent_str: &String, child_str: &String) -> bool {
    let parent_ref: &str = parent_str.as_ref();
    child_str.starts_with(parent_ref) &&
    Path::new(parent_str).parent() != Path::new(child_str).parent()
}

pub fn get_selected_path(state: &State) -> Option<String> {
    let mut iter = widgets::TreeIter::new().unwrap();

    if state.tree_selection.get_selected(state.tree_model, &mut iter) {
        state.tree_model.get_value(&iter, 1).get_string()
    } else {
        None
    }
}

fn is_project_path(path: &Path) -> bool {
    path.join("Cargo.toml").exists()
}

fn is_project_root(state: &State, path: &Path) -> bool {
    if let Some(path_str) = path.to_str() {
        state.projects.contains(&path_str.to_string())
    } else {
        false
    }
}

pub fn get_project_path(state: &State, path: &Path) -> Option<PathBuf> {
    if is_project_path(path) || is_project_root(state, path) {
        Some(PathBuf::from(path))
    } else {
        if let Some(parent_path) = path.parent() {
            get_project_path(state, parent_path.deref())
        } else {
            None
        }
    }
}

pub fn get_selected_project_path(state: &State) -> Option<PathBuf> {
    if let Some(path_str) = get_selected_path(state) {
        get_project_path(state, Path::new(&path_str))
    } else {
        None
    }
}

pub fn write_prefs(state: &State) {
    let prefs = get_prefs(state);

    let mut json_str = String::new();
    {
        let mut encoder = json::Encoder::new_pretty(&mut json_str);
        prefs.encode(&mut encoder).ok().expect("Error encoding prefs.");
    }

    let prefs_path = get_home_dir().deref().join(DATA_DIR).join(PREFS_FILE);
    if let Some(mut f) = fs::File::create(&prefs_path).ok() {
        match f.write(json_str.as_bytes()) {
            Ok(_) => {},
            Err(e) => println!("Error writing prefs: {}", e)
        };
    }
}

pub fn read_prefs(state: &mut State) {
    let prefs_path = get_home_dir().deref().join(DATA_DIR).join(PREFS_FILE);
    if let Some(mut f) = fs::File::open(&prefs_path).ok() {
        let mut json_str = String::new();
        let prefs_option : Option<Prefs> = match f.read_to_string(&mut json_str) {
            Ok(_) => {
                match json::decode(json_str.as_ref()) {
                    Ok(object) => Some(object),
                    Err(e) => {
                        println!("Error decoding prefs: {}", e);
                        None
                    }
                }
            },
            Err(_) => None
        };

        if let Some(prefs) = prefs_option {
            state.projects.clear();
            for path_str in prefs.projects.iter() {
                state.projects.insert(path_str.clone());
            }

            state.expansions.clear();
            for path_str in prefs.expansions.iter() {
                state.expansions.insert(path_str.clone());
            }

            state.selection = prefs.selection;
            state.easy_mode = prefs.easy_mode;

            if (prefs.font_size >= MIN_FONT_SIZE) && (prefs.font_size <= MAX_FONT_SIZE) {
                state.font_size = prefs.font_size;
            }
        }
    }
}

fn get_settings() -> Settings {
    Settings {
        keys: ::utils::KeySettings {
            new_project: Some("p".to_string()),
            import: Some("o".to_string()),
            rename: Some("n".to_string()),
            remove: Some("x".to_string()),

            run: Some("n".to_string()),
            build: Some("k".to_string()),
            test: Some("t".to_string()),
            clean: Some("l".to_string()),
            stop: Some("i".to_string()),

            save: Some("s".to_string()),
            undo: Some("z".to_string()),
            redo: Some("r".to_string()),
            font_dec: Some("minus".to_string()),
            font_inc: Some("equal".to_string()),
            close: Some("w".to_string())
        }
    }
}

pub fn write_settings() {
    let settings_path = get_home_dir().deref().join(DATA_DIR).join(SETTINGS_FILE);
    if settings_path.exists() { // don't overwrite existing file, so user can modify it
        return;
    }

    let default_settings = get_settings();

    let mut json_str = String::new();
    {
        let mut encoder = json::Encoder::new_pretty(&mut json_str);
        default_settings.encode(&mut encoder).ok().expect("Error encoding settings.");
    }

    if let Some(mut f) = fs::File::create(&settings_path).ok() {
        match f.write(json_str.as_bytes()) {
            Ok(_) => {},
            Err(e) => println!("Error writing settings: {}", e)
        };
    }
}

pub fn read_settings() -> Settings {
    let default_settings = get_settings();
    let settings_path = get_home_dir().deref().join(DATA_DIR).join(SETTINGS_FILE);

    if let Some(mut f) = fs::File::open(&settings_path).ok() {
        let mut json_str = String::new();
        let settings_opt : Option<Settings> = match f.read_to_string(&mut json_str) {
            Ok(_) => {
                match json::decode(json_str.as_ref()) {
                    Ok(object) => Some(object),
                    Err(e) => {
                        println!("Error decoding settings: {}", e);
                        None
                    }
                }
            },
            Err(_) => None
        };

        if let Some(mut settings) = settings_opt {
            let keys = default_settings.keys;

            if let Some(key) = keys.new_project {
                settings.keys.new_project = Some(settings.keys.new_project.unwrap_or(key));
            }
            if let Some(key) = keys.import {
                settings.keys.import = Some(settings.keys.import.unwrap_or(key));
            }
            if let Some(key) = keys.rename {
                settings.keys.rename = Some(settings.keys.rename.unwrap_or(key));
            }
            if let Some(key) = keys.remove {
                settings.keys.remove = Some(settings.keys.remove.unwrap_or(key));
            }

            if let Some(key) = keys.run {
                settings.keys.run = Some(settings.keys.run.unwrap_or(key));
            }
            if let Some(key) = keys.build {
                settings.keys.build = Some(settings.keys.build.unwrap_or(key));
            }
            if let Some(key) = keys.test {
                settings.keys.test = Some(settings.keys.test.unwrap_or(key));
            }
            if let Some(key) = keys.clean {
                settings.keys.clean = Some(settings.keys.clean.unwrap_or(key));
            }
            if let Some(key) = keys.stop {
                settings.keys.stop = Some(settings.keys.stop.unwrap_or(key))
            }

            if let Some(key) = keys.save {
                settings.keys.save = Some(settings.keys.save.unwrap_or(key));
            }
            if let Some(key) = keys.undo {
                settings.keys.undo = Some(settings.keys.undo.unwrap_or(key));
            }
            if let Some(key) = keys.redo {
                settings.keys.redo = Some(settings.keys.redo.unwrap_or(key));
            }
            if let Some(key) = keys.font_dec {
                settings.keys.font_dec = Some(settings.keys.font_dec.unwrap_or(key));
            }
            if let Some(key) = keys.font_inc {
                settings.keys.font_inc = Some(settings.keys.font_inc.unwrap_or(key));
            }
            if let Some(key) = keys.close {
                settings.keys.close = Some(settings.keys.close.unwrap_or(key));
            }

            return settings;
        }
    }

    default_settings
}
<|endoftext|>