<commit_before>use glutin_window::GlutinWindow;
use graphics::{DrawState, Transformed};
use graphics::text::Text;
use opengl_graphics::GlGraphics;
use opengl_graphics::glyph_cache::GlyphCache;
use piston::event_loop::Events;
use piston::input::{Button, Event, Input, Key, RenderArgs, UpdateArgs};
use rand::Rng;
use std::cell::RefCell;
use std::borrow::BorrowMut;
use std::path::Path;
use std::iter::repeat;
use std::rc::Rc;

use actors::{Astroid, Bullet, Spaceship};

pub trait Scene {
    fn events(&mut self, &mut Rng, Rc<RefCell<GlutinWindow>>, &mut GlGraphics, (f64, f64)) -> Option<Box<Scene>>;
}

#[derive(Clone)]
pub struct MainScene {
    difficulty: usize,
    spaceship: Spaceship,
    bullets: Vec<Bullet>,
    astroids: Vec<Astroid>,
}

impl MainScene {
    pub fn new(difficulty: usize, rng: &mut Rng) -> MainScene {
        return MainScene{
            difficulty: difficulty,
            spaceship: Spaceship::new(),
            bullets: Vec::new(),
            astroids: repeat(0).take(difficulty).map(|_| Astroid::large_new(rng))
                .collect(),
        };
    }

    fn draw(&self, r: RenderArgs, ds: DrawState, gl: &mut GlGraphics) {
        use graphics::clear;
        gl.draw(r.viewport(), |c, gl| {
            clear(BLACK, gl);
            for astroid in self.astroids.iter() {
                astroid.draw(WHITE, &ds, c.transform, gl);
            }
            self.spaceship.draw(WHITE, &ds, c.transform, gl);
            for bullet in self.bullets.iter() {
                bullet.draw(WHITE, c.transform, gl);
            }
        })
    }

    fn update(&mut self, u: UpdateArgs, rng: &mut Rng, (width, height): (f64, f64)) -> Option<Box<Scene>> {
        self.spaceship.accelerate(u.dt);
        self.spaceship.turn(u.dt);
        self.spaceship.go(u.dt, width, height);
        self.spaceship.cooldown(u.dt);
        for ref mut astroid in self.astroids.iter_mut() {
            astroid.go(u.dt, width, height);
        }
        {
            let astroid_edges = self.astroids.iter()
                .flat_map(|astroid| astroid.edges());
            if self.spaceship.collides(astroid_edges) {
                return Some(Box::new(GameOverScene::new(self)));
            }
        }
        if self.spaceship.is_firing() && self.spaceship.ready_to_fire() {
            self.spaceship.fire(&mut self.bullets);
        }
        let mut new_bullets = Vec::with_capacity(self.bullets.len());
        for mut bullet in self.bullets.iter_mut() {
            bullet.go(u.dt, width, height);
            let mut collided = false;
            self.astroids = self.astroids.iter().flat_map(|a| {
                if bullet.collides(a) {
                    collided = true;
                    a.explode(rng)
                } else {
                    vec![a.clone()]
                }
            }).collect();
            if !collided {
                new_bullets.push(bullet.clone());
            }
        }
        new_bullets.retain(Bullet::is_alive);
        self.bullets = new_bullets;
        if self.astroids.len() == 0 {
            return Some(Box::new(MainScene::new(self.difficulty + 1, rng)));
        }
        return None;
    }
}

const WHITE: [f32; 4] = [1.0, 1.0, 1.0, 1.0];
const BLACK: [f32; 4] = [0.0, 0.0, 0.0, 1.0];

impl Scene for MainScene {
    fn events(&mut self, mut rng: &mut Rng, window: Rc<RefCell<GlutinWindow>>, gl: &mut GlGraphics, dimensions: (f64, f64)) -> Option<Box<Scene>> {

        let ds = DrawState::new();
        let ev = window.events();
        for e in ev {
            match e {
                Event::Update(u) => {
                    let scene_change = self.update(u, rng, dimensions);
                    if scene_change.is_some() {
                        return scene_change;
                    }
                },
                Event::Render(r) => self.draw(r, ds, gl),
                Event::Input(Input::Press(Button::Keyboard(k))) => {
                    self.spaceship.handle_press(k);
                    match k {
                        Key::R => return Some(Box::new(MainScene::new(1, &mut rng))),
                        Key::Q => return None,
                        _ => (),
                    }
                },
                Event::Input(Input::Release(Button::Keyboard(k))) => {
                    self.spaceship.handle_release(k);
                },
                _ => (),
            }
        }
        return None;
    }
}

struct GameOverScene {
    end_game: MainScene
}

impl GameOverScene {
    fn new(end_game: &MainScene) -> GameOverScene {
        GameOverScene {
            end_game: end_game.clone(),
        }
    }
}

impl Scene for GameOverScene {
    fn events(&mut self, rng: &mut Rng, window: Rc<RefCell<GlutinWindow>>, gl: &mut GlGraphics, (x_max, y_max): (f64, f64)) -> Option<Box<Scene>> {
        let ds = DrawState::new();
        let game_over_text = Text::new_color(WHITE, 20);
        let mut character_cache: Box<GlyphCache> = Box::new(GlyphCache::new(Path::new("/usr/share/fonts/TTF/DejaVuSans.ttf")).unwrap());
        for e in window.events() {
            match e {
                Event::Render(r) => {
                    self.end_game.draw(r, ds, gl);
                    gl.draw(r.viewport(), |c, gl| {
                        game_over_text.draw("Game Over", character_cache.borrow_mut() as &mut GlyphCache, &ds, c.transform.trans(x_max/2.0, y_max/2.0), gl);
                    });
                },
                Event::Input(Input::Press(k)) => match k {
                    Button::Keyboard(Key::Space) => return Some(Box::new(MainScene::new(1, rng))),
                    Button::Keyboard(Key::Q) => return None,
                    _ => (),
                },
                _ => (),
            }
        }
        return None;
    }
}<commit_msg>R now restarts the game on the game over screen<commit_after>use glutin_window::GlutinWindow;
use graphics::{DrawState, Transformed};
use graphics::text::Text;
use opengl_graphics::GlGraphics;
use opengl_graphics::glyph_cache::GlyphCache;
use piston::event_loop::Events;
use piston::input::{Button, Event, Input, Key, RenderArgs, UpdateArgs};
use rand::Rng;
use std::cell::RefCell;
use std::borrow::BorrowMut;
use std::path::Path;
use std::iter::repeat;
use std::rc::Rc;

use actors::{Astroid, Bullet, Spaceship};

pub trait Scene {
    fn events(&mut self, &mut Rng, Rc<RefCell<GlutinWindow>>, &mut GlGraphics, (f64, f64)) -> Option<Box<Scene>>;
}

#[derive(Clone)]
pub struct MainScene {
    difficulty: usize,
    spaceship: Spaceship,
    bullets: Vec<Bullet>,
    astroids: Vec<Astroid>,
}

impl MainScene {
    pub fn new(difficulty: usize, rng: &mut Rng) -> MainScene {
        return MainScene{
            difficulty: difficulty,
            spaceship: Spaceship::new(),
            bullets: Vec::new(),
            astroids: repeat(0).take(difficulty).map(|_| Astroid::large_new(rng))
                .collect(),
        };
    }

    fn draw(&self, r: RenderArgs, ds: DrawState, gl: &mut GlGraphics) {
        use graphics::clear;
        gl.draw(r.viewport(), |c, gl| {
            clear(BLACK, gl);
            for astroid in self.astroids.iter() {
                astroid.draw(WHITE, &ds, c.transform, gl);
            }
            self.spaceship.draw(WHITE, &ds, c.transform, gl);
            for bullet in self.bullets.iter() {
                bullet.draw(WHITE, c.transform, gl);
            }
        })
    }

