<commit_before>use backend::Backend;
use provider::error;
use provider::Provider;
use provider::Output;
use libc::uint32_t;

pub struct File<'a> {
    name: &'static str,
    backend: &'a Backend,
    provider: &'a Provider,
}

impl<'a> File<'a> {
    pub fn new(n: &'static str, b: &'a Backend, p: &'a Provider) -> File<'a> {
        File {
            name: n,
            backend: b,
            provider: p,
        }
    }

    pub fn mode(&self) -> Result<u32, error::Error> {
        self.backend
            .handle(self.provider.file.mode(self.name))
            .and_then(Output::to_u32)
    }

    pub fn size(&self) -> Result<i64, error::Error> {
        self.backend
            .handle(self.provider.file.size(self.name))
            .and_then(Output::to_i64)
    }

    pub fn is_file(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_file(self.name))
            .and_then(Output::to_bool)
    }

    pub fn exist(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.exist(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_directory(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_directory(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_block_device(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_block_device(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_character_device(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_character_device(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_pipe(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_pipe(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_socket(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_socket(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_symlink(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_symlink(self.name))
            .and_then(Output::to_bool)
    }

    pub fn contents(&self) -> Result<String, error::Error> {
        self.backend
            .handle(self.provider.file.contents(self.name))
            .and_then(Output::to_string)
    }

    pub fn owner(&self) -> Result<String, error::Error> {
        self.backend
            .handle(self.provider.file.owner(self.name))
            .and_then(Output::to_string)
    }

    pub fn group(&self) -> Result<String, error::Error> {
        self.backend
            .handle(self.provider.file.group(self.name))
            .and_then(Output::to_string)
    }

    pub fn linked_to(&self) -> Result<String, error::Error> {
        self.backend
            .handle(self.provider.file.linked_to(self.name))
            .and_then(Output::to_string)
    }

    pub fn is_readable(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_readable(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_readable_by_owner(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_readable_by_owner(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_readable_by_group(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_readable_by_group(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_readable_by_others(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_readable_by_others(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_readable_by_user(&self, user: &'static str) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_readable_by_user(self.name, user))
            .and_then(Output::to_bool)
    }

    pub fn is_writable(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_writable(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_writable_by_owner(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_writable_by_owner(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_writable_by_group(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_writable_by_group(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_writable_by_others(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_writable_by_others(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_writable_by_user(&self, user: &'static str) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_writable_by_user(self.name, user))
            .and_then(Output::to_bool)
    }

    pub fn md5sum(&self) -> Result<String, error::Error> {
        self.backend
            .handle(self.provider.file.md5sum(self.name))
            .and_then(Output::to_string)
    }

    pub fn sha256sum(&self) -> Result<String, error::Error> {
        self.backend
            .handle(self.provider.file.sha256sum(self.name))
            .and_then(Output::to_string)
    }
}

// Wrapper functions for FFI

#[no_mangle]
pub extern "C" fn resource_file_free(ptr: *mut File) {
    if ptr.is_null() {
        return;
    }
    unsafe {
        Box::from_raw(ptr);
    }
}

#[no_mangle]
pub extern "C" fn resource_file_mode(ptr: *const File) -> uint32_t {
    let f = unsafe {
        assert!(!ptr.is_null());
        &*ptr
    };

    f.mode().unwrap()
}
<commit_msg>Add wrapper function for file.exist()<commit_after>use backend::Backend;
use provider::error;
use provider::Provider;
use provider::Output;
use libc::uint32_t;

pub struct File<'a> {
    name: &'static str,
    backend: &'a Backend,
    provider: &'a Provider,
}

impl<'a> File<'a> {
    pub fn new(n: &'static str, b: &'a Backend, p: &'a Provider) -> File<'a> {
        File {
            name: n,
            backend: b,
            provider: p,
        }
    }

    pub fn mode(&self) -> Result<u32, error::Error> {
        self.backend
            .handle(self.provider.file.mode(self.name))
            .and_then(Output::to_u32)
    }

    pub fn size(&self) -> Result<i64, error::Error> {
        self.backend
            .handle(self.provider.file.size(self.name))
            .and_then(Output::to_i64)
    }

    pub fn is_file(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_file(self.name))
            .and_then(Output::to_bool)
    }

    pub fn exist(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.exist(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_directory(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_directory(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_block_device(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_block_device(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_character_device(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_character_device(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_pipe(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_pipe(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_socket(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_socket(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_symlink(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_symlink(self.name))
            .and_then(Output::to_bool)
    }

    pub fn contents(&self) -> Result<String, error::Error> {
        self.backend
            .handle(self.provider.file.contents(self.name))
            .and_then(Output::to_string)
    }

    pub fn owner(&self) -> Result<String, error::Error> {
        self.backend
            .handle(self.provider.file.owner(self.name))
            .and_then(Output::to_string)
    }

    pub fn group(&self) -> Result<String, error::Error> {
        self.backend
            .handle(self.provider.file.group(self.name))
            .and_then(Output::to_string)
    }

    pub fn linked_to(&self) -> Result<String, error::Error> {
        self.backend
            .handle(self.provider.file.linked_to(self.name))
            .and_then(Output::to_string)
    }

    pub fn is_readable(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_readable(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_readable_by_owner(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_readable_by_owner(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_readable_by_group(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_readable_by_group(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_readable_by_others(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_readable_by_others(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_readable_by_user(&self, user: &'static str) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_readable_by_user(self.name, user))
            .and_then(Output::to_bool)
    }

    pub fn is_writable(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_writable(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_writable_by_owner(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_writable_by_owner(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_writable_by_group(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_writable_by_group(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_writable_by_others(&self) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_writable_by_others(self.name))
            .and_then(Output::to_bool)
    }

    pub fn is_writable_by_user(&self, user: &'static str) -> Result<bool, error::Error> {
        self.backend
            .handle(self.provider.file.is_writable_by_user(self.name, user))
            .and_then(Output::to_bool)
    }

    pub fn md5sum(&self) -> Result<String, error::Error> {
        self.backend
            .handle(self.provider.file.md5sum(self.name))
            .and_then(Output::to_string)
    }

    pub fn sha256sum(&self) -> Result<String, error::Error> {
        self.backend
            .handle(self.provider.file.sha256sum(self.name))
            .and_then(Output::to_string)
    }
}

// Wrapper functions for FFI

#[no_mangle]
pub extern "C" fn resource_file_free(ptr: *mut File) {
    if ptr.is_null() {
        return;
    }
    unsafe {
        Box::from_raw(ptr);
    }
}

#[no_mangle]
pub extern "C" fn resource_file_mode(ptr: *const File) -> uint32_t {
    let f = unsafe {
        assert!(!ptr.is_null());
        &*ptr
    };

    f.mode().unwrap()
}

#[no_mangle]
pub extern "C" fn resource_file_exist(ptr: *const File) -> uint32_t {
    let f = unsafe {
        assert!(!ptr.is_null());
        &*ptr
    };

    if f.exist().unwrap() { 1 } else { 0 }
}
<|endoftext|>


<commit_before>use std::ascii::AsciiExt;
use core::position::{Size, HasSize};
use core::cellbuffer::CellAccessor;

use ui::core::{
    Alignable,
    HorizontalAlign,
    VerticalAlign,
    Widget,
    Frame,
    Painter,
};

/// Display text to widgets
///
/// # Examples
///
/// ```
/// use rustty::ui::core::{VerticalAlign, HorizontalAlign, Widget};
/// use rustty::ui::{Dialog, Label};
///
/// let mut maindlg = Dialog::new(60, 10);
///
/// let mut label = Label::from_str("Hi, this is an example!");
/// label.pack(&maindlg, HorizontalAlign::Middle, VerticalAlign::Middle, (0,0));
///
/// maindlg.add_label(label);
/// maindlg.draw_box();
/// ```
///
pub struct Label {
    frame: Frame,
    text: Vec<String>,
    x: usize,
    y: usize,
    t_halign: HorizontalAlign,
    t_valign: VerticalAlign,
    t_margin: (usize, usize)
}

impl Label {
    /// Construct a new Label widget `cols` wide by `rols` high. Initial text is empty
    /// and left aligned
    ///
    /// # Examples
    ///
    /// ```
    /// use rustty::ui::Label;
    ///
    /// let mut label = Label::new(60, 10);
    /// ```
    ///
    pub fn new(cols: usize, rows: usize) -> Label {
        Label {
            frame: Frame::new(cols, rows),
            text: Vec::new(),
            x: 0,
            y: 0,
            t_halign: HorizontalAlign::Left,
            t_valign: VerticalAlign::Middle,
            t_margin: (0, 0),
        }
    }

    /// Construct a new label widget from an existing string *s*. *s* can either be a
    /// `&str` or `String` , and a label will be constructed that is the size of the
    /// length of characters in *s*. Text is left aligned by default
    ///
    /// # Examples
    ///
    /// ```
    /// use rustty::ui::Label;
    ///
    /// let mut label1 = Label::from_str("This is a label");    // label is size (15x1)
    ///
    /// let s = "Here's another label".to_string();
    /// let mut label2 = Label::from_str(s);                    // label is size (20x1)
    /// ```
    ///
    pub fn from_str<S: Into<String>>(s: S) -> Label {
        let s = s.into();
        Label {
            frame: Frame::new(s.len(), 1),
            text: vec![s.into()],
            x: 0,
            y: 0,
            t_halign: HorizontalAlign::Left,
            t_valign: VerticalAlign::Middle,
            t_margin: (0, 0),
        }
    }

    /// Construct a new label widget from an existing string *s*. *s* can either be a
    /// `&str` or `String` , and a label will be constructed that is the size of the
    /// length of characters in *s*. Text is left aligned by default
    ///
    /// # Examples
    ///
    /// ```
    /// use rustty::ui::Label;
    ///
    /// let mut label1 = Label::from_str("This is a label");    // label is size (15x1)
    ///
    /// let s = "Here's another label".to_string();
    /// let mut label2 = Label::from_str(s);                    // label is size (20x1)
    /// ```
    ///
    pub fn from_str_ref<S: AsRef<str>>(s: S) -> Label {
        let s = s.as_ref().into();
        Label {
            frame: Frame::new(s.len(), 1),
            text: vec![s.as_ref().into()],
            x: 0,
            y: 0,
            t_halign: HorizontalAlign::Left,
            t_valign: VerticalAlign::Middle,
            t_margin: (0, 0),
        }
    }
    /// Specify a custom alignment for the text within the widget. Each line
    /// drawn within the label will adhere to the alignments passed for the
    /// text. *note that text alignment is with respect to the *label*
    ///
    /// # Examples
    ///
    /// ```
    /// use rustty::ui::core::{HorizontalAlign, VerticalAlign};
    /// use rustty::ui::Label;
    ///
    /// let mut label = Label::new(20, 3);
    /// label.set_text("Centered");
    /// label.align_text(HorizontalAlign::Middle, VerticalAlign::Middle, (0,0));
    /// ```
    ///
    pub fn align_text(&mut self, halign: HorizontalAlign, valign: VerticalAlign,
                    margin: (usize, usize)) {
        self.t_halign = halign;
        self.t_valign = valign;
        self.t_margin = margin;
    }

    /// Set the text of the widget to the passed `&str` or `String`. If the
    /// widget does not have enough room to display the new text, the label
    /// will only show the truncated text. *resize()* must be called to extend
    /// the size of the label.
    ///
    /// # Examples
    ///
    /// ```
    /// use rustty::HasSize;
    /// use rustty::ui::core::Widget;
    /// use rustty::ui::Label;
    ///
    /// let mut label1 = Label::new(20, 3);
    /// label1.set_text("Initial text");
    /// ```
    ///
    pub fn set_text<S: Into<String>>(&mut self, new_str: S) {
        let (framex, _) = self.frame.size();
        self.text = Vec::new();
        let mut parse = new_str.into();
        let mut line = String::new();

        // This loop below will accomplish splitting a line of text
        // into lines that adhere to the amount of rows in a label
        loop {
            // Look for a word until a whitespace is reached
            if let Some(loc) = parse.find(char::is_whitespace) {
                let line_len = line.len();
                let tmp = parse[..loc].to_owned();
                // If the word can fit on the current line, add it
                if line_len + tmp.len() + self.t_margin.0 < framex {
                    line.push_str(&tmp);
                } else {
                    line = line.trim_right().to_owned();
                    self.text.push(line);
                    line = tmp.to_owned();
                }
                parse = parse[loc..].to_owned();
            } else {
                // If no whitespace detected, there may still be one
                // more word so attempt to add it
                if parse.len() != 0 {
                    let line_len = line.len();
                    if line_len + parse.len() + self.t_margin.0 < framex {
                        line.push_str(&parse);
                        self.text.push(line);
                    } else {
                        self.text.push(line);
                        self.text.push(parse);
                    }
                }
                break;
            }

            // Look for the range of spaces between words
            if let Some(loc) = parse.find(|c: char| c != ' ') {
                let line_len = line.len();
                let tmp = parse[..loc].to_owned();
                // If the next word can fit on the current line, do so
                if line_len + tmp.len() + self.t_margin.0 < framex {
                    line.push_str(&tmp);
                } else {
                    line = line.trim_right().to_owned();
                    self.text.push(line);
                    line = "".to_string();
                }
                parse = parse[loc..].to_owned();
            } else {
                // We don't care if there's spaces at the end, so don't check
                break;
            }
        }
    }
}

impl Widget for Label {
    fn draw(&mut self, parent: &mut CellAccessor) {
        // For every line to be written, align it correctly as defined by the user in
        // align_text, if not this text will be left and middle aligned by default
        for (i, item) in self.text.iter().enumerate() {
            self.x = self.frame.halign_line(&item, self.t_halign.clone(), self.t_margin.0);
            self.y = self.frame.valign_line(&item, self.t_valign.clone(), self.t_margin.1);
            self.frame.printline(self.x, self.y + i, &item);
        }
        self.frame.draw_into(parent);
    }

    fn pack(&mut self, parent: &HasSize, halign: HorizontalAlign, valign: VerticalAlign,
                margin: (usize, usize)) {
        self.frame.align(parent, halign, valign, margin);
    }

    fn draw_box(&mut self) {
        self.frame.draw_box();
    }

    fn resize(&mut self, new_size: Size) {
        self.frame.resize(new_size);
    }

    fn frame(&self) -> &Frame {
        &self.frame
    }

    fn frame_mut(&mut self) -> &mut Frame {
        &mut self.frame
    }
}
<commit_msg>Fix from_str_ref<commit_after>use core::position::{Size, HasSize};
use core::cellbuffer::CellAccessor;

use ui::core::{
    Alignable,
    HorizontalAlign,
    VerticalAlign,
    Widget,
    Frame,
    Painter,
};

/// Display text to widgets
///
/// # Examples
///
/// ```
/// use rustty::ui::core::{VerticalAlign, HorizontalAlign, Widget};
/// use rustty::ui::{Dialog, Label};
///
/// let mut maindlg = Dialog::new(60, 10);
///
/// let mut label = Label::from_str("Hi, this is an example!");
/// label.pack(&maindlg, HorizontalAlign::Middle, VerticalAlign::Middle, (0,0));
///
/// maindlg.add_label(label);
/// maindlg.draw_box();
/// ```
///
pub struct Label {
    frame: Frame,
    text: Vec<String>,
    x: usize,
    y: usize,
    t_halign: HorizontalAlign,
    t_valign: VerticalAlign,
    t_margin: (usize, usize)
}

impl Label {
    /// Construct a new Label widget `cols` wide by `rols` high. Initial text is empty
    /// and left aligned
    ///
    /// # Examples
    ///
    /// ```
    /// use rustty::ui::Label;
    ///
    /// let mut label = Label::new(60, 10);
    /// ```
    ///
    pub fn new(cols: usize, rows: usize) -> Label {
        Label {
            frame: Frame::new(cols, rows),
            text: Vec::new(),
            x: 0,
            y: 0,
            t_halign: HorizontalAlign::Left,
            t_valign: VerticalAlign::Middle,
            t_margin: (0, 0),
        }
    }

    /// Construct a new label widget from an existing string *s*. *s* can either be a
    /// `&str` or `String` , and a label will be constructed that is the size of the
    /// length of characters in *s*. Text is left aligned by default
    ///
    /// # Examples
    ///
    /// ```
    /// use rustty::ui::Label;
    ///
    /// let mut label1 = Label::from_str("This is a label");    // label is size (15x1)
    ///
    /// let s = "Here's another label".to_string();
    /// let mut label2 = Label::from_str(s);                    // label is size (20x1)
    /// ```
    ///
    pub fn from_str<S: Into<String>>(s: S) -> Label {
        let s = s.into();
        Label {
            frame: Frame::new(s.len(), 1),
            text: vec![s.into()],
            x: 0,
            y: 0,
            t_halign: HorizontalAlign::Left,
            t_valign: VerticalAlign::Middle,
            t_margin: (0, 0),
        }
    }

    /// Construct a new label widget from an existing string *s*. *s* can either be a
    /// `&str` or `String` , and a label will be constructed that is the size of the
    /// length of characters in *s*. Text is left aligned by default
    ///
    /// # Examples
    ///
    /// ```
    /// use rustty::ui::Label;
    ///
    /// let mut label1 = Label::from_str("This is a label");    // label is size (15x1)
    ///
    /// let s = "Here's another label".to_string();
    /// let mut label2 = Label::from_str(s);                    // label is size (20x1)
    /// ```
    ///
    pub fn from_str_ref(s: &str) -> Label
    {
        Label {
            frame: Frame::new(s.len(), 1),
            text: vec![s.to_string()],
            x: 0,
            y: 0,
            t_halign: HorizontalAlign::Left,
            t_valign: VerticalAlign::Middle,
            t_margin: (0, 0),
        }
    }
    /// Specify a custom alignment for the text within the widget. Each line
    /// drawn within the label will adhere to the alignments passed for the
    /// text. *note that text alignment is with respect to the *label*
    ///
    /// # Examples
    ///
    /// ```
    /// use rustty::ui::core::{HorizontalAlign, VerticalAlign};
    /// use rustty::ui::Label;
    ///
    /// let mut label = Label::new(20, 3);
    /// label.set_text("Centered");
    /// label.align_text(HorizontalAlign::Middle, VerticalAlign::Middle, (0,0));
    /// ```
    ///
    pub fn align_text(&mut self, halign: HorizontalAlign, valign: VerticalAlign,
                    margin: (usize, usize)) {
        self.t_halign = halign;
        self.t_valign = valign;
        self.t_margin = margin;
    }

    /// Set the text of the widget to the passed `&str` or `String`. If the
    /// widget does not have enough room to display the new text, the label
    /// will only show the truncated text. *resize()* must be called to extend
    /// the size of the label.
    ///
    /// # Examples
    ///
    /// ```
    /// use rustty::HasSize;
    /// use rustty::ui::core::Widget;
    /// use rustty::ui::Label;
    ///
    /// let mut label1 = Label::new(20, 3);
    /// label1.set_text("Initial text");
    /// ```
    ///
    pub fn set_text<S: Into<String>>(&mut self, new_str: S) {
        let (framex, _) = self.frame.size();
        self.text = Vec::new();
        let mut parse = new_str.into();
        let mut line = String::new();

        // This loop below will accomplish splitting a line of text
        // into lines that adhere to the amount of rows in a label
        loop {
            // Look for a word until a whitespace is reached
            if let Some(loc) = parse.find(char::is_whitespace) {
                let line_len = line.len();
                let tmp = parse[..loc].to_owned();
                // If the word can fit on the current line, add it
                if line_len + tmp.len() + self.t_margin.0 < framex {
                    line.push_str(&tmp);
                } else {
                    line = line.trim_right().to_owned();
                    self.text.push(line);
                    line = tmp.to_owned();
                }
                parse = parse[loc..].to_owned();
            } else {
                // If no whitespace detected, there may still be one
                // more word so attempt to add it
                if parse.len() != 0 {
                    let line_len = line.len();
                    if line_len + parse.len() + self.t_margin.0 < framex {
                        line.push_str(&parse);
                        self.text.push(line);
                    } else {
                        self.text.push(line);
                        self.text.push(parse);
                    }
                }
                break;
            }

            // Look for the range of spaces between words
            if let Some(loc) = parse.find(|c: char| c != ' ') {
                let line_len = line.len();
                let tmp = parse[..loc].to_owned();
                // If the next word can fit on the current line, do so
                if line_len + tmp.len() + self.t_margin.0 < framex {
                    line.push_str(&tmp);
                } else {
                    line = line.trim_right().to_owned();
                    self.text.push(line);
                    line = "".to_string();
                }
                parse = parse[loc..].to_owned();
            } else {
                // We don't care if there's spaces at the end, so don't check
                break;
            }
        }
    }
}

impl Widget for Label {
    fn draw(&mut self, parent: &mut CellAccessor) {
        // For every line to be written, align it correctly as defined by the user in
        // align_text, if not this text will be left and middle aligned by default
        for (i, item) in self.text.iter().enumerate() {
            self.x = self.frame.halign_line(&item, self.t_halign.clone(), self.t_margin.0);
            self.y = self.frame.valign_line(&item, self.t_valign.clone(), self.t_margin.1);
            self.frame.printline(self.x, self.y + i, &item);
        }
        self.frame.draw_into(parent);
    }

    fn pack(&mut self, parent: &HasSize, halign: HorizontalAlign, valign: VerticalAlign,
                margin: (usize, usize)) {
        self.frame.align(parent, halign, valign, margin);
    }

    fn draw_box(&mut self) {
        self.frame.draw_box();
    }

    fn resize(&mut self, new_size: Size) {
        self.frame.resize(new_size);
    }

    fn frame(&self) -> &Frame {
        &self.frame
    }

    fn frame_mut(&mut self) -> &mut Frame {
        &mut self.frame
    }
}
<|endoftext|>


<commit_before>#[link(name = "rust_fuse",
uuid = "d37c5c30-fdcd-459d-bfca-ebb8da04b2a0",
url = "https://github.com/MicahChalmer/rust-fuse")];

#[comment = "FUSE bindings"];
#[license = "MIT"];
#[crate_type = "lib"];

use std::libc::{
    c_char,
    c_int,
    c_uint,
    c_ulong,
    c_void,
    mode_t,
    off_t,
    pid_t,
    size_t,
    stat,
    uid_t,
    gid_t
};

use std::ptr;
use std::str;
use std::vec;
use std::sys::size_of;
use std::cast;
use std::Result;

// A cfuncptr is used here to stand in for a C function pointer.
// For this struct, see fuse.h
type cfuncptr = *u8;
struct c_fuse_operations {
    getattr: cfuncptr,
    readlink: cfuncptr,
    getdir: cfuncptr,
    mknod: cfuncptr,
    mkdir: cfuncptr,
    unlink: cfuncptr,
    rmdir: cfuncptr,
    symlink: cfuncptr,
    rename: cfuncptr,
    link: cfuncptr,
    chmod: cfuncptr,
    chown: cfuncptr,
    truncate: cfuncptr,
    utime: cfuncptr,
    open: cfuncptr,
    read: cfuncptr,
    write: cfuncptr,
    statfs: cfuncptr,
    flush: cfuncptr,
    release: cfuncptr,
    fsync: cfuncptr,
    setxattr: cfuncptr,
    getxattr: cfuncptr,
    listxattr: cfuncptr,
    removexattr: cfuncptr,
    opendir: cfuncptr,
    readdir: cfuncptr,
    releasedir: cfuncptr,
    fsyncdir: cfuncptr,
    init: cfuncptr,
    destroy: cfuncptr,
    access: cfuncptr,
    create: cfuncptr,
    ftruncate: cfuncptr,
    fgetattr: cfuncptr,
    lock: cfuncptr,
    utimens: cfuncptr,
    bmap: cfuncptr,

    // flag_nullpath_ok, flag_nopath, flag_utime_omit_ok, flag_reserved
    flags: u32,

    ioctl: cfuncptr,
    poll: cfuncptr,
    write_buf: cfuncptr,
    read_buf: cfuncptr,
    flock: cfuncptr
}

// TODO: this should not be public
pub struct fuse_file_info {
    flags: c_int,
    fh_old: c_ulong, // Old file handle, don't use
    writepage: c_int,
    direct_io: c_uint,
    keep_cache: c_uint,
    flush: c_uint,
    nonseekable: c_uint,
    flock_release: c_uint,
    padding: c_uint, // Padding.  Do not use
    fh: u64,
    lock_owner: u64
}

struct c_fuse_context {
    fuse: *c_void,
    uid: uid_t,
    gid: gid_t,
    pid: pid_t,
    private_data: *rust_fuse_data,  // we use this to know what object to call
    umask: mode_t
}

struct rust_fuse_data {
    ops: ~FuseOperations
}

#[link_args = "-lfuse"]
extern {
    fn fuse_main_real(argc:c_int, argv:**c_char,
                      op:*c_fuse_operations, op_size: size_t,
                      user_data: *c_void) -> c_int;

    fn fuse_get_context() -> *c_fuse_context;
}

#[link_args = "-lfuserustwrapper -L../../wrapper/lib"]
extern {

    // Workaround for the fact that we can't call into c via a function ptr right
    // from rust
    fn call_filler_function(filler: cfuncptr, buf: *c_void, name: *c_char, stbuf: *stat,
                           off: off_t) -> c_int;
}

// Used for return values from FS operations
pub type errno = c_int;

pub type fuse_fill_dir_func<'self> = &'self fn (&str, Option<stat>, off_t) -> c_int;

pub type filehandle = u64;

pub trait FuseOperations {
    fn getattr(&self, path:&str) -> Result<stat, errno>;
    fn readdir(&self, path:&str, filler: fuse_fill_dir_func,
               offset: off_t, info: &fuse_file_info) -> Result<(), errno>;
    fn open(&self, path:&str, info: &fuse_file_info) -> Result<filehandle, errno>;
    fn read(&self, path:&str, buf:&mut [u8], size: size_t, offset: off_t,
            info: &fuse_file_info) -> Result<c_int, errno>;
}

unsafe fn get_context_ops() -> &~FuseOperations {
    &((*(*fuse_get_context()).private_data).ops)
}

extern fn c_getattr(path: *c_char, stbuf: *mut stat) -> errno {
    unsafe {
        let ops = get_context_ops();
        ptr::zero_memory(stbuf, 1);
        match ops.getattr(str::raw::from_c_str(path)) {
            Err(e) => -e,
            Ok(st) => { ptr::copy_memory(stbuf, &st, 1); 0 }
        }
    }
}

unsafe fn option_to_ptr<T>(opt: Option<T>) -> *T {
    match opt {
        Some(ref t) => ptr::to_unsafe_ptr(t),
        None => ptr::null()
    }
}

extern fn c_readdir(path: *c_char, buf: *c_void, filler: cfuncptr,
                    offset: off_t, fi: *fuse_file_info) -> c_int {
    unsafe {
        let ops = get_context_ops();
        let fill_func: fuse_fill_dir_func = |name, st, ofs| -> c_int {
            do name.as_c_str |c_name| {
                call_filler_function(filler, buf, c_name, option_to_ptr(st), ofs)
            }
        };
        match ops.readdir(str::raw::from_c_str(path), fill_func, offset, &*fi) {
            Err(e) => -e,
            Ok(_) => 0
        }
    }
}

extern fn c_open(path: *c_char, info: *mut fuse_file_info) -> c_int {
    unsafe {
        let ops = get_context_ops();
        match ops.open(str::raw::from_c_str(path), &*info) {
            Err(e) => -e,
            Ok(fh) => { (*info).fh = fh; 0 }
        }
    }
}

extern fn c_read(path: *c_char, buf: *mut u8, size: size_t, offset: off_t,
                 fi: *fuse_file_info) -> c_int {
    unsafe {
        let ops = get_context_ops();
        do vec::raw::mut_buf_as_slice(buf, size as uint) |slice| {
            match ops.read(str::raw::from_c_str(path), slice, size, offset, &*fi) {
                Err(e) => -e,
                Ok(sz) => sz
            }
        }
    }
}

pub fn fuse_main(args: ~[~str], ops: ~FuseOperations) -> int {
    let cfo = c_fuse_operations {
        getattr: c_getattr,
        readdir: c_readdir,
        open: c_open,
        read: c_read,

        readlink: ptr::null(),
        getdir: ptr::null(),
        mknod: ptr::null(),
        mkdir: ptr::null(),
        unlink: ptr::null(),
        rmdir: ptr::null(),
        symlink: ptr::null(),
        rename: ptr::null(),
        link: ptr::null(),
        chmod: ptr::null(),
        chown: ptr::null(),
        truncate: ptr::null(),
        utime: ptr::null(),
        write: ptr::null(),
        statfs: ptr::null(),
        flush: ptr::null(),
        release: ptr::null(),
        fsync: ptr::null(),
        setxattr: ptr::null(),
        getxattr: ptr::null(),
        listxattr: ptr::null(),
        removexattr: ptr::null(),
        opendir: ptr::null(),
        releasedir: ptr::null(),
        fsyncdir: ptr::null(),
        init: ptr::null(),
        destroy: ptr::null(),
        access: ptr::null(),
        create: ptr::null(),
        ftruncate: ptr::null(),
        fgetattr: ptr::null(),
        lock: ptr::null(),
        utimens: ptr::null(),
        bmap: ptr::null(),
        flags:0,
        ioctl: ptr::null(),
        poll: ptr::null(),
        write_buf: ptr::null(),
        read_buf: ptr::null(),
        flock: ptr::null()
    };
    unsafe {
        let arg_c_strs_owner: ~[*u8] = args.map(|s| vec::raw::to_ptr(s.as_bytes_with_null()));
        let arg_c_strs_ptr = vec::raw::to_ptr(arg_c_strs_owner);
//        cast::forget(arg_c_strs_owner);

        fuse_main_real(args.len() as c_int, cast::transmute(arg_c_strs_ptr),
                       &cfo, size_of::<c_fuse_operations>() as size_t,
                       cast::transmute(~rust_fuse_data{ ops: ops }))  as int
    }
}
<commit_msg>Add dev version tag, fix whitespace<commit_after>#[link(name = "rust-fuse",
uuid = "d37c5c30-fdcd-459d-bfca-ebb8da04b2a0",
url = "https://github.com/MicahChalmer/rust-fuse",
vers = "dev")];

#[comment = "FUSE bindings"];
#[license = "MIT"];
#[crate_type = "lib"];

use std::libc::{
    c_char,
    c_int,
    c_uint,
    c_ulong,
    c_void,
    mode_t,
    off_t,
    pid_t,
    size_t,
    stat,
    uid_t,
    gid_t
};

use std::ptr;
use std::str;
use std::vec;
use std::sys::size_of;
use std::cast;
use std::Result;

// A cfuncptr is used here to stand in for a C function pointer.
// For this struct, see fuse.h
type cfuncptr = *u8;
struct c_fuse_operations {
    getattr: cfuncptr,
    readlink: cfuncptr,
    getdir: cfuncptr,
    mknod: cfuncptr,
    mkdir: cfuncptr,
    unlink: cfuncptr,
    rmdir: cfuncptr,
    symlink: cfuncptr,
    rename: cfuncptr,
    link: cfuncptr,
    chmod: cfuncptr,
    chown: cfuncptr,
    truncate: cfuncptr,
    utime: cfuncptr,
    open: cfuncptr,
    read: cfuncptr,
    write: cfuncptr,
    statfs: cfuncptr,
    flush: cfuncptr,
    release: cfuncptr,
    fsync: cfuncptr,
    setxattr: cfuncptr,
    getxattr: cfuncptr,
    listxattr: cfuncptr,
    removexattr: cfuncptr,
    opendir: cfuncptr,
    readdir: cfuncptr,
    releasedir: cfuncptr,
    fsyncdir: cfuncptr,
    init: cfuncptr,
    destroy: cfuncptr,
    access: cfuncptr,
    create: cfuncptr,
    ftruncate: cfuncptr,
    fgetattr: cfuncptr,
    lock: cfuncptr,
    utimens: cfuncptr,
    bmap: cfuncptr,

    // flag_nullpath_ok, flag_nopath, flag_utime_omit_ok, flag_reserved
    flags: u32,

    ioctl: cfuncptr,
    poll: cfuncptr,
    write_buf: cfuncptr,
    read_buf: cfuncptr,
    flock: cfuncptr
}

// TODO: this should not be public
pub struct fuse_file_info {
    flags: c_int,
    fh_old: c_ulong, // Old file handle, don't use
    writepage: c_int,
    direct_io: c_uint,
    keep_cache: c_uint,
    flush: c_uint,
    nonseekable: c_uint,
    flock_release: c_uint,
    padding: c_uint, // Padding.  Do not use
    fh: u64,
    lock_owner: u64
}

struct c_fuse_context {
    fuse: *c_void,
    uid: uid_t,
    gid: gid_t,
    pid: pid_t,
    private_data: *rust_fuse_data,  // we use this to know what object to call
    umask: mode_t
}

struct rust_fuse_data {
    ops: ~FuseOperations
}

#[link_args = "-lfuse"]
extern {
    fn fuse_main_real(argc:c_int, argv:**c_char,
                      op:*c_fuse_operations, op_size: size_t,
                      user_data: *c_void) -> c_int;

    fn fuse_get_context() -> *c_fuse_context;
}

#[link_args = "-lfuserustwrapper -Lwrapper/lib"]
extern {

    // Workaround for the fact that we can't call into c via a function ptr
    // right from rust
    fn call_filler_function(filler: cfuncptr, buf: *c_void, name: *c_char,
                            stbuf: *stat, off: off_t) -> c_int;
}

// Used for return values from FS operations
pub type errno = c_int;

pub type fuse_fill_dir_func<'self> = &'self fn (&str, Option<stat>, off_t) -> c_int;

pub type filehandle = u64;

pub trait FuseOperations {
    fn getattr(&self, path:&str) -> Result<stat, errno>;
    fn readdir(&self, path:&str, filler: fuse_fill_dir_func,
               offset: off_t, info: &fuse_file_info) -> Result<(), errno>;
    fn open(&self, path:&str, info: &fuse_file_info) -> Result<filehandle, errno>;
    fn read(&self, path:&str, buf:&mut [u8], size: size_t, offset: off_t,
            info: &fuse_file_info) -> Result<c_int, errno>;
}

unsafe fn get_context_ops() -> &~FuseOperations {
    &((*(*fuse_get_context()).private_data).ops)
}

extern fn c_getattr(path: *c_char, stbuf: *mut stat) -> errno {
    unsafe {
        let ops = get_context_ops();
        ptr::zero_memory(stbuf, 1);
        match ops.getattr(str::raw::from_c_str(path)) {
            Err(e) => -e,
            Ok(st) => { ptr::copy_memory(stbuf, &st, 1); 0 }
        }
    }
}

unsafe fn option_to_ptr<T>(opt: Option<T>) -> *T {
    match opt {
        Some(ref t) => ptr::to_unsafe_ptr(t),
        None => ptr::null()
    }
}

extern fn c_readdir(path: *c_char, buf: *c_void, filler: cfuncptr,
                    offset: off_t, fi: *fuse_file_info) -> c_int {
    unsafe {
        let ops = get_context_ops();
        let fill_func: fuse_fill_dir_func = |name, st, ofs| -> c_int {
            do name.as_c_str |c_name| {
                call_filler_function(filler, buf, c_name, option_to_ptr(st), ofs)
            }
        };
        match ops.readdir(str::raw::from_c_str(path), fill_func, offset, &*fi) {
            Err(e) => -e,
            Ok(_) => 0
        }
    }
}

extern fn c_open(path: *c_char, info: *mut fuse_file_info) -> c_int {
    unsafe {
        let ops = get_context_ops();
        match ops.open(str::raw::from_c_str(path), &*info) {
            Err(e) => -e,
            Ok(fh) => { (*info).fh = fh; 0 }
        }
    }
}

extern fn c_read(path: *c_char, buf: *mut u8, size: size_t, offset: off_t,
                 fi: *fuse_file_info) -> c_int {
    unsafe {
        let ops = get_context_ops();
        do vec::raw::mut_buf_as_slice(buf, size as uint) |slice| {
            match ops.read(str::raw::from_c_str(path), slice, size, offset, &*fi) {
                Err(e) => -e,
                Ok(sz) => sz
            }
        }
    }
}

pub fn fuse_main(args: ~[~str], ops: ~FuseOperations) -> int {
    let cfo = c_fuse_operations {
        getattr: c_getattr,
        readdir: c_readdir,
        open: c_open,
        read: c_read,

        readlink: ptr::null(),
        getdir: ptr::null(),
        mknod: ptr::null(),
        mkdir: ptr::null(),
        unlink: ptr::null(),
        rmdir: ptr::null(),
        symlink: ptr::null(),
        rename: ptr::null(),
        link: ptr::null(),
        chmod: ptr::null(),
        chown: ptr::null(),
        truncate: ptr::null(),
        utime: ptr::null(),
        write: ptr::null(),
        statfs: ptr::null(),
        flush: ptr::null(),
        release: ptr::null(),
        fsync: ptr::null(),
        setxattr: ptr::null(),
        getxattr: ptr::null(),
        listxattr: ptr::null(),
        removexattr: ptr::null(),
        opendir: ptr::null(),
        releasedir: ptr::null(),
        fsyncdir: ptr::null(),
        init: ptr::null(),
        destroy: ptr::null(),
        access: ptr::null(),
        create: ptr::null(),
        ftruncate: ptr::null(),
        fgetattr: ptr::null(),
        lock: ptr::null(),
        utimens: ptr::null(),
        bmap: ptr::null(),
        flags:0,
        ioctl: ptr::null(),
        poll: ptr::null(),
        write_buf: ptr::null(),
        read_buf: ptr::null(),
        flock: ptr::null()
    };
    unsafe {
        let arg_c_strs_owner: ~[*u8] = args.map(|s| vec::raw::to_ptr(s.as_bytes_with_null()));
        let arg_c_strs_ptr = vec::raw::to_ptr(arg_c_strs_owner);
//        cast::forget(arg_c_strs_owner);

        fuse_main_real(args.len() as c_int, cast::transmute(arg_c_strs_ptr),
                       &cfo, size_of::<c_fuse_operations>() as size_t,
                       cast::transmute(~rust_fuse_data{ ops: ops }))  as int
    }
}
<|endoftext|>


<commit_before>use common::*;
use tweet;

use chrono;

use super::UserEntities;

#[derive(Debug, Clone, Deserialize)]
pub struct RawTwitterUser {
    /// Indicates this user has an account with "contributor mode" enabled, allowing
    /// for Tweets issued by the user to be co-authored by another account. Rarely `true`.
    pub contributors_enabled: bool,
    /// The UTC timestamp for when this user account was created on Twitter.
    #[serde(deserialize_with = "deserialize_datetime")]
    pub created_at: chrono::DateTime<chrono::Utc>,
    /// When true, indicates that this user has not altered the theme or background of
    /// their user profile.
    pub default_profile: bool,
    /// When true, indicates that the user has not uploaded their own avatar and a default
    /// egg avatar is used instead.
    pub default_profile_image: bool,
    /// The user-defined string describing their account.
    pub description: Option<String>,
    /// Link information that has been parsed out of the `url` or `description` fields given by the
    /// user.
    #[serde(default)]
    pub entities: UserEntities,
    /// The number of tweets this user has favorited or liked in the account's lifetime.
    /// The term "favourites" and its British spelling are used for historical reasons.
    pub favourites_count: i32,
    /// When true, indicates that the authenticating user has issued a follow request to
    /// this protected account.
    pub follow_request_sent: Option<bool>,
    /// The number of followers this account has.
    ///
    /// In certain server-stress conditions, this may temporarily mistakenly return 0.
    pub followers_count: i32,
    /// The number of users this account follows, aka its "followings".
    ///
    /// In certain server-stress conditions, this may temporarily mistakenly return 0.
    pub friends_count: i32,
    /// Indicates whether this user as enabled their tweets to be geotagged.
    ///
    /// If this is set for the current user, then they can attach geographic data when
    /// posting a new Tweet.
    pub geo_enabled: bool,
    /// Unique identifier for this user.
    pub id: u64,
    /// Indicates whether the user participates in Twitter's translator community.
    pub is_translator: bool,
    /// Language code for the user's self-declared interface language.
    ///
    /// Codes are formatted as a language tag from [BCP 47][]. Only indicates the user's
    /// interface language, not necessarily the content of their Tweets.
    ///
    /// [BCP 47]: https://tools.ietf.org/html/bcp47
    pub lang: String,
    /// The number of public lists the user is a member of.
    pub listed_count: i32,
    /// The user-entered location field from their profile. Not necessarily parseable
    /// or even a location.
    pub location: Option<String>,
    /// The user-entered display name.
    pub name: String,
    /// The hex color chosen by the user for their profile background.
    pub profile_background_color: String,
    /// A URL pointing to the background image chosen by the user for their profile. Uses
    /// HTTP as the protocol.
    pub profile_background_image_url: Option<String>,
    /// A URL pointing to the background image chosen by the user for their profile. Uses
    /// HTTPS as the protocol.
    pub profile_background_image_url_https: Option<String>,
    /// Indicates whether the user's `profile_background_image_url` should be tiled when
    /// displayed.
    pub profile_background_tile: Option<bool>,
    /// A URL pointing to the banner image chosen by the user. Uses HTTPS as the protocol.
    ///
    /// This is a base URL that a size specifier can be appended onto to get variously
    /// sized images, with size specifiers according to [Profile Images and Banners][profile-img].
    ///
    /// [profile-img]: https://dev.twitter.com/overview/general/user-profile-images-and-banners
    pub profile_banner_url: Option<String>,
    /// A URL pointing to the user's avatar image. Uses HTTP as the protocol. Size
    /// specifiers can be used according to [Profile Images and Banners][profile-img].
    ///
    /// [profile-img]: https://dev.twitter.com/overview/general/user-profile-images-and-banners
    pub profile_image_url: String,
    /// A URL pointing to the user's avatar image. Uses HTTPS as the protocol. Size
    /// specifiers can be used according to [Profile Images and Banners][profile-img].
    ///
    /// [profile-img]: https://dev.twitter.com/overview/general/user-profile-images-and-banners
    pub profile_image_url_https: String,
    /// The hex color chosen by the user to display links in the Twitter UI.
    pub profile_link_color: String,
    /// The hex color chosen by the user to display sidebar borders in the Twitter UI.
    pub profile_sidebar_border_color: String,
    /// The hex color chosen by the user to display sidebar backgrounds in the Twitter UI.
    pub profile_sidebar_fill_color: String,
    /// The hex color chosen by the user to display text in the Twitter UI.
    pub profile_text_color: String,
    /// Indicates whether the user wants their uploaded background image to be used.
    pub profile_use_background_image: bool,
    /// Indicates whether the user is a [protected][] account.
    ///
    /// [protected]: https://support.twitter.com/articles/14016
    pub protected: bool,
    /// The screen name or handle identifying this user.
    ///
    /// Screen names are unique per-user but can be changed. Use `id` for an immutable identifier
    /// for an account.
    ///
    /// Typically a maximum of 15 characters long, but older accounts may exist with longer screen
    /// names.
    pub screen_name: String,
    /// Indicates that the user would like to see media inline. "Somewhat disused."
    pub show_all_inline_media: Option<bool>,
    /// If possible, the most recent tweet or retweet from this user.
    ///
    /// "In some circumstances, this data cannot be provided and this field will be omitted, null,
    /// or empty." Do not depend on this field being filled. Also note that this is actually their
    /// most-recent tweet, not the status pinned to their profile.
    ///
    /// "Perspectival" items within this tweet that depend on the authenticating user
    /// [may not be completely reliable][stale-embed] in this embed.
    ///
    /// [stale-embed]: https://dev.twitter.com/docs/faq/basics/why-are-embedded-objects-stale-or-inaccurate
    pub status: Option<Box<tweet::Tweet>>,
    /// The number of tweets (including retweets) posted by this user.
    pub statuses_count: i32,
    /// The full name of the time zone the user has set their UI preference to.
    pub time_zone: Option<String>,
    /// The website link given by this user in their profile.
    pub url: Option<String>,
    /// The UTC offset of `time_zone` in minutes.
    pub utc_offset: Option<i32>,
    /// Indicates whether this user is a verified account.
    pub verified: bool,
    /// When present, lists the countries this user has been withheld from.
    pub withheld_in_countries: Option<Vec<String>>,
    /// When present, indicates whether the content being withheld is a "status" or "user".
    pub withheld_scope: Option<String>,
}
<commit_msg>add MPL header to src/user/raw.rs<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use common::*;
use tweet;

use chrono;

use super::UserEntities;

#[derive(Debug, Clone, Deserialize)]
pub struct RawTwitterUser {
    /// Indicates this user has an account with "contributor mode" enabled, allowing
    /// for Tweets issued by the user to be co-authored by another account. Rarely `true`.
    pub contributors_enabled: bool,
    /// The UTC timestamp for when this user account was created on Twitter.
    #[serde(deserialize_with = "deserialize_datetime")]
    pub created_at: chrono::DateTime<chrono::Utc>,
    /// When true, indicates that this user has not altered the theme or background of
    /// their user profile.
    pub default_profile: bool,
    /// When true, indicates that the user has not uploaded their own avatar and a default
    /// egg avatar is used instead.
    pub default_profile_image: bool,
    /// The user-defined string describing their account.
    pub description: Option<String>,
    /// Link information that has been parsed out of the `url` or `description` fields given by the
    /// user.
    #[serde(default)]
    pub entities: UserEntities,
    /// The number of tweets this user has favorited or liked in the account's lifetime.
    /// The term "favourites" and its British spelling are used for historical reasons.
    pub favourites_count: i32,
    /// When true, indicates that the authenticating user has issued a follow request to
    /// this protected account.
    pub follow_request_sent: Option<bool>,
    /// The number of followers this account has.
    ///
    /// In certain server-stress conditions, this may temporarily mistakenly return 0.
    pub followers_count: i32,
    /// The number of users this account follows, aka its "followings".
    ///
    /// In certain server-stress conditions, this may temporarily mistakenly return 0.
    pub friends_count: i32,
    /// Indicates whether this user as enabled their tweets to be geotagged.
    ///
    /// If this is set for the current user, then they can attach geographic data when
    /// posting a new Tweet.
    pub geo_enabled: bool,
    /// Unique identifier for this user.
    pub id: u64,
    /// Indicates whether the user participates in Twitter's translator community.
    pub is_translator: bool,
    /// Language code for the user's self-declared interface language.
    ///
    /// Codes are formatted as a language tag from [BCP 47][]. Only indicates the user's
    /// interface language, not necessarily the content of their Tweets.
    ///
    /// [BCP 47]: https://tools.ietf.org/html/bcp47
    pub lang: String,
    /// The number of public lists the user is a member of.
    pub listed_count: i32,
    /// The user-entered location field from their profile. Not necessarily parseable
    /// or even a location.
    pub location: Option<String>,
    /// The user-entered display name.
    pub name: String,
    /// The hex color chosen by the user for their profile background.
    pub profile_background_color: String,
    /// A URL pointing to the background image chosen by the user for their profile. Uses
    /// HTTP as the protocol.
    pub profile_background_image_url: Option<String>,
    /// A URL pointing to the background image chosen by the user for their profile. Uses
    /// HTTPS as the protocol.
    pub profile_background_image_url_https: Option<String>,
    /// Indicates whether the user's `profile_background_image_url` should be tiled when
    /// displayed.
    pub profile_background_tile: Option<bool>,
    /// A URL pointing to the banner image chosen by the user. Uses HTTPS as the protocol.
    ///
    /// This is a base URL that a size specifier can be appended onto to get variously
    /// sized images, with size specifiers according to [Profile Images and Banners][profile-img].
    ///
    /// [profile-img]: https://dev.twitter.com/overview/general/user-profile-images-and-banners
    pub profile_banner_url: Option<String>,
    /// A URL pointing to the user's avatar image. Uses HTTP as the protocol. Size
    /// specifiers can be used according to [Profile Images and Banners][profile-img].
    ///
    /// [profile-img]: https://dev.twitter.com/overview/general/user-profile-images-and-banners
    pub profile_image_url: String,
    /// A URL pointing to the user's avatar image. Uses HTTPS as the protocol. Size
    /// specifiers can be used according to [Profile Images and Banners][profile-img].
    ///
    /// [profile-img]: https://dev.twitter.com/overview/general/user-profile-images-and-banners
    pub profile_image_url_https: String,
    /// The hex color chosen by the user to display links in the Twitter UI.
    pub profile_link_color: String,
    /// The hex color chosen by the user to display sidebar borders in the Twitter UI.
    pub profile_sidebar_border_color: String,
    /// The hex color chosen by the user to display sidebar backgrounds in the Twitter UI.
    pub profile_sidebar_fill_color: String,
    /// The hex color chosen by the user to display text in the Twitter UI.
    pub profile_text_color: String,
    /// Indicates whether the user wants their uploaded background image to be used.
    pub profile_use_background_image: bool,
    /// Indicates whether the user is a [protected][] account.
    ///
    /// [protected]: https://support.twitter.com/articles/14016
    pub protected: bool,
    /// The screen name or handle identifying this user.
    ///
    /// Screen names are unique per-user but can be changed. Use `id` for an immutable identifier
    /// for an account.
    ///
    /// Typically a maximum of 15 characters long, but older accounts may exist with longer screen
    /// names.
    pub screen_name: String,
    /// Indicates that the user would like to see media inline. "Somewhat disused."
    pub show_all_inline_media: Option<bool>,
    /// If possible, the most recent tweet or retweet from this user.
    ///
    /// "In some circumstances, this data cannot be provided and this field will be omitted, null,
    /// or empty." Do not depend on this field being filled. Also note that this is actually their
    /// most-recent tweet, not the status pinned to their profile.
    ///
    /// "Perspectival" items within this tweet that depend on the authenticating user
    /// [may not be completely reliable][stale-embed] in this embed.
    ///
    /// [stale-embed]: https://dev.twitter.com/docs/faq/basics/why-are-embedded-objects-stale-or-inaccurate
    pub status: Option<Box<tweet::Tweet>>,
    /// The number of tweets (including retweets) posted by this user.
    pub statuses_count: i32,
    /// The full name of the time zone the user has set their UI preference to.
    pub time_zone: Option<String>,
    /// The website link given by this user in their profile.
    pub url: Option<String>,
    /// The UTC offset of `time_zone` in minutes.
    pub utc_offset: Option<i32>,
    /// Indicates whether this user is a verified account.
    pub verified: bool,
    /// When present, lists the countries this user has been withheld from.
    pub withheld_in_countries: Option<Vec<String>>,
    /// When present, indicates whether the content being withheld is a "status" or "user".
    pub withheld_scope: Option<String>,
}
<|endoftext|>


<commit_before>use sys::joystick as ll;

use SdlResult;
use get_error;
use clear_error;
use sys::event::{SDL_QUERY, SDL_ENABLE};
use std::ffi::{CString, CStr, NulError};
use std::fmt::{Display, Formatter, Error};
use libc::c_char;

/// Retreive the total number of attached joysticks *and* controllers
/// identified by SDL.
pub fn num_joysticks() -> SdlResult<i32> {
    let result = unsafe { ll::SDL_NumJoysticks() };

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

/// Get the GUID for the joystick number `id`
pub fn get_device_guid(id: i32) -> SdlResult<Guid> {
    let raw = unsafe { ll::SDL_JoystickGetDeviceGUID(id) };

    let guid = Guid { raw: raw };

    if guid.is_zero() {
        Err(get_error())
    } else {
        Ok(guid)
    }
}

/// If state is `true` joystick events are processed, otherwise
/// they're ignored.
pub fn set_event_state(state: bool) {
    unsafe { ll::SDL_JoystickEventState(state as i32) };
}

/// Return `true` if joystick events are processed.
pub fn get_event_state() -> bool {
    unsafe { ll::SDL_JoystickEventState(SDL_QUERY as i32)
             == SDL_ENABLE as i32 }
}

/// Return the name of the joystick at index `id`
pub fn name_for_index(id: i32) -> SdlResult<String> {
    let name = unsafe { ll::SDL_JoystickNameForIndex(id) };

    c_str_to_string_or_err(name)
}

/// Force joystick update when not using the event loop
pub fn update() {
    unsafe { ll::SDL_JoystickUpdate() };
}

/// Wrapper around the SDL_Joystick object
pub struct Joystick {
    raw: *mut ll::SDL_Joystick,
}

impl Joystick {
    /// Attempt to open the joystick at number `id` and return it.
    pub fn open(id: i32) -> SdlResult<Joystick> {
        let joystick = unsafe { ll::SDL_JoystickOpen(id) };

        if joystick.is_null() {
            Err(get_error())
        } else {
            Ok(Joystick { raw: joystick })
        }
    }

    /// Return the name of the joystick or an empty string if no name
    /// is found.
    pub fn name(&self) -> String {
        let name = unsafe { ll::SDL_JoystickName(self.raw) };

        c_str_to_string(name)
    }

    /// Return true if the joystick has been opened and currently
    /// connected.
    pub fn get_attached(&self) -> bool {
        unsafe { ll::SDL_JoystickGetAttached(self.raw) != 0 }
    }

    pub fn get_instance_id(&self) -> i32 {
        let result = unsafe { ll::SDL_JoystickInstanceID(self.raw) };

        if result < 0 {
            // Should only fail if the joystick is NULL.
            panic!(get_error())
        } else {
            result
        }
    }

    /// Retreive the joystick's GUID
    pub fn get_guid(&self) -> Guid {
        let raw = unsafe { ll::SDL_JoystickGetGUID(self.raw) };

        let guid = Guid { raw: raw };

        if guid.is_zero() {
            // Should only fail if the joystick is NULL.
            panic!(get_error())
        } else {
            guid
        }
    }

    /// Retreive the number of axes for this joystick
    pub fn get_num_axes(&self) -> i32 {
        let result = unsafe { ll::SDL_JoystickNumAxes(self.raw) };

        if result < 0 {
            // Should only fail if the joystick is NULL.
            panic!(get_error())
        } else {
            result
        }
    }

    /// Gets the position of the given `axis`.
    ///
    /// The function will fail if the joystick doesn't have the provided axis.
    pub fn get_axis(&self, axis: i32) -> SdlResult<i16> {
        // This interface is a bit messed up: 0 is a valid position
        // but can also mean that an error occured. As far as I can
        // tell the only way to know if an error happened is to see if
        // get_error() returns a non-empty string.
        clear_error();

        let pos = unsafe { ll::SDL_JoystickGetAxis(self.raw, axis) };

        if pos != 0 {
            Ok(pos)
        } else {
            let err = get_error();

            if err.is_empty() {
                Ok(pos)
            } else {
                Err(err)
            }
        }
    }

    /// Retreive the number of buttons for this joystick
    pub fn get_num_buttons(&self) -> i32 {
        let result = unsafe { ll::SDL_JoystickNumButtons(self.raw) };

        if result < 0 {
            // Should only fail if the joystick is NULL.
            panic!(get_error())
        } else {
            result
        }
    }

    /// Return `Ok(true)` if `button` is pressed.
    ///
    /// The function will fail if the joystick doesn't have the provided button.
    pub fn get_button(&self, button: i32) -> SdlResult<bool> {
        // Same deal as get_axis, 0 can mean both unpressed or
        // error...
        clear_error();

        let pressed = unsafe { ll::SDL_JoystickGetButton(self.raw, button) };

        match pressed {
            1 => Ok(true),
            0 => {
                let err = get_error();

                if err.is_empty() {
                    // Button is not pressed
                    Ok(false)
                } else {
                    Err(err)
                }
            }
            // Should be unreachable
            _ => Err(get_error()),
        }
    }

    /// Retreive the number of balls for this joystick
    pub fn get_num_balls(&self) -> i32 {
        let result = unsafe { ll::SDL_JoystickNumBalls(self.raw) };

        if result < 0 {
            // Should only fail if the joystick is NULL.
            panic!(get_error())
        } else {
            result
        }
    }

    /// Return a pair `(dx, dy)` containing the difference in axis
    /// position since the last poll
    pub fn get_ball(&self, ball: i32) -> SdlResult<(i32, i32)> {
        let mut dx = 0;
        let mut dy = 0;

        let result =
            unsafe {
                ll::SDL_JoystickGetBall(self.raw, ball, &mut dx, &mut dy)
            };

        if result == 0 {
            Ok((dx, dy))
        } else {
            Err(get_error())
        }
    }

    /// Retreive the number of balls for this joystick
    pub fn get_num_hats(&self) -> i32 {
        let result = unsafe { ll::SDL_JoystickNumHats(self.raw) };

        if result < 0 {
            // Should only fail if the joystick is NULL.
            panic!(get_error())
        } else {
            result
        }
    }

    /// Return the position of `hat` for this joystick
    pub fn get_hat(&self, hat: i32) -> SdlResult<HatState> {
        // Guess what? This function as well uses 0 to report an error
        // but 0 is also a valid value (HatState::Centered). So we
        // have to use the same hack as `get_axis`...
        clear_error();

        let result = unsafe { ll::SDL_JoystickGetHat(self.raw, hat) };

        let state = HatState::from_raw(result as u8);

        if result != 0 {
            Ok(state)
        } else {
            let err = get_error();

            if err.is_empty() {
                Ok(state)
            } else {
                Err(err)
            }
        }
    }
}

impl Drop for Joystick {
    fn drop(&mut self) {
        unsafe { ll::SDL_JoystickClose(self.raw) }
    }
}

/// Wrapper around a SDL_JoystickGUID, a globally unique identifier
/// for a joystick.
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub struct Guid {
    raw: ll::SDL_JoystickGUID,
}

impl Guid {
    /// Create a GUID from a string representation.
    pub fn from_string(guid: &str) -> Result<Guid, NulError> {
        let guid = try!(CString::new(guid));

        let raw = unsafe { ll::SDL_JoystickGetGUIDFromString(guid.as_ptr()) };

        Ok(Guid { raw: raw })
    }

    /// Return `true` if GUID is full 0s
    pub fn is_zero(&self) -> bool {
        for &i in self.raw.data.iter() {
            if i != 0 {
                return false;
            }
        }

        return true;
    }

    /// Return a String representation of GUID
    pub fn get_string(&self) -> String {
        // Doc says "buf should supply at least 33bytes". I took that
        // to mean that 33bytes should be enough in all cases, but
        // maybe I'm wrong?
        let mut buf = [0; 33];

        let len   = buf.len() as i32;
        let c_str = buf.as_mut_ptr();

        unsafe {
            ll::SDL_JoystickGetGUIDString(self.raw, c_str, len);
        }

        // The buffer should always be NUL terminated (the
        // documentation doesn't explicitely say it but I checked the
        // code)
        c_str_to_string(c_str)
    }

    /// Return a copy of the internal SDL_JoystickGUID
    pub fn raw(self) -> ll::SDL_JoystickGUID {
        self.raw
    }
}

impl Display for Guid {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        write!(f, "{}", self.get_string())
    }
}

/// This is represented in SDL2 as a bitfield but obviously not all
/// combinations make sense: 5 for instance would mean up and down at
/// the same time... To simplify things I turn it into an enum which
/// is how the SDL2 docs present it anyway (using macros).
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum HatState {
    Centered  = 0,
    Up        = 0x01,
    Right     = 0x02,
    Down      = 0x04,
    Left      = 0x08,
    RightUp   = 0x02 | 0x01,
    RightDown = 0x02 | 0x04,
    LeftUp    = 0x08 | 0x01,
    Leftdown  = 0x08 | 0x04,
}

impl HatState {
    pub fn from_raw(raw: u8) -> HatState {
        match raw {
            0  => HatState::Centered,
            1  => HatState::Up,
            2  => HatState::Right,
            4  => HatState::Down,
            8  => HatState::Left,
            3  => HatState::RightUp,
            6  => HatState::RightDown,
            9  => HatState::LeftUp,
            12 => HatState::Leftdown,
            _  => panic!("Unexpected hat position: {}", raw),
        }
    }
}

/// Convert C string `c_str` to a String. Return an empty string if
/// c_str is NULL.
fn c_str_to_string(c_str: *const c_char) -> String {
    if c_str.is_null() {
        String::new()
    } else {
        let bytes = unsafe { CStr::from_ptr(c_str).to_bytes() };

        String::from_utf8_lossy(bytes).to_string()
    }
}

/// Convert C string `c_str` to a String. Return an SDL error if
/// `c_str` is NULL.
fn c_str_to_string_or_err(c_str: *const c_char) -> SdlResult<String> {
    if c_str.is_null() {
        Err(get_error())
    } else {
        let bytes = unsafe { CStr::from_ptr(c_str).to_bytes() };

        Ok(String::from_utf8_lossy(bytes).to_string())
    }
}
<commit_msg>Replace i32 with u32<commit_after>use sys::joystick as ll;

use SdlResult;
use get_error;
use clear_error;
use sys::event::{SDL_QUERY, SDL_ENABLE};
use std::ffi::{CString, CStr, NulError};
use std::fmt::{Display, Formatter, Error};
use libc::c_char;

/// Retreive the total number of attached joysticks *and* controllers
/// identified by SDL.
pub fn num_joysticks() -> SdlResult<i32> {
    let result = unsafe { ll::SDL_NumJoysticks() };

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

/// Get the GUID for the joystick number `id`
pub fn get_device_guid(id: i32) -> SdlResult<Guid> {
    let raw = unsafe { ll::SDL_JoystickGetDeviceGUID(id) };

    let guid = Guid { raw: raw };

    if guid.is_zero() {
        Err(get_error())
    } else {
        Ok(guid)
    }
}

/// If state is `true` joystick events are processed, otherwise
/// they're ignored.
pub fn set_event_state(state: bool) {
    unsafe { ll::SDL_JoystickEventState(state as i32) };
}

/// Return `true` if joystick events are processed.
pub fn get_event_state() -> bool {
    unsafe { ll::SDL_JoystickEventState(SDL_QUERY as i32)
             == SDL_ENABLE as i32 }
}

/// Return the name of the joystick at index `id`
pub fn name_for_index(id: i32) -> SdlResult<String> {
    let name = unsafe { ll::SDL_JoystickNameForIndex(id) };

    c_str_to_string_or_err(name)
}

/// Force joystick update when not using the event loop
pub fn update() {
    unsafe { ll::SDL_JoystickUpdate() };
}

/// Wrapper around the SDL_Joystick object
pub struct Joystick {
    raw: *mut ll::SDL_Joystick,
}

impl Joystick {
    /// Attempt to open the joystick at number `id` and return it.
    pub fn open(id: i32) -> SdlResult<Joystick> {
        let joystick = unsafe { ll::SDL_JoystickOpen(id) };

        if joystick.is_null() {
            Err(get_error())
        } else {
            Ok(Joystick { raw: joystick })
        }
    }

    /// Return the name of the joystick or an empty string if no name
    /// is found.
    pub fn name(&self) -> String {
        let name = unsafe { ll::SDL_JoystickName(self.raw) };

        c_str_to_string(name)
    }

    /// Return true if the joystick has been opened and currently
    /// connected.
    pub fn get_attached(&self) -> bool {
        unsafe { ll::SDL_JoystickGetAttached(self.raw) != 0 }
    }

    pub fn get_instance_id(&self) -> i32 {
        let result = unsafe { ll::SDL_JoystickInstanceID(self.raw) };

        if result < 0 {
            // Should only fail if the joystick is NULL.
            panic!(get_error())
        } else {
            result
        }
    }

    /// Retreive the joystick's GUID
    pub fn get_guid(&self) -> Guid {
        let raw = unsafe { ll::SDL_JoystickGetGUID(self.raw) };

        let guid = Guid { raw: raw };

        if guid.is_zero() {
            // Should only fail if the joystick is NULL.
            panic!(get_error())
        } else {
            guid
        }
    }

    /// Retreive the number of axes for this joystick
    pub fn get_num_axes(&self) -> u32 {
        let result = unsafe { ll::SDL_JoystickNumAxes(self.raw) };

        if result < 0 {
            // Should only fail if the joystick is NULL.
            panic!(get_error())
        } else {
            result as u32
        }
    }

    /// Gets the position of the given `axis`.
    ///
    /// The function will fail if the joystick doesn't have the provided axis.
    pub fn get_axis(&self, axis: u32) -> SdlResult<i16> {
        // This interface is a bit messed up: 0 is a valid position
        // but can also mean that an error occured. As far as I can
        // tell the only way to know if an error happened is to see if
        // get_error() returns a non-empty string.
        clear_error();

        let axis = try!(u32_to_int!(axis));
        let pos = unsafe { ll::SDL_JoystickGetAxis(self.raw, axis) };

        if pos != 0 {
            Ok(pos)
        } else {
            let err = get_error();

            if err.is_empty() {
                Ok(pos)
            } else {
                Err(err)
            }
        }
    }

    /// Retreive the number of buttons for this joystick
    pub fn get_num_buttons(&self) -> u32 {
        let result = unsafe { ll::SDL_JoystickNumButtons(self.raw) };

        if result < 0 {
            // Should only fail if the joystick is NULL.
            panic!(get_error())
        } else {
            result as u32
        }
    }

    /// Return `Ok(true)` if `button` is pressed.
    ///
    /// The function will fail if the joystick doesn't have the provided button.
    pub fn get_button(&self, button: u32) -> SdlResult<bool> {
        // Same deal as get_axis, 0 can mean both unpressed or
        // error...
        clear_error();

        let button = try!(u32_to_int!(button));
        let pressed = unsafe { ll::SDL_JoystickGetButton(self.raw, button) };

        match pressed {
            1 => Ok(true),
            0 => {
                let err = get_error();

                if err.is_empty() {
                    // Button is not pressed
                    Ok(false)
                } else {
                    Err(err)
                }
            }
            // Should be unreachable
            _ => Err(get_error()),
        }
    }

    /// Retreive the number of balls for this joystick
    pub fn get_num_balls(&self) -> u32 {
        let result = unsafe { ll::SDL_JoystickNumBalls(self.raw) };

        if result < 0 {
            // Should only fail if the joystick is NULL.
            panic!(get_error())
        } else {
            result as u32
        }
    }

    /// Return a pair `(dx, dy)` containing the difference in axis
    /// position since the last poll
    pub fn get_ball(&self, ball: u32) -> SdlResult<(i32, i32)> {
        let mut dx = 0;
        let mut dy = 0;

        let ball = try!(u32_to_int!(ball));
        let result = unsafe { ll::SDL_JoystickGetBall(self.raw, ball, &mut dx, &mut dy) };

        if result == 0 {
            Ok((dx, dy))
        } else {
            Err(get_error())
        }
    }

    /// Retreive the number of balls for this joystick
    pub fn get_num_hats(&self) -> u32 {
        let result = unsafe { ll::SDL_JoystickNumHats(self.raw) };

        if result < 0 {
            // Should only fail if the joystick is NULL.
            panic!(get_error())
        } else {
            result as u32
        }
    }

    /// Return the position of `hat` for this joystick
    pub fn get_hat(&self, hat: u32) -> SdlResult<HatState> {
        // Guess what? This function as well uses 0 to report an error
        // but 0 is also a valid value (HatState::Centered). So we
        // have to use the same hack as `get_axis`...
        clear_error();

        let hat = try!(u32_to_int!(hat));
        let result = unsafe { ll::SDL_JoystickGetHat(self.raw, hat) };

        let state = HatState::from_raw(result as u8);

        if result != 0 {
            Ok(state)
        } else {
            let err = get_error();

            if err.is_empty() {
                Ok(state)
            } else {
                Err(err)
            }
        }
    }
}

impl Drop for Joystick {
    fn drop(&mut self) {
        unsafe { ll::SDL_JoystickClose(self.raw) }
    }
}

/// Wrapper around a SDL_JoystickGUID, a globally unique identifier
/// for a joystick.
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub struct Guid {
    raw: ll::SDL_JoystickGUID,
}

impl Guid {
    /// Create a GUID from a string representation.
    pub fn from_string(guid: &str) -> Result<Guid, NulError> {
        let guid = try!(CString::new(guid));

        let raw = unsafe { ll::SDL_JoystickGetGUIDFromString(guid.as_ptr()) };

        Ok(Guid { raw: raw })
    }

    /// Return `true` if GUID is full 0s
    pub fn is_zero(&self) -> bool {
        for &i in self.raw.data.iter() {
            if i != 0 {
                return false;
            }
        }

        return true;
    }

    /// Return a String representation of GUID
    pub fn get_string(&self) -> String {
        // Doc says "buf should supply at least 33bytes". I took that
        // to mean that 33bytes should be enough in all cases, but
        // maybe I'm wrong?
        let mut buf = [0; 33];

        let len   = buf.len() as i32;
        let c_str = buf.as_mut_ptr();

        unsafe {
            ll::SDL_JoystickGetGUIDString(self.raw, c_str, len);
        }

        // The buffer should always be NUL terminated (the
        // documentation doesn't explicitely say it but I checked the
        // code)
        c_str_to_string(c_str)
    }

    /// Return a copy of the internal SDL_JoystickGUID
    pub fn raw(self) -> ll::SDL_JoystickGUID {
        self.raw
    }
}

impl Display for Guid {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        write!(f, "{}", self.get_string())
    }
}

/// This is represented in SDL2 as a bitfield but obviously not all
/// combinations make sense: 5 for instance would mean up and down at
/// the same time... To simplify things I turn it into an enum which
/// is how the SDL2 docs present it anyway (using macros).
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum HatState {
    Centered  = 0,
    Up        = 0x01,
    Right     = 0x02,
    Down      = 0x04,
    Left      = 0x08,
    RightUp   = 0x02 | 0x01,
    RightDown = 0x02 | 0x04,
    LeftUp    = 0x08 | 0x01,
    Leftdown  = 0x08 | 0x04,
}

impl HatState {
    pub fn from_raw(raw: u8) -> HatState {
        match raw {
            0  => HatState::Centered,
            1  => HatState::Up,
            2  => HatState::Right,
            4  => HatState::Down,
            8  => HatState::Left,
            3  => HatState::RightUp,
            6  => HatState::RightDown,
            9  => HatState::LeftUp,
            12 => HatState::Leftdown,
            _  => panic!("Unexpected hat position: {}", raw),
        }
    }
}

/// Convert C string `c_str` to a String. Return an empty string if
/// c_str is NULL.
fn c_str_to_string(c_str: *const c_char) -> String {
    if c_str.is_null() {
        String::new()
    } else {
        let bytes = unsafe { CStr::from_ptr(c_str).to_bytes() };

        String::from_utf8_lossy(bytes).to_string()
    }
}

/// Convert C string `c_str` to a String. Return an SDL error if
/// `c_str` is NULL.
fn c_str_to_string_or_err(c_str: *const c_char) -> SdlResult<String> {
    if c_str.is_null() {
        Err(get_error())
    } else {
        let bytes = unsafe { CStr::from_ptr(c_str).to_bytes() };

        Ok(String::from_utf8_lossy(bytes).to_string())
    }
}
<|endoftext|>


<commit_before>//! Define semi-implicit schemes

use super::traits::*;
use super::diag::Diagonal;

use ndarray::*;
use ndarray_linalg::{Scalar, into_scalar};

pub struct DiagRK4<A, S, F, D>
    where A: Scalar,
          S: Data<Elem = A>,
          D: Dimension
{
    f: F,
    lin_half: Diagonal<A, S, D>,
    dt: A::Real,
}

pub fn diag_rk4<A, S, F, D>(f: F, dt: A::Real) -> DiagRK4<A, S, F, D>
    where A: Scalar,
          S: DataClone<Elem = A> + DataMut,
          F: SemiImplicitDiag<S, S, D>,
          D: Dimension
{
    DiagRK4::new(f, dt)
}

impl<A, S, F, D> DiagRK4<A, S, F, D>
    where A: Scalar,
          S: DataClone<Elem = A> + DataMut,
          D: Dimension
{
    pub fn new(f: F, dt: A::Real) -> Self
        where F: SemiImplicitDiag<S, S, D>
    {
        let diag = f.diag();
        let lin_half = Diagonal::new(diag, dt / into_scalar(2.0));
        DiagRK4 {
            f: f,
            lin_half: lin_half,
            dt: dt,
        }
    }
}

impl<A, S, F, D> ModelSize<D> for DiagRK4<A, S, F, D>
    where A: Scalar,
          F: ModelSize<D>,
          S: DataClone<Elem = A> + DataMut,
          D: Dimension
{
    fn model_size(&self) -> D::Pattern {
        self.f.model_size()
    }
}

impl<A, S, F, D> TimeEvolutionBase<S, D> for DiagRK4<A, S, F, D>
    where A: Scalar,
          S: DataMut<Elem = A> + DataClone + DataOwned,
          F: SemiImplicitDiag<S, S, D, Time = A::Real, Scalar = A>,
          D: Dimension
{
    type Scalar = F::Scalar;
    type Time = F::Time;

    fn iterate<'a>(&self, x: &'a mut ArrayBase<S, D>) -> &'a mut ArrayBase<S, D> {
        // constants
        let dt = self.dt;
        let dt_2 = self.dt / into_scalar(2.0);
        let dt_3 = self.dt / into_scalar(3.0);
        let dt_6 = self.dt / into_scalar(6.0);
        // operators
        let l = &self.lin_half;
        let f = &self.f;
        // calc
        let mut x_ = x.to_owned();
        let mut lx = x.to_owned();
        l.iterate(&mut lx);
        let mut k1 = f.nlin(x);
        let k1_ = k1.to_owned();
        Zip::from(&mut *k1)
            .and(&x_)
            .apply(|k1, &x_| { *k1 = x_ + k1.mul_real(dt_2); });
        let mut k2 = f.nlin(l.iterate(k1));
        let k2_ = k2.to_owned();
        Zip::from(&mut *k2)
            .and(&lx)
            .apply(|k2, &lx| { *k2 = lx + k2.mul_real(dt_2); });
        let mut k3 = f.nlin(k2);
        let k3_ = k3.to_owned();
        Zip::from(&mut *k3)
            .and(&lx)
            .apply(|k3, &lx| { *k3 = lx + k3.mul_real(dt); });
        let mut k4 = f.nlin(l.iterate(k3));
        azip!(mut x_, k1_ in { *x_ = *x_ + k1_.mul_real(dt_6) });
        l.iterate(&mut x_);
        azip!(mut x_, k2_, k3_ in { *x_ = *x_ + (k2_ + k3_).mul_real(dt_3) });
        l.iterate(&mut x_);
        Zip::from(&mut *k4)
            .and(&x_)
            .apply(|k4, &x_| { *k4 = x_ + k4.mul_real(dt_6); });
        k4
    }
}
<commit_msg>Rewrite stiff-rk4 algorithm using SemiImplicit{NonLinear,Linear}<commit_after>//! Define semi-implicit schemes

use super::traits::*;

use ndarray::*;
use ndarray_linalg::*;

pub struct StiffRK4<NLin, Lin, Time: RealScalar> {
    nlin: NLin,
    lin: Lin,
    dt: Time,
}

impl<D, NLin, Lin, Time> ModelSize<D> for StiffRK4<NLin, Lin, Time>
    where D: Dimension,
          NLin: ModelSize<D>,
          Lin: ModelSize<D>,
          Time: RealScalar
{
    fn model_size(&self) -> D::Pattern {
        self.nlin.model_size() // TODO check
    }
}

impl<A, S, D, NLin, Lin> TimeEvolutionBase<S, D> for StiffRK4<NLin, Lin, A::Real>
    where A: Scalar,
          S: DataMut<Elem = A> + DataOwned,
          D: Dimension,
          NLin: SemiImplicitNonLinear<S, D, Scalar = A, Time = A::Real>,
          Lin: SemiImplicitLinear<S, D, Scalar = A, Time = A::Real>
{
    type Scalar = A;
    type Time = A::Real;

    fn iterate<'a>(&self, x: &'a mut ArrayBase<S, D>) -> &'a mut ArrayBase<S, D> {
        // constants
        let dt = self.dt;
        let dt_2 = self.dt / into_scalar(2.0);
        let dt_3 = self.dt / into_scalar(3.0);
        let dt_6 = self.dt / into_scalar(6.0);
        // operators
        let l = &self.lin;
        let f = &self.nlin;
        // calc
        let mut x_ = replicate(&x);
        let mut lx = replicate(&x);
        l.lin(&mut lx);
        let mut k1 = f.nlin(x);
        let k1_ = k1.to_owned();
        Zip::from(&mut *k1)
            .and(&x_)
            .apply(|k1, &x_| { *k1 = x_ + k1.mul_real(dt_2); });
        let mut k2 = f.nlin(l.lin(k1));
        let k2_ = k2.to_owned();
        Zip::from(&mut *k2)
            .and(&lx)
            .apply(|k2, &lx| { *k2 = lx + k2.mul_real(dt_2); });
        let mut k3 = f.nlin(k2);
        let k3_ = k3.to_owned();
        Zip::from(&mut *k3)
            .and(&lx)
            .apply(|k3, &lx| { *k3 = lx + k3.mul_real(dt); });
        let mut k4 = f.nlin(l.lin(k3));
        azip!(mut x_, k1_ in { *x_ = *x_ + k1_.mul_real(dt_6) });
        l.lin(&mut x_);
        azip!(mut x_, k2_, k3_ in { *x_ = *x_ + (k2_ + k3_).mul_real(dt_3) });
        l.lin(&mut x_);
        Zip::from(&mut *k4)
            .and(&x_)
            .apply(|k4, &x_| { *k4 = x_ + k4.mul_real(dt_6); });
        k4
    }
}
<|endoftext|>


<commit_before>use libimagstore::store::EntryHeader;

use link::{Link, Links};
use result::Result;

pub fn get_link(header: &EntryHeader) -> Result<Link> {
    unimplemented!()
}

/// Set an external link in the header
///
/// Return the previous set link if there was any
pub fn set_link(header: &mut EntryHeader, l: Link) -> Option<Link> {
    unimplemented!()
}

<commit_msg>Implement: external::get_link()<commit_after>use libimagstore::store::EntryHeader;

use error::{LinkError, LinkErrorKind};
use link::{Link, Links};
use result::Result;

use toml::Value;
use toml::Table;

pub fn get_link(header: &EntryHeader) -> Result<Option<Link>> {
    let uri = header.read("imag.content.uri");

    if uri.is_err() {
        let kind = LinkErrorKind::EntryHeaderReadError;
        let lerr = LinkError::new(kind, Some(Box::new(uri.err().unwrap())));
        return Err(lerr);
    }
    let uri = uri.unwrap();

    match uri {
        Some(Value::String(s)) => Ok(Some(Link::new(s))),
        _ => Err(LinkError::new(LinkErrorKind::ExistingLinkTypeWrong, None)),
    }
}

/// Set an external link in the header
///
/// Return the previous set link if there was any
pub fn set_link(header: &mut EntryHeader, l: Link) -> Option<Link> {
    unimplemented!()
}

<|endoftext|>