<commit_before>#![feature(test)]
extern crate test;

extern crate bincode;
extern crate rustc_serialize;
#[macro_use]
extern crate log;

use std::collections::HashMap;
use std::thread;
use std::fs;
use std::fs::File;
use std::io::prelude::*;

use bincode::SizeLimit;
use bincode::rustc_serialize::{encode, decode};

use rustc_serialize::{ Encodable, Decodable };

#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
pub enum Value {
    String(String),
    Int(i32),
    Float(f32),
    Map(HashMap<String, Value>),
}

pub struct KV<V> {
    cab: HashMap<String, V>,
    path: &'static str,
}

impl<V: Clone + Encodable + Decodable> KV<V> {
    /// create a new instance of the KV store
    pub fn new(p:&'static str) -> KV<V> {
        let mut store = KV {
            cab: HashMap::new(),
            path: p,
        };

        match store.load_from_persist() {
            Ok(f) => trace!("{}", f),
            Err(e) => {
                warn!("{}", e);
                let _ = File::create(p);
            },
        };

        KV::<V>::lock_cab(p, true);

        store
    }

    /// insert a key, value pair into the KV Store
    pub fn insert(&mut self, key: String, value: V) -> Result<bool, &str> {
        // make sure mem version up to date
        let _ = self.load_from_persist();
        // insert into the HashMap
        self.cab.insert(key, value);
        // persist
        self.write_to_persist()
    }

    /// get a value from a key
    pub fn get(&mut self, key: String) -> Option<V> {
        // make sure mem version up to date
        let _ = self.load_from_persist();
        // get the value from the cab
        match self.cab.get(&key) {
            Some(v) => Some((*v).clone()),
            None => None
        }
    }

    /// remove a key and associated value from the KV Store
    pub fn remove(&mut self, key: String) -> Result<bool, &str> {
        // make sure mem version up to date
        let _ = self.load_from_persist();
        // remove from the HashMap
        self.cab.remove(&key);
        // persist
        self.write_to_persist()
    }

    /// get all the keys contained in the KV Store
    pub fn keys(&mut self) -> Vec<String> {
        // make sure mem version up to date
        let _ = self.load_from_persist();
        // create a vec from the cabs keys
        self.cab.keys().map(|k| k.clone()).collect()
    }

    /// Locks/unlocks cab for writing purposes
    fn lock_cab(path:&'static str, lock:bool) {
        // set not readonly while writing
        let mut perms = fs::metadata(path).unwrap().permissions();
        perms.set_readonly(lock);
        fs::set_permissions(path, perms).unwrap();
    }

    /// Write the KV Store to file
    fn write_to_persist(&mut self) -> Result<bool, &str> {
        if !self.wait_for_free().is_ok() {
            return Err("File doesn't exist or is not readeable");
        }

        let path = self.path.clone();
        KV::<V>::lock_cab(path, false);

        // encode the cab as a u8 vec
        let byte_vec: Vec<u8> = match encode(&mut self.cab, SizeLimit::Infinite) {
            Ok(bv) => bv,
            Err(e) => {
                warn!("{}", e);
                return Err("Could not encode cab");
            },
        };

        let _ = thread::spawn(move || {
            // create the file
            let mut f = File::create(path).unwrap();
            // write the bytes to it
            f.write_all(byte_vec.as_slice()).unwrap();
            let _ = f.flush();

            KV::<V>::lock_cab(path, true);
        });

        Ok(true)
    }

    /// Wait for the cab to become free
    fn wait_for_free(&self) -> Result<bool, &str> {
        loop {
            // check if the cab is being written to
            let metadata = match fs::metadata(self.path) {
                Ok(m) => m,
                Err(_) => return Err("File doesn't exist or is not readeable"),
            };

            if metadata.permissions().readonly() {
                break;
            }
        }

        Ok(true)
    }

    /// Load from file
    fn load_from_persist(&mut self) -> Result<bool, &str> {
        if !self.wait_for_free().is_ok() {
            return Err("File doesn't exist or is not readeable");
        }

        // open the cab
        let mut f = File::open(self.path).unwrap();

        let mut byte_vec = Vec::new();
        let _ = f.read_to_end(&mut byte_vec);

        // decode u8 vec back into HashMap
        let decoded: HashMap<String, V> = match decode(byte_vec.as_slice()) {
            Ok(f) => f,
            Err(e) => {
                warn!("{}", e);
                return Err("Couldn't decode cab");
            },
        };
        self.cab = decoded;

        Ok(true)
    }
}

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

    macro_rules! bench_teardown {
        ( $p:ident ) => {
            use std::{thread, time};

            thread::sleep(time::Duration::from_secs(2));
            let _ = std::fs::remove_file($p);
        }
    }

    #[bench]
    fn bench_get_int(b: &mut Bencher) {
        let test_cab_path = "./bench_get_many.cab";
        let mut test_store = KV::<Value>::new(test_cab_path);

        let _ = test_store.insert("test".to_string(), Value::Int(1));

        b.iter(|| {
            test_store.get("test".to_string());
        });

        bench_teardown!(test_cab_path);
    }

    #[bench]
    fn bench_insert_int(b: &mut Bencher) {
        let test_cab_path = "./bench_insert_many.cab";
        let mut test_store = KV::<Value>::new(test_cab_path);

        b.iter(|| {
            let _ = test_store.insert("test".to_string(), Value::Int(1));
        });

        bench_teardown!(test_cab_path);
    }
}
<commit_msg>locking happens after wait<commit_after>#![feature(test)]
extern crate test;

extern crate bincode;
extern crate rustc_serialize;
#[macro_use]
extern crate log;

use std::collections::HashMap;
use std::thread;
use std::fs;
use std::fs::File;
use std::io::prelude::*;

use bincode::SizeLimit;
use bincode::rustc_serialize::{encode, decode};

use rustc_serialize::{ Encodable, Decodable };

#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
pub enum Value {
    String(String),
    Int(i32),
    Float(f32),
    Map(HashMap<String, Value>),
}

pub struct KV<V> {
    cab: HashMap<String, V>,
    path: &'static str,
}

impl<V: Clone + Encodable + Decodable> KV<V> {
    /// create a new instance of the KV store
    pub fn new(p:&'static str) -> KV<V> {
        let mut store = KV {
            cab: HashMap::new(),
            path: p,
        };

        match store.load_from_persist() {
            Ok(f) => trace!("{}", f),
            Err(e) => {
                warn!("{}", e);
                let _ = File::create(p);
            },
        };

        KV::<V>::lock_cab(p, true);

        store
    }

    /// insert a key, value pair into the KV Store
    pub fn insert(&mut self, key: String, value: V) -> Result<bool, &str> {
        // make sure mem version up to date
        let _ = self.load_from_persist();
        // insert into the HashMap
        self.cab.insert(key, value);
        // persist
        self.write_to_persist()
    }

    /// get a value from a key
    pub fn get(&mut self, key: String) -> Option<V> {
        // make sure mem version up to date
        let _ = self.load_from_persist();
        // get the value from the cab
        match self.cab.get(&key) {
            Some(v) => Some((*v).clone()),
            None => None
        }
    }

    /// remove a key and associated value from the KV Store
    pub fn remove(&mut self, key: String) -> Result<bool, &str> {
        // make sure mem version up to date
        let _ = self.load_from_persist();
        // remove from the HashMap
        self.cab.remove(&key);
        // persist
        self.write_to_persist()
    }

    /// get all the keys contained in the KV Store
    pub fn keys(&mut self) -> Vec<String> {
        // make sure mem version up to date
        let _ = self.load_from_persist();
        // create a vec from the cabs keys
        self.cab.keys().map(|k| k.clone()).collect()
    }

    /// Locks/unlocks cab for writing purposes
    fn lock_cab(path:&'static str, lock:bool) {
        // set not readonly while writing
        let mut perms = fs::metadata(path).unwrap().permissions();
        perms.set_readonly(lock);
        fs::set_permissions(path, perms).unwrap();
    }

    /// Write the KV Store to file
    fn write_to_persist(&mut self) -> Result<bool, &str> {
        if !self.wait_for_free().is_ok() {
            return Err("File doesn't exist or is not readeable");
        }
        KV::<V>::lock_cab(self.path, false);

        // encode the cab as a u8 vec
        let byte_vec: Vec<u8> = match encode(&mut self.cab, SizeLimit::Infinite) {
            Ok(bv) => bv,
            Err(e) => {
                warn!("{}", e);
                return Err("Could not encode cab");
            },
        };

        let path = self.path.clone();
        let _ = thread::spawn(move || {
            // create the file
            let mut f = File::create(path).unwrap();
            // write the bytes to it
            f.write_all(byte_vec.as_slice()).unwrap();
            let _ = f.flush();

            KV::<V>::lock_cab(path, true);
        });

        Ok(true)
    }

    /// Wait for the cab to become free
    fn wait_for_free(&self) -> Result<bool, &str> {
        loop {
            // check if the cab is being written to
            let metadata = match fs::metadata(self.path) {
                Ok(m) => m,
                Err(_) => return Err("File doesn't exist or is not readeable"),
            };

            if metadata.permissions().readonly() {
                break;
            }
        }

        Ok(true)
    }

    /// Load from file
    fn load_from_persist(&mut self) -> Result<bool, &str> {
        if !self.wait_for_free().is_ok() {
            return Err("File doesn't exist or is not readeable");
        }

        // open the cab
        let mut f = File::open(self.path).unwrap();

        let mut byte_vec = Vec::new();
        let _ = f.read_to_end(&mut byte_vec);

        // decode u8 vec back into HashMap
        let decoded: HashMap<String, V> = match decode(byte_vec.as_slice()) {
            Ok(f) => f,
            Err(e) => {
                warn!("{}", e);
                return Err("Couldn't decode cab");
            },
        };
        self.cab = decoded;

        Ok(true)
    }
}

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

    macro_rules! bench_teardown {
        ( $p:ident ) => {
            use std::{thread, time};

            thread::sleep(time::Duration::from_secs(2));
            let _ = std::fs::remove_file($p);
        }
    }

    #[bench]
    fn bench_get_int(b: &mut Bencher) {
        let test_cab_path = "./bench_get_many.cab";
        let mut test_store = KV::<Value>::new(test_cab_path);

        let _ = test_store.insert("test".to_string(), Value::Int(1));

        b.iter(|| {
            test_store.get("test".to_string());
        });

        bench_teardown!(test_cab_path);
    }

    #[bench]
    fn bench_insert_int(b: &mut Bencher) {
        let test_cab_path = "./bench_insert_many.cab";
        let mut test_store = KV::<Value>::new(test_cab_path);

        b.iter(|| {
            let _ = test_store.insert("test".to_string(), Value::Int(1));
        });

        bench_teardown!(test_cab_path);
    }
}
<|endoftext|>


<commit_before>
#![crate_name = "sprite"]
#![deny(missing_docs)]
#![deny(missing_copy_implementations)]
#![warn(dead_code)]
#![feature(box_syntax, core)]

//! A library for sprite hierarchy and scene management

extern crate quack;
extern crate uuid;
extern crate ai_behavior;
extern crate event;
extern crate graphics;
extern crate interpolation;

pub use animation::{
    Animation,
    AnimationState,

    MoveTo,
    MoveBy,
    RotateTo,
    RotateBy,
    ScaleTo,
    ScaleBy,

    FlipX,
    FlipY,

    Show,
    Hide,
    ToggleVisibility,
    Blink,
    FadeIn,
    FadeOut,
    FadeTo,

    Ease,
};
pub use scene::Scene;
pub use sprite::Sprite;
pub use interpolation::EaseFunction;

mod animation;
mod scene;
mod sprite;
<commit_msg>Fix rust features<commit_after>#![crate_name = "sprite"]
#![deny(missing_docs)]
#![deny(missing_copy_implementations)]
#![warn(dead_code)]
#![feature(box_syntax, box_patterns, std_misc)]