    fn update(&mut self, u: UpdateArgs, rng: &mut Rng, (width, height): (f64, f64)) -> Option<Box<Scene>> {
        self.spaceship.accelerate(u.dt);
        self.spaceship.turn(u.dt);
        self.spaceship.go(u.dt, width, height);
        self.spaceship.cooldown(u.dt);
        for ref mut astroid in self.astroids.iter_mut() {
            astroid.go(u.dt, width, height);
        }
        {
            let astroid_edges = self.astroids.iter()
                .flat_map(|astroid| astroid.edges());
            if self.spaceship.collides(astroid_edges) {
                return Some(Box::new(GameOverScene::new(self)));
            }
        }
        if self.spaceship.is_firing() && self.spaceship.ready_to_fire() {
            self.spaceship.fire(&mut self.bullets);
        }
        let mut new_bullets = Vec::with_capacity(self.bullets.len());
        for mut bullet in self.bullets.iter_mut() {
            bullet.go(u.dt, width, height);
            let mut collided = false;
            self.astroids = self.astroids.iter().flat_map(|a| {
                if bullet.collides(a) {
                    collided = true;
                    a.explode(rng)
                } else {
                    vec![a.clone()]
                }
            }).collect();
            if !collided {
                new_bullets.push(bullet.clone());
            }
        }
        new_bullets.retain(Bullet::is_alive);
        self.bullets = new_bullets;
        if self.astroids.len() == 0 {
            return Some(Box::new(MainScene::new(self.difficulty + 1, rng)));
        }
        return None;
    }
}

const WHITE: [f32; 4] = [1.0, 1.0, 1.0, 1.0];
const BLACK: [f32; 4] = [0.0, 0.0, 0.0, 1.0];

impl Scene for MainScene {
    fn events(&mut self, mut rng: &mut Rng, window: Rc<RefCell<GlutinWindow>>, gl: &mut GlGraphics, dimensions: (f64, f64)) -> Option<Box<Scene>> {

        let ds = DrawState::new();
        let ev = window.events();
        for e in ev {
            match e {
                Event::Update(u) => {
                    let scene_change = self.update(u, rng, dimensions);
                    if scene_change.is_some() {
                        return scene_change;
                    }
                },
                Event::Render(r) => self.draw(r, ds, gl),
                Event::Input(Input::Press(Button::Keyboard(k))) => {
                    self.spaceship.handle_press(k);
                    match k {
                        Key::R => return Some(Box::new(MainScene::new(1, &mut rng))),
                        Key::Q => return None,
                        _ => (),
                    }
                },
                Event::Input(Input::Release(Button::Keyboard(k))) => {
                    self.spaceship.handle_release(k);
                },
                _ => (),
            }
        }
        return None;
    }
}

struct GameOverScene {
    end_game: MainScene
}

impl GameOverScene {
    fn new(end_game: &MainScene) -> GameOverScene {
        GameOverScene {
            end_game: end_game.clone(),
        }
    }
}

impl Scene for GameOverScene {
    fn events(&mut self, rng: &mut Rng, window: Rc<RefCell<GlutinWindow>>, gl: &mut GlGraphics, (x_max, y_max): (f64, f64)) -> Option<Box<Scene>> {
        let ds = DrawState::new();
        let game_over_text = Text::new_color(WHITE, 20);
        let mut character_cache: Box<GlyphCache> = Box::new(GlyphCache::new(Path::new("/usr/share/fonts/TTF/DejaVuSans.ttf")).unwrap());
        for e in window.events() {
            match e {
                Event::Render(r) => {
                    self.end_game.draw(r, ds, gl);
                    gl.draw(r.viewport(), |c, gl| {
                        game_over_text.draw("Game Over", character_cache.borrow_mut() as &mut GlyphCache, &ds, c.transform.trans(x_max/2.0, y_max/2.0), gl);
                    });
                },
                Event::Input(Input::Press(k)) => match k {
                    Button::Keyboard(Key::Space)|Button::Keyboard(Key::R) => return Some(Box::new(MainScene::new(1, rng))),
                    Button::Keyboard(Key::Q) => return None,
                    _ => (),
                },
                _ => (),
            }
        }
        return None;
    }
}<|endoftext|>


<commit_before>use std::borrow::Borrow;

use cfg_if::cfg_if;

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

/// An OAuth token used to log into Twitter.
#[cfg_attr(
    feature = "tweetust",
    doc = "

This implements `tweetust::conn::Authenticator` so you can pass it to
`tweetust::TwitterClient` as if it were `tweetust::OAuthAuthenticator`"
)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[derive(Copy, Clone, Debug)]
pub struct Token<C = String, A = String> {
    pub consumer_key: C,
    pub consumer_secret: C,
    pub access_key: A,
    pub access_secret: A,
}

impl<C: Borrow<str>, A: Borrow<str>> Token<C, A> {
    pub fn new(consumer_key: C, consumer_secret: C, access_key: A, access_secret: A) -> Self {
        Token {
            consumer_key,
            consumer_secret,
            access_key,
            access_secret,
        }
    }

    /// Borrow token strings from `self` and make a new `Token` with them.
    pub fn borrowed(&self) -> Token<&str, &str> {
        Token::new(
            self.consumer_key.borrow(),
            self.consumer_secret.borrow(),
            self.access_key.borrow(),
            self.access_secret.borrow(),
        )
    }
}

cfg_if! {
    if #[cfg(feature = "egg-mode")] {
        extern crate egg_mode;

        use std::borrow::Cow;

        use self::egg_mode::KeyPair;

        impl<'a, C, A> From<Token<C, A>> for egg_mode::Token
            where C: Into<Cow<'static, str>>, A: Into<Cow<'static, str>>
        {
            fn from(t: Token<C, A>) -> Self {
                egg_mode::Token::Access {
                    consumer: KeyPair::new(t.consumer_key, t.consumer_secret),
                    access: KeyPair::new(t.access_key, t.access_secret),
                }
            }
        }
    }
}

cfg_if! {
    if #[cfg(feature = "use-tweetust")] {
        extern crate oauthcli;
        extern crate tweetust;

        use self::oauthcli::{OAuthAuthorizationHeaderBuilder, SignatureMethod};
        use self::tweetust::conn::{Request, RequestContent};
        use self::tweetust::conn::oauth_authenticator::OAuthAuthorizationScheme;

        impl<C, A> tweetust::conn::Authenticator for Token<C, A>
            where C: Borrow<str>, A: Borrow<str>
        {
            type Scheme = OAuthAuthorizationScheme;

            fn create_authorization_header(&self, request: &Request)
                -> Option<OAuthAuthorizationScheme>
            {
                let mut header = OAuthAuthorizationHeaderBuilder::new(
                    request.method.as_ref(),
                    &request.url,
                    self.consumer_key.borrow(),
                    self.consumer_secret.borrow(),
                    SignatureMethod::HmacSha1,
                );

                if let RequestContent::WwwForm(ref params) = request.content {
                    header.request_parameters(
                        params.iter().map(|&(ref k, ref v)| (&**k, &**v))
                    );
                }

                Some(OAuthAuthorizationScheme(header.finish_for_twitter()))
            }
        }
    }
}
<commit_msg>Fix `tweetust::conn::Authenticator` impl for `Token`<commit_after>use std::borrow::Borrow;

use cfg_if::cfg_if;

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

/// An OAuth token used to log into Twitter.
#[cfg_attr(
    feature = "tweetust",
    doc = "

This implements `tweetust::conn::Authenticator` so you can pass it to
`tweetust::TwitterClient` as if it were `tweetust::OAuthAuthenticator`"
)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[derive(Copy, Clone, Debug)]
pub struct Token<C = String, A = String> {
    pub consumer_key: C,
    pub consumer_secret: C,
    pub access_key: A,
    pub access_secret: A,
}

impl<C: Borrow<str>, A: Borrow<str>> Token<C, A> {
    pub fn new(consumer_key: C, consumer_secret: C, access_key: A, access_secret: A) -> Self {
        Token {
            consumer_key,
            consumer_secret,
            access_key,
            access_secret,
        }
    }

    /// Borrow token strings from `self` and make a new `Token` with them.
    pub fn borrowed(&self) -> Token<&str, &str> {
        Token::new(
            self.consumer_key.borrow(),
            self.consumer_secret.borrow(),
            self.access_key.borrow(),
            self.access_secret.borrow(),
        )
    }
}

cfg_if! {
    if #[cfg(feature = "egg-mode")] {
        extern crate egg_mode;

        use std::borrow::Cow;

        use self::egg_mode::KeyPair;

        impl<'a, C, A> From<Token<C, A>> for egg_mode::Token
            where C: Into<Cow<'static, str>>, A: Into<Cow<'static, str>>
        {
            fn from(t: Token<C, A>) -> Self {
                egg_mode::Token::Access {
                    consumer: KeyPair::new(t.consumer_key, t.consumer_secret),
                    access: KeyPair::new(t.access_key, t.access_secret),
                }
            }
        }
    }
}

cfg_if! {
    if #[cfg(feature = "use-tweetust")] {
        extern crate oauthcli;
        extern crate tweetust;

        use self::oauthcli::{OAuthAuthorizationHeaderBuilder, SignatureMethod};
        use self::tweetust::conn::{Request, RequestContent};
        use self::tweetust::conn::oauth_authenticator::OAuthAuthorizationScheme;

        impl<C, A> tweetust::conn::Authenticator for Token<C, A>
            where C: Borrow<str>, A: Borrow<str>
        {
            type Scheme = OAuthAuthorizationScheme;

            fn create_authorization_header(&self, request: &Request)
                -> Option<OAuthAuthorizationScheme>
            {
                let mut header = OAuthAuthorizationHeaderBuilder::new(
                    request.method.as_ref(),
                    &request.url,
                    self.consumer_key.borrow(),
                    self.consumer_secret.borrow(),
                    SignatureMethod::HmacSha1,
                );
                header.token(self.access_key.borrow(), self.access_secret.borrow());

                if let RequestContent::WwwForm(ref params) = request.content {
                    header.request_parameters(
                        params.iter().map(|&(ref k, ref v)| (&**k, &**v))
                    );
                }

                Some(OAuthAuthorizationScheme(header.finish_for_twitter()))
            }
        }
    }
}
<|endoftext|>


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    let default_settings = get_settings();

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

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

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

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

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

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

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

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

            return settings;
        }
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    let default_settings = get_settings();

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

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

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

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

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

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

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

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

            return settings;
        }
    }

    default_settings
}
<|endoftext|>


<commit_before>use libc::{c_char, c_uint, c_int};
use ffi::prelude::LLVMValueRef;
use ffi::{core, LLVMAttribute};
use std::ffi::CString;
use std::{fmt, mem, ptr};
use std::ops::{Deref, Index};
use block::BasicBlock;
use context::{Context, GetContext};
use ty::{FunctionType, Type};
use util::{self, CastFrom};

/// A typed value that can be used as an operand in instructions.
pub struct Value;
native_ref!(&Value = LLVMValueRef);
impl Value {
    /// Create a new constant struct from the values given.
    pub fn new_struct<'a>(context: &'a Context, vals: &[&'a Value], packed: bool) -> &'a Value {
        unsafe { core::LLVMConstStructInContext(context.into(), vals.as_ptr() as *mut LLVMValueRef, vals.len() as c_uint, packed as c_int) }.into()
    }
    /// Create a new constant vector from the values given.
    pub fn new_vector<'a>(vals: &[&'a Value]) -> &'a Value {
        unsafe { core::LLVMConstVector(vals.as_ptr() as *mut LLVMValueRef, vals.len() as c_uint).into() }
    }
    /// Create a new constant C string from the text given.
    pub fn new_string<'a>(context: &'a Context, text: &str, rust_style: bool) -> &'a Value {
        unsafe {
            let ptr = text.as_ptr() as *const c_char;
            let len = text.len() as c_uint;
            core::LLVMConstStringInContext(context.into(), ptr, len, rust_style as c_int).into()
        }
    }
    /// Create a new constant undefined value of the given type.
    pub fn new_undef<'a>(ty: &'a Type) -> &'a Value {
        unsafe { core::LLVMGetUndef(ty.into()).into() }
    }
    /// Returns the name of this value, or `None` if it lacks a name
    pub fn get_name(&self) -> Option<&str> {
        unsafe {
            let c_name = core::LLVMGetValueName(self.into());
            util::to_null_str(c_name as *mut i8)
        }
    }
    /// Sets the name of this value
    pub fn set_name(&self, name: &str) {
        let c_name = CString::new(name).unwrap();
        unsafe {
            core::LLVMSetValueName(self.into(), c_name.as_ptr())
        }
    }
    /// Returns the type of this value
    pub fn get_type(&self) -> &Type {
        unsafe { core::LLVMTypeOf(self.into()) }.into()
    }
}

pub struct GlobalValue;
native_ref!(&GlobalValue = LLVMValueRef);
deref!(GlobalValue, Value);

impl GlobalValue
{
	/// Sets the initial value for this global.
	pub fn set_initializer(&self, value: &Value)
	{
	  unsafe { core::LLVMSetInitializer(self.into(), value.into()) }
	}

	/// Gets the initial value for this global.
	pub fn get_initializer(&self) -> &Value
	{
	  unsafe { core::LLVMGetInitializer(self.into()) }.into()
	}
}

impl CastFrom for GlobalValue
{
  type From = Value;

  fn cast<'a>(val: &'a Value) -> Option<&'a GlobalValue>
  {
    let gv = unsafe { core::LLVMIsAGlobalValue(val.into()) };
    if gv == ptr::null_mut() {
      None
    } else {
      Some(gv.into())
    }
 }
}

/// Comparative operations on values.
#[derive(Copy, Clone, Eq, PartialEq)]
pub enum Predicate {
    Equal,
    NotEqual,
    GreaterThan,
    GreaterThanOrEqual,
    LessThan,
    LessThanOrEqual
}
/// A function argument.
pub struct Arg;
native_ref!(&Arg = LLVMValueRef);
impl Deref for Arg {
    type Target = Value;
    fn deref(&self) -> &Value {
        unsafe { mem::transmute(self) }
    }
}
impl Arg {
    /// Add the attribute given to this argument.
    pub fn add_attribute(&self, attr: Attribute) {
        unsafe { core::LLVMAddAttribute(self.into(), attr.into()) }
    }
    /// Add all the attributes given to this argument.
    pub fn add_attributes(&self, attrs: &[Attribute]) {
        let mut sum = LLVMAttribute::empty();
        for attr in attrs {
            let attr:LLVMAttribute = (*attr).into();
            sum = sum | attr;
        }
        unsafe { core::LLVMAddAttribute(self.into(), sum.into()) }
    }
    /// Returns true if this argument has the attribute given.
    pub fn has_attribute(&self, attr: Attribute) -> bool {
        unsafe {
            let other = core::LLVMGetAttribute(self.into());
            other.contains(attr.into())
        }
    }
    /// Returns true if this argument has all the attributes given.
    pub fn has_attributes(&self, attrs: &[Attribute]) -> bool {
        unsafe {
            let other = core::LLVMGetAttribute(self.into());
            for &attr in attrs {
                if !other.contains(attr.into()) {
                    return false;
                }
            }
            return true;
        }
    }
    /// Remove an attribute from this argument.
    pub fn remove_attribute(&self, attr: Attribute) {
        unsafe { core::LLVMRemoveAttribute(self.into(), attr.into()) }
    }
}