//! A library for sprite hierarchy and scene management

extern crate quack;
extern crate uuid;
extern crate ai_behavior;
extern crate event;
extern crate graphics;
extern crate interpolation;

pub use animation::{
    Animation,
    AnimationState,

    MoveTo,
    MoveBy,
    RotateTo,
    RotateBy,
    ScaleTo,
    ScaleBy,

    FlipX,
    FlipY,

    Show,
    Hide,
    ToggleVisibility,
    Blink,
    FadeIn,
    FadeOut,
    FadeTo,

    Ease,
};
pub use scene::Scene;
pub use sprite::Sprite;
pub use interpolation::EaseFunction;

mod animation;
mod scene;
mod sprite;
<|endoftext|>


<commit_before>#![crate_name = "cam"]
#![deny(missing_docs)]
#![allow(unstable)]

//! A library for 3D camera and navigation.

#[macro_use] extern crate rustc_bitflags;
extern crate event;
extern crate input;
extern crate vecmath;

pub use camera::{
    Camera,
    CameraPerspective,
    model_view_projection,
};
pub use first_person::{
    FirstPerson,
    FirstPersonSettings,
};

mod camera;
mod first_person;

<commit_msg>Fixed bitflags<commit_after>#![crate_name = "cam"]
#![deny(missing_docs)]
#![allow(unstable)]

//! A library for 3D camera and navigation.

#[macro_use]
extern crate bitflags;
extern crate event;
extern crate input;
extern crate vecmath;

pub use camera::{
    Camera,
    CameraPerspective,
    model_view_projection,
};
pub use first_person::{
    FirstPerson,
    FirstPersonSettings,
};

mod camera;
mod first_person;

<|endoftext|>


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

#![crate_name = "js"]
#![crate_type = "rlib"]

#![feature(core_intrinsics)]
#![feature(link_args)]
#![feature(str_utf16)]
#![feature(unsafe_no_drop_flag)]

#![allow(non_upper_case_globals, non_camel_case_types, non_snake_case, improper_ctypes, raw_pointer_derive)]

extern crate libc;
#[macro_use]
extern crate log;
#[macro_use]
extern crate heapsize;
extern crate rustc_serialize as serialize;

pub mod jsapi;
pub mod linkhack;
pub mod rust;
pub mod glue;
pub mod jsval;

use jsapi::{JSContext, JSProtoKey, Heap};
use jsval::JSVal;
use rust::GCMethods;

use libc::c_uint;

use heapsize::HeapSizeOf;

pub const default_heapsize: u32 = 32_u32 * 1024_u32 * 1024_u32;
pub const default_stacksize: usize = 8192;

pub const JSID_TYPE_STRING: i64 = 0;
pub const JSID_TYPE_INT: i64 = 1;
pub const JSID_TYPE_VOID: i64 = 2;
pub const JSID_TYPE_OBJECT: i64 = 4;
pub const JSID_TYPE_DEFAULT_XML_NAMESPACE: i64 = 6;
pub const JSID_TYPE_MASK: i64 = 7;

pub const JSFUN_CONSTRUCTOR: u32 = 0x400; /* native that can be called as a ctor */

pub const JSPROP_ENUMERATE: c_uint = 0x01;
pub const JSPROP_READONLY: c_uint  = 0x02;
pub const JSPROP_PERMANENT: c_uint = 0x04;
pub const JSPROP_GETTER: c_uint = 0x10;
pub const JSPROP_SETTER: c_uint = 0x20;
pub const JSPROP_SHARED: c_uint =    0x40;
pub const JSPROP_NATIVE_ACCESSORS: c_uint = 0x08;

pub const JSCLASS_RESERVED_SLOTS_SHIFT: c_uint = 8;
pub const JSCLASS_RESERVED_SLOTS_WIDTH: c_uint = 8;
pub const JSCLASS_RESERVED_SLOTS_MASK: c_uint = ((1 << JSCLASS_RESERVED_SLOTS_WIDTH) - 1) as c_uint;

pub const JSCLASS_HIGH_FLAGS_SHIFT: c_uint =
    JSCLASS_RESERVED_SLOTS_SHIFT + JSCLASS_RESERVED_SLOTS_WIDTH;
pub const JSCLASS_IS_GLOBAL: c_uint = 1 << (JSCLASS_HIGH_FLAGS_SHIFT + 1);
pub const JSCLASS_GLOBAL_APPLICATION_SLOTS: c_uint = 4;
pub const JSCLASS_GLOBAL_SLOT_COUNT: c_uint = JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProtoKey::JSProto_LIMIT as u32 * 3 + 31;

pub const JSCLASS_IS_DOMJSCLASS: u32 = 1 << 4;
pub const JSCLASS_IMPLEMENTS_BARRIERS: u32 = 1 << 5;
pub const JSCLASS_USERBIT1: u32 = 1 << 7;

pub const JSCLASS_IS_PROXY: u32 = 1 << (JSCLASS_HIGH_FLAGS_SHIFT+4);

pub const JSSLOT_PROXY_PRIVATE: u32 = 1;

pub const JS_DEFAULT_ZEAL_FREQ: u32 = 100;

pub const JSTrue: u8 = 1;
pub const JSFalse: u8 = 0;

#[link(name = "jsglue")]
extern { }

#[cfg(target_os = "android")]
#[link(name = "stdc++")]
extern { }

#[cfg(target_os = "android")]
#[link(name = "gcc")]
extern { }

#[inline(always)]
pub unsafe fn JS_ARGV(_cx: *mut JSContext, vp: *mut JSVal) -> *mut JSVal {
    vp.offset(2)
}

#[inline(always)]
pub unsafe fn JS_CALLEE(_cx: *mut JSContext, vp: *mut JSVal) -> JSVal {
    *vp
}

// This is measured properly by the heap measurement implemented in SpiderMonkey.
impl<T: Copy + GCMethods<T>> HeapSizeOf for Heap<T> {
    fn heap_size_of_children(&self) -> usize {
        0
    }
}
known_heap_size!(0, JSVal);

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

#![crate_name = "js"]
#![crate_type = "rlib"]

#![feature(core_intrinsics)]
#![feature(link_args)]
#![feature(str_utf16)]
#![feature(unsafe_no_drop_flag)]

#![allow(non_upper_case_globals, non_camel_case_types, non_snake_case, improper_ctypes, raw_pointer_derive)]

extern crate libc;
#[macro_use]
extern crate log;
#[macro_use]
extern crate heapsize;
extern crate rustc_serialize as serialize;

pub mod jsapi;
pub mod linkhack;
pub mod rust;
pub mod glue;
pub mod jsval;

use jsapi::{JSContext, JSProtoKey, Heap};
use jsval::JSVal;
use rust::GCMethods;

use libc::c_uint;

use heapsize::HeapSizeOf;

pub const default_heapsize: u32 = 32_u32 * 1024_u32 * 1024_u32;
pub const default_stacksize: usize = 8192;

pub const JSID_TYPE_STRING: i64 = 0;
pub const JSID_TYPE_INT: i64 = 1;
pub const JSID_TYPE_VOID: i64 = 2;
pub const JSID_TYPE_OBJECT: i64 = 4;
pub const JSID_TYPE_DEFAULT_XML_NAMESPACE: i64 = 6;
pub const JSID_TYPE_MASK: i64 = 7;

pub const JSFUN_CONSTRUCTOR: u32 = 0x400; /* native that can be called as a ctor */

pub const JSPROP_ENUMERATE: c_uint = 0x01;
pub const JSPROP_READONLY: c_uint  = 0x02;
pub const JSPROP_PERMANENT: c_uint = 0x04;
pub const JSPROP_GETTER: c_uint = 0x10;
pub const JSPROP_SETTER: c_uint = 0x20;
pub const JSPROP_SHARED: c_uint =    0x40;
pub const JSPROP_NATIVE_ACCESSORS: c_uint = 0x08;

pub const JSCLASS_RESERVED_SLOTS_SHIFT: c_uint = 8;
pub const JSCLASS_RESERVED_SLOTS_WIDTH: c_uint = 8;
pub const JSCLASS_RESERVED_SLOTS_MASK: c_uint = ((1 << JSCLASS_RESERVED_SLOTS_WIDTH) - 1) as c_uint;

pub const JSCLASS_HIGH_FLAGS_SHIFT: c_uint =
    JSCLASS_RESERVED_SLOTS_SHIFT + JSCLASS_RESERVED_SLOTS_WIDTH;
pub const JSCLASS_IS_GLOBAL: c_uint = 1 << (JSCLASS_HIGH_FLAGS_SHIFT + 1);
pub const JSCLASS_GLOBAL_APPLICATION_SLOTS: c_uint = 4;
pub const JSCLASS_GLOBAL_SLOT_COUNT: c_uint = JSCLASS_GLOBAL_APPLICATION_SLOTS + JSProtoKey::JSProto_LIMIT as u32 * 3 + 31;

pub const JSCLASS_IS_DOMJSCLASS: u32 = 1 << 4;
pub const JSCLASS_IMPLEMENTS_BARRIERS: u32 = 1 << 5;
pub const JSCLASS_USERBIT1: u32 = 1 << 7;

pub const JSCLASS_IS_PROXY: u32 = 1 << (JSCLASS_HIGH_FLAGS_SHIFT+4);

pub const JSSLOT_PROXY_PRIVATE: u32 = 1;

pub const JS_DEFAULT_ZEAL_FREQ: u32 = 100;

pub const JSTrue: u8 = 1;
pub const JSFalse: u8 = 0;

pub const JSITER_ENUMERATE: c_uint   = 0x1;
pub const JSITER_FOREACH: c_uint     = 0x2;
pub const JSITER_KEYVALUE: c_uint    = 0x4;
pub const JSITER_OWNONLY: c_uint     = 0x8;
pub const JSITER_HIDDEN: c_uint      = 0x10;
pub const JSITER_SYMBOLS: c_uint     = 0x20;
pub const JSITER_SYMBOLSONLY: c_uint = 0x40;

#[link(name = "jsglue")]
extern { }

#[cfg(target_os = "android")]
#[link(name = "stdc++")]
extern { }

#[cfg(target_os = "android")]
#[link(name = "gcc")]
extern { }

#[inline(always)]
pub unsafe fn JS_ARGV(_cx: *mut JSContext, vp: *mut JSVal) -> *mut JSVal {
    vp.offset(2)
}

#[inline(always)]
pub unsafe fn JS_CALLEE(_cx: *mut JSContext, vp: *mut JSVal) -> JSVal {
    *vp
}

// This is measured properly by the heap measurement implemented in SpiderMonkey.
impl<T: Copy + GCMethods<T>> HeapSizeOf for Heap<T> {
    fn heap_size_of_children(&self) -> usize {
        0
    }
}
known_heap_size!(0, JSVal);

<|endoftext|>


<commit_before>#[macro_use]
extern crate log;

mod acquire;
mod analog;
mod burst;
mod data;
mod digital;
mod generator;
mod socket;
mod trigger;

pub struct Redpitaya {
    pub acquire: acquire::Acquire,
    pub analog: analog::Analog,
    pub burst: burst::Burst,
    pub digital: digital::Digital,
    pub generator: generator::Generator,
    pub trigger: trigger::Trigger,
    pub data: data::Data,
}

impl Redpitaya {
    pub fn new(addr: ::std::net::SocketAddr) -> Redpitaya {
        let socket = socket::Socket::new(addr);

        Redpitaya {
            acquire: acquire::Acquire::new(socket.clone()),
            analog: analog::Analog::new(socket.clone()),
            burst: burst::Burst::new(socket.clone()),
            digital: digital::Digital::new(socket.clone()),
            generator: generator::Generator::new(socket.clone()),
            trigger: trigger::Trigger::new(socket.clone()),
            data: data::Data::new(socket.clone()),
        }
    }
}