/// A function that can be called and contains blocks.
pub struct Function;
native_ref!(&Function = LLVMValueRef);
impl Deref for Function {
    type Target = Value;
    fn deref(&self) -> &Value {
        unsafe { mem::transmute(self) }
    }
}
impl Index<usize> for Function {
    type Output = Arg;
    fn index(&self, index: usize) -> &Arg {
        unsafe {
            if index < core::LLVMCountParams(self.into()) as usize {
                core::LLVMGetParam(self.into(), index as c_uint).into()
            } else {
                panic!("no such index {} on {:?}", index, self.get_type())
            }
        }
    }
}
impl CastFrom for Function {
    type From = Value;
    fn cast<'a>(val: &'a Value) -> Option<&'a Function> {
        let ty = val.get_type();
        let mut is_func = ty.is_function();
        if let Some(elem) = ty.get_element() {
            is_func = is_func || elem.is_function()
        }
        if is_func {
            Some(unsafe { mem::transmute(val) })
        } else {
            None
        }
    }
}
impl Function {
    /// Add a basic block with the name given to the function and return it.
    pub fn append<'a>(&'a self, name: &str) -> &'a BasicBlock {
        util::with_cstr(name, |ptr| unsafe {
            core::LLVMAppendBasicBlockInContext(self.get_context().into(), self.into(), ptr).into()
        })
    }
    /// Returns the entry block of this function or `None` if there is none.
    pub fn get_entry(&self) -> Option<&BasicBlock> {
        unsafe { mem::transmute(core::LLVMGetEntryBasicBlock(self.into())) }
    }
    /// Returns the name of this function.
    pub fn get_name(&self) -> &str {
        unsafe {
            let c_name = core::LLVMGetValueName(self.into());
            util::to_str(c_name as *mut i8)
        }
    }
    /// Returns the function signature representing this function's signature.
    pub fn get_signature(&self) -> &FunctionType {
        unsafe {
            let ty = core::LLVMTypeOf(self.into());
            core::LLVMGetElementType(ty).into()
        }
    }
    /// Add the attribute given to this function.
    pub fn add_attribute(&self, attr: Attribute) {
        unsafe { core::LLVMAddFunctionAttr(self.into(), attr.into()) }
    }
    /// Add all the attributes given to this function.
    pub fn add_attributes(&self, attrs: &[Attribute]) {
        let mut sum = LLVMAttribute::empty();
        for attr in attrs {
            let attr:LLVMAttribute = (*attr).into();
            sum = sum | attr;
        }
        unsafe { core::LLVMAddFunctionAttr(self.into(), sum.into()) }
    }
    /// Returns true if the attribute given is set in this function.
    pub fn has_attribute(&self, attr: Attribute) -> bool {
        unsafe {
            let other = core::LLVMGetFunctionAttr(self.into());
            other.contains(attr.into())
        }
    }
    /// Returns true if all the attributes given is set in this function.
    pub fn has_attributes(&self, attrs: &[Attribute]) -> bool {
        unsafe {
            let other = core::LLVMGetFunctionAttr(self.into());
            for &attr in attrs {
                if !other.contains(attr.into()) {
                    return false;
                }
            }
            return true;
        }
    }
    /// Remove the attribute given from this function.
    pub fn remove_attribute(&self, attr: Attribute) {
        unsafe { core::LLVMRemoveFunctionAttr(self.into(), attr.into()) }
    }
}

impl<'a> IntoIterator for &'a Function
{
  type Item = &'a Arg;
  type IntoIter = ValueIter<'a, &'a Arg>;
  /// Iterate through the functions in the module
  fn into_iter(self) -> ValueIter<'a, &'a Arg>
  {
 		ValueIter::new(
 			unsafe { core::LLVMGetFirstParam(self.into()) },
 			core::LLVMGetNextParam
 		)
  }
}

impl GetContext for Function {
    fn get_context(&self) -> &Context {
        self.get_type().get_context()
    }
}
/// A way of indicating to LLVM how you want arguments / functions to be handled.
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
#[repr(C)]
pub enum Attribute {
    /// Zero-extended before or after call.
    ZExt =              0b1,
    /// Sign-extended before or after call.
    SExt =              0b10,
    /// Mark the function as not returning.
    NoReturn =          0b100,
    /// Force argument to be passed in register.
    InReg =             0b1000,
    /// Hidden pointer to structure to return.
    StructRet =         0b10000,
    /// Function doesn't unwind stack.
    NoUnwind =          0b100000,
    /// Consider to not alias after call.
    NoAlias =           0b1000000,
    /// Pass structure by value.
    ByVal =             0b10000000,
    /// Nested function static chain.
    Nest =              0b100000000,
    /// Function doesn't access memory.
    ReadNone =          0b1000000000,
    /// Function only reads from memory.
    ReadOnly =          0b10000000000,
    /// Never inline this function.
    NoInline =          0b100000000000,
    /// Always inline this function.
    AlwaysInline =      0b1000000000000,
    /// Optimize this function for size.
    OptimizeForSize =   0b10000000000000,
    /// Stack protection.
    StackProtect =      0b100000000000000,
    /// Stack protection required.
    StackProtectReq =   0b1000000000000000,
    /// Alignment of parameter (5 bits) stored as log2 of alignment with +1 bias 0 means unaligned (different from align(1)).
    Alignment =         0b10000000000000000,
    /// Function creates no aliases of pointer.
    NoCapture =         0b100000000000000000,
    /// Disable redzone.
    NoRedZone =         0b1000000000000000000,
    /// Disable implicit float instructions.
    NoImplicitFloat =   0b10000000000000000000,
    /// Naked function.
    Naked =             0b100000000000000000000,
    /// The source language has marked this function as inline.
    InlineHint =        0b1000000000000000000000,
    /// Alignment of stack for function (3 bits) stored as log2 of alignment with +1 bias 0 means unaligned (different from alignstack=(1)).
    StackAlignment =    0b11100000000000000000000000000,
    /// This function returns twice.
    ReturnsTwice =      0b100000000000000000000000000000,
    /// Function must be in unwind table.
    UWTable =           0b1000000000000000000000000000000,
    /// Function is called early/often, so lazy binding isn't effective.
    NonLazyBind =       0b10000000000000000000000000000000
}
impl From<LLVMAttribute> for Attribute {
    fn from(attr: LLVMAttribute) -> Attribute {
        unsafe { mem::transmute(attr) }
    }
}
impl From<Attribute> for LLVMAttribute {
    fn from(attr: Attribute) -> LLVMAttribute {
        unsafe { mem::transmute(attr) }
    }
}
impl GetContext for Value {
    fn get_context(&self) -> &Context {
        self.get_type().get_context()
    }
}
impl_display!(Value, LLVMPrintValueToString);

/// Value Iterator implementation.
///
/// T can be all descendent types of LLVMValueRef.
#[derive(Copy, Clone)]
pub struct ValueIter<'a, T: From<LLVMValueRef>> {
  cur    : LLVMValueRef,
  step   : unsafe extern "C" fn(LLVMValueRef) -> LLVMValueRef,
  marker1: ::std::marker::PhantomData<&'a ()>,
  marker2: ::std::marker::PhantomData<T>,
}

impl<'a, T: From<LLVMValueRef>> ValueIter<'a, T>
{
	pub fn new(cur: LLVMValueRef,
		         step: unsafe extern "C" fn(LLVMValueRef) -> LLVMValueRef) -> Self
	{
		ValueIter {
			cur: cur,
			step: step,
			marker1: ::std::marker::PhantomData,
			marker2: ::std::marker::PhantomData
		}
	}
}

impl<'a, T: From<LLVMValueRef>> Iterator for ValueIter<'a, T> {
  type Item = T;

  fn next(&mut self) -> Option<T> {
    let old: LLVMValueRef = self.cur;
      if !old.is_null() {
        self.cur = unsafe { (self.step)(old) };
        Some(old.into())
      } else {
        None
      }
    }
}<commit_msg>Reformat value.rs.<commit_after>use std::ffi::CString;
use std::{fmt, mem, ptr};
use std::ops::{Deref, Index};

use libc::{c_char, c_int, c_uint};
use ffi::core;
use ffi::prelude::LLVMValueRef;
use ffi::LLVMAttribute;
use ffi::core::{
	LLVMConstStringInContext,
	LLVMConstStructInContext,
	LLVMConstVector,

	LLVMGetValueName,
	LLVMSetValueName,

	LLVMGetElementType,
	LLVMGetEntryBasicBlock,
	LLVMAppendBasicBlockInContext,

	LLVMAddAttribute,
	LLVMGetAttribute,
	LLVMRemoveAttribute,

  LLVMAddFunctionAttr,
  LLVMGetFunctionAttr,
  LLVMRemoveFunctionAttr,

  LLVMGetParam,
  LLVMCountParams,
  LLVMGetFirstParam,
  LLVMGetNextParam,

  LLVMGetInitializer,
  LLVMSetInitializer,

  LLVMIsAGlobalValue,
  LLVMGetUndef,
  LLVMTypeOf,
};

use block::BasicBlock;
use context::{Context, GetContext};
use util::{self, CastFrom};
use ty::{FunctionType, Type};

/// A typed value that can be used as an operand in instructions.
pub struct Value;
native_ref!(&Value = LLVMValueRef);

impl Value
{
  /// Create a new constant struct from the values given.
  pub fn new_struct<'a>(context: &'a Context,
  	                    vals: &[&'a Value], packed: bool) -> &'a Value
  {
    unsafe {
    	LLVMConstStructInContext(context.into(),
    	                         vals.as_ptr() as *mut LLVMValueRef,
    		                       vals.len() as c_uint,
    		                       packed as c_int)
    }.into()
  }

  /// Create a new constant vector from the values given.
  pub fn new_vector<'a>(vals: &[&'a Value]) -> &'a Value
  {
    unsafe {
    	LLVMConstVector(vals.as_ptr() as *mut LLVMValueRef,
    		              vals.len() as c_uint)
    }.into()
  }

  /// Create a new constant C string from the text given.
  pub fn new_string<'a>(context: &'a Context,
  	                    text: &str,
  	                    rust_style: bool) -> &'a Value
  {
    unsafe {
      let ptr = text.as_ptr() as *const c_char;
      let len = text.len() as c_uint;
      LLVMConstStringInContext(context.into(), ptr, len, rust_style as c_int).into()
    }
  }

  /// Create a new constant undefined value of the given type.
  pub fn new_undef<'a>(ty: &'a Type) -> &'a Value
  {
    unsafe { LLVMGetUndef(ty.into()) }.into()
  }

  /// Returns the name of this value, or `None` if it lacks a name
  pub fn get_name(&self) -> Option<&str>
  {
    unsafe {
      let c_name = LLVMGetValueName(self.into());
      util::to_null_str(c_name as *mut i8)
    }
  }

  /// Sets the name of this value
  pub fn set_name(&self, name: &str)
  {
    let c_name = CString::new(name).unwrap();
    unsafe {
      LLVMSetValueName(self.into(), c_name.as_ptr())
    }
  }

  /// Returns the type of this value
  pub fn get_type(&self) -> &Type
  {
    unsafe { LLVMTypeOf(self.into()) }.into()
  }
}

pub struct GlobalValue;
native_ref!(&GlobalValue = LLVMValueRef);
deref!(GlobalValue, Value);

impl GlobalValue
{
	/// Sets the initial value for this global.
	pub fn set_initializer(&self, value: &Value)
	{
	  unsafe { LLVMSetInitializer(self.into(), value.into()) }
	}

	/// Gets the initial value for this global.
	pub fn get_initializer(&self) -> &Value
	{
	  unsafe { LLVMGetInitializer(self.into()) }.into()
	}
}

impl CastFrom for GlobalValue
{
  type From = Value;

  fn cast<'a>(val: &'a Value) -> Option<&'a GlobalValue>
  {
    let gv = unsafe { LLVMIsAGlobalValue(val.into()) };
    if gv == ptr::null_mut() {
      None
    } else {
      Some(gv.into())
    }
  }
}

/// Comparative operations on values.
#[derive(Copy, Clone, Eq, PartialEq)]
pub enum Predicate
{
  Equal,
  NotEqual,
  GreaterThan,
  GreaterThanOrEqual,
  LessThan,
  LessThanOrEqual
}

/// A function argument.
pub struct Arg;
native_ref!(&Arg = LLVMValueRef);

impl Deref for Arg
{
  type Target = Value;

  fn deref(&self) -> &Value
  {
    unsafe { mem::transmute(self) }
  }
}

impl Arg
{
  /// Add the attribute given to this argument.
  pub fn add_attribute(&self, attr: Attribute)
  {
    unsafe { LLVMAddAttribute(self.into(), attr.into()) }
  }

  /// Add all the attributes given to this argument.
  pub fn add_attributes(&self, attrs: &[Attribute])
  {
    let mut sum = LLVMAttribute::empty();
    for attr in attrs {
      let attr:LLVMAttribute = (*attr).into();
      sum = sum | attr;
    }
    unsafe { LLVMAddAttribute(self.into(), sum.into()) }
  }

  /// Returns true if this argument has the attribute given.
  pub fn has_attribute(&self, attr: Attribute) -> bool
  {
    unsafe {
      let other = LLVMGetAttribute(self.into());
      other.contains(attr.into())
    }
  }

  /// Returns true if this argument has all the attributes given.
  pub fn has_attributes(&self, attrs: &[Attribute]) -> bool
  {
    unsafe {
      let other = LLVMGetAttribute(self.into());
      for &attr in attrs {
        if !other.contains(attr.into()) {
            return false;
        }
      }
      return true;
    }
  }

  /// Remove an attribute from this argument.
  pub fn remove_attribute(&self, attr: Attribute)
  {
    unsafe {
    	LLVMRemoveAttribute(self.into(), attr.into())
    }
  }
}

/// A function that can be called and contains blocks.
pub struct Function;
native_ref!(&Function = LLVMValueRef);

impl Deref for Function
{
  type Target = Value;

  fn deref(&self) -> &Value
  {
    unsafe { mem::transmute(self) }
  }
}

impl Index<usize> for Function
{
  type Output = Arg;

  fn index(&self, index: usize) -> &Arg
  {
    unsafe {
      if index < LLVMCountParams(self.into()) as usize {
        LLVMGetParam(self.into(), index as c_uint).into()
      } else {
        panic!("no such index {} on {:?}", index, self.get_type())
      }
    }
  }
}

impl CastFrom for Function
{
  type From = Value;

  fn cast<'a>(val: &'a Value) -> Option<&'a Function>
  {
    let ty = val.get_type();
    let mut is_func = ty.is_function();

    if let Some(elem) = ty.get_element() {
      is_func = is_func || elem.is_function()
    }

    if is_func {
      Some(unsafe { mem::transmute(val) })
    } else {
      None
    }
  }
}

impl Function
{
  /// Add a basic block with the name given to the function and return it.
  pub fn append<'a>(&'a self, name: &str) -> &'a BasicBlock
  {
    util::with_cstr(name, |ptr| unsafe {
      LLVMAppendBasicBlockInContext(self.get_context().into(), self.into(), ptr).into()
    })
  }

  /// Returns the entry block of this function or `None` if there is none.
  pub fn get_entry(&self) -> Option<&BasicBlock>
  {
    unsafe { mem::transmute(LLVMGetEntryBasicBlock(self.into())) }
  }

  /// Returns the name of this function.
  pub fn get_name(&self) -> &str
  {
    unsafe {
      let c_name = LLVMGetValueName(self.into());
      util::to_str(c_name as *mut i8)
    }
  }

  /// Returns the function signature representing this function's signature.
  pub fn get_signature(&self) -> &FunctionType
  {
    unsafe {
      let ty = LLVMTypeOf(self.into());
      LLVMGetElementType(ty).into()
    }
  }

  /// Add the attribute given to this function.
  pub fn add_attribute(&self, attr: Attribute)
  {
    unsafe { LLVMAddFunctionAttr(self.into(), attr.into()) }
  }

  /// Add all the attributes given to this function.
  pub fn add_attributes(&self, attrs: &[Attribute])
  {
    let mut sum = LLVMAttribute::empty();

    for attr in attrs {
        let attr:LLVMAttribute = (*attr).into();
        sum = sum | attr;
    }

    unsafe { LLVMAddFunctionAttr(self.into(), sum.into()) }
  }

  /// Returns true if the attribute given is set in this function.
  pub fn has_attribute(&self, attr: Attribute) -> bool
  {
    unsafe {
      let other = LLVMGetFunctionAttr(self.into());
      other.contains(attr.into())
    }
  }

  /// Returns true if all the attributes given is set in this function.
  pub fn has_attributes(&self, attrs: &[Attribute]) -> bool
  {
    unsafe {
      let other = LLVMGetFunctionAttr(self.into());

      for &attr in attrs {
          if !other.contains(attr.into()) {
              return false;
          }
      }

      return true;
    }
  }
  /// Remove the attribute given from this function.
  pub fn remove_attribute(&self, attr: Attribute)
  {
    unsafe { LLVMRemoveFunctionAttr(self.into(), attr.into()) }
  }
}

impl<'a> IntoIterator for &'a Function
{
  type Item = &'a Arg;
  type IntoIter = ValueIter<'a, &'a Arg>;