#[cfg(test)]
mod test {
    use ::std::io::Read;
    use ::std::io::Write;

    pub fn launch_server() -> (::std::net:: SocketAddr, ::std::sync::mpsc::Receiver<String>) {
        let addr = next_test_ip4();
        let listener = ::std::net::TcpListener::bind(format!("{}", addr))
            .unwrap();

        let (tx, rx) = ::std::sync::mpsc::channel();

        ::std::thread::spawn(move || {
            loop {
                if let Ok((mut stream, _)) =  listener.accept() {
                    let tx = tx.clone();

                    ::std::thread::spawn(move || {
                        let mut message = String::new();

                        loop {
                            let mut buffer = [0; 1];

                            stream.read(&mut buffer[..])
                                .unwrap();
                            message.push(buffer[0] as char);

                            if buffer[0] == ('\n' as u8) {
                                break;
                            }
                        }

                        match message.as_str() {
                            "ACQ:DEC?\r\n" => {
                                stream.write("1\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:AVG?\r\n" => {
                                stream.write("ON\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:WPOS?\r\n" => {
                                stream.write("1024\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:TPOS?\r\n" => {
                                stream.write("512\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:SOUR1:DATA:STA:END? 10,13\r\n" => {
                                stream.write("{123,231,-231}\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:SOUR1:DATA:STA:N? 10,3\r\n" => {
                                stream.write("{1.2,3.2,-1.2}\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:SOUR1:DATA?\r\n" => {
                                stream.write("{1.2,3.2,-1.2}\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:SOUR1:DATA:OLD:N? 2\r\n" => {
                                stream.write("{3.2,-1.2}\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:SOUR1:DATA:LAT:N? 2\r\n" => {
                                stream.write("{1.2,3.2}\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:BUF:SIZE?\r\n" => {
                                stream.write("16384\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:TRIG:STAT?\r\n" => {
                                stream.write("WAIT\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:TRIG:DLY?\r\n" => {
                                stream.write("2314\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:TRIG:DLY:NS?\r\n" => {
                                stream.write("128ns\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:TRIG:LEV?\r\n" => {
                                stream.write("123mV\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ANALOG:PIN? AIN1\r\n" => {
                                stream.write("1.34\r\n".as_bytes())
                                    .unwrap();
                            },
                            "DIG:PIN? DIO0_N\r\n" => {
                                stream.write("1\r\n".as_bytes())
                                    .unwrap();
                            },
                            _ => tx.send(message).unwrap(),
                        };
                    });
                }
            }
        });

        (addr, rx)
    }

    static PORT: ::std::sync::atomic::AtomicUsize = ::std::sync::atomic::ATOMIC_USIZE_INIT;

    fn next_test_ip4() -> ::std::net::SocketAddr {
        let port = PORT.fetch_add(1, ::std::sync::atomic::Ordering::SeqCst) as u16 + base_port();
        ::std::net::SocketAddr::V4(::std::net::SocketAddrV4::new(::std::net::Ipv4Addr::new(127, 0, 0, 1), port))
    }

    // The bots run multiple builds at the same time, and these builds
    // all want to use ports. This function figures out which workspace
    // it is running in and assigns a port range based on it.
    fn base_port() -> u16 {
        let cwd = ::std::env::current_dir().unwrap();
        let dirs = ["32-opt", "32-nopt",
        "musl-64-opt", "cross-opt",
        "64-opt", "64-nopt", "64-opt-vg", "64-debug-opt",
        "all-opt", "snap3", "dist"];
        dirs.iter().enumerate().find(|&(_, dir)| {
            cwd.to_str().unwrap().contains(dir)
        }).map(|p| p.0).unwrap_or(0) as u16 * 1000 + 19600
    }
}
<commit_msg>Make all modules public<commit_after>#[macro_use]
extern crate log;

pub mod acquire;
pub mod analog;
pub mod burst;
pub mod data;
pub mod digital;
pub mod generator;
pub mod socket;
pub mod trigger;

pub struct Redpitaya {
    pub acquire: acquire::Acquire,
    pub analog: analog::Analog,
    pub burst: burst::Burst,
    pub digital: digital::Digital,
    pub generator: generator::Generator,
    pub trigger: trigger::Trigger,
    pub data: data::Data,
}

impl Redpitaya {
    pub fn new(addr: ::std::net::SocketAddr) -> Redpitaya {
        let socket = socket::Socket::new(addr);

        Redpitaya {
            acquire: acquire::Acquire::new(socket.clone()),
            analog: analog::Analog::new(socket.clone()),
            burst: burst::Burst::new(socket.clone()),
            digital: digital::Digital::new(socket.clone()),
            generator: generator::Generator::new(socket.clone()),
            trigger: trigger::Trigger::new(socket.clone()),
            data: data::Data::new(socket.clone()),
        }
    }
}

#[cfg(test)]
mod test {
    use ::std::io::Read;
    use ::std::io::Write;

    pub fn launch_server() -> (::std::net:: SocketAddr, ::std::sync::mpsc::Receiver<String>) {
        let addr = next_test_ip4();
        let listener = ::std::net::TcpListener::bind(format!("{}", addr))
            .unwrap();

        let (tx, rx) = ::std::sync::mpsc::channel();

        ::std::thread::spawn(move || {
            loop {
                if let Ok((mut stream, _)) =  listener.accept() {
                    let tx = tx.clone();

                    ::std::thread::spawn(move || {
                        let mut message = String::new();

                        loop {
                            let mut buffer = [0; 1];

                            stream.read(&mut buffer[..])
                                .unwrap();
                            message.push(buffer[0] as char);

                            if buffer[0] == ('\n' as u8) {
                                break;
                            }
                        }

                        match message.as_str() {
                            "ACQ:DEC?\r\n" => {
                                stream.write("1\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:AVG?\r\n" => {
                                stream.write("ON\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:WPOS?\r\n" => {
                                stream.write("1024\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:TPOS?\r\n" => {
                                stream.write("512\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:SOUR1:DATA:STA:END? 10,13\r\n" => {
                                stream.write("{123,231,-231}\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:SOUR1:DATA:STA:N? 10,3\r\n" => {
                                stream.write("{1.2,3.2,-1.2}\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:SOUR1:DATA?\r\n" => {
                                stream.write("{1.2,3.2,-1.2}\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:SOUR1:DATA:OLD:N? 2\r\n" => {
                                stream.write("{3.2,-1.2}\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:SOUR1:DATA:LAT:N? 2\r\n" => {
                                stream.write("{1.2,3.2}\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:BUF:SIZE?\r\n" => {
                                stream.write("16384\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:TRIG:STAT?\r\n" => {
                                stream.write("WAIT\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:TRIG:DLY?\r\n" => {
                                stream.write("2314\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:TRIG:DLY:NS?\r\n" => {
                                stream.write("128ns\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ACQ:TRIG:LEV?\r\n" => {
                                stream.write("123mV\r\n".as_bytes())
                                    .unwrap();
                            },
                            "ANALOG:PIN? AIN1\r\n" => {
                                stream.write("1.34\r\n".as_bytes())
                                    .unwrap();
                            },
                            "DIG:PIN? DIO0_N\r\n" => {
                                stream.write("1\r\n".as_bytes())
                                    .unwrap();
                            },
                            _ => tx.send(message).unwrap(),
                        };
                    });
                }
            }
        });

        (addr, rx)
    }

    static PORT: ::std::sync::atomic::AtomicUsize = ::std::sync::atomic::ATOMIC_USIZE_INIT;

    fn next_test_ip4() -> ::std::net::SocketAddr {
        let port = PORT.fetch_add(1, ::std::sync::atomic::Ordering::SeqCst) as u16 + base_port();
        ::std::net::SocketAddr::V4(::std::net::SocketAddrV4::new(::std::net::Ipv4Addr::new(127, 0, 0, 1), port))
    }

    // The bots run multiple builds at the same time, and these builds
    // all want to use ports. This function figures out which workspace
    // it is running in and assigns a port range based on it.
    fn base_port() -> u16 {
        let cwd = ::std::env::current_dir().unwrap();
        let dirs = ["32-opt", "32-nopt",
        "musl-64-opt", "cross-opt",
        "64-opt", "64-nopt", "64-opt-vg", "64-debug-opt",
        "all-opt", "snap3", "dist"];
        dirs.iter().enumerate().find(|&(_, dir)| {
            cwd.to_str().unwrap().contains(dir)
        }).map(|p| p.0).unwrap_or(0) as u16 * 1000 + 19600
    }
}
<|endoftext|>


<commit_before>#![feature(convert)]
#![crate_type="lib"]
extern crate byteorder;
pub mod xdr;

#[test]
fn u16_writer_test() {
	let mut x = xdr::XdrWriter::new();
	let wtr = vec![0,0,2,5];

	x.pack(517u16);
	assert_eq!(x.get_buffer(),wtr);
}

#[test]
fn u16_reader_test() {
	let wtr = vec![0,0,2,5];
	let mut x = xdr::XdrReader::new(&wtr);

	let v = x.unpack::<u16>().unwrap();
	assert_eq!(v,517u16);
}

#[test]
fn r_w_primitive_test() {
	let mut wr = xdr::XdrWriter::new();
	wr.pack(0xCCu8);
	wr.pack(0xAAAAu16);
	wr.pack(0xDEADBEEFu32);
	wr.pack(-1i8);
	wr.pack(-256i16);
	wr.pack(-20i32);
	wr.pack(100.500f32);
	wr.pack(-100.500e10f64);

	let buf = &wr.get_buffer();
	let mut rdr = xdr::XdrReader::new(buf);

	assert_eq!(0xCCu8,rdr.unpack::<u8>().unwrap());
	assert_eq!(0xAAAAu16,rdr.unpack::<u16>().unwrap());
	assert_eq!(0xDEADBEEFu32,rdr.unpack::<u32>().unwrap());
	assert_eq!(-1i8,rdr.unpack::<i8>().unwrap());
	assert_eq!(-256i16,rdr.unpack::<i16>().unwrap());
	assert_eq!(-20i32,rdr.unpack::<i32>().unwrap());
	assert_eq!(100.500f32,rdr.unpack::<f32>().unwrap());
	assert_eq!(-100.500e10f64,rdr.unpack::<f64>().unwrap());
}

#[test]
fn variable_length_array_test() {
	let mut wr = xdr::XdrWriter::new();
	let vec = vec![0u32,1,2,3,4,5];

	wr.pack(vec);
	let buf = &wr.get_buffer();
	let mut rdr = xdr::XdrReader::new(buf);

	let res = rdr.unpack::<Vec<u32>>().unwrap();

	assert_eq!(vec![0u32,1,2,3,4,5], res)
}
<commit_msg>add fixed length array pack/unpack test<commit_after>#![feature(convert)]
#![crate_type="lib"]
extern crate byteorder;
pub mod xdr;

#[test]
fn u16_writer_test() {
	let mut x = xdr::XdrWriter::new();
	let wtr = vec![0,0,2,5];

	x.pack(517u16);
	assert_eq!(x.get_buffer(),wtr);
}

#[test]
fn u16_reader_test() {
	let wtr = vec![0,0,2,5];
	let mut x = xdr::XdrReader::new(&wtr);

	let v = x.unpack::<u16>().unwrap();
	assert_eq!(v,517u16);
}

#[test]
fn r_w_primitive_test() {
	let mut wr = xdr::XdrWriter::new();
	wr.pack(0xCCu8);
	wr.pack(0xAAAAu16);
	wr.pack(0xDEADBEEFu32);
	wr.pack(-1i8);
	wr.pack(-256i16);
	wr.pack(-20i32);
	wr.pack(100.500f32);
	wr.pack(-100.500e10f64);

	let buf = &wr.get_buffer();
	let mut rdr = xdr::XdrReader::new(buf);

	assert_eq!(0xCCu8,rdr.unpack::<u8>().unwrap());
	assert_eq!(0xAAAAu16,rdr.unpack::<u16>().unwrap());
	assert_eq!(0xDEADBEEFu32,rdr.unpack::<u32>().unwrap());
	assert_eq!(-1i8,rdr.unpack::<i8>().unwrap());
	assert_eq!(-256i16,rdr.unpack::<i16>().unwrap());
	assert_eq!(-20i32,rdr.unpack::<i32>().unwrap());
	assert_eq!(100.500f32,rdr.unpack::<f32>().unwrap());
	assert_eq!(-100.500e10f64,rdr.unpack::<f64>().unwrap());
}

#[test]
fn variable_length_array_test() {
	let mut wr = xdr::XdrWriter::new();
	let vec = vec![0u32,1,2,3,4,5];

	wr.pack(vec);
	let buf = &wr.get_buffer();
	let mut rdr = xdr::XdrReader::new(buf);

	let res = rdr.unpack::<Vec<u32>>().unwrap();

	assert_eq!(vec![0u32,1,2,3,4,5], res)
}

#[test]
fn fixed_length_array_test() {
	let mut wr = xdr::XdrWriter::new();
	let vec = vec![0u32,1,2,3,4,5];

	wr.pack_array(vec);
	let buf = &wr.get_buffer();
	let mut rdr = xdr::XdrReader::new(buf);

	let res = rdr.unpack_array::<u32>(6).unwrap();

	assert_eq!(vec![0u32,1,2,3,4,5], res)
}
<|endoftext|>


<commit_before>extern crate libinspire;

/// Re-export slog
///
/// Users of this library can, but don't have to use slog to build their own loggers
#[macro_use]
pub extern crate slog ;
extern crate slog_stdlog;

use slog::DrainExt;

extern crate regex;
use regex::Regex;

pub struct Inspirer {
    logger: slog::Logger,
    inspire: libinspire::Api,
}

#[derive(Debug,PartialEq)]
pub enum Sources<'a> {
    Inspire(libinspire::RecID<'a>),
    Ads,
    Arxiv,
    None,
}

impl Inspirer {
    /// Initialize 'Inspirer'
    ///
    /// Either provide a custom slog::Logger or default to the standard `log`
    /// crate.
    ///
    /// # Examples
    /// ```
    /// inspirer::Inspirer::init(None);
    /// ```
    pub fn init(logger: Option<slog::Logger>) -> Self {
        let logger = logger.unwrap_or_else(|| slog::Logger::root(slog_stdlog::StdLog.fuse(), o!()));

        Inspirer {
            logger: logger,
            // inspire: libinspire::Api::init(Some(logger)),
            inspire: libinspire::Api::init(None),
        }
    }

    /// The `aux2key` function extracts TeX keys from LaTeX .aux files. These can be for either
    /// BibTeX or BibLaTeX.
    ///
    /// # Examples
    ///
    /// ## bibtex
    ///
    /// ```
    /// let inspirer = inspirer::Inspirer::init(None);
    ///
    /// let input =
    /// r"\relax
    /// \citation{Abramovici:1992ah}".to_string();
    ///
    /// assert_eq!(inspirer.aux2key(input), vec!("Abramovici:1992ah"));
    /// ```
    ///
    /// ## biber
    ///
    /// ```
    /// let inspirer = inspirer::Inspirer::init(None);
    ///
    /// let input =
    /// r"\relax
    /// \abx@aux@cite{Cutler:1992tc}".to_string();
    ///
    /// assert_eq!(inspirer.aux2key(input), vec!("Cutler:1992tc"));
    /// ```
    pub fn aux2key(&self, input_data: String) -> Vec<String> {

        let regex = Regex::new(r"(\\citation|\\abx@aux@cite)\{([a-zA-Z]+:\d{4}[a-z]{2,3})\}")
            .unwrap();

        regex
            .captures_iter(&input_data)
            .map(|c| c.get(2).unwrap().as_str().to_string())
            .collect()
    }

    ///  The blg2key function extracts missing references from bibtex logs
    pub fn blg2key(&self, input_data: String) -> Vec<String> {

        let regex = Regex::new(r#"(Warning--|WARN - )I didn't find a database entry for ["']([a-zA-Z]+:\d{4}[a-z]{2,3})["']"#)
            .unwrap();

        regex
            .captures_iter(&input_data)
            .map(|c| c.get(2).unwrap().as_str().to_string())
            .collect()
    }

    /// Fetch BibTeX entries
    pub fn bibtex(&self, key: &str) -> Option<String> {
        let key = self.classify(key);

        match key {
            Sources::Inspire(k) => {
                debug!(self.logger, "Got Inspire record"; "key" => k.id);
                self.inspire.fetch_bibtex_with_key(k)
            }
            _ => {
                // debug!(self.logger, "Unknown record source"; "key" => key);
                debug!(self.logger, "Unknown record source");
                None
            }
        }
    }

    /// Guess a likely source of BibTeX key
    ///
    /// # Examples
    /// ```
    /// extern crate inspirer;
    /// extern crate libinspire;
    /// let inspirer = inspirer::Inspirer::init(None);
    ///
    /// assert_eq!(
    ///     inspirer.classify("Randall:1999ee"),
    ///     inspirer::Sources::Inspire(libinspire::RecID::new("Randall:1999ee").unwrap())
    /// );
    /// ```
    pub fn classify<'a>(&self, s: &'a str) -> Sources<'a> {
        if libinspire::validate_recid(s) {
            debug!(self.logger, "Detected an Inspire record"; "key" => s);
            Sources::Inspire(libinspire::RecID::new(s).unwrap())
        } else {
            debug!(self.logger, "Unknown record type"; "key" => s);
            Sources::None
        }
    }
}

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

    #[test]
    fn test_aux_bibtex_0_citations() {
        let input = r"\relax ".to_string();

        let output: Vec<String> = Vec::new();
        assert_eq!(Inspirer::init(None).aux2key(input), output);
    }

    #[test]
    fn test_aux_bibtex_1_citation() {
        let input = r"\relax
            \citation{Abramovici:1992ah}"
                .to_string();

        assert_eq!(Inspirer::init(None).aux2key(input),
                   vec!["Abramovici:1992ah"]);
    }

    #[test]
    fn test_aux_bibtex_2_citation() {
        let input = r"\relax
            \citation{Abramovici:1992ah}
            \citation{Thorne:1992sdb}"
                .to_string();

        assert_eq!(Inspirer::init(None).aux2key(input),
                   vec!["Abramovici:1992ah", "Thorne:1992sdb"]);
    }
}
<commit_msg>Sources: impl from<&str><commit_after>extern crate libinspire;

/// Re-export slog
///
/// Users of this library can, but don't have to use slog to build their own loggers
#[macro_use]
pub extern crate slog ;
extern crate slog_stdlog;

use slog::DrainExt;

extern crate regex;
use regex::Regex;

pub struct Inspirer {
    logger: slog::Logger,
    inspire: libinspire::Api,
}

impl Inspirer {
    /// Initialize 'Inspirer'
    ///
    /// Either provide a custom slog::Logger or default to the standard `log`
    /// crate.
    ///
    /// # Examples
    /// ```
    /// inspirer::Inspirer::init(None);
    /// ```
    pub fn init(logger: Option<slog::Logger>) -> Self {
        let logger = logger.unwrap_or_else(|| slog::Logger::root(slog_stdlog::StdLog.fuse(), o!()));

        Inspirer {
            logger: logger,
            // inspire: libinspire::Api::init(Some(logger)),
            inspire: libinspire::Api::init(None),
        }
    }

    /// The `aux2key` function extracts TeX keys from LaTeX .aux files. These can be for either
    /// BibTeX or BibLaTeX.
    ///
    /// # Examples
    ///
    /// ## bibtex
    ///
    /// ```
    /// let inspirer = inspirer::Inspirer::init(None);
    ///
    /// let input =
    /// r"\relax
    /// \citation{Abramovici:1992ah}".to_string();
    ///
    /// assert_eq!(inspirer.aux2key(input), vec!("Abramovici:1992ah"));
    /// ```
    ///
    /// ## biber
    ///
    /// ```
    /// let inspirer = inspirer::Inspirer::init(None);
    ///
    /// let input =
    /// r"\relax
    /// \abx@aux@cite{Cutler:1992tc}".to_string();
    ///
    /// assert_eq!(inspirer.aux2key(input), vec!("Cutler:1992tc"));
    /// ```
    pub fn aux2key(&self, input_data: String) -> Vec<String> {

        let regex = Regex::new(r"(\\citation|\\abx@aux@cite)\{([a-zA-Z]+:\d{4}[a-z]{2,3})\}")
            .unwrap();

        regex
            .captures_iter(&input_data)
            .map(|c| c.get(2).unwrap().as_str().to_string())
            .collect()
    }

    ///  The blg2key function extracts missing references from bibtex logs
    pub fn blg2key(&self, input_data: String) -> Vec<String> {

        let regex = Regex::new(r#"(Warning--|WARN - )I didn't find a database entry for ["']([a-zA-Z]+:\d{4}[a-z]{2,3})["']"#)
            .unwrap();

        regex
            .captures_iter(&input_data)
            .map(|c| c.get(2).unwrap().as_str().to_string())
            .collect()
    }

    /// Fetch BibTeX entries
    pub fn bibtex(&self, key: &str) -> Option<String> {
        let key = Sources::from(key);

        match key {
            Sources::Inspire(k) => {
                debug!(self.logger, "Got Inspire record"; "key" => k.id);
                self.inspire.fetch_bibtex_with_key(k)
            }
            _ => {
                // debug!(self.logger, "Unknown record source"; "key" => key);
                debug!(self.logger, "Unknown record source");
                None
            }
        }
    }
}

#[derive(Debug,PartialEq)]
pub enum Sources<'a> {
    Inspire(libinspire::RecID<'a>),
    Ads,
    Arxiv,
    None,
}

/// Guess a likely source for a BibTeX key
///
/// Returns `Sources::None` if unable to make a good guess.
///
/// # Examples
/// ```
/// extern crate inspirer;
/// extern crate libinspire;
/// let inspirer = inspirer::Inspirer::init(None);
///
/// assert_eq!(
///     inspirer::Sources::from("Randall:1999ee"),
///     inspirer::Sources::Inspire(libinspire::RecID::new("Randall:1999ee").unwrap())
/// );
/// ```
impl<'a> From<&'a str> for Sources<'a> {
    fn from(s: &'a str) -> Sources<'a> {
        if libinspire::validate_recid(s) {
            Sources::Inspire(libinspire::RecID::new(s).unwrap())
        } else {
            Sources::None
        }
    }
}

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

    #[test]
    fn test_aux_bibtex_0_citations() {
        let input = r"\relax ".to_string();

        let output: Vec<String> = Vec::new();
        assert_eq!(Inspirer::init(None).aux2key(input), output);
    }

    #[test]
    fn test_aux_bibtex_1_citation() {
        let input = r"\relax
            \citation{Abramovici:1992ah}"
                .to_string();

        assert_eq!(Inspirer::init(None).aux2key(input),
                   vec!["Abramovici:1992ah"]);
    }

    #[test]
    fn test_aux_bibtex_2_citation() {
        let input = r"\relax
            \citation{Abramovici:1992ah}
            \citation{Thorne:1992sdb}"
                .to_string();

        assert_eq!(Inspirer::init(None).aux2key(input),
                   vec!["Abramovici:1992ah", "Thorne:1992sdb"]);
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2014, 2015, 2017 Robert Clipsham <robert@octarineparrot.com>
//
// 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.

//! Packet helpers for `pnet_macros`

use pnet_base;
use std::ops::{Deref, DerefMut, Index, IndexMut, Range, RangeFrom, RangeFull, RangeTo};

/// Represents a generic network packet
pub trait Packet {
    /// Retreive the underlying buffer for the packet
    fn packet(&self) -> &[u8];

    /// Retreive the payload for the packet
    fn payload(&self) -> &[u8];
}

/// Represents a generic, mutable, network packet
pub trait MutablePacket: Packet {
    /// Retreive the underlying, mutable, buffer for the packet
    fn packet_mut(&mut self) -> &mut [u8];

    /// Retreive the mutable payload for the packet
    fn payload_mut(&mut self) -> &mut [u8];

    /// Initialize this packet by cloning another
    fn clone_from<T: Packet>(&mut self, other: &T) {
        use std::ptr;

        assert!(self.packet().len() >= other.packet().len());
        unsafe {
            ptr::copy_nonoverlapping(other.packet().as_ptr(),
                                     self.packet_mut().as_mut_ptr(),
                                     other.packet().len());
        }
    }
}

/// Used to convert on-the-wire packets to their #[packet] equivalent
pub trait FromPacket: Packet {
    /// The type of the packet to convert from
    type T;

    /// Converts a wire-format packet to #[packet] struct format
    fn from_packet(&self) -> Self::T;
}

/// Used to find the calculated size of the packet. This is used for occasions where the underlying
/// buffer is not the same length as the packet itself.
pub trait PacketSize: Packet {
    /// Get the calculated size of the packet
    fn packet_size(&self) -> usize;
}

macro_rules! impl_index {
    ($t:ident, $index_t:ty, $output_t:ty) => {
        impl<'p> Index<$index_t> for $t<'p> {
            type Output = $output_t;

            fn index(&self, index: $index_t) -> &$output_t {
                &self.as_slice().index(index)
            }
        }
    };
}

macro_rules! impl_index_mut {
    ($t:ident, $index_t:ty, $output_t:ty) => {
        impl<'p> IndexMut<$index_t> for $t<'p> {
            fn index_mut(&mut self, index: $index_t) -> &mut $output_t {
                self.as_mut_slice().index_mut(index)
            }
        }
    };
}

/// Packet data
#[derive(PartialEq)]
pub enum PacketData<'p> {
    /// Packet owns its contents
    Owned(Vec<u8>),
    /// Packet borrows its contents
    Borrowed(&'p [u8]),
}

impl<'p> PacketData<'p> {
    /// Get a slice of the packet data
    pub fn as_slice(&self) -> &[u8] {
        match self {
            &PacketData::Owned(ref data) => data.deref(),
            &PacketData::Borrowed(ref data) => data,
        }
    }

    /// No-op - returns `self`
    pub fn to_immutable(self) -> PacketData<'p> {
        self
    }

    /// Length of the packet data
    pub fn len(&self) -> usize {
        self.as_slice().len()
    }
}

impl_index!(PacketData, usize, u8);
impl_index!(PacketData, Range<usize>, [u8]);
impl_index!(PacketData, RangeTo<usize>, [u8]);
impl_index!(PacketData, RangeFrom<usize>, [u8]);
impl_index!(PacketData, RangeFull, [u8]);

/// Mutable packet data
#[derive(PartialEq)]
pub enum MutPacketData<'p> {
    /// Owned mutable packet data
    Owned(Vec<u8>),
    /// Borrowed mutable packet data
    Borrowed(&'p mut [u8]),
}

impl<'p> MutPacketData<'p> {
    /// Get packet data as a slice
    pub fn as_slice(&self) -> &[u8] {
        match self {
            &MutPacketData::Owned(ref data) => data.deref(),
            &MutPacketData::Borrowed(ref data) => data,
        }
    }

    /// Get packet data as a mutable slice
    pub fn as_mut_slice(&mut self) -> &mut [u8] {
        match self {
            &mut MutPacketData::Owned(ref mut data) => data.deref_mut(),
            &mut MutPacketData::Borrowed(ref mut data) => data,
        }
    }

    /// Get an immutable version of the packet data
    pub fn to_immutable(self) -> PacketData<'p> {
        match self {
            MutPacketData::Owned(data) => PacketData::Owned(data),
            MutPacketData::Borrowed(data) => PacketData::Borrowed(data),
        }
    }

    /// Get the length of data in the packet
    pub fn len(&self) -> usize {
        self.as_slice().len()
    }
}

impl_index!(MutPacketData, usize, u8);
impl_index!(MutPacketData, Range<usize>, [u8]);
impl_index!(MutPacketData, RangeTo<usize>, [u8]);
impl_index!(MutPacketData, RangeFrom<usize>, [u8]);
impl_index!(MutPacketData, RangeFull, [u8]);

impl_index_mut!(MutPacketData, usize, u8);
impl_index_mut!(MutPacketData, Range<usize>, [u8]);
impl_index_mut!(MutPacketData, RangeTo<usize>, [u8]);
impl_index_mut!(MutPacketData, RangeFrom<usize>, [u8]);
impl_index_mut!(MutPacketData, RangeFull, [u8]);

/// Used to convert a type to primitive values representing it
pub trait PrimitiveValues {
    /// A tuple of types, to represent the current value
    type T;

    /// Convert a value to primitive types representing it
    fn to_primitive_values(&self) -> Self::T;
}

impl PrimitiveValues for pnet_base::MacAddr {
    type T = (u8, u8, u8, u8, u8, u8);
    fn to_primitive_values(&self) -> (u8, u8, u8, u8, u8, u8) {
        (self.0, self.1, self.2, self.3, self.4, self.5)
    }
}

impl PrimitiveValues for ::std::net::Ipv4Addr {
    type T = (u8, u8, u8, u8);
    fn to_primitive_values(&self) -> (u8, u8, u8, u8) {
        let octets = self.octets();

        (octets[0], octets[1], octets[2], octets[3])
    }
}

impl PrimitiveValues for ::std::net::Ipv6Addr {
    type T = (u16, u16, u16, u16, u16, u16, u16, u16);
    fn to_primitive_values(&self) -> (u16, u16, u16, u16, u16, u16, u16, u16) {
        let segments = self.segments();

        (segments[0],
         segments[1],
         segments[2],
         segments[3],
         segments[4],
         segments[5],
         segments[6],
         segments[7])
    }
}

<commit_msg>Fixed typo<commit_after>// Copyright (c) 2014, 2015, 2017 Robert Clipsham <robert@octarineparrot.com>
//
// 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.

//! Packet helpers for `pnet_macros`

use pnet_base;
use std::ops::{Deref, DerefMut, Index, IndexMut, Range, RangeFrom, RangeFull, RangeTo};

/// Represents a generic network packet
pub trait Packet {
    /// Retrieve the underlying buffer for the packet
    fn packet(&self) -> &[u8];

    /// Retrieve the payload for the packet
    fn payload(&self) -> &[u8];
}

/// Represents a generic, mutable, network packet
pub trait MutablePacket: Packet {
    /// Retreive the underlying, mutable, buffer for the packet
    fn packet_mut(&mut self) -> &mut [u8];

    /// Retreive the mutable payload for the packet
    fn payload_mut(&mut self) -> &mut [u8];

    /// Initialize this packet by cloning another
    fn clone_from<T: Packet>(&mut self, other: &T) {
        use std::ptr;

        assert!(self.packet().len() >= other.packet().len());
        unsafe {
            ptr::copy_nonoverlapping(other.packet().as_ptr(),
                                     self.packet_mut().as_mut_ptr(),
                                     other.packet().len());
        }
    }
}

/// Used to convert on-the-wire packets to their #[packet] equivalent
pub trait FromPacket: Packet {
    /// The type of the packet to convert from
    type T;

    /// Converts a wire-format packet to #[packet] struct format
    fn from_packet(&self) -> Self::T;
}

/// Used to find the calculated size of the packet. This is used for occasions where the underlying
/// buffer is not the same length as the packet itself.
pub trait PacketSize: Packet {
    /// Get the calculated size of the packet
    fn packet_size(&self) -> usize;
}

macro_rules! impl_index {
    ($t:ident, $index_t:ty, $output_t:ty) => {
        impl<'p> Index<$index_t> for $t<'p> {
            type Output = $output_t;

            fn index(&self, index: $index_t) -> &$output_t {
                &self.as_slice().index(index)
            }
        }
    };
}

macro_rules! impl_index_mut {
    ($t:ident, $index_t:ty, $output_t:ty) => {
        impl<'p> IndexMut<$index_t> for $t<'p> {
            fn index_mut(&mut self, index: $index_t) -> &mut $output_t {
                self.as_mut_slice().index_mut(index)
            }
        }
    };
}

/// Packet data
#[derive(PartialEq)]
pub enum PacketData<'p> {
    /// Packet owns its contents
    Owned(Vec<u8>),
    /// Packet borrows its contents
    Borrowed(&'p [u8]),
}

impl<'p> PacketData<'p> {
    /// Get a slice of the packet data
    pub fn as_slice(&self) -> &[u8] {
        match self {
            &PacketData::Owned(ref data) => data.deref(),
            &PacketData::Borrowed(ref data) => data,
        }
    }

    /// No-op - returns `self`
    pub fn to_immutable(self) -> PacketData<'p> {
        self
    }

    /// Length of the packet data
    pub fn len(&self) -> usize {
        self.as_slice().len()
    }
}

impl_index!(PacketData, usize, u8);
impl_index!(PacketData, Range<usize>, [u8]);
impl_index!(PacketData, RangeTo<usize>, [u8]);
impl_index!(PacketData, RangeFrom<usize>, [u8]);
impl_index!(PacketData, RangeFull, [u8]);

/// Mutable packet data
#[derive(PartialEq)]
pub enum MutPacketData<'p> {
    /// Owned mutable packet data
    Owned(Vec<u8>),
    /// Borrowed mutable packet data
    Borrowed(&'p mut [u8]),
}

impl<'p> MutPacketData<'p> {
    /// Get packet data as a slice
    pub fn as_slice(&self) -> &[u8] {
        match self {
            &MutPacketData::Owned(ref data) => data.deref(),
            &MutPacketData::Borrowed(ref data) => data,
        }
    }

    /// Get packet data as a mutable slice
    pub fn as_mut_slice(&mut self) -> &mut [u8] {
        match self {
            &mut MutPacketData::Owned(ref mut data) => data.deref_mut(),
            &mut MutPacketData::Borrowed(ref mut data) => data,
        }
    }

    /// Get an immutable version of the packet data
    pub fn to_immutable(self) -> PacketData<'p> {
        match self {
            MutPacketData::Owned(data) => PacketData::Owned(data),
            MutPacketData::Borrowed(data) => PacketData::Borrowed(data),
        }
    }

    /// Get the length of data in the packet
    pub fn len(&self) -> usize {
        self.as_slice().len()
    }
}

impl_index!(MutPacketData, usize, u8);
impl_index!(MutPacketData, Range<usize>, [u8]);
impl_index!(MutPacketData, RangeTo<usize>, [u8]);
impl_index!(MutPacketData, RangeFrom<usize>, [u8]);
impl_index!(MutPacketData, RangeFull, [u8]);

impl_index_mut!(MutPacketData, usize, u8);
impl_index_mut!(MutPacketData, Range<usize>, [u8]);
impl_index_mut!(MutPacketData, RangeTo<usize>, [u8]);
impl_index_mut!(MutPacketData, RangeFrom<usize>, [u8]);
impl_index_mut!(MutPacketData, RangeFull, [u8]);

/// Used to convert a type to primitive values representing it
pub trait PrimitiveValues {
    /// A tuple of types, to represent the current value
    type T;

    /// Convert a value to primitive types representing it
    fn to_primitive_values(&self) -> Self::T;
}

impl PrimitiveValues for pnet_base::MacAddr {
    type T = (u8, u8, u8, u8, u8, u8);
    fn to_primitive_values(&self) -> (u8, u8, u8, u8, u8, u8) {
        (self.0, self.1, self.2, self.3, self.4, self.5)
    }
}

impl PrimitiveValues for ::std::net::Ipv4Addr {
    type T = (u8, u8, u8, u8);
    fn to_primitive_values(&self) -> (u8, u8, u8, u8) {
        let octets = self.octets();

        (octets[0], octets[1], octets[2], octets[3])
    }
}

impl PrimitiveValues for ::std::net::Ipv6Addr {
    type T = (u16, u16, u16, u16, u16, u16, u16, u16);
    fn to_primitive_values(&self) -> (u16, u16, u16, u16, u16, u16, u16, u16) {
        let segments = self.segments();

        (segments[0],
         segments[1],
         segments[2],
         segments[3],
         segments[4],
         segments[5],
         segments[6],
         segments[7])
    }
}

<|endoftext|>


<commit_before>#![doc(html_logo_url = "https://avatars0.githubusercontent.com/u/7853871?s=128", html_favicon_url = "https://avatars0.githubusercontent.com/u/7853871?s=256", html_root_url = "http://ironframework.io/core/staticfile")]
#![crate_name = "staticfile"]
#![deny(missing_doc)]
#![feature(phase)]

//! Static file-serving middleware.

extern crate url;
#[phase(plugin)]
extern crate regex_macros;
extern crate regex;

extern crate http;
extern crate iron;
#[phase(plugin, link)]
extern crate log;
extern crate mount;

use http::headers::content_type::MediaType;
use iron::{Request, Response, Middleware, Alloy, Status, Continue, Unwind};
use iron::mixin::{GetUrl, Serve};
use mount::OriginalUrl;

/// The static file-serving `Middleware`.
#[deriving(Clone)]
pub struct Static {
    root_path: Path
}

#[deriving(Clone)]
#[doc(hidden)]
struct Favicon {
    max_age: u8,
    favicon_path: Path
}

impl Static {
    /// Create a new instance of `Static` with a given root path.
    ///
    /// This will attempt to serve static files from the given root path.
    /// The path may be relative or absolute. If `Path::new("")` is given,
    /// files will be served from the current directory.
    ///
    /// If a static file exists and can be read from, `enter` will serve it to
    /// the `Response` and `Unwind` the middleware stack with a status of `200`.
    ///
    /// In the case of any error, it will `Continue` through the stack.
    /// If a file should have been read but cannot, due to permissions or
    /// read errors, a different `Middleware` should handle it.
    ///
    /// If the path is '/', it will attempt to serve `index.html`.
    pub fn new(root_path: Path) -> Static {
        Static {
            root_path: root_path
        }
    }

    /// Create a favicon server from the given filepath.
    ///
    /// This will serve your favicon, as specified by `favicon_path`,
    /// to every request ending in "/favicon.ico" that it sees,
    /// and then unwind the middleware stack for those requests.
    ///
    /// It should be linked first in order to avoid additional processing
    /// for simple favicon requests.
    ///
    /// Unlike normally served static files, favicons are given a max-age,
    /// specified in seconds.
    #[allow(visible_private_types)]
    pub fn favicon(favicon_path: Path, max_age: u8) -> Favicon {
        Favicon {
            max_age: max_age,
            favicon_path: favicon_path
        }
    }
}

impl Middleware for Static {
    fn enter(&mut self, req: &mut Request, res: &mut Response, alloy: &mut Alloy) -> Status {
        match req.url() {
            Some(path) => {
                // Check for requested file
                match res.serve_file(&self.root_path.join(
                    Path::new(
                        // Coerce to relative path.
                        // We include the slash to ensure that you never have a path like ".index.html"
                        // when you meant "./index.html", see http://is.gd/yz9p0B for an example.
                        "./".to_string().append(path.as_slice())))) {
                    Ok(()) => {
                        debug!("Serving static file at {}.",
                            &self.root_path.join("./".to_string().append(path.as_slice())).display());
                        return Unwind
                    },
                    Err(_) => ()
                }

                // Check for index.html
                let index_path = self.root_path.join(
                    Path::new("./".to_string().append(path.as_slice()))
                        .join("./index.html".to_string()));
                if index_path.is_file() {
                    // Avoid serving as a directory
                    if path.len() > 0 {
                        match path.as_slice().char_at_reverse(path.len()) {
                            '/' => {
                                match res.serve_file(&index_path) {
                                    Ok(()) => {
                                        debug!("Serving static file at {}.",
                                            &index_path.display());
                                        return Unwind
                                    },
                                    Err(err) => {
                                        debug!("Failed while trying to serve index.html: {}", err)
                                        return Continue
                                    }
                                }
                            },
                    // 303:
                            _ => ()
                        }
                    }
                    let redirect_path = match alloy.find::<OriginalUrl>() {
                        Some(&OriginalUrl(ref original_url)) => original_url.clone(),
                        None => path.clone()
                    }.append("/");
                    res.headers.extensions.insert("Location".to_string(), redirect_path.clone());
                    let _ = res.serve(::http::status::SeeOther,
                        format!("Redirecting to {}/", redirect_path).as_slice());
                    return Unwind
                }
            },
            None => ()
        }
        Continue
    }
}

impl Middleware for Favicon {
    fn enter(&mut self, req: &mut Request, res: &mut Response, _alloy: &mut Alloy) -> Status {
        match req.url() {
            Some(path) => {
                if regex!("/favicon.ico$").is_match(path.as_slice()) {
                    res.headers.content_type = Some(MediaType {
                        type_: "image".to_string(),
                        subtype: "x-icon".to_string(),
                        parameters: vec![]
                    });
                    res.headers.cache_control = Some(format!("public, max-age={}", self.max_age));
                    let _ = res.try_write_headers();
                    match res.serve_file(&self.favicon_path) {
                        Ok(()) => (),
                        Err(_) => {
                            let _ = res.serve(::http::status::InternalServerError,
                                "Failed to serve favicon.ico.");
                        }
                    }
                    return Unwind;
                }
            },
            None => ()
        }
        Continue
    }
}
<commit_msg>(feat) Refactored for new Iron APIs.<commit_after>#![doc(html_logo_url = "https://avatars0.githubusercontent.com/u/7853871?s=128", html_favicon_url = "https://avatars0.githubusercontent.com/u/7853871?s=256", html_root_url = "http://ironframework.io/core/staticfile")]
#![crate_name = "staticfile"]
#![deny(missing_doc)]
#![feature(phase)]

//! Static file-serving middleware.

extern crate url;
#[phase(plugin)]
extern crate regex_macros;
extern crate regex;

extern crate http;
extern crate iron;
#[phase(plugin, link)]
extern crate log;
extern crate mount;

use http::headers::content_type::MediaType;
use iron::{Request, Response, Middleware, Alloy, Status, Continue, Unwind};
use mount::OriginalUrl;

/// The static file-serving `Middleware`.
#[deriving(Clone)]
pub struct Static {
    root_path: Path
}

#[deriving(Clone)]
#[doc(hidden)]
struct Favicon {
    max_age: u8,
    favicon_path: Path
}

impl Static {
    /// Create a new instance of `Static` with a given root path.
    ///
    /// This will attempt to serve static files from the given root path.
    /// The path may be relative or absolute. If `Path::new("")` is given,
    /// files will be served from the current directory.
    ///
    /// If a static file exists and can be read from, `enter` will serve it to
    /// the `Response` and `Unwind` the middleware stack with a status of `200`.
    ///
    /// In the case of any error, it will `Continue` through the stack.
    /// If a file should have been read but cannot, due to permissions or
    /// read errors, a different `Middleware` should handle it.
    ///
    /// If the path is '/', it will attempt to serve `index.html`.
    pub fn new(root_path: Path) -> Static {
        Static {
            root_path: root_path
        }
    }

    /// Create a favicon server from the given filepath.
    ///
    /// This will serve your favicon, as specified by `favicon_path`,
    /// to every request ending in "/favicon.ico" that it sees,
    /// and then unwind the middleware stack for those requests.
    ///
    /// It should be linked first in order to avoid additional processing
    /// for simple favicon requests.
    ///
    /// Unlike normally served static files, favicons are given a max-age,
    /// specified in seconds.
    #[allow(visible_private_types)]
    pub fn favicon(favicon_path: Path, max_age: u8) -> Favicon {
        Favicon {
            max_age: max_age,
            favicon_path: favicon_path
        }
    }
}

impl Middleware for Static {
    fn enter(&mut self, req: &mut Request, res: &mut Response, alloy: &mut Alloy) -> Status {
        // Coerce to relative path.
        // We include the slash to ensure that you never have a path like ".index.html"
        // when you meant "./index {
        let requested_path =
            &self.root_path.join(Path::new("./".to_string().append(req.url.as_slice())));

        if requested_path.is_file() {
            match res.serve_file(requested_path) {
                Ok(()) => {
                    debug!("Serving static file at {}", requested_path.display());
                    return Unwind;
                },
                Err(e) => {
                    error!("Errored trying to send file at {} with {}",
                          requested_path.display(), e);
                    return Continue;
                }
            }
        }

        // Check for index.html
        let index_path = self.root_path.join(
            Path::new("./".to_string().append(req.url.as_slice()))
                .join("./index.html".to_string())
        );

        // Avoid serving a directory
        if index_path.is_file() {
            if req.url.len() > 0 {
                match req.url.as_slice().char_at_reverse(req.url.len()) {
                    '/' => {
                        match res.serve_file(&index_path) {
                            Ok(()) => {
                                debug!("Serving static file at {}.", &index_path.display());
                                return Unwind
                            },
                            Err(err) => {
                                debug!("Failed while trying to serve index.html: {}", err);
                                return Continue
                            }
                        }
                    },
                    // 303:
                    _ => ()
                }
            }

            let redirect_path = match alloy.find::<OriginalUrl>() {
                Some(&OriginalUrl(ref original_url)) => original_url.clone(),
                None => req.url.clone()
            }.append("/");
            res.headers.extensions.insert("Location".to_string(), redirect_path.clone());
            let _ = res.serve(::http::status::SeeOther,
                              format!("Redirecting to {}/", redirect_path));
            return Unwind
        }

        Continue
    }
}

impl Middleware for Favicon {
    fn enter(&mut self, req: &mut Request, res: &mut Response, _alloy: &mut Alloy) -> Status {
        if regex!("/favicon.ico$").is_match(req.url.as_slice()) {
            res.headers.content_type = Some(MediaType {
                type_: "image".to_string(),
                subtype: "x-icon".to_string(),
                parameters: vec![]
            });
            res.headers.cache_control = Some(format!("public, max-age={}", self.max_age));
            match res.serve_file(&self.favicon_path) {
                Ok(()) => (),
                Err(_) => {
                    let _ = res.serve(::http::status::InternalServerError,
                                      "Failed to serve favicon.ico.");
                }
            }
            Unwind
        } else {
            Continue
        }
    }
}
<|endoftext|>


<commit_before>// Forsaken docs justly quibble the vexed programmer's waning zeal
//! Text hyphenation in a variety of languages.
//!
//!
//! ## Usage
//!
//! A typical import comprises the `Hyphenation` trait, the `Standard`
//! hyphenator, and the `Language` enum. This exposes the crate's core
//! functionality, and the set of available languages.
//!
//! ```ignore
//! extern crate hyphenation;
//
//! use hyphenation::{Hyphenation, Standard, Language};
//! ```
//!
//! To begin with, we must initiate the `Corpus` for our working language.
//!
//! ```ignore
//! let english_us = hyphenation::load(Language::English_US).unwrap();
//! ```
//!
//! Our English `Corpus` can now be used by `Hyphenation` methods.
//! Core functionality is provided by `opportunities()`, which returns the
//! byte indices of valid hyphenation points within a word.
//!
//! ```ignore
//! let indices = "hyphenation".opportunities(&english_us);
//! assert_eq!(indices, vec![2, 6]);
//! ```
//!
//! The same `Corpus` may also be used by *hyphenators*: iterators which
//! segment words in accordance with hyphenation practices, as described
//! by the corpus.
//!
//! The simplest (and, presently, only) hyphenator is `Standard`:
//!
//! ```ignore
//! let h: Standard = "hyphenation".hyphenate(&english_us);
//! ```
//!
//! The `Standard` hyphenator does not allocate new strings, returning
//! slices instead.
//!
//! ```ignore
//! let v: Vec<&str> = h.collect();
//! assert_eq!(v, vec!["hy", "phen", "ation"]);
//! ```
//!
//! ## Full-text Hyphenation
//! While hyphenation is always performed on a per-word basis, convenience
//! calls for a subtrait to provide methods to work with full text.
//!
//! ```ignore
//! use hyphenation::{FullTextHyphenation};
//!
//! let h2: Standard = "Word hyphenation by computer.".fulltext_hyphenate(&english_us);
//! let v2: Vec<&str> = h2.collect();
//! assert_eq!(v2, vec!["Word hy", "phen", "ation by com", "puter."]);
//! ```
//!
//! Hyphenators also expose some simple methods to render hyphenated text:
//! `punctuate()` and `punctuate_with(string)`, which mark hyphenation
//! opportunities respectively with soft hyphens (Unicode `U+00AD SOFT HYPHEN`)
//! and any given `string`.
//!
//! ```ignore
//! let h3 = "anfractuous".hyphenate(&english_us);
//! let s3: String = h2.clone().punctuate().collect();
//! assert_eq!(s3, "an\u{ad}frac\u{ad}tu\u{ad}ous".to_owned());
//!
//! let s4: String = h2.punctuate_with("-").collect()
//! assert_eq!(s4, "an-frac-tu-ous".to_owned());
//! ```

extern crate bincode;
extern crate fnv;
extern crate klpattern;
extern crate unicode_segmentation;

mod resources;
mod utilia;
pub mod hyphenator;
pub mod language;
pub mod load;

pub use klpattern::{KLPair, KLPTrie, Exceptions, Patterns};
pub use hyphenator::{Hyphenation, FullTextHyphenation, Standard};
pub use language::{Language, Corpus};
pub use load::{language as load};
<commit_msg>Comment naming of exported method `load`<commit_after>// Forsaken docs justly quibble the vexed programmer's waning zeal
//! Text hyphenation in a variety of languages.
//!
//!
//! ## Usage
//!
//! A typical import comprises the `Hyphenation` trait, the `Standard`
//! hyphenator, and the `Language` enum. This exposes the crate's core
//! functionality, and the set of available languages.
//!
//! ```ignore
//! extern crate hyphenation;
//
//! use hyphenation::{Hyphenation, Standard, Language};
//! ```
//!
//! To begin with, we must initiate the `Corpus` for our working language.
//!
//! ```ignore
//! let english_us = hyphenation::load(Language::English_US).unwrap();
//! ```
//!
//! Our English `Corpus` can now be used by `Hyphenation` methods.
//! Core functionality is provided by `opportunities()`, which returns the
//! byte indices of valid hyphenation points within a word.
//!
//! ```ignore
//! let indices = "hyphenation".opportunities(&english_us);
//! assert_eq!(indices, vec![2, 6]);
//! ```
//!
//! The same `Corpus` may also be used by *hyphenators*: iterators which
//! segment words in accordance with hyphenation practices, as described
//! by the corpus.
//!
//! The simplest (and, presently, only) hyphenator is `Standard`:
//!
//! ```ignore
//! let h: Standard = "hyphenation".hyphenate(&english_us);
//! ```
//!
//! The `Standard` hyphenator does not allocate new strings, returning
//! slices instead.
//!
//! ```ignore
//! let v: Vec<&str> = h.collect();
//! assert_eq!(v, vec!["hy", "phen", "ation"]);
//! ```
//!
//! ## Full-text Hyphenation
//! While hyphenation is always performed on a per-word basis, convenience
//! calls for a subtrait to provide methods to work with full text.
//!
//! ```ignore
//! use hyphenation::{FullTextHyphenation};
//!
//! let h2: Standard = "Word hyphenation by computer.".fulltext_hyphenate(&english_us);
//! let v2: Vec<&str> = h2.collect();
//! assert_eq!(v2, vec!["Word hy", "phen", "ation by com", "puter."]);
//! ```
//!
//! Hyphenators also expose some simple methods to render hyphenated text:
//! `punctuate()` and `punctuate_with(string)`, which mark hyphenation
//! opportunities respectively with soft hyphens (Unicode `U+00AD SOFT HYPHEN`)
//! and any given `string`.
//!
//! ```ignore
//! let h3 = "anfractuous".hyphenate(&english_us);
//! let s3: String = h2.clone().punctuate().collect();
//! assert_eq!(s3, "an\u{ad}frac\u{ad}tu\u{ad}ous".to_owned());
//!
//! let s4: String = h2.punctuate_with("-").collect()
//! assert_eq!(s4, "an-frac-tu-ous".to_owned());
//! ```

extern crate bincode;
extern crate fnv;
extern crate klpattern;
extern crate unicode_segmentation;

mod resources;
mod utilia;
pub mod hyphenator;
pub mod language;
pub mod load;

pub use klpattern::{KLPair, KLPTrie, Exceptions, Patterns};
pub use hyphenator::{Hyphenation, FullTextHyphenation, Standard};
pub use language::{Language, Corpus};

// Note: the name "load" is misleading, as we are merely accessing embedded tries.
// However, future versions of `hyphenation` should support both embedding
// and runtime loading of pattern data, with loading being the default;
// anticipating such changes, we keep `load` as a public export.
pub use load::{language as load};
<|endoftext|>


<commit_before>extern crate base64;
extern crate hyper;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
extern crate log4rs;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;

pub mod ctapi;
pub mod http;
pub mod logging;

#[no_mangle]
#[allow(non_snake_case, unused_must_use)]
pub extern "system" fn CT_init(ctn: u16, pn: u16) -> i8 {
    ctapi::init::init(ctn, pn)
}

#[no_mangle]
#[allow(non_snake_case)]
pub extern "system" fn CT_data(ctn: u16,
                               dad: *mut u8,
                               sad: *mut u8,
                               lenc: usize,
                               command: *const u8,
                               lenr: *mut usize,
                               response: *mut u8)
                               -> i8 {
    ctapi::data::data(ctn, dad, sad, lenc, command, lenr, response)
}

#[no_mangle]
#[allow(non_snake_case)]
pub extern "system" fn CT_close(ctn: u16) -> i8 {
    ctapi::close::close(ctn)
}
<commit_msg>remove unused meta info from public extern CT_init<commit_after>extern crate base64;
extern crate hyper;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
extern crate log4rs;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;

pub mod ctapi;
pub mod http;
pub mod logging;

#[no_mangle]
#[allow(non_snake_case)]
pub extern "system" fn CT_init(ctn: u16, pn: u16) -> i8 {
    ctapi::init::init(ctn, pn)
}

#[no_mangle]
#[allow(non_snake_case)]
pub extern "system" fn CT_data(ctn: u16,
                               dad: *mut u8,
                               sad: *mut u8,
                               lenc: usize,
                               command: *const u8,
                               lenr: *mut usize,
                               response: *mut u8)
                               -> i8 {
    ctapi::data::data(ctn, dad, sad, lenc, command, lenr, response)
}

#[no_mangle]
#[allow(non_snake_case)]
pub extern "system" fn CT_close(ctn: u16) -> i8 {
    ctapi::close::close(ctn)
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2016 Boucher, Antoni <bouanto@zoho.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/*
 * TODO: Try to return an Application directly instead of an Rc<Application>.
 * TODO: support shortcuts with number like "50G".
 */

//! Minimal UI library based on GTK+.

#![warn(missing_docs)]

extern crate gdk;
extern crate glib;
extern crate gtk;
extern crate gtk_sys;
extern crate mg_settings;

mod key_converter;
#[macro_use]
mod widget;
mod status_bar;

use std::cell::RefCell;
use std::collections::HashMap;
use std::fs::File;
use std::io::BufReader;
use std::rc::Rc;

use gdk::{CONTROL_MASK, EventKey};
use gdk::enums::key::{Escape, colon};
use gtk::{ContainerExt, Grid, Inhibit, IsA, Widget, WidgetExt, Window, WindowExt, WindowType};
use mg_settings::{Config, EnumFromStr, Parser};
use mg_settings::Command::{Custom, Include, Map, Set, Unmap};
use mg_settings::error::{Error, Result};
use mg_settings::error::ErrorType::{MissingArgument, NoCommand, Parse, UnknownCommand};
use mg_settings::key::Key;

use key_converter::gdk_key_to_key;
use self::ShortcutCommand::{Complete, Incomplete};
use status_bar::StatusBar;

/// A command from a map command.
#[derive(Debug)]
enum ShortcutCommand {
    /// A complete command that is to be executed.
    Complete(String),
    /// An incomplete command where the user needs to complete it and press Enter.
    Incomplete(String),
    /// No command.
    NoCommand,
}

/// Create a new MG application window.
/// This window contains a status bar where the user can type a command and a central widget.
pub struct Application<T> {
    command_callback: RefCell<Option<Box<Fn(T)>>>,
    current_mode: String,
    current_shortcut: RefCell<Vec<Key>>,
    mappings: RefCell<HashMap<String, HashMap<Vec<Key>, String>>>,
    settings_parser: RefCell<Parser<T>>,
    status_bar: StatusBar,
    vbox: Grid,
    window: Window,
}

impl<T: EnumFromStr + 'static> Application<T> {
    /// Create a new application.
    #[allow(new_without_default)]
    pub fn new() -> Rc<Self> {
        Application::new_with_config(Config::default())
    }

    /// Create a new application with configuration.
    pub fn new_with_config(config: Config) -> Rc<Self> {
        let window = Window::new(WindowType::Toplevel);
        window.connect_delete_event(|_, _| {
            gtk::main_quit();
            Inhibit(false)
        });

        let grid = Grid::new();
        window.add(&grid);

        let status_bar = StatusBar::new();
        grid.attach(&status_bar, 0, 1, 1, 1);
        window.show_all();
        status_bar.hide();

        let app = Rc::new(Application {
            command_callback: RefCell::new(None),
            current_mode: "n".to_string(),
            current_shortcut: RefCell::new(vec![]),
            mappings: RefCell::new(HashMap::new()),
            settings_parser: RefCell::new(Parser::new_with_config(config)),
            status_bar: status_bar,
            vbox: grid,
            window: window,
        });

        {
            let instance = app.clone();
            app.status_bar.connect_activate(move |command| instance.handle_command(command));
        }

        {
            let instance = app.clone();
            app.window.connect_key_press_event(move |_, key| instance.key_press(key));
        }

        app
    }

    /// Convert an action String to a command String.
    fn action_to_command(&self, action: &str) -> ShortcutCommand {
        if let Some(':') = action.chars().next() {
            if let Some(index) = action.find("<Enter>") {
                Complete(action[1..index].to_string())
            }
            else {
                Incomplete(action[1..].to_string())
            }
        }
        else {
            ShortcutCommand::NoCommand
        }
    }

    /// Add the key to the current shortcut.
    fn add_to_shortcut(&self, key: Key) {
        let mut shortcut = self.current_shortcut.borrow_mut();
        shortcut.push(key);
    }

    /// Add a callback to the command event.
    pub fn connect_command<F: Fn(T) + 'static>(&self, callback: F) {
        *self.command_callback.borrow_mut() = Some(Box::new(callback));
    }

    /// Handle the command activate event.
    fn handle_command(&self, command: Option<String>) {
        if let Some(command) = command {
            if let Some(ref callback) = *self.command_callback.borrow() {
                let result = self.settings_parser.borrow_mut().parse_line(&command);
                match result {
                    Ok(command) => {
                        match command {
                            Custom(command) => callback(command),
                            _ => unimplemented!(),
                        }
                    },
                    Err(error) => {
                        if let Some(error) = error.downcast_ref::<Error>() {
                            let message =
                                match error.typ {
                                    MissingArgument => "Argument required".to_string(),
                                    NoCommand => return,
                                    Parse => format!("Parse error: unexpected {}, expecting: {}", error.unexpected, error.expected),
                                    UnknownCommand => format!("Not a command: {}", error.unexpected),
                                };
                            self.status_bar.show_error(&message);
                        }
                    },
                }
            }
            self.status_bar.hide_entry();
        }
    }

    /// Handle a possible input of a shortcut.
    fn handle_shortcut(&self, key: &EventKey) -> Inhibit {
        if !self.status_bar.entry_shown() {
            let control_pressed = key.get_state() & CONTROL_MASK == CONTROL_MASK;
            if let Some(key) = gdk_key_to_key(key.get_keyval(), control_pressed) {
                self.add_to_shortcut(key);
                let action = {
                    let shortcut = self.current_shortcut.borrow();
                    let mappings = self.mappings.borrow();
                    mappings[&self.current_mode].get(&*shortcut).cloned()
                };
                if let Some(action) = action {
                    self.reset();
                    match self.action_to_command(&action) {
                        Complete(command) => self.handle_command(Some(command)),
                        Incomplete(command) => {
                            self.input_command(&command);
                            return Inhibit(true);
                        },
                        ShortcutCommand::NoCommand => (),
                    }
                }
            }
        }
        Inhibit(false)
    }

    /// Input the specified command.
    fn input_command(&self, command: &str) {
        self.status_bar.show_entry();
        self.status_bar.set_command(&format!("{} ", command));
    }

    /// Handle the key press event.
    #[allow(non_upper_case_globals)]
    fn key_press(&self, key: &EventKey) -> Inhibit {
        match key.get_keyval() {
            colon => {
                if !self.status_bar.entry_shown() {
                    self.reset();
                    self.status_bar.show_entry();
                    Inhibit(true)
                }
                else {
                    Inhibit(false)
                }
            },
            Escape => {
                self.reset();
                Inhibit(true)
            },
            _ => self.handle_shortcut(key),
        }
    }

    /// Parse a configuration file.
    pub fn parse_config(&self, filename: &str) -> Result<()> {
        let file = try!(File::open(filename));
        let buf_reader = BufReader::new(file);
        let commands = try!(self.settings_parser.borrow_mut().parse(buf_reader));
        for command in commands {
            match command {
                Custom(_) => (), // TODO: call the callback?
                Include(_) => (), // TODO: parse the included file.
                Map { action, keys, mode } => {
                    let mut mappings = self.mappings.borrow_mut();
                    let mappings = mappings.entry(mode).or_insert_with(HashMap::new);
                    mappings.insert(keys, action);
                },
                Set(_, _) => (), // TODO: set settings.
                Unmap { .. } => (), // TODO
            }
        }
        Ok(())
    }

    /// Handle the escape event.
    fn reset(&self) {
        self.status_bar.hide();
        let mut shortcut = self.current_shortcut.borrow_mut();
        shortcut.clear();
    }

    /// Set the main widget.
    pub fn set_view<W: IsA<Widget> + WidgetExt>(&self, view: &W) {
        view.set_hexpand(true);
        view.set_vexpand(true);
        view.show_all();
        self.vbox.attach(view, 0, 0, 1, 1);
    }

    /// Set the window title.
    pub fn set_window_title(&self, title: &str) {
        self.window.set_title(title);
    }

    /// Get the application window.
    pub fn window(&self) -> &Window {
        &self.window
    }
}
<commit_msg>Fixed shortcut bug.<commit_after>/*
 * Copyright (c) 2016 Boucher, Antoni <bouanto@zoho.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/*
 * TODO: Try to return an Application directly instead of an Rc<Application>.
 * TODO: support shortcuts with number like "50G".
 */

//! Minimal UI library based on GTK+.

#![warn(missing_docs)]

extern crate gdk;
extern crate glib;
extern crate gtk;
extern crate gtk_sys;
extern crate mg_settings;

mod key_converter;
#[macro_use]
mod widget;
mod status_bar;

use std::cell::RefCell;
use std::collections::HashMap;
use std::fs::File;
use std::io::BufReader;
use std::rc::Rc;

use gdk::{CONTROL_MASK, EventKey};
use gdk::enums::key::{Escape, colon};
use gtk::{ContainerExt, Grid, Inhibit, IsA, Widget, WidgetExt, Window, WindowExt, WindowType};
use mg_settings::{Config, EnumFromStr, Parser};
use mg_settings::Command::{Custom, Include, Map, Set, Unmap};
use mg_settings::error::{Error, Result};
use mg_settings::error::ErrorType::{MissingArgument, NoCommand, Parse, UnknownCommand};
use mg_settings::key::Key;

use key_converter::gdk_key_to_key;
use self::ShortcutCommand::{Complete, Incomplete};
use status_bar::StatusBar;

/// A command from a map command.
#[derive(Debug)]
enum ShortcutCommand {
    /// A complete command that is to be executed.
    Complete(String),
    /// An incomplete command where the user needs to complete it and press Enter.
    Incomplete(String),
    /// No command.
    NoCommand,
}

/// Create a new MG application window.
/// This window contains a status bar where the user can type a command and a central widget.
pub struct Application<T> {
    command_callback: RefCell<Option<Box<Fn(T)>>>,
    current_mode: String,
    current_shortcut: RefCell<Vec<Key>>,
    mappings: RefCell<HashMap<String, HashMap<Vec<Key>, String>>>,
    settings_parser: RefCell<Parser<T>>,
    status_bar: StatusBar,
    vbox: Grid,
    window: Window,
}

impl<T: EnumFromStr + 'static> Application<T> {
    /// Create a new application.
    #[allow(new_without_default)]
    pub fn new() -> Rc<Self> {
        Application::new_with_config(Config::default())
    }

    /// Create a new application with configuration.
    pub fn new_with_config(config: Config) -> Rc<Self> {
        let window = Window::new(WindowType::Toplevel);
        window.connect_delete_event(|_, _| {
            gtk::main_quit();
            Inhibit(false)
        });

        let grid = Grid::new();
        window.add(&grid);

        let status_bar = StatusBar::new();
        grid.attach(&status_bar, 0, 1, 1, 1);
        window.show_all();
        status_bar.hide();

        let app = Rc::new(Application {
            command_callback: RefCell::new(None),
            current_mode: "n".to_string(),
            current_shortcut: RefCell::new(vec![]),
            mappings: RefCell::new(HashMap::new()),
            settings_parser: RefCell::new(Parser::new_with_config(config)),
            status_bar: status_bar,
            vbox: grid,
            window: window,
        });

        {
            let instance = app.clone();
            app.status_bar.connect_activate(move |command| instance.handle_command(command));
        }

        {
            let instance = app.clone();
            app.window.connect_key_press_event(move |_, key| instance.key_press(key));
        }

        app
    }

    /// Convert an action String to a command String.
    fn action_to_command(&self, action: &str) -> ShortcutCommand {
        if let Some(':') = action.chars().next() {
            if let Some(index) = action.find("<Enter>") {
                Complete(action[1..index].to_string())
            }
            else {
                Incomplete(action[1..].to_string())
            }
        }
        else {
            ShortcutCommand::NoCommand
        }
    }

    /// Add the key to the current shortcut.
    fn add_to_shortcut(&self, key: Key) {
        let mut shortcut = self.current_shortcut.borrow_mut();
        shortcut.push(key);
    }

    /// Add a callback to the command event.
    pub fn connect_command<F: Fn(T) + 'static>(&self, callback: F) {
        *self.command_callback.borrow_mut() = Some(Box::new(callback));
    }

    /// Handle the command activate event.
    fn handle_command(&self, command: Option<String>) {
        if let Some(command) = command {
            if let Some(ref callback) = *self.command_callback.borrow() {
                let result = self.settings_parser.borrow_mut().parse_line(&command);
                match result {
                    Ok(command) => {
                        match command {
                            Custom(command) => callback(command),
                            _ => unimplemented!(),
                        }
                    },
                    Err(error) => {
                        if let Some(error) = error.downcast_ref::<Error>() {
                            let message =
                                match error.typ {
                                    MissingArgument => "Argument required".to_string(),
                                    NoCommand => return,
                                    Parse => format!("Parse error: unexpected {}, expecting: {}", error.unexpected, error.expected),
                                    UnknownCommand => format!("Not a command: {}", error.unexpected),
                                };
                            self.status_bar.show_error(&message);
                        }
                    },
                }
            }
            self.status_bar.hide_entry();
        }
    }

    /// Handle a possible input of a shortcut.
    fn handle_shortcut(&self, key: &EventKey) -> Inhibit {
        if !self.status_bar.entry_shown() {
            let control_pressed = key.get_state() & CONTROL_MASK == CONTROL_MASK;
            if let Some(key) = gdk_key_to_key(key.get_keyval(), control_pressed) {
                self.add_to_shortcut(key);
                let action = {
                    let shortcut = self.current_shortcut.borrow();
                    let mappings = self.mappings.borrow();
                    mappings.get(&self.current_mode)
                        .and_then(|mappings| mappings.get(&*shortcut).cloned())
                };
                if let Some(action) = action {
                    self.reset();
                    match self.action_to_command(&action) {
                        Complete(command) => self.handle_command(Some(command)),
                        Incomplete(command) => {
                            self.input_command(&command);
                            return Inhibit(true);
                        },
                        ShortcutCommand::NoCommand => (),
                    }
                }
            }
        }
        Inhibit(false)
    }

    /// Input the specified command.
    fn input_command(&self, command: &str) {
        self.status_bar.show_entry();
        self.status_bar.set_command(&format!("{} ", command));
    }

    /// Handle the key press event.
    #[allow(non_upper_case_globals)]
    fn key_press(&self, key: &EventKey) -> Inhibit {
        match key.get_keyval() {
            colon => {
                if !self.status_bar.entry_shown() {
                    self.reset();
                    self.status_bar.show_entry();
                    Inhibit(true)
                }
                else {
                    Inhibit(false)
                }
            },
            Escape => {
                self.reset();
                Inhibit(true)
            },
            _ => self.handle_shortcut(key),
        }
    }

    /// Parse a configuration file.
    pub fn parse_config(&self, filename: &str) -> Result<()> {
        let file = try!(File::open(filename));
        let buf_reader = BufReader::new(file);
        let commands = try!(self.settings_parser.borrow_mut().parse(buf_reader));
        for command in commands {
            match command {
                Custom(_) => (), // TODO: call the callback?
                Include(_) => (), // TODO: parse the included file.
                Map { action, keys, mode } => {
                    let mut mappings = self.mappings.borrow_mut();
                    let mappings = mappings.entry(mode).or_insert_with(HashMap::new);
                    mappings.insert(keys, action);
                },
                Set(_, _) => (), // TODO: set settings.
                Unmap { .. } => (), // TODO
            }
        }
        Ok(())
    }

    /// Handle the escape event.
    fn reset(&self) {
        self.status_bar.hide();
        let mut shortcut = self.current_shortcut.borrow_mut();
        shortcut.clear();
    }

    /// Set the main widget.
    pub fn set_view<W: IsA<Widget> + WidgetExt>(&self, view: &W) {
        view.set_hexpand(true);
        view.set_vexpand(true);
        view.show_all();
        self.vbox.attach(view, 0, 0, 1, 1);
    }

    /// Set the window title.
    pub fn set_window_title(&self, title: &str) {
        self.window.set_title(title);
    }

    /// Get the application window.
    pub fn window(&self) -> &Window {
        &self.window
    }
}
<|endoftext|>