  /// Iterate through the functions in the module
  fn into_iter(self) -> ValueIter<'a, &'a Arg>
  {
 		ValueIter::new(
 			unsafe { LLVMGetFirstParam(self.into()) },
 			LLVMGetNextParam)
  }
}

impl GetContext for Function
{
  fn get_context(&self) -> &Context
  {
    self.get_type().get_context()
  }
}

/// A way of indicating to LLVM how you want arguments / functions to be handled.
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
#[repr(C)]
pub enum Attribute
{
  /// Zero-extended before or after call.
  ZExt =              0b1,
  /// Sign-extended before or after call.
  SExt =              0b10,
  /// Mark the function as not returning.
  NoReturn =          0b100,
  /// Force argument to be passed in register.
  InReg =             0b1000,
  /// Hidden pointer to structure to return.
  StructRet =         0b10000,
  /// Function doesn't unwind stack.
  NoUnwind =          0b100000,
  /// Consider to not alias after call.
  NoAlias =           0b1000000,
  /// Pass structure by value.
  ByVal =             0b10000000,
  /// Nested function static chain.
  Nest =              0b100000000,
  /// Function doesn't access memory.
  ReadNone =          0b1000000000,
  /// Function only reads from memory.
  ReadOnly =          0b10000000000,
  /// Never inline this function.
  NoInline =          0b100000000000,
  /// Always inline this function.
  AlwaysInline =      0b1000000000000,
  /// Optimize this function for size.
  OptimizeForSize =   0b10000000000000,
  /// Stack protection.
  StackProtect =      0b100000000000000,
  /// Stack protection required.
  StackProtectReq =   0b1000000000000000,
  /// Alignment of parameter (5 bits) stored as log2 of alignment with +1 bias 0 means unaligned (different from align(1)).
  Alignment =         0b10000000000000000,
  /// Function creates no aliases of pointer.
  NoCapture =         0b100000000000000000,
  /// Disable redzone.
  NoRedZone =         0b1000000000000000000,
  /// Disable implicit float instructions.
  NoImplicitFloat =   0b10000000000000000000,
  /// Naked function.
  Naked =             0b100000000000000000000,
  /// The source language has marked this function as inline.
  InlineHint =        0b1000000000000000000000,
  /// Alignment of stack for function (3 bits) stored as log2 of alignment with +1 bias 0 means unaligned (different from alignstack=(1)).
  StackAlignment =    0b11100000000000000000000000000,
  /// This function returns twice.
  ReturnsTwice =      0b100000000000000000000000000000,
  /// Function must be in unwind table.
  UWTable =           0b1000000000000000000000000000000,
  /// Function is called early/often, so lazy binding isn't effective.
  NonLazyBind =       0b10000000000000000000000000000000
}

impl From<LLVMAttribute> for Attribute
{
  fn from(attr: LLVMAttribute) -> Attribute {
    unsafe { mem::transmute(attr) }
  }
}

impl From<Attribute> for LLVMAttribute
{
  fn from(attr: Attribute) -> LLVMAttribute {
    unsafe { mem::transmute(attr) }
  }
}

impl GetContext for Value
{
  fn get_context(&self) -> &Context {
    self.get_type().get_context()
  }
}
impl_display!(Value, LLVMPrintValueToString);

/// Value Iterator implementation.
///
/// T can be all descendent types of LLVMValueRef.
#[derive(Copy, Clone)]
pub struct ValueIter<'a, T: From<LLVMValueRef>> {
  cur    : LLVMValueRef,
  step   : unsafe extern "C" fn(LLVMValueRef) -> LLVMValueRef,
  marker1: ::std::marker::PhantomData<&'a ()>,
  marker2: ::std::marker::PhantomData<T>,
}

impl<'a, T: From<LLVMValueRef>> ValueIter<'a, T>
{
	pub fn new(cur: LLVMValueRef,
		         step: unsafe extern "C" fn(LLVMValueRef) -> LLVMValueRef) -> Self
	{
		ValueIter {
			cur: cur,
			step: step,
			marker1: ::std::marker::PhantomData,
			marker2: ::std::marker::PhantomData
		}
	}
}

impl<'a, T: From<LLVMValueRef>> Iterator for ValueIter<'a, T>
{
  type Item = T;

  fn next(&mut self) -> Option<T> {
    let old: LLVMValueRef = self.cur;

    if !old.is_null() {
      self.cur = unsafe { (self.step)(old) };
      Some(old.into())
    } else {
      None
    }
  }
}<|endoftext|>


<commit_before>
use ::std;
use ::std::ffi::OsString;
use ::std::os::windows::ffi::OsStringExt;

use ::WCString;
use ::NoNulError;
use ::error;

/// Representation of a borrowed Win32 style "wide" string.
#[derive(PartialEq, PartialOrd, Eq, Ord, Hash)]
pub struct WCStr {
    inner: [u16]
}

impl WCStr {
    /// Create a ```&WCStr``` from a raw pointer and a length.
    ///
    /// This function is unsafe for the reasons mentioned below.
    ///
    /// This function assumes that the pointer passed in has these properties:
    ///
    /// * It is not null.
    /// * It is a valid pointer.
    /// * It points to an array of ```u16```'s that does not contain any ```nul``` values.
    /// * It points to an array of ```u16```'s that is terminated with a ```nul``` at exactly the offset "```len```".
    ///
    /// This function will assert/panic when ```nul``` is not found at offset "```len```".
    ///
    /// The lifetime of the ```&WCStr``` returned from this function is not guranteed to be correct and
    /// it is up to the caller to determine the appropriate lifetime.
    ///
    /// # ```from_raw_parts()``` example
    ///
    ///     use wcstr::WCStr;
    ///     static a : &'static [u16] = &[116u16, 101u16, 115u16, 116u16, 0];
    ///     let s = unsafe { WCStr::from_raw_parts(a.as_ptr(), a.len() - 1) };
    ///     assert!(s.len() == (a.len() - 1));
    pub unsafe fn from_raw_parts<'a>(ptr: *const u16, len: usize) -> &'a WCStr {
        assert!(*ptr.offset(len as isize) == 0u16);
        std::mem::transmute(std::slice::from_raw_parts(ptr, len + 1))
    }

    /// Create a ```&WCStr``` from a slice of ```u16```'s.
    /// This function will scan the slice for ```nul``` and assume that ```nul``` terminates the string.
    /// If no ```nul``` is found in the slice, it will return ```Err(NoNulError(None))```
    /// # ```frm_slice_with_nul()``` example
    ///
    ///     use wcstr::WCStr;
    ///     static a : &'static [u16] = &[116u16, 101u16, 115u16, 116u16, 0];
    ///     let s = WCStr::from_slice_with_nul(a).unwrap();
    ///     assert!(s.len() == (a.len() - 1));
    pub fn from_slice_with_nul<'a>(slice: &'a [u16]) -> Result<&'a WCStr, NoNulError> {
        match slice.iter().position(|x| *x == 0) {
            None => Err(error::no_nul(None)),
            Some(i) => Ok(unsafe { std::mem::transmute(&slice[..i + 1]) }),
        }
    }

    /// length of the string in u16 units
    pub fn len(&self) -> usize {
        self.inner.len() - 1
    }

    /// Return a raw pointer to this "wide" string.
    ///
    ///  * The pointer remains valid only as long as this string is valid.
    ///  * The pointer points to a contiguous region of memory terminated with ```nul```.
    pub fn as_ptr(&self) -> *const u16 {
        self.inner.as_ptr()
    }

    /// Return this "wide" string as a slice of ```u16```s without a ```nul``` terminator.
    pub fn to_slice(&self) -> &[u16] {
        &self.inner[..self.len()]
    }

    /// Return this "wide" string as a slice of ```u16```s with a ```nul``` terminator.
    pub fn to_slice_with_nul(&self) -> &[u16] {
        &self.inner
    }

    /// Convert this "wide" string to a ```String``` by using ```String::from_utf16```
    pub fn to_string(&self) -> Result<String, std::string::FromUtf16Error> {
        String::from_utf16(&self.inner)
    }

    /// Convert this "wide" string to a ```String``` by using ```String::from_utf16_lossy```
    pub fn to_string_lossy(&self) -> String {
        String::from_utf16_lossy(&self.inner)
    }

    /// Convert this "wide" string to an ```OsString``` by using ```OsString::from_wide```
    pub fn to_os_string(&self) -> OsString {
        OsString::from_wide(self.to_slice())
    }
}

impl std::fmt::Debug for WCStr {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        try!(write!(f, "\""));
        for &w in self.to_slice().iter() {
            if w < 0xD800 || w >= 0xE000 {
                for c in unsafe { std::char::from_u32_unchecked(w as u32) }.escape_default() {
                    use std::fmt::Write;
                    try!(f.write_char(c));
                }
            }
            else {
                try!(write!(f, "\\u{{{:X}}}", w));
            }
        }
        write!(f, "\"")
    }
}

impl AsRef<WCStr> for WCStr {
    fn as_ref(&self) -> &WCStr {
        self
    }
}

impl AsRef<[u16]> for WCStr {
    fn as_ref(&self) -> &[u16] {
        &self.inner[..self.len()]
    }
}

impl ToOwned for WCStr {
    type Owned = WCString;
    fn to_owned(&self) -> WCString {
        unsafe {
            WCString::from_vec_with_nul_unchecked(self.inner.to_owned())
        }
    }
}

<commit_msg>use API that is available in older versions of rust<commit_after>
use ::std;
use ::std::ffi::OsString;
use ::std::os::windows::ffi::OsStringExt;

use ::WCString;
use ::NoNulError;
use ::error;

/// Representation of a borrowed Win32 style "wide" string.
#[derive(PartialEq, PartialOrd, Eq, Ord, Hash)]
pub struct WCStr {
    inner: [u16]
}

impl WCStr {
    /// Create a ```&WCStr``` from a raw pointer and a length.
    ///
    /// This function is unsafe for the reasons mentioned below.
    ///
    /// This function assumes that the pointer passed in has these properties:
    ///
    /// * It is not null.
    /// * It is a valid pointer.
    /// * It points to an array of ```u16```'s that does not contain any ```nul``` values.
    /// * It points to an array of ```u16```'s that is terminated with a ```nul``` at exactly the offset "```len```".
    ///
    /// This function will assert/panic when ```nul``` is not found at offset "```len```".
    ///
    /// The lifetime of the ```&WCStr``` returned from this function is not guranteed to be correct and
    /// it is up to the caller to determine the appropriate lifetime.
    ///
    /// # ```from_raw_parts()``` example
    ///
    ///     use wcstr::WCStr;
    ///     static a : &'static [u16] = &[116u16, 101u16, 115u16, 116u16, 0];
    ///     let s = unsafe { WCStr::from_raw_parts(a.as_ptr(), a.len() - 1) };
    ///     assert!(s.len() == (a.len() - 1));
    pub unsafe fn from_raw_parts<'a>(ptr: *const u16, len: usize) -> &'a WCStr {
        assert!(*ptr.offset(len as isize) == 0u16);
        std::mem::transmute(std::slice::from_raw_parts(ptr, len + 1))
    }

    /// Create a ```&WCStr``` from a slice of ```u16```'s.
    /// This function will scan the slice for ```nul``` and assume that ```nul``` terminates the string.
    /// If no ```nul``` is found in the slice, it will return ```Err(NoNulError(None))```
    /// # ```frm_slice_with_nul()``` example
    ///
    ///     use wcstr::WCStr;
    ///     static a : &'static [u16] = &[116u16, 101u16, 115u16, 116u16, 0];
    ///     let s = WCStr::from_slice_with_nul(a).unwrap();
    ///     assert!(s.len() == (a.len() - 1));
    pub fn from_slice_with_nul<'a>(slice: &'a [u16]) -> Result<&'a WCStr, NoNulError> {
        match slice.iter().position(|x| *x == 0) {
            None => Err(error::no_nul(None)),
            Some(i) => Ok(unsafe { std::mem::transmute(&slice[..i + 1]) }),
        }
    }

    /// length of the string in u16 units
    pub fn len(&self) -> usize {
        self.inner.len() - 1
    }

    /// Return a raw pointer to this "wide" string.
    ///
    ///  * The pointer remains valid only as long as this string is valid.
    ///  * The pointer points to a contiguous region of memory terminated with ```nul```.
    pub fn as_ptr(&self) -> *const u16 {
        self.inner.as_ptr()
    }

    /// Return this "wide" string as a slice of ```u16```s without a ```nul``` terminator.
    pub fn to_slice(&self) -> &[u16] {
        &self.inner[..self.len()]
    }

    /// Return this "wide" string as a slice of ```u16```s with a ```nul``` terminator.
    pub fn to_slice_with_nul(&self) -> &[u16] {
        &self.inner
    }

    /// Convert this "wide" string to a ```String``` by using ```String::from_utf16```
    pub fn to_string(&self) -> Result<String, std::string::FromUtf16Error> {
        String::from_utf16(&self.inner)
    }

    /// Convert this "wide" string to a ```String``` by using ```String::from_utf16_lossy```
    pub fn to_string_lossy(&self) -> String {
        String::from_utf16_lossy(&self.inner)
    }

    /// Convert this "wide" string to an ```OsString``` by using ```OsString::from_wide```
    pub fn to_os_string(&self) -> OsString {
        OsString::from_wide(self.to_slice())
    }
}

impl std::fmt::Debug for WCStr {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        try!(write!(f, "\""));
        for &w in self.to_slice().iter() {
            if w < 0xD800 || w >= 0xE000 {
                for c in std::char::from_u32(w as u32).unwrap().escape_default() {
                    use std::fmt::Write;
                    try!(f.write_char(c));
                }
            }
            else {
                try!(write!(f, "\\u{{{:X}}}", w));
            }
        }
        write!(f, "\"")
    }
}

impl AsRef<WCStr> for WCStr {
    fn as_ref(&self) -> &WCStr {
        self
    }
}

impl AsRef<[u16]> for WCStr {
    fn as_ref(&self) -> &[u16] {
        &self.inner[..self.len()]
    }
}

impl ToOwned for WCStr {
    type Owned = WCString;
    fn to_owned(&self) -> WCString {
        unsafe {
            WCString::from_vec_with_nul_unchecked(self.inner.to_owned())
        }
    }
}

<|endoftext|>


<commit_before>use std::mem::transmute;
use std::os::unix::io::AsRawFd;
use std::time::Duration;
use std::thread::sleep;
use std::io::Write;

use wayland_client::wayland::get_display;
use wayland_client::wayland::compositor::{WlCompositor, WlSurface};
use wayland_client::wayland::shell::{WlShellSurface, WlShell};
use wayland_client::wayland::shm::{WlBuffer, WlShm, WlShmFormat};
use wayland_client::wayland::seat::{WlSeat, WlPointerEvent};
use wayland_client::wayland::WlDisplay;
use wayland_client::cursor::{CursorTheme, Cursor, load_theme};
use wayland_client::{EventIterator, Proxy};

use rustwlc::WlcOutput;
use tempfile;

use byteorder::{NativeEndian, WriteBytesExt};

wayland_env!(WaylandEnv,
             compositor: WlCompositor,
             shell: WlShell,
             shm: WlShm,
             seat: WlSeat
);

#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
/// Holds the bytes to represent a colored background.
/// To be written into a wayland surface.
pub struct Color(pub [u8; 4]);

impl Color {
    /// Generate a new color out of a u32.
    /// E.G: 0xFFFFFFFF
    pub fn from_u32(color: u32) -> Self {
        unsafe { Color(transmute(color)) }
    }
}

pub fn generate_solid_background(color: Color, output: WlcOutput) {
    // Get shortcuts to the globals.
    let (display, iter) = get_display()
        .expect("Unable to connect to a wayland compositor");
    let (env, mut evt_iter) = WaylandEnv::init(display, iter);
    let compositor = env.compositor.as_ref().map(|o| &o.0).unwrap();
    let shell = env.shell.as_ref().map(|o| &o.0).unwrap();
    let shm = env.shm.as_ref().map(|o| &o.0).unwrap();
    let seat = env.seat.as_ref().map(|o| &o.0).unwrap();

    // Create the surface we are going to write into
    let surface = compositor.create_surface();
    let shell_surface = shell.get_shell_surface(&surface);
    let mut tmp = tempfile::tempfile().ok().expect("Unable to create a tempfile.");

    // Calculate how big the buffer needs to be from the output resolution
    let resolution = output.get_resolution().clone();
    let (width, height) = (resolution.w as i32, resolution.h as i32);
    let size = (resolution.w * resolution.h) as i32;

    // Write in the color coding to the surface
    for _ in 0..size {
        unsafe {
            tmp.write_u32::<NativeEndian>(transmute(color.0))
                .expect("Could not write to file")
        }
    }
    tmp.flush()
        .expect("Could not flush buffer");

    // Create the buffer that is mem-mapped to the temp file descriptor
    let pool = shm.create_pool(tmp.as_raw_fd(), size);
    let buffer = pool.create_buffer(0, width, height, width, WlShmFormat::Argb8888);
    // Tell Way Cooler not to set put this in the tree, treat as background
    shell_surface.set_class("Background".into());

    // Attach the buffer to the surface
    surface.attach(Some(&buffer), 0, 0);
    surface.set_buffer_scale(4);

    main_background_loop(compositor, shell, shm, seat, surface,
                         shell_surface, buffer, evt_iter);
}

/// Main loop for rendering backgrounds.
/// Need to keep the surface alive, and update it if the
/// user wants to change the background.
#[allow(unused_variables)]
fn main_background_loop(compositor: &WlCompositor, shell: &WlShell, shm: &WlShm,
                        seat: &WlSeat,
                        surface: WlSurface, shell_surface: WlShellSurface,
                        buffer: WlBuffer, mut event_iter: EventIterator) {
    use wayland_client::wayland::WaylandProtocolEvent;
    use wayland_client::Event;
    println!("Entering main loop");
    // For now just loop and do nothing
    // Eventually need to query the background state and update
    let cursor_surface = compositor.create_surface();
    let mut pointer = seat.get_pointer();
    let cursor_theme = load_theme(None, 16, shm);
    // TODO Figure out why not working on Timidger's machine
    let cursor = cursor_theme.get_cursor("default")
        .expect("Couldn't load cursor from theme");
    let cursor_buffer = cursor.frame_buffer(0).expect("Couldn't get frame_buffer");
    cursor_surface.attach(Some(&*cursor_buffer), 0, 0);
    pointer.set_event_iterator(&event_iter);
    pointer.set_cursor(0, Some(&cursor_surface), 0, 0);
    surface.commit();
    event_iter.sync_roundtrip().unwrap();
    loop {
        for event in &mut event_iter {
            match event {
                Event::Wayland(wayland_event) => {
                    match wayland_event {
                        WaylandProtocolEvent::WlPointer(id, pointer_event) => {
                            match pointer_event {
                                WlPointerEvent::Enter(serial, surface, surface_x, surface_y) => {
                                    // Set the surface to use a cursor
                                    pointer.set_cursor(0, Some(&cursor_surface), 0, 0);
                                },
                                _ => {
                                }
                            }
                        },
                        _ => {/* unhandled events */}
                    }
                }
                _ => { /* unhandled events */ }
            }
        }
        event_iter.dispatch().expect("Connection with the compositor was lost.");
    }
}
<commit_msg>Background cleanup, better error logging<commit_after>use std::mem::transmute;
use std::os::unix::io::AsRawFd;
use std::io::Write;

use wayland_client::wayland::get_display;
use wayland_client::wayland::compositor::{WlCompositor, WlSurface};
use wayland_client::wayland::shell::{WlShellSurface, WlShell};
use wayland_client::wayland::shm::{WlBuffer, WlShm, WlShmFormat};
use wayland_client::wayland::seat::{WlSeat, WlPointerEvent};
use wayland_client::cursor::load_theme;
use wayland_client::{EventIterator, Proxy};

use rustwlc::WlcOutput;
use tempfile;

use byteorder::{NativeEndian, WriteBytesExt};

wayland_env!(WaylandEnv,
             compositor: WlCompositor,
             shell: WlShell,
             shm: WlShm,
             seat: WlSeat
);

#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
/// Holds the bytes to represent a colored background.
/// To be written into a wayland surface.
pub struct Color(pub [u8; 4]);

impl Color {
    /// Generate a new color out of a u32.
    /// E.G: 0xFFFFFF
    pub fn from_u32(color: u32) -> Self {
        unsafe { Color(transmute(color)) }
    }
}

pub fn generate_solid_background(color: Color, output: WlcOutput) {
    // Get shortcuts to the globals.
    let (display, iter) = get_display()
        .expect("Unable to connect to a wayland compositor");
    let (env, evt_iter) = WaylandEnv::init(display, iter);
    let compositor = env.compositor.as_ref().map(|o| &o.0).unwrap();
    let shell = env.shell.as_ref().map(|o| &o.0).unwrap();
    let shm = env.shm.as_ref().map(|o| &o.0).unwrap();
    let seat = env.seat.as_ref().map(|o| &o.0).unwrap();

    // Create the surface we are going to write into
    let surface = compositor.create_surface();
    let shell_surface = shell.get_shell_surface(&surface);
    let mut tmp = tempfile::tempfile().ok().expect("Unable to create a tempfile.");

    // Calculate how big the buffer needs to be from the output resolution
    let resolution = output.get_resolution().clone();
    let (width, height) = (resolution.w as i32, resolution.h as i32);
    let size = (resolution.w * resolution.h) as i32;

    // Write in the color coding to the surface
    for _ in 0..size {
        unsafe {
            tmp.write_u32::<NativeEndian>(transmute(color.0))
                .expect("Could not write to file")
        }
    }
    tmp.flush()
        .expect("Could not flush buffer");

    // Create the buffer that is mem-mapped to the temp file descriptor
    let pool = shm.create_pool(tmp.as_raw_fd(), size);
    let buffer = pool.create_buffer(0, width, height, width, WlShmFormat::Argb8888);
    // Tell Way Cooler not to set put this in the tree, treat as background
    shell_surface.set_class("Background".into());

    // Attach the buffer to the surface
    surface.attach(Some(&buffer), 0, 0);

    main_background_loop(compositor, shell, shm, seat, surface,
                         shell_surface, buffer, evt_iter);
}

/// Main loop for rendering backgrounds.
/// Need to keep the surface alive, and update it if the
/// user wants to change the background.
#[allow(unused_variables)]
fn main_background_loop(compositor: &WlCompositor, shell: &WlShell, shm: &WlShm,
                        seat: &WlSeat,
                        surface: WlSurface, shell_surface: WlShellSurface,
                        buffer: WlBuffer, mut event_iter: EventIterator) {
    use wayland_client::wayland::WaylandProtocolEvent;
    use wayland_client::Event;
    println!("Entering main loop");
    // For now just loop and do nothing
    // Eventually need to query the background state and update
    let cursor_surface = compositor.create_surface();
    let mut pointer = seat.get_pointer();
    let cursor_theme = load_theme(None, 16, shm);
    let maybe_cursor = cursor_theme.get_cursor("default");
    if maybe_cursor.is_none() {
        error!("Could not load cursor theme properly, cannot load background");
        error!("Please consult the developers about this issue with your distro version, this is a known issue");
        return;
    }
    let cursor = maybe_cursor.unwrap();
    let cursor_buffer = cursor.frame_buffer(0).expect("Couldn't get frame_buffer");
    cursor_surface.attach(Some(&*cursor_buffer), 0, 0);
    pointer.set_event_iterator(&event_iter);
    pointer.set_cursor(0, Some(&cursor_surface), 0, 0);
    surface.commit();
    event_iter.sync_roundtrip().unwrap();
    loop {
        for event in &mut event_iter {
            match event {
                Event::Wayland(wayland_event) => {
                    match wayland_event {
                        WaylandProtocolEvent::WlPointer(id, pointer_event) => {
                            match pointer_event {
                                WlPointerEvent::Enter(serial, surface, surface_x, surface_y) => {
                                    pointer.set_cursor(0, Some(&cursor_surface), 0, 0);
                                },
                                _ => {
                                }
                            }
                        },
                        _ => {/* unhandled events */}
                    }
                }
                _ => { /* unhandled events */ }
            }
        }
        event_iter.dispatch().expect("Connection with the compositor was lost.");
    }
}
<|endoftext|>