<commit_before>use gtmpl_value::Value;
use std::char;

pub fn unquote_char(s: &str, quote: char) -> Option<char> {
    if s.len() < 2 || !s.starts_with(quote) || !s.ends_with(quote) {
        return None;
    }
    let raw = &s[1..s.len() - 1];
    match unqote(raw) {
        Some((c, l)) => {
            if l == raw.len() {
                c.chars().next()
            } else {
                None
            }
        }
        _ => None,
    }
}

pub fn unquote_str(s: &str) -> Option<String> {
    if s.len() < 2 {
        return None;
    }
    let quote = &s[0..1];
    if !s.ends_with(quote) {
        return None;
    }
    let mut r = String::new();
    let raw = &s[1..s.len() - 1];
    let mut i = 0;
    while i < raw.len() {
        match unqote(&raw[i..]) {
            Some((c, len)) => {
                r += &c;
                i += len;
            }
            None => return None,
        }
    }
    Some(r)
}

fn unqote(raw: &str) -> Option<(String, usize)> {
    if raw.starts_with('\\') {
        match &raw[..2] {
            r"\x" => extract_bytes_x(raw),
            r"\U" => extract_bytes_u32(raw),
            r"\u" => extract_bytes_u16(raw),
            r"\b" => Some(('\u{0008}'.to_string(), 2)),
            r"\f" => Some(('\u{000C}'.to_string(), 2)),
            r"\n" => Some(('\n'.to_string(), 2)),
            r"\r" => Some(('\r'.to_string(), 2)),
            r"\t" => Some(('\t'.to_string(), 2)),
            r"\'" => Some(('\''.to_string(), 2)),
            r#"\""# => Some(('\"'.to_string(), 2)),
            r#"\\"# => Some(('\\'.to_string(), 2)),
            _ => None,
        }
    } else {
        get_char(raw)
    }
}

fn get_char(s: &str) -> Option<(String, usize)> {
    s.char_indices()
        .next()
        .map(|(i, c)| (c.to_string(), i + c.len_utf8()))
}

fn extract_bytes_u32(s: &str) -> Option<(String, usize)> {
    if s.len() != 10 {
        return None;
    }
    u32::from_str_radix(&s[2..10], 16)
        .ok()
        .and_then(char::from_u32)
        .map(|c| (c.to_string(), 10))
}

fn extract_bytes_u16(s: &str) -> Option<(String, usize)> {
    let mut bytes = vec![];
    let mut i = 0;
    while s.len() > i && s.starts_with(r"\u") && s[i..].len() >= 6 {
        match u16::from_str_radix(&s[(i + 2)..(i + 6)], 16) {
            Ok(x) => bytes.push(x),
            _ => {
                return None;
            }
        };
        i += 6;
    }
    String::from_utf16(&bytes).ok().map(|s| (s, i))
}

fn extract_bytes_x(s: &str) -> Option<(String, usize)> {
    let mut bytes = vec![];
    let mut i = 0;
    while s.len() > i && s.starts_with(r"\x") && s[i..].len() >= 4 {
        match u8::from_str_radix(&s[(i + 2)..(i + 4)], 16) {
            Ok(x) => bytes.push(x),
            _ => {
                return None;
            }
        };
        i += 4;
    }
    String::from_utf8(bytes).ok().map(|s| (s, i))
}

/// Returns
pub fn is_true(val: &Value) -> bool {
    match *val {
        Value::Bool(ref b) => *b,
        Value::String(ref s) => !s.is_empty(),
        Value::Array(ref a) => !a.is_empty(),
        Value::Object(ref o) => !o.is_empty(),
        Value::Map(ref m) => !m.is_empty(),
        Value::Function(_) => true,
        Value::NoValue | Value::Nil => false,
        Value::Number(ref n) => n.as_u64().map(|u| u != 0).unwrap_or_else(|| true),
    }
}

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

    #[test]
    fn test_unquote_char() {
        let s = "'→'";
        let c = unquote_char(s, '\'');
        assert_eq!(c, Some('→'));
        let s = "'→←'";
        let c = unquote_char(s, '\'');
        assert_eq!(c, None);
        let s = r"'\xf0\x9f\x92\xa9'";
        let c = unquote_char(s, '\'');
        assert_eq!(c, Some('💩'));
        let s = r"'\xf0\x9f\x92\xa'";
        let c = unquote_char(s, '\'');
        assert_eq!(c, None);
        let s = r"'\xf0\x9f\x92\xa99'";
        let c = unquote_char(s, '\'');
        assert_eq!(c, None);
        let s = r"'\u263a'";
        let c = unquote_char(s, '\'');
        assert_eq!(c, Some('☺'));
        let s = r"'\uD83D\uDCA9'";
        let c = unquote_char(s, '\'');
        assert_eq!(c, Some('💩'));
        let s = r"'\uD83\uDCA9'";
        let c = unquote_char(s, '\'');
        assert_eq!(c, None);
        let s = r"'\uD83D\uDCA9B'";
        let c = unquote_char(s, '\'');
        assert_eq!(c, None);
        let s = r"'\U0001F4A9'";
        let c = unquote_char(s, '\'');
        assert_eq!(c, Some('💩'));
        let s = r"'\U0001F4A'";
        let c = unquote_char(s, '\'');
        assert_eq!(c, None);
        let s = r"'\U0001F4A99'";
        let c = unquote_char(s, '\'');
        assert_eq!(c, None);
    }

    #[test]
    fn test_unquote_str() {
        let s = r#""Fran & Freddie's Diner""#;
        let u = unquote_str(s);
        assert_eq!(u, Some("Fran & Freddie's Diner".to_owned()));
        let s = r#""Fran & Freddie's Diner\t\u263a""#;
        let u = unquote_str(s);
        assert_eq!(u, Some("Fran & Freddie's Diner\t☺".to_owned()));
    }

    #[test]
    fn test_is_true() {
        let t = Value::from(1i8);
        assert!(is_true(&t));
        let t = Value::from(0u32);
        assert!(is_true(&t));
    }
}
<commit_msg>fix test<commit_after>use gtmpl_value::Value;
use std::char;

pub fn unquote_char(s: &str, quote: char) -> Option<char> {
    if s.len() < 2 || !s.starts_with(quote) || !s.ends_with(quote) {
        return None;
    }
    let raw = &s[1..s.len() - 1];
    match unqote(raw) {
        Some((c, l)) => {
            if l == raw.len() {
                c.chars().next()
            } else {
                None
            }
        }
        _ => None,
    }
}

pub fn unquote_str(s: &str) -> Option<String> {
    if s.len() < 2 {
        return None;
    }
    let quote = &s[0..1];
    if !s.ends_with(quote) {
        return None;
    }
    let mut r = String::new();
    let raw = &s[1..s.len() - 1];
    let mut i = 0;
    while i < raw.len() {
        match unqote(&raw[i..]) {
            Some((c, len)) => {
                r += &c;
                i += len;
            }
            None => return None,
        }
    }
    Some(r)
}

fn unqote(raw: &str) -> Option<(String, usize)> {
    if raw.starts_with('\\') {
        match &raw[..2] {
            r"\x" => extract_bytes_x(raw),
            r"\U" => extract_bytes_u32(raw),
            r"\u" => extract_bytes_u16(raw),
            r"\b" => Some(('\u{0008}'.to_string(), 2)),
            r"\f" => Some(('\u{000C}'.to_string(), 2)),
            r"\n" => Some(('\n'.to_string(), 2)),
            r"\r" => Some(('\r'.to_string(), 2)),
            r"\t" => Some(('\t'.to_string(), 2)),
            r"\'" => Some(('\''.to_string(), 2)),
            r#"\""# => Some(('\"'.to_string(), 2)),
            r#"\\"# => Some(('\\'.to_string(), 2)),
            _ => None,
        }
    } else {
        get_char(raw)
    }
}

fn get_char(s: &str) -> Option<(String, usize)> {
    s.char_indices()
        .next()
        .map(|(i, c)| (c.to_string(), i + c.len_utf8()))
}

fn extract_bytes_u32(s: &str) -> Option<(String, usize)> {
    if s.len() != 10 {
        return None;
    }
    u32::from_str_radix(&s[2..10], 16)
        .ok()
        .and_then(char::from_u32)
        .map(|c| (c.to_string(), 10))
}

fn extract_bytes_u16(s: &str) -> Option<(String, usize)> {
    let mut bytes = vec![];
    let mut i = 0;
    while s.len() > i && s.starts_with(r"\u") && s[i..].len() >= 6 {
        match u16::from_str_radix(&s[(i + 2)..(i + 6)], 16) {
            Ok(x) => bytes.push(x),
            _ => {
                return None;
            }
        };
        i += 6;
    }
    String::from_utf16(&bytes).ok().map(|s| (s, i))
}

fn extract_bytes_x(s: &str) -> Option<(String, usize)> {
    let mut bytes = vec![];
    let mut i = 0;
    while s.len() > i && s.starts_with(r"\x") && s[i..].len() >= 4 {
        match u8::from_str_radix(&s[(i + 2)..(i + 4)], 16) {
            Ok(x) => bytes.push(x),
            _ => {
                return None;
            }
        };
        i += 4;
    }
    String::from_utf8(bytes).ok().map(|s| (s, i))
}

/// Returns
pub fn is_true(val: &Value) -> bool {
    match *val {
        Value::Bool(ref b) => *b,
        Value::String(ref s) => !s.is_empty(),
        Value::Array(ref a) => !a.is_empty(),
        Value::Object(ref o) => !o.is_empty(),
        Value::Map(ref m) => !m.is_empty(),
        Value::Function(_) => true,
        Value::NoValue | Value::Nil => false,
        Value::Number(ref n) => n.as_u64().map(|u| u != 0).unwrap_or_else(|| true),
    }
}

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

    #[test]
    fn test_unquote_char() {
        let s = "'→'";
        let c = unquote_char(s, '\'');
        assert_eq!(c, Some('→'));
        let s = "'→←'";
        let c = unquote_char(s, '\'');
        assert_eq!(c, None);
        let s = r"'\xf0\x9f\x92\xa9'";
        let c = unquote_char(s, '\'');
        assert_eq!(c, Some('💩'));
        let s = r"'\xf0\x9f\x92\xa'";
        let c = unquote_char(s, '\'');
        assert_eq!(c, None);
        let s = r"'\xf0\x9f\x92\xa99'";
        let c = unquote_char(s, '\'');
        assert_eq!(c, None);
        let s = r"'\u263a'";
        let c = unquote_char(s, '\'');
        assert_eq!(c, Some('☺'));
        let s = r"'\uD83D\uDCA9'";
        let c = unquote_char(s, '\'');
        assert_eq!(c, Some('💩'));
        let s = r"'\uD83\uDCA9'";
        let c = unquote_char(s, '\'');
        assert_eq!(c, None);
        let s = r"'\uD83D\uDCA9B'";
        let c = unquote_char(s, '\'');
        assert_eq!(c, None);
        let s = r"'\U0001F4A9'";
        let c = unquote_char(s, '\'');
        assert_eq!(c, Some('💩'));
        let s = r"'\U0001F4A'";
        let c = unquote_char(s, '\'');
        assert_eq!(c, None);
        let s = r"'\U0001F4A99'";
        let c = unquote_char(s, '\'');
        assert_eq!(c, None);
    }

    #[test]
    fn test_unquote_str() {
        let s = r#""Fran & Freddie's Diner""#;
        let u = unquote_str(s);
        assert_eq!(u, Some("Fran & Freddie's Diner".to_owned()));
        let s = r#""Fran & Freddie's Diner\t\u263a""#;
        let u = unquote_str(s);
        assert_eq!(u, Some("Fran & Freddie's Diner\t☺".to_owned()));
    }

    #[test]
    fn test_is_true() {
        let t = Value::from(1i8);
        assert!(is_true(&t));
        let t = Value::from(0u32);
        assert!(!is_true(&t));
    }
}
<|endoftext|>


<commit_before>//! Value module.

use std::cmp::{Eq, Ordering};
use std::collections::BTreeMap;
use std::hash::{Hash, Hasher};

use serde::de::{DeserializeSeed, Deserializer, MapAccess, SeqAccess, Visitor};

use de::{Error as RonError, Result};

/// A wrapper for `f64` which guarantees that the inner value
/// is finite and thus implements `Eq`, `Hash` and `Ord`.
#[derive(Copy, Clone, Debug, PartialOrd, PartialEq)]
pub struct Number(f64);

impl Number {
    /// Panics if `v` is not a real number
    /// (infinity, NaN, ..).
    pub fn new(v: f64) -> Self {
        if !v.is_finite() {
            panic!("Tried to create Number with a NaN / infinity");
        }

        Number(v)
    }

    /// Returns the wrapped float.
    pub fn get(&self) -> f64 {
        self.0
    }
}

impl Eq for Number {}

impl Hash for Number {
    fn hash<H: Hasher>(&self, state: &mut H) {
        state.write_u64(self.0 as u64);
    }
}

impl Ord for Number {
    fn cmp(&self, other: &Self) -> Ordering {
        self.partial_cmp(other).expect("Bug: Contract violation")
    }
}

#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum Value {
    Bool(bool),
    Char(char),
    Map(BTreeMap<Value, Value>),
    Number(Number),
    Option(Option<Box<Value>>),
    String(String),
    Seq(Vec<Value>),
    Unit,
}

/// Deserializer implementation for RON `Value`.
/// This does not support enums (because `Value` doesn't store them).
impl<'de> Deserializer<'de> for Value {
    type Error = RonError;

    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        match self {
            Value::Bool(b) => visitor.visit_bool(b),
            Value::Char(c) => visitor.visit_char(c),
            Value::Map(m) => visitor.visit_map(Map {
                keys: m.keys().cloned().collect(),
                values: m.values().cloned().collect(),
            }),
            Value::Number(n) => visitor.visit_f64(n.get()),
            Value::Option(Some(o)) => visitor.visit_some(*o),
            Value::Option(None) => visitor.visit_none(),
            Value::String(s) => visitor.visit_string(s),
            Value::Seq(seq) => visitor.visit_seq(Seq { seq }),
            Value::Unit => visitor.visit_unit(),
        }
    }

    forward_to_deserialize_any! {
        bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
        byte_buf option unit unit_struct newtype_struct seq tuple
        tuple_struct map struct enum identifier ignored_any
    }
}

struct Map {
    keys: Vec<Value>,
    values: Vec<Value>,
}

impl<'de> MapAccess<'de> for Map {
    type Error = RonError;

    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
    where
        K: DeserializeSeed<'de>,
    {
        self.keys
            .drain(..)
            .next()
            .map_or(Ok(None), |v| seed.deserialize(v).map(Some))
    }

    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
    where
        V: DeserializeSeed<'de>,
    {
        self.values
            .drain(..)
            .next()
            .map(|v| seed.deserialize(v))
            .expect("Contract violation")
    }
}

struct Seq {
    seq: Vec<Value>,
}

impl<'de> SeqAccess<'de> for Seq {
    type Error = RonError;

    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
    where
        T: DeserializeSeed<'de>,
    {
        self.seq
            .drain(..)
            .next()
            .map_or(Ok(None), |v| seed.deserialize(v).map(Some))
    }
}
<commit_msg>Add tests for Value deserializer<commit_after>//! Value module.

use std::cmp::{Eq, Ordering};
use std::collections::BTreeMap;
use std::hash::{Hash, Hasher};

use serde::de::{DeserializeSeed, Deserializer, MapAccess, SeqAccess, Visitor};

use de::{Error as RonError, Result};

/// A wrapper for `f64` which guarantees that the inner value
/// is finite and thus implements `Eq`, `Hash` and `Ord`.
#[derive(Copy, Clone, Debug, PartialOrd, PartialEq)]
pub struct Number(f64);

impl Number {
    /// Panics if `v` is not a real number
    /// (infinity, NaN, ..).
    pub fn new(v: f64) -> Self {
        if !v.is_finite() {
            panic!("Tried to create Number with a NaN / infinity");
        }

        Number(v)
    }

    /// Returns the wrapped float.
    pub fn get(&self) -> f64 {
        self.0
    }
}

impl Eq for Number {}

impl Hash for Number {
    fn hash<H: Hasher>(&self, state: &mut H) {
        state.write_u64(self.0 as u64);
    }
}

impl Ord for Number {
    fn cmp(&self, other: &Self) -> Ordering {
        self.partial_cmp(other).expect("Bug: Contract violation")
    }
}

#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum Value {
    Bool(bool),
    Char(char),
    Map(BTreeMap<Value, Value>),
    Number(Number),
    Option(Option<Box<Value>>),
    String(String),
    Seq(Vec<Value>),
    Unit,
}

/// Deserializer implementation for RON `Value`.
/// This does not support enums (because `Value` doesn't store them).
impl<'de> Deserializer<'de> for Value {
    type Error = RonError;

    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
    where
        V: Visitor<'de>,
    {
        match self {
            Value::Bool(b) => visitor.visit_bool(b),
            Value::Char(c) => visitor.visit_char(c),
            Value::Map(m) => visitor.visit_map(Map {
                keys: m.keys().cloned().rev().collect(),
                values: m.values().cloned().rev().collect(),
            }),
            Value::Number(n) => visitor.visit_f64(n.get()),
            Value::Option(Some(o)) => visitor.visit_some(*o),
            Value::Option(None) => visitor.visit_none(),
            Value::String(s) => visitor.visit_string(s),
            Value::Seq(mut seq) => {
                seq.reverse();

                visitor.visit_seq(Seq { seq })
            }
            Value::Unit => visitor.visit_unit(),
        }
    }

    forward_to_deserialize_any! {
        bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
        byte_buf option unit unit_struct newtype_struct seq tuple
        tuple_struct map struct enum identifier ignored_any
    }
}

struct Map {
    keys: Vec<Value>,
    values: Vec<Value>,
}

impl<'de> MapAccess<'de> for Map {
    type Error = RonError;

    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
    where
        K: DeserializeSeed<'de>,
    {
        // The `Vec` is reversed, so we can pop to get the originally first element
        self.keys
            .pop()
            .map_or(Ok(None), |v| seed.deserialize(v).map(Some))
    }

    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
    where
        V: DeserializeSeed<'de>,
    {
        // The `Vec` is reversed, so we can pop to get the originally first element
        self.values
            .pop()
            .map(|v| seed.deserialize(v))
            .expect("Contract violation")
    }
}

struct Seq {
    seq: Vec<Value>,
}

impl<'de> SeqAccess<'de> for Seq {
    type Error = RonError;

    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
    where
        T: DeserializeSeed<'de>,
    {
        // The `Vec` is reversed, so we can pop to get the originally first element
        self.seq
            .pop()
            .map_or(Ok(None), |v| seed.deserialize(v).map(Some))
    }
}

#[cfg(test)]
mod tests {
    use std::fmt::Debug;
    use serde::Deserialize;
    use super::*;

    fn assert_same<'de, T>(s: &'de str)
    where
        T: Debug + Deserialize<'de> + PartialEq,
    {
        use de::from_str;

        let direct: T = from_str(s).unwrap();
        let value: Value = from_str(s).unwrap();
        let value = T::deserialize(value).unwrap();

        assert_eq!(direct, value, "Deserialization for {:?} is not the same", s);
    }

    #[test]
    fn boolean() {
        assert_same::<bool>("true");
        assert_same::<bool>("false");
    }

    #[test]
    fn float() {
        assert_same::<f64>("0.123");
        assert_same::<f64>("-4.19");
    }

    #[test]
    fn char() {
        assert_same::<char>("'4'");
        assert_same::<char>("'c'");
    }

    #[test]
    fn map() {
        assert_same::<BTreeMap<char, String>>(
            "{
'a': \"Hello\",
'b': \"Bye\",
        }",
        );
    }

    #[test]
    fn option() {
        assert_same::<Option<char>>("Some('a')");
        assert_same::<Option<char>>("None");
    }

    #[test]
    fn seq() {
        assert_same::<Vec<f64>>("[1.0, 2.0, 3.0, 4.0]");
    }

    #[test]
    fn unit() {
        assert_same::<()>("()");
    }
}
<|endoftext|>


<commit_before>// This file is part of Grust, GObject introspection bindings for Rust
//
// Copyright (C) 2014, 2015  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

use boxed;
use boxed::BoxedType;
use enumeration;
use enumeration::{EnumType, IntrospectedEnum};
use enumeration::UnknownValue as UnknownEnumValue;
use flags;
use flags::{FlagsType, IntrospectedFlags, UnknownFlags};
use gstr::OwnedGStr;
use gtype::GType;
use object;
use object::ObjectType;
use types::{gboolean, gchar, gdouble, gfloat, gint, glong, gpointer};
use types::{guchar, guint, gulong};
use util::is_true;

use gobject as ffi;

use std::ffi::CStr;
use std::fmt;
use std::mem;
use std::ops::Deref;

#[unsafe_no_drop_flag]
pub struct Value(ffi::GValue);

impl Drop for Value {
    fn drop(&mut self) {
        if self.as_raw().g_type == 0 {
            return;
        }
        unsafe {
            ffi::g_value_unset(self.as_mut_raw());
        }
    }
}

impl Clone for Value {
    fn clone(&self) -> Value {
        Value(unsafe {
            let mut raw: ffi::GValue = mem::zeroed();
            ffi::g_value_init(&mut raw, self.as_raw().g_type);
            ffi::g_value_copy(self.as_raw(), &mut raw);
            raw
        })
    }
}

impl Value {
    pub fn new(g_type: GType) -> Value {
        Value(unsafe {
            let mut raw: ffi::GValue = mem::zeroed();
            ffi::g_value_init(&mut raw, g_type.to_raw());
            raw
        })
    }

    #[inline]
    fn as_raw(&self) -> &ffi::GValue {
        &self.0
    }

    #[inline]
    unsafe fn as_mut_raw(&mut self) -> &mut ffi::GValue {
        &mut self.0
    }

    #[inline]
    pub fn value_type(&self) -> GType {
        unsafe { GType::from_raw(self.as_raw().g_type) }
    }

    pub fn reset(&mut self) {
        unsafe {
            ffi::g_value_reset(self.as_mut_raw());
        }
    }

    pub fn get_boolean(&self) -> bool {
        is_true(unsafe { ffi::g_value_get_boolean(self.as_raw()) })
    }

    pub fn set_boolean(&mut self, val: bool) {
        unsafe { ffi::g_value_set_boolean(self.as_mut_raw(), val as gboolean) };
    }

    pub fn get_char(&self) -> gchar {
        unsafe { ffi::g_value_get_char(self.as_raw()) }
    }

    pub fn set_char(&mut self, val: gchar) {
        unsafe { ffi::g_value_set_char(self.as_mut_raw(), val) };
    }

    pub fn get_schar(&self) -> i8 {
        unsafe { ffi::g_value_get_schar(self.as_raw()) }
    }

    pub fn set_schar(&mut self, val: i8) {
        unsafe { ffi::g_value_set_schar(self.as_mut_raw(), val) };
    }

    pub fn get_uchar(&self) -> guchar {
        unsafe { ffi::g_value_get_uchar(self.as_raw()) }
    }

    pub fn set_uchar(&mut self, val: guchar) {
        unsafe { ffi::g_value_set_uchar(self.as_mut_raw(), val) };
    }

    pub fn get_int(&self) -> gint {
        unsafe { ffi::g_value_get_int(self.as_raw()) }
    }

    pub fn set_int(&mut self, val: gint) {
        unsafe { ffi::g_value_set_int(self.as_mut_raw(), val) };
    }

    pub fn get_uint(&self) -> guint {
        unsafe { ffi::g_value_get_uint(self.as_raw()) }
    }

    pub fn set_uint(&mut self, val: guint) {
        unsafe { ffi::g_value_set_uint(self.as_mut_raw(), val) };
    }

    pub fn get_long(&self) -> glong {
        unsafe { ffi::g_value_get_long(self.as_raw()) }
    }

    pub fn set_long(&mut self, val: glong) {
        unsafe { ffi::g_value_set_long(self.as_mut_raw(), val) };
    }

    pub fn get_ulong(&self) -> gulong {
        unsafe { ffi::g_value_get_ulong(self.as_raw()) }
    }

    pub fn set_ulong(&mut self, val: gulong) {
        unsafe { ffi::g_value_set_ulong(self.as_mut_raw(), val) };
    }

    pub fn get_int64(&self) -> i64 {
        unsafe { ffi::g_value_get_int64(self.as_raw()) }
    }

    pub fn set_int64(&mut self, val: i64) {
        unsafe { ffi::g_value_set_int64(self.as_mut_raw(), val) };
    }

    pub fn get_uint64(&self) -> u64 {
        unsafe { ffi::g_value_get_uint64(self.as_raw()) }
    }

    pub fn set_uint64(&mut self, val: u64) {
        unsafe { ffi::g_value_set_uint64(self.as_mut_raw(), val) };
    }

    pub fn get_float(&self) -> gfloat {
        unsafe { ffi::g_value_get_float(self.as_raw()) }
    }

    pub fn set_float(&mut self, val: gfloat) {
        unsafe { ffi::g_value_set_float(self.as_mut_raw(), val) };
    }

    pub fn get_double(&self) -> gdouble {
        unsafe { ffi::g_value_get_double(self.as_raw()) }
    }

    pub fn set_double(&mut self, val: gdouble) {
        unsafe { ffi::g_value_set_double(self.as_mut_raw(), val) };
    }

    fn assert_enum_type<T>(&self) where T: EnumType {
        debug_assert!(self.value_type() == enumeration::type_of::<T>(),
                      "GValue does not have the enumeration type {}",
                      enumeration::type_of::<T>().name());
    }

    pub fn get_enum<T>(&self) -> Result<T, UnknownEnumValue>
        where T: EnumType
    {
        self.assert_enum_type::<T>();
        unsafe {
            let v = ffi::g_value_get_enum(self.as_raw());
            IntrospectedEnum::from_int(v)
        }
    }

    pub fn set_enum<T>(&mut self, val: T) where T: EnumType {
        self.assert_enum_type::<T>();
        unsafe {
            ffi::g_value_set_enum(self.as_mut_raw(), val.to_int());
        }
    }

    fn assert_flags_type<T>(&self) where T: FlagsType {
        debug_assert!(self.value_type() == flags::type_of::<T>(),
                      "GValue does not have the flags type {}",
                      flags::type_of::<T>().name());
    }

    pub fn get_flags<T>(&self) -> Result<T, UnknownFlags>
        where T: FlagsType
    {
        self.assert_flags_type::<T>();
        unsafe {
            let v = ffi::g_value_get_flags(self.as_raw());
            IntrospectedFlags::from_uint(v)
        }
    }

    pub fn set_flags<T>(&mut self, val: T) where T: FlagsType {
        self.assert_flags_type::<T>();
        unsafe {
            ffi::g_value_set_flags(self.as_mut_raw(), val.to_uint());
        }
    }

    pub fn get_string(&self) -> Option<&CStr> {
        unsafe {
            let ptr = ffi::g_value_get_string(self.as_raw());
            if ptr.is_null() {
                return None;
            }
            Some(CStr::from_ptr(ptr))
        }
    }

    pub fn set_string(&mut self, val: &CStr) {
        unsafe { ffi::g_value_set_string(self.as_mut_raw(), val.as_ptr()) }
    }

    pub fn set_static_string(&mut self, val: &'static CStr) {
        unsafe {
            ffi::g_value_set_static_string(self.as_mut_raw(), val.as_ptr())
        }
    }

    pub fn take_string(&mut self, consumed: OwnedGStr) {
        unsafe {
            let ptr = consumed.as_ptr() as *mut gchar;
            ffi::g_value_take_string(self.as_mut_raw(), ptr);
            mem::forget(consumed);
        }
    }

    pub fn get_object<T>(&self) -> Option<&T>
        where T: ObjectType
    {
        assert!(self.value_type() == object::type_of::<T>(),
                "GValue does not have the object type {}",
                object::type_of::<T>().name());
        let p = unsafe { ffi::g_value_get_object(self.as_raw()) as *const T };
        if p.is_null() {
            return None;
        }
        Some(unsafe { mem::copy_lifetime(self, &*p) })
    }

    pub fn set_object<T>(&mut self, val: &T)
        where T: ObjectType
    {
        let p = val as *const _;
        unsafe { ffi::g_value_set_object(self.as_mut_raw(), p as gpointer) }
    }

    fn assert_boxed_type<T>(&self)
        where T: BoxedType
    {
        assert!(self.value_type() == boxed::type_of::<T>(),
                "GValue does not have the boxed type {}",
                boxed::type_of::<T>().name());
    }

    pub fn dup_boxed<T>(&self) -> Option<T>
        where T: BoxedType
    {
        self.assert_boxed_type::<T>();
        let p = unsafe { ffi::g_value_dup_boxed(self.as_raw()) };
        if p.is_null() {
            return None;
        }
        Some(unsafe {
            let boxed: T = BoxedType::from_ptr(p);
            boxed
        })
    }

    pub fn deref_boxed<T>(&self) -> Option<&<T as Deref>::Target>
        where T: BoxedType + Deref
    {
        self.assert_boxed_type::<T>();
        let p = unsafe { ffi::g_value_get_boxed(self.as_raw()) };
        if p.is_null() {
            return None;
        }
        unsafe {
            let boxed: T = BoxedType::from_ptr(p);
            let ret = Some(mem::copy_lifetime(self, &*boxed));

            // Lose the box by "subliming" it back into the raw pointer
            let q = boxed.into_ptr();
            debug_assert!(q == p,
                "BoxedType invariant violation: into_ptr does not reverse from_ptr");

            ret
        }
    }

    pub fn take_boxed<T>(&mut self, val: T) where T: BoxedType {
        unsafe {
            let p = val.into_ptr();
            ffi::g_value_take_boxed(self.as_mut_raw(), p);
        }
    }
}

impl fmt::Debug for Value {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let contents = unsafe {
            let ptr = ffi::g_strdup_value_contents(self.as_raw());
            OwnedGStr::from_ptr(ptr)
        };
        write!(f, "GValue({})", String::from_utf8_lossy(contents.to_bytes()))
    }
}
<commit_msg>Replace usage of std::mem::copy_lifetime with transmute<commit_after>// This file is part of Grust, GObject introspection bindings for Rust
//
// Copyright (C) 2014, 2015  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

use boxed;
use boxed::BoxedType;
use enumeration;
use enumeration::{EnumType, IntrospectedEnum};
use enumeration::UnknownValue as UnknownEnumValue;
use flags;
use flags::{FlagsType, IntrospectedFlags, UnknownFlags};
use gstr::OwnedGStr;
use gtype::GType;
use object;
use object::ObjectType;
use types::{gboolean, gchar, gdouble, gfloat, gint, glong, gpointer};
use types::{guchar, guint, gulong};
use util::is_true;

use gobject as ffi;

use std::ffi::CStr;
use std::fmt;
use std::mem;
use std::ops::Deref;

#[unsafe_no_drop_flag]
pub struct Value(ffi::GValue);

impl Drop for Value {
    fn drop(&mut self) {
        if self.as_raw().g_type == 0 {
            return;
        }
        unsafe {
            ffi::g_value_unset(self.as_mut_raw());
        }
    }
}

impl Clone for Value {
    fn clone(&self) -> Value {
        Value(unsafe {
            let mut raw: ffi::GValue = mem::zeroed();
            ffi::g_value_init(&mut raw, self.as_raw().g_type);
            ffi::g_value_copy(self.as_raw(), &mut raw);
            raw
        })
    }
}

impl Value {
    pub fn new(g_type: GType) -> Value {
        Value(unsafe {
            let mut raw: ffi::GValue = mem::zeroed();
            ffi::g_value_init(&mut raw, g_type.to_raw());
            raw
        })
    }

    #[inline]
    fn as_raw(&self) -> &ffi::GValue {
        &self.0
    }

    #[inline]
    unsafe fn as_mut_raw(&mut self) -> &mut ffi::GValue {
        &mut self.0
    }

    #[inline]
    pub fn value_type(&self) -> GType {
        unsafe { GType::from_raw(self.as_raw().g_type) }
    }

    pub fn reset(&mut self) {
        unsafe {
            ffi::g_value_reset(self.as_mut_raw());
        }
    }

    pub fn get_boolean(&self) -> bool {
        is_true(unsafe { ffi::g_value_get_boolean(self.as_raw()) })
    }

    pub fn set_boolean(&mut self, val: bool) {
        unsafe { ffi::g_value_set_boolean(self.as_mut_raw(), val as gboolean) };
    }

    pub fn get_char(&self) -> gchar {
        unsafe { ffi::g_value_get_char(self.as_raw()) }
    }

    pub fn set_char(&mut self, val: gchar) {
        unsafe { ffi::g_value_set_char(self.as_mut_raw(), val) };
    }

    pub fn get_schar(&self) -> i8 {
        unsafe { ffi::g_value_get_schar(self.as_raw()) }
    }

    pub fn set_schar(&mut self, val: i8) {
        unsafe { ffi::g_value_set_schar(self.as_mut_raw(), val) };
    }

    pub fn get_uchar(&self) -> guchar {
        unsafe { ffi::g_value_get_uchar(self.as_raw()) }
    }

    pub fn set_uchar(&mut self, val: guchar) {
        unsafe { ffi::g_value_set_uchar(self.as_mut_raw(), val) };
    }

    pub fn get_int(&self) -> gint {
        unsafe { ffi::g_value_get_int(self.as_raw()) }
    }

    pub fn set_int(&mut self, val: gint) {
        unsafe { ffi::g_value_set_int(self.as_mut_raw(), val) };
    }

    pub fn get_uint(&self) -> guint {
        unsafe { ffi::g_value_get_uint(self.as_raw()) }
    }

    pub fn set_uint(&mut self, val: guint) {
        unsafe { ffi::g_value_set_uint(self.as_mut_raw(), val) };
    }

    pub fn get_long(&self) -> glong {
        unsafe { ffi::g_value_get_long(self.as_raw()) }
    }

    pub fn set_long(&mut self, val: glong) {
        unsafe { ffi::g_value_set_long(self.as_mut_raw(), val) };
    }

    pub fn get_ulong(&self) -> gulong {
        unsafe { ffi::g_value_get_ulong(self.as_raw()) }
    }

    pub fn set_ulong(&mut self, val: gulong) {
        unsafe { ffi::g_value_set_ulong(self.as_mut_raw(), val) };
    }

    pub fn get_int64(&self) -> i64 {
        unsafe { ffi::g_value_get_int64(self.as_raw()) }
    }

    pub fn set_int64(&mut self, val: i64) {
        unsafe { ffi::g_value_set_int64(self.as_mut_raw(), val) };
    }

    pub fn get_uint64(&self) -> u64 {
        unsafe { ffi::g_value_get_uint64(self.as_raw()) }
    }

    pub fn set_uint64(&mut self, val: u64) {
        unsafe { ffi::g_value_set_uint64(self.as_mut_raw(), val) };
    }

    pub fn get_float(&self) -> gfloat {
        unsafe { ffi::g_value_get_float(self.as_raw()) }
    }

    pub fn set_float(&mut self, val: gfloat) {
        unsafe { ffi::g_value_set_float(self.as_mut_raw(), val) };
    }

    pub fn get_double(&self) -> gdouble {
        unsafe { ffi::g_value_get_double(self.as_raw()) }
    }

    pub fn set_double(&mut self, val: gdouble) {
        unsafe { ffi::g_value_set_double(self.as_mut_raw(), val) };
    }

    fn assert_enum_type<T>(&self) where T: EnumType {
        debug_assert!(self.value_type() == enumeration::type_of::<T>(),
                      "GValue does not have the enumeration type {}",
                      enumeration::type_of::<T>().name());
    }

    pub fn get_enum<T>(&self) -> Result<T, UnknownEnumValue>
        where T: EnumType
    {
        self.assert_enum_type::<T>();
        unsafe {
            let v = ffi::g_value_get_enum(self.as_raw());
            IntrospectedEnum::from_int(v)
        }
    }

    pub fn set_enum<T>(&mut self, val: T) where T: EnumType {
        self.assert_enum_type::<T>();
        unsafe {
            ffi::g_value_set_enum(self.as_mut_raw(), val.to_int());
        }
    }

    fn assert_flags_type<T>(&self) where T: FlagsType {
        debug_assert!(self.value_type() == flags::type_of::<T>(),
                      "GValue does not have the flags type {}",
                      flags::type_of::<T>().name());
    }

    pub fn get_flags<T>(&self) -> Result<T, UnknownFlags>
        where T: FlagsType
    {
        self.assert_flags_type::<T>();
        unsafe {
            let v = ffi::g_value_get_flags(self.as_raw());
            IntrospectedFlags::from_uint(v)
        }
    }

    pub fn set_flags<T>(&mut self, val: T) where T: FlagsType {
        self.assert_flags_type::<T>();
        unsafe {
            ffi::g_value_set_flags(self.as_mut_raw(), val.to_uint());
        }
    }

    pub fn get_string(&self) -> Option<&CStr> {
        unsafe {
            let ptr = ffi::g_value_get_string(self.as_raw());
            if ptr.is_null() {
                return None;
            }
            Some(CStr::from_ptr(ptr))
        }
    }

    pub fn set_string(&mut self, val: &CStr) {
        unsafe { ffi::g_value_set_string(self.as_mut_raw(), val.as_ptr()) }
    }

    pub fn set_static_string(&mut self, val: &'static CStr) {
        unsafe {
            ffi::g_value_set_static_string(self.as_mut_raw(), val.as_ptr())
        }
    }

    pub fn take_string(&mut self, consumed: OwnedGStr) {
        unsafe {
            let ptr = consumed.as_ptr() as *mut gchar;
            ffi::g_value_take_string(self.as_mut_raw(), ptr);
            mem::forget(consumed);
        }
    }

    pub fn get_object<T>(&self) -> Option<&T>
        where T: ObjectType
    {
        assert!(self.value_type() == object::type_of::<T>(),
                "GValue does not have the object type {}",
                object::type_of::<T>().name());
        let p = unsafe { ffi::g_value_get_object(self.as_raw()) as *const T };
        if p.is_null() {
            return None;
        }
        Some(unsafe { mem::transmute(&*p) })
    }

    pub fn set_object<T>(&mut self, val: &T)
        where T: ObjectType
    {
        let p = val as *const _;
        unsafe { ffi::g_value_set_object(self.as_mut_raw(), p as gpointer) }
    }

    fn assert_boxed_type<T>(&self)
        where T: BoxedType
    {
        assert!(self.value_type() == boxed::type_of::<T>(),
                "GValue does not have the boxed type {}",
                boxed::type_of::<T>().name());
    }

    pub fn dup_boxed<T>(&self) -> Option<T>
        where T: BoxedType
    {
        self.assert_boxed_type::<T>();
        let p = unsafe { ffi::g_value_dup_boxed(self.as_raw()) };
        if p.is_null() {
            return None;
        }
        Some(unsafe {
            let boxed: T = BoxedType::from_ptr(p);
            boxed
        })
    }

    pub fn deref_boxed<T>(&self) -> Option<&<T as Deref>::Target>
        where T: BoxedType + Deref
    {
        self.assert_boxed_type::<T>();
        let p = unsafe { ffi::g_value_get_boxed(self.as_raw()) };
        if p.is_null() {
            return None;
        }
        unsafe {
            let boxed: T = BoxedType::from_ptr(p);
            let ret = Some(mem::transmute(&*boxed));

            // Lose the box by "subliming" it back into the raw pointer
            let q = boxed.into_ptr();
            debug_assert!(q == p,
                "BoxedType invariant violation: into_ptr does not reverse from_ptr");

            ret
        }
    }

    pub fn take_boxed<T>(&mut self, val: T) where T: BoxedType {
        unsafe {
            let p = val.into_ptr();
            ffi::g_value_take_boxed(self.as_mut_raw(), p);
        }
    }
}

impl fmt::Debug for Value {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let contents = unsafe {
            let ptr = ffi::g_strdup_value_contents(self.as_raw());
            OwnedGStr::from_ptr(ptr)
        };
        write!(f, "GValue({})", String::from_utf8_lossy(contents.to_bytes()))
    }
}
<|endoftext|>


<commit_before>use sdl2;

pub fn main() {
    sdl2::init(sdl2::InitVideo);

    let title = "rusteroids";
    let window_x_pos = sdl2::video::PosCentered;
    let window_y_pos = sdl2::video::PosCentered;
    let window_width = 800;
    let window_height = 600;
    /*  Flags
        Fullscreen              |   SDL_WINDOW_FULLSCREEN           |   fullscreen window
        OpenGL                  |   SDL_WINDOW_OPENGL               |   window usable with OpenGL context
        Shown                   |   SDL_WINDOW_SHOWN                |   window is visible
        Hidden                  |   SDL_WINDOW_HIDDEN               |   window is not visible
        Borderless              |   SDL_WINDOW_BORDERLESS           |   no window decoration
        Resizable               |   SDL_WINDOW_RESIZABLE            |   window can be resized
        Minimized               |   SDL_WINDOW_MINIMIZED            |   window is minimized
        Maximized               |   SDL_WINDOW_MAXIMIZED            |   window is maximized
        InputGrabbed            |   SDL_WINDOW_INPUT_GRABBED        |   window has grabbed input focus
        InputFocus              |   SDL_WINDOW_INPUT_FOCUS          |   window has input focus
        MouseFocus              |   SDL_WINDOW_MOUSE_FOCUS          |   window has mouse focus
        FullscreenDesktop       |   SDL_WINDOW_FULLSCREEN_DESKTOP   |   fullscreen window
        Foreign                 |   SDL_WINDOW_FOREIGN              |   window not created by SDL
        SDL_WINDOW_OPENGL

        OR'd together
        e.g:

        sdl2::video::OpenGL | sdl2::video::Borderless
     */
    let window_flags = /*sdl2::video::Fullscreen | */ sdl2::video::OpenGL | sdl2::video::Borderless;

    let window = match sdl2::video::Window::new(title, window_x_pos, window_y_pos, window_width, window_height, window_flags) {
        Ok(window) => window,
        Err(err) => fail!(format!("failed to create window: {}", err))
    };

    let renderer = match sdl2::render::Renderer::from_window(window, sdl2::render::DriverAuto, sdl2::render::Accelerated) {
        Ok(renderer) => renderer,
        Err(err) => fail!(format!("failed to create renderer: {}", err))
    };

    let _ = renderer.set_draw_color(sdl2::pixels::RGB(255, 0, 0));
    let _ = renderer.clear();
    renderer.present();

    'main : loop {
        'event : loop {
            match sdl2::event::poll_event() {
                sdl2::event::QuitEvent(_) => break 'main,
                sdl2::event::KeyDownEvent(_, _, key, _, _) => {
                    if key == sdl2::keycode::EscapeKey {
                        break 'main
                    }
                },
                sdl2::event::NoEvent => break 'event,
                // MouseButtonDownEvent(event.timestamp as uint, window,
                                     // event.which as uint,
                                     // mouse::wrap_mouse(event.button),
                                     // event.x as int, event.y as int)
                sdl2::event::MouseButtonDownEvent(_, _, _, _, x, y) => println!("{}, {}", x, y),
                _ => {},
            }

        }
    }

    sdl2::quit();
}
<commit_msg>some movement on the go<commit_after>use sdl2;

pub fn main() {
    sdl2::init(sdl2::InitVideo);

    let title = "rusteroids";
    let window_x_pos = sdl2::video::PosCentered;
    let window_y_pos = sdl2::video::PosCentered;
    let window_width = 800;
    let window_height = 600;
    /*  Flags
        Fullscreen              |   SDL_WINDOW_FULLSCREEN           |   fullscreen window
        OpenGL                  |   SDL_WINDOW_OPENGL               |   window usable with OpenGL context
        Shown                   |   SDL_WINDOW_SHOWN                |   window is visible
        Hidden                  |   SDL_WINDOW_HIDDEN               |   window is not visible
        Borderless              |   SDL_WINDOW_BORDERLESS           |   no window decoration
        Resizable               |   SDL_WINDOW_RESIZABLE            |   window can be resized
        Minimized               |   SDL_WINDOW_MINIMIZED            |   window is minimized
        Maximized               |   SDL_WINDOW_MAXIMIZED            |   window is maximized
        InputGrabbed            |   SDL_WINDOW_INPUT_GRABBED        |   window has grabbed input focus
        InputFocus              |   SDL_WINDOW_INPUT_FOCUS          |   window has input focus
        MouseFocus              |   SDL_WINDOW_MOUSE_FOCUS          |   window has mouse focus
        FullscreenDesktop       |   SDL_WINDOW_FULLSCREEN_DESKTOP   |   fullscreen window
        Foreign                 |   SDL_WINDOW_FOREIGN              |   window not created by SDL
        SDL_WINDOW_OPENGL

        OR'd together
        e.g:

        sdl2::video::OpenGL | sdl2::video::Borderless
     */
    let window_flags = /*sdl2::video::Fullscreen | */ sdl2::video::OpenGL | sdl2::video::Borderless;

    let window = match sdl2::video::Window::new(title, window_x_pos, window_y_pos, window_width, window_height, window_flags) {
        Ok(window) => window,
        Err(err) => fail!(format!("failed to create window: {}", err))
    };

    let renderer = match sdl2::render::Renderer::from_window(window, sdl2::render::DriverAuto, sdl2::render::Accelerated) {
        Ok(renderer) => renderer,
        Err(err) => fail!(format!("failed to create renderer: {}", err))
    };

    let mut x = 50;
    let mut y = 50;

    draw_screen(&renderer, x, y);

    'main : loop {
        'event : loop {
            match sdl2::event::poll_event() {
                sdl2::event::QuitEvent(_) => break 'main,
                sdl2::event::KeyDownEvent(_, _, key, _, _) => {
                    match key {
                        sdl2::keycode::EscapeKey => break 'main,
                        sdl2::keycode::LeftKey   => x -= 1,
                        sdl2::keycode::RightKey  => x += 1,
                        sdl2::keycode::UpKey     => y -= 1,
                        sdl2::keycode::DownKey   => y += 1,
                        _                        => ()
                    }
                },
                sdl2::event::NoEvent => break 'event,
                // MouseButtonDownEvent(event.timestamp as uint, window,
                                     // event.which as uint,
                                     // mouse::wrap_mouse(event.button),
                                     // event.x as int, event.y as int)
                sdl2::event::MouseButtonDownEvent(_, _, _, _, x, y) => println!("{}, {}", x, y),
                _ => {},
            }

        }

        draw_screen(&renderer, x, y);
    }

    sdl2::quit();
}

fn draw_screen(renderer: &sdl2::render::Renderer<sdl2::video::Window>, x:i32, y:i32){
    let _ = renderer.set_draw_color(sdl2::pixels::RGB(100, 0, 0));
    let _ = renderer.clear();
    let _ = renderer.set_draw_color(sdl2::pixels::RGB(255, 255, 255));
    let r = sdl2::rect::Rect::new(x, y, 100, 100);
    let _ = renderer.fill_rect(&r);
    renderer.present();
}
<|endoftext|>


<commit_before>pub fn make_path(parent: &str, child: &str) -> String {
    let mut result = parent.to_owned();
    if parent.chars().last().unwrap() != '/' {
        result.push('/');
    }
    result.push_str(child);
    result
}
<commit_msg>Adds documentation for paths.rs (and a unit test).<commit_after>/// Combine two paths into a single path, possibly inserting a '/' between them.
pub fn make_path(parent: &str, child: &str) -> String {
    if parent.chars().last() == Some('/') {
        format!("{}{}", parent, child)
    } else {
        format!("{}/{}", parent, child)
    }
}

#[cfg(test)]
#[test]
fn make_path_tests() {
    assert_eq!("/a/b", make_path("/a", "b"));
    assert_eq!("/a/b", make_path("/a/", "b"));
}
<|endoftext|>


<commit_before>//! Serialization code.

use std::io::{self, Write};
use std::mem::size_of;
use byteorder::WriteBytesExt;
use byteorder::NativeEndian as E;

use super::{
	SIGNATURE, FORMAT, VERSION, DATA, TEST_INT, TEST_NUMBER,
	Int, Size, Instruction, Integer, Number,
	Constant, Upvalue, Function,
};

/// Serialize a `Function` to bytecode.
pub fn write_file<W: Write>(write: W, function: &Function) -> io::Result<()> {
	let mut writer = Writer { out: write };
	try!(writer.write_header());
	try!(writer.out.write_u8(function.upvalues.len() as u8));
	writer.write_function(function)
}

struct Writer<W: Write> {
	out: W,
}

impl<W: Write> Writer<W> {
	fn write_header(&mut self) -> io::Result<()> {
		try!(self.out.write_all(SIGNATURE));
		try!(self.out.write_u8(VERSION));
		try!(self.out.write_u8(FORMAT));
		try!(self.out.write_all(DATA));
		try!(self.out.write_u8(size_of::<Int>() as u8));
		try!(self.out.write_u8(size_of::<Size>() as u8));
		try!(self.out.write_u8(size_of::<Instruction>() as u8));
		try!(self.out.write_u8(size_of::<Integer>() as u8));
		try!(self.out.write_u8(size_of::<Number>() as u8));
		try!(self.out.write_i64::<E>(TEST_INT));
		try!(self.out.write_f64::<E>(TEST_NUMBER));
		Ok(())
	}

	fn write_function(&mut self, function: &Function) -> io::Result<()> {
		try!(self.write_string(&function.source));
		try!(self.out.write_i32::<E>(function.line_start));
		try!(self.out.write_i32::<E>(function.line_end));
		try!(self.out.write_u8(function.num_params));
		try!(self.out.write_u8(if function.is_vararg { 1 } else { 0 }));
		try!(self.out.write_u8(function.max_stack_size));

		try!(self.out.write_u32::<E>(function.code.len() as u32));
		for &ins in &function.code {
			try!(self.out.write_u32::<E>(ins));
		}
		try!(self.out.write_u32::<E>(function.constants.len() as u32));
		for cons in &function.constants {
			match cons {
				&Constant::Nil => try!(self.out.write_u8(0x00)),
				&Constant::Boolean(b) => try!(self.out.write_all(&[0x01, if b { 1 } else { 0 }])),
				&Constant::Float(n) => {
					try!(self.out.write_u8(0x03));
					try!(self.out.write_f64::<E>(n));
				}
				&Constant::Int(n) => {
					try!(self.out.write_u8(0x13));
					try!(self.out.write_i64::<E>(n));
				}
				&Constant::ShortString(ref s) => {
					try!(self.out.write_u8(0x04));
					try!(self.write_string(s));
				}
				&Constant::LongString(ref s) => {
					try!(self.out.write_u8(0x14));
					try!(self.write_string(s));
				}
			}
		}
		try!(self.out.write_u32::<E>(function.upvalues.len() as u32));
		for upval in &function.upvalues {
			try!(match upval {
				&Upvalue::Outer(idx) => self.out.write_all(&[0, idx]),
				&Upvalue::Stack(idx) => self.out.write_all(&[1, idx]),
			});
		}
		try!(self.out.write_u32::<E>(function.protos.len() as u32));
		for proto in &function.protos {
			try!(self.write_function(proto));
		}
		// debug
		try!(self.out.write_u32::<E>(function.debug.lineinfo.len() as u32));
		for &line in &function.debug.lineinfo {
			try!(self.out.write_i32::<E>(line));
		}
		try!(self.out.write_u32::<E>(function.debug.localvars.len() as u32));
		for var in &function.debug.localvars {
			try!(self.write_string(&var.name));
			try!(self.out.write_i32::<E>(var.start_pc));
			try!(self.out.write_i32::<E>(var.end_pc));
		}
		try!(self.out.write_u32::<E>(function.debug.upvalues.len() as u32));
		for upval in &function.debug.upvalues {
			try!(self.write_string(upval));
		}
		Ok(())
	}

	fn write_string(&mut self, string: &str) -> io::Result<()> {
		if string.len() == 0 {
			try!(self.out.write_u8(0))
		} else {
			if string.len() >= 0xff {
				try!(self.out.write_u8(0xff));
				try!(self.out.write_u32::<E>(string.len() as u32 + 1));
			} else {
				try!(self.out.write_u8(string.len() as u8 + 1));
			}
			try!(self.out.write_all(string.as_bytes()))
		}
		Ok(())
	}
}
<commit_msg>Stop writing empty strings as null<commit_after>//! Serialization code.

use std::io::{self, Write};
use std::mem::size_of;
use byteorder::WriteBytesExt;
use byteorder::NativeEndian as E;

use super::{
	SIGNATURE, FORMAT, VERSION, DATA, TEST_INT, TEST_NUMBER,
	Int, Size, Instruction, Integer, Number,
	Constant, Upvalue, Function,
};

/// Serialize a `Function` to bytecode.
pub fn write_file<W: Write>(write: W, function: &Function) -> io::Result<()> {
	let mut writer = Writer { out: write };
	try!(writer.write_header());
	try!(writer.out.write_u8(function.upvalues.len() as u8));
	writer.write_function(function)
}

struct Writer<W: Write> {
	out: W,
}

impl<W: Write> Writer<W> {
	fn write_header(&mut self) -> io::Result<()> {
		try!(self.out.write_all(SIGNATURE));
		try!(self.out.write_u8(VERSION));
		try!(self.out.write_u8(FORMAT));
		try!(self.out.write_all(DATA));
		try!(self.out.write_u8(size_of::<Int>() as u8));
		try!(self.out.write_u8(size_of::<Size>() as u8));
		try!(self.out.write_u8(size_of::<Instruction>() as u8));
		try!(self.out.write_u8(size_of::<Integer>() as u8));
		try!(self.out.write_u8(size_of::<Number>() as u8));
		try!(self.out.write_i64::<E>(TEST_INT));
		try!(self.out.write_f64::<E>(TEST_NUMBER));
		Ok(())
	}

	fn write_function(&mut self, function: &Function) -> io::Result<()> {
		try!(self.write_string(&function.source));
		try!(self.out.write_i32::<E>(function.line_start));
		try!(self.out.write_i32::<E>(function.line_end));
		try!(self.out.write_u8(function.num_params));
		try!(self.out.write_u8(if function.is_vararg { 1 } else { 0 }));
		try!(self.out.write_u8(function.max_stack_size));

		try!(self.out.write_u32::<E>(function.code.len() as u32));
		for &ins in &function.code {
			try!(self.out.write_u32::<E>(ins));
		}
		try!(self.out.write_u32::<E>(function.constants.len() as u32));
		for cons in &function.constants {
			match cons {
				&Constant::Nil => try!(self.out.write_u8(0x00)),
				&Constant::Boolean(b) => try!(self.out.write_all(&[0x01, if b { 1 } else { 0 }])),
				&Constant::Float(n) => {
					try!(self.out.write_u8(0x03));
					try!(self.out.write_f64::<E>(n));
				}
				&Constant::Int(n) => {
					try!(self.out.write_u8(0x13));
					try!(self.out.write_i64::<E>(n));
				}
				&Constant::ShortString(ref s) => {
					try!(self.out.write_u8(0x04));
					try!(self.write_string(s));
				}
				&Constant::LongString(ref s) => {
					try!(self.out.write_u8(0x14));
					try!(self.write_string(s));
				}
			}
		}
		try!(self.out.write_u32::<E>(function.upvalues.len() as u32));
		for upval in &function.upvalues {
			try!(match upval {
				&Upvalue::Outer(idx) => self.out.write_all(&[0, idx]),
				&Upvalue::Stack(idx) => self.out.write_all(&[1, idx]),
			});
		}
		try!(self.out.write_u32::<E>(function.protos.len() as u32));
		for proto in &function.protos {
			try!(self.write_function(proto));
		}
		// debug
		try!(self.out.write_u32::<E>(function.debug.lineinfo.len() as u32));
		for &line in &function.debug.lineinfo {
			try!(self.out.write_i32::<E>(line));
		}
		try!(self.out.write_u32::<E>(function.debug.localvars.len() as u32));
		for var in &function.debug.localvars {
			try!(self.write_string(&var.name));
			try!(self.out.write_i32::<E>(var.start_pc));
			try!(self.out.write_i32::<E>(var.end_pc));
		}
		try!(self.out.write_u32::<E>(function.debug.upvalues.len() as u32));
		for upval in &function.debug.upvalues {
			try!(self.write_string(upval));
		}
		Ok(())
	}

	fn write_string(&mut self, string: &str) -> io::Result<()> {
		if string.len() >= 0xff {
			try!(self.out.write_u8(0xff));
			try!(self.out.write_u32::<E>(string.len() as u32 + 1));
		} else {
			try!(self.out.write_u8(string.len() as u8 + 1));
		}
		self.out.write_all(string.as_bytes())
	}
}
<|endoftext|>


<commit_before>
use error::MpdResult;
use connection::{FromConn, MpdConnection, mpd_connection};
use songs::{MpdSong, MpdSongs, mpd_song};
use std::c_str::CString;
use libc::{c_uint, c_int, c_char};

extern {
    fn mpd_run_get_queue_song_pos(connection: *mut mpd_connection, pos: c_uint) -> *mut mpd_song;
    fn mpd_run_get_queue_song_id(connection: *mut mpd_connection, id: c_uint) -> *mut mpd_song;
    fn mpd_run_move_id(connection: *mut mpd_connection, from: c_uint, to: c_uint) -> bool;
    fn mpd_run_move(connection: *mut mpd_connection, from: c_uint, to: c_uint) -> bool;
    fn mpd_run_move_range(connection: *mut mpd_connection, start: c_uint, end: c_uint, to: c_uint) -> bool;
    fn mpd_run_swap_id(connection: *mut mpd_connection, id1: c_uint, id2: c_uint) -> bool;
    fn mpd_run_swap(connection: *mut mpd_connection, pos1: c_uint, pos2: c_uint) -> bool;
    fn mpd_run_add_id(connection: *mut mpd_connection, file: *const c_char) -> c_int;
    fn mpd_run_add_id_to(connection: *mut mpd_connection, uri: *const c_char, to: c_uint) -> c_int;
    fn mpd_send_list_queue_meta(connection: *mut mpd_connection) -> bool;
    fn mpd_send_list_queue_range_meta(connection: *mut mpd_connection, start: c_uint, end: c_uint) -> bool;
    fn mpd_run_delete(connection: *mut mpd_connection, pos: c_uint) -> bool;
    fn mpd_run_delete_range(connection: *mut mpd_connection, start: c_uint, end: c_uint) -> bool;
    fn mpd_run_delete_id(connection: *mut mpd_connection, id: c_uint) -> bool;
}

pub struct MpdQueue<'a> {
    pub conn: &'a MpdConnection
}

impl<'a> MpdQueue<'a> {
    pub fn from_conn(conn: &'a MpdConnection) -> MpdQueue<'a> {
        MpdQueue { conn: conn }
    }

    /// Get song at some position in queue
    pub fn nth(&self, index: uint) -> MpdResult<MpdSong> {
        let song = unsafe { mpd_run_get_queue_song_pos(self.conn.conn, index as c_uint) };
        if song.is_null() {
            Err(FromConn::from_conn(self.conn).unwrap())
        } else {
            Ok(MpdSong { song: song })
        }
    }

    /// Get song by queue id
    pub fn get(&self, id: uint) -> MpdResult<MpdSong> {
        let song = unsafe { mpd_run_get_queue_song_id(self.conn.conn, id as c_uint) };
        if song.is_null() {
            Err(FromConn::from_conn(self.conn).unwrap())
        } else {
            Ok(MpdSong { song: song })
        }
    }

    /// Insert new song into queue at given position
    pub fn insert<T: ToSongUri>(&mut self, pos: uint, song: T) -> MpdResult<uint> {
        let uid = unsafe { mpd_run_add_id_to(self.conn.conn, song.song_uri().as_ptr(), pos as c_uint) };
        if uid < 0 {
            Err(FromConn::from_conn(self.conn).unwrap())
        } else {
            Ok(uid as uint)
        }
    }

    /// Add song at the end of the queue
    pub fn push<T: ToSongUri>(&mut self, song: T) -> MpdResult<uint> {
        let uid = unsafe { mpd_run_add_id(self.conn.conn, song.song_uri().as_ptr()) };
        if uid < 0 {
            Err(FromConn::from_conn(self.conn).unwrap())
        } else {
            Ok(uid as uint)
        }
    }

    /// Move song to some position in queue
    pub fn move_pos(&mut self, to: uint, from: uint) -> MpdResult<()> {
        if unsafe { mpd_run_move(self.conn.conn, from as c_uint, to as c_uint) } {
            Ok(())
        } else {
            Err(FromConn::from_conn(self.conn).unwrap())
        }
    }

    /// Move songs in given range
    pub fn move_range(&mut self, pos: uint, start: uint, end: uint) -> MpdResult<()> {
        if unsafe { mpd_run_move_range(self.conn.conn, start as c_uint, end as c_uint, pos as c_uint) } {
            Ok(())
        } else {
            Err(FromConn::from_conn(self.conn).unwrap())
        }
    }

    /// Move song to some position in queue by id
    pub fn move_to(&mut self, pos: uint, song: &MpdSong) -> MpdResult<()> {
        self.move_id(pos, song.id())
    }

    pub fn move_id(&mut self, pos: uint, id: uint) -> MpdResult<()> {
        if unsafe { mpd_run_move_id(self.conn.conn, id as c_uint, pos as c_uint) } {
            Ok(())
        } else {
            Err(FromConn::from_conn(self.conn).unwrap())
        }
    }

    /// Swap two songs in given positions
    pub fn swap_pos(&mut self, song1: uint, song2: uint) -> MpdResult<()> {
        if unsafe { mpd_run_swap(self.conn.conn, song1 as c_uint, song2 as c_uint) } {
            Ok(())
        } else {
            Err(FromConn::from_conn(self.conn).unwrap())
        }
    }

    /// Swap two songs in given positions by id
    pub fn swap(&mut self, song1: &MpdSong, song2: &MpdSong) -> MpdResult<()> {
        self.swap_id(song1.id(), song2.id())
    }

    pub fn swap_id(&mut self, song1: uint, song2: uint) -> MpdResult<()> {
        if unsafe { mpd_run_swap_id(self.conn.conn, song1 as c_uint, song2 as c_uint) } {
            Ok(())
        } else {
            Err(FromConn::from_conn(self.conn).unwrap())
        }
    }

    /// Remove a song
    pub fn remove(&mut self, song: &MpdSong) -> MpdResult<()> {
        self.remove_id(song.id())
    }

    pub fn remove_id(&mut self, id: uint) -> MpdResult<()> {
        if unsafe { mpd_run_delete_id(self.conn.conn, id as c_uint) } {
            Ok(())
        } else {
            Err(FromConn::from_conn(self.conn).unwrap())
        }
    }

    /// Remove songs at given position
    pub fn remove_pos(&mut self, pos: uint) -> MpdResult<()> {
        if unsafe { mpd_run_delete(self.conn.conn, pos as c_uint) } {
            Ok(())
        } else {
            Err(FromConn::from_conn(self.conn).unwrap())
        }
    }

    /// Remove songs in given range
    pub fn remove_range(&mut self, start: uint, end: uint) -> MpdResult<()> {
        if unsafe { mpd_run_delete_range(self.conn.conn, start as c_uint, end as c_uint) } {
            Ok(())
        } else {
            Err(FromConn::from_conn(self.conn).unwrap())
        }
    }

    /// Iterate over songs in the queue
    pub fn iter(&self) -> MpdResult<MpdSongs> {
        if unsafe { mpd_send_list_queue_meta(self.conn.conn) } {
            Ok(MpdSongs { conn: self.conn })
        } else {
            Err(FromConn::from_conn(self.conn).unwrap())
        }
    }

    /// Iterate over songs in given range
    pub fn iter_range(&self, start: uint, end: uint) -> MpdResult<MpdSongs> {
        if unsafe { mpd_send_list_queue_range_meta(self.conn.conn, start as c_uint, end as c_uint) } {
            Ok(MpdSongs { conn: self.conn })
        } else {
            Err(FromConn::from_conn(self.conn).unwrap())
        }
    }

    /// Length of the queue
    pub fn len(&self) -> MpdResult<uint> {
        self.conn.status().map(|s| s.queue_len())
    }

    /// Returns true if queue is empty
    pub fn is_empty(&self) -> MpdResult<bool> {
        self.len().map(|v| v == 0)
    }
}

pub trait ToSongUri {
    fn song_uri(&self) -> CString;
}

impl ToSongUri for MpdSong {
    #[inline] fn song_uri(&self) -> CString {
        self.uri().to_c_str()
    }
}

impl<T: ToCStr> ToSongUri for T {
    #[inline] fn song_uri(&self) -> CString {
        self.to_c_str()
    }
}
<commit_msg>queue shuffle and clear<commit_after>
use error::MpdResult;
use connection::{FromConn, MpdConnection, mpd_connection};
use songs::{MpdSong, MpdSongs, mpd_song};
use std::c_str::CString;
use libc::{c_uint, c_int, c_char};

extern {
    fn mpd_run_get_queue_song_pos(connection: *mut mpd_connection, pos: c_uint) -> *mut mpd_song;
    fn mpd_run_get_queue_song_id(connection: *mut mpd_connection, id: c_uint) -> *mut mpd_song;
    fn mpd_run_move_id(connection: *mut mpd_connection, from: c_uint, to: c_uint) -> bool;
    fn mpd_run_move(connection: *mut mpd_connection, from: c_uint, to: c_uint) -> bool;
    fn mpd_run_move_range(connection: *mut mpd_connection, start: c_uint, end: c_uint, to: c_uint) -> bool;
    fn mpd_run_shuffle(connection: *mut mpd_connection) -> bool;
    fn mpd_run_shuffle_range(connection: *mut mpd_connection, start: c_uint, end: c_uint) -> bool;
    fn mpd_run_swap_id(connection: *mut mpd_connection, id1: c_uint, id2: c_uint) -> bool;
    fn mpd_run_swap(connection: *mut mpd_connection, pos1: c_uint, pos2: c_uint) -> bool;
    fn mpd_run_add_id(connection: *mut mpd_connection, file: *const c_char) -> c_int;
    fn mpd_run_add_id_to(connection: *mut mpd_connection, uri: *const c_char, to: c_uint) -> c_int;
    fn mpd_send_list_queue_meta(connection: *mut mpd_connection) -> bool;
    fn mpd_send_list_queue_range_meta(connection: *mut mpd_connection, start: c_uint, end: c_uint) -> bool;
    fn mpd_run_delete(connection: *mut mpd_connection, pos: c_uint) -> bool;
    fn mpd_run_delete_range(connection: *mut mpd_connection, start: c_uint, end: c_uint) -> bool;
    fn mpd_run_delete_id(connection: *mut mpd_connection, id: c_uint) -> bool;
    fn mpd_run_clear(connection: *mut mpd_connection) -> bool;
}

pub struct MpdQueue<'a> {
    pub conn: &'a MpdConnection
}

impl<'a> MpdQueue<'a> {
    pub fn from_conn(conn: &'a MpdConnection) -> MpdQueue<'a> {
        MpdQueue { conn: conn }
    }

    /// Get song at some position in queue
    pub fn nth(&self, index: uint) -> MpdResult<MpdSong> {
        let song = unsafe { mpd_run_get_queue_song_pos(self.conn.conn, index as c_uint) };
        if song.is_null() {
            Err(FromConn::from_conn(self.conn).unwrap())
        } else {
            Ok(MpdSong { song: song })
        }
    }

    /// Get song by queue id
    pub fn get(&self, id: uint) -> MpdResult<MpdSong> {
        let song = unsafe { mpd_run_get_queue_song_id(self.conn.conn, id as c_uint) };
        if song.is_null() {
            Err(FromConn::from_conn(self.conn).unwrap())
        } else {
            Ok(MpdSong { song: song })
        }
    }

    /// Insert new song into queue at given position
    pub fn insert<T: ToSongUri>(&mut self, pos: uint, song: T) -> MpdResult<uint> {
        let uid = unsafe { mpd_run_add_id_to(self.conn.conn, song.song_uri().as_ptr(), pos as c_uint) };
        if uid < 0 {
            Err(FromConn::from_conn(self.conn).unwrap())
        } else {
            Ok(uid as uint)
        }
    }

    /// Add song at the end of the queue
    pub fn push<T: ToSongUri>(&mut self, song: T) -> MpdResult<uint> {
        let uid = unsafe { mpd_run_add_id(self.conn.conn, song.song_uri().as_ptr()) };
        if uid < 0 {
            Err(FromConn::from_conn(self.conn).unwrap())
        } else {
            Ok(uid as uint)
        }
    }

    /// Move song to some position in queue
    pub fn move_pos(&mut self, to: uint, from: uint) -> MpdResult<()> {
        if unsafe { mpd_run_move(self.conn.conn, from as c_uint, to as c_uint) } {
            Ok(())
        } else {
            Err(FromConn::from_conn(self.conn).unwrap())
        }
    }

    /// Move songs in given range
    pub fn move_range(&mut self, pos: uint, start: uint, end: uint) -> MpdResult<()> {
        if unsafe { mpd_run_move_range(self.conn.conn, start as c_uint, end as c_uint, pos as c_uint) } {
            Ok(())
        } else {
            Err(FromConn::from_conn(self.conn).unwrap())
        }
    }

    /// Move song to some position in queue by id
    pub fn move_to(&mut self, pos: uint, song: &MpdSong) -> MpdResult<()> {
        self.move_id(pos, song.id())
    }

    pub fn move_id(&mut self, pos: uint, id: uint) -> MpdResult<()> {
        if unsafe { mpd_run_move_id(self.conn.conn, id as c_uint, pos as c_uint) } {
            Ok(())
        } else {
            Err(FromConn::from_conn(self.conn).unwrap())
        }
    }

    /// Swap two songs in given positions
    pub fn swap_pos(&mut self, song1: uint, song2: uint) -> MpdResult<()> {
        if unsafe { mpd_run_swap(self.conn.conn, song1 as c_uint, song2 as c_uint) } {
            Ok(())
        } else {
            Err(FromConn::from_conn(self.conn).unwrap())
        }
    }

    /// Swap two songs in given positions by id
    pub fn swap(&mut self, song1: &MpdSong, song2: &MpdSong) -> MpdResult<()> {
        self.swap_id(song1.id(), song2.id())
    }

    pub fn swap_id(&mut self, song1: uint, song2: uint) -> MpdResult<()> {
        if unsafe { mpd_run_swap_id(self.conn.conn, song1 as c_uint, song2 as c_uint) } {
            Ok(())
        } else {
            Err(FromConn::from_conn(self.conn).unwrap())
        }
    }

    pub fn shuffle(&mut self) -> MpdResult<()> {
        if unsafe { mpd_run_shuffle(self.conn.conn) } {
            Ok(())
        } else {
            Err(FromConn::from_conn(self.conn).unwrap())
        }
    }

    pub fn shuffle_range(&mut self, start: uint, end: uint) -> MpdResult<()> {
        if unsafe { mpd_run_shuffle_range(self.conn.conn, start as c_uint, end as c_uint) } {
            Ok(())
        } else {
            Err(FromConn::from_conn(self.conn).unwrap())
        }
    }

    /// Remove a song
    pub fn remove(&mut self, song: &MpdSong) -> MpdResult<()> {
        self.remove_id(song.id())
    }

    pub fn remove_id(&mut self, id: uint) -> MpdResult<()> {
        if unsafe { mpd_run_delete_id(self.conn.conn, id as c_uint) } {
            Ok(())
        } else {
            Err(FromConn::from_conn(self.conn).unwrap())
        }
    }

    /// Remove songs at given position
    pub fn remove_pos(&mut self, pos: uint) -> MpdResult<()> {
        if unsafe { mpd_run_delete(self.conn.conn, pos as c_uint) } {
            Ok(())
        } else {
            Err(FromConn::from_conn(self.conn).unwrap())
        }
    }

    /// Remove songs in given range
    pub fn remove_range(&mut self, start: uint, end: uint) -> MpdResult<()> {
        if unsafe { mpd_run_delete_range(self.conn.conn, start as c_uint, end as c_uint) } {
            Ok(())
        } else {
            Err(FromConn::from_conn(self.conn).unwrap())
        }
    }

    /// Iterate over songs in the queue
    pub fn iter(&self) -> MpdResult<MpdSongs> {
        if unsafe { mpd_send_list_queue_meta(self.conn.conn) } {
            Ok(MpdSongs { conn: self.conn })
        } else {
            Err(FromConn::from_conn(self.conn).unwrap())
        }
    }

    /// Iterate over songs in given range
    pub fn iter_range(&self, start: uint, end: uint) -> MpdResult<MpdSongs> {
        if unsafe { mpd_send_list_queue_range_meta(self.conn.conn, start as c_uint, end as c_uint) } {
            Ok(MpdSongs { conn: self.conn })
        } else {
            Err(FromConn::from_conn(self.conn).unwrap())
        }
    }

    /// Length of the queue
    pub fn len(&self) -> MpdResult<uint> {
        self.conn.status().map(|s| s.queue_len())
    }

    /// Returns true if queue is empty
    pub fn is_empty(&self) -> MpdResult<bool> {
        self.len().map(|v| v == 0)
    }

    /// Clear queue
    pub fn clear(&mut self) -> MpdResult<()> {
        if unsafe { mpd_run_clear(self.conn.conn) } {
            Ok(())
        } else {
            Err(FromConn::from_conn(self.conn).unwrap())
        }
    }
}

pub trait ToSongUri {
    fn song_uri(&self) -> CString;
}

impl ToSongUri for MpdSong {
    #[inline] fn song_uri(&self) -> CString {
        self.uri().to_c_str()
    }
}

impl<T: ToCStr> ToSongUri for T {
    #[inline] fn song_uri(&self) -> CString {
        self.to_c_str()
    }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::marker::PhantomData;
use std::ops::Deref;
use std::path::Path;

use model::Model;
use resource::ResourceManager;

/// A typed identifier.
#[derive(Debug)]
pub struct Id<T> {
  pub id: u32,
  _t: PhantomData<*const T>
}

impl<T> Id<T> {
  pub fn new(id: u32) -> Self {
    Id {
      id: id,
      _t: PhantomData
    }
  }
}

impl<T> Clone for Id<T> {
  fn clone(&self) -> Self {
    self.id.into()
  }
}

impl<T> Deref for Id<T> {
  type Target = u32;

  fn deref(&self) -> &Self::Target {
    &self.id
  }
}

impl<T> From<u32> for Id<T> {
  fn from(id: u32) -> Self {
    Id::new(id)
  }
}

/// The scene type.
///
/// This type gathers all the required objects a scene needs to correctly handle and render all
/// visual effects.
pub struct Scene {
  /// Resource manager; used to handle scarce resources.
  res_manager: ResourceManager,
  /// List of all models used in the scene.
  models: Vec<Model>,
  /// Model cache used to resolve Id based on instance name.
  model_cache: HashMap<String, Id<Model>>,
}

impl Scene {
  pub fn new<P>(root: P) -> Self where P: AsRef<Path>{
    Scene {
      res_manager: ResourceManager::new(root),
      models: Vec::new(),
      model_cache: HashMap::new(),
    }
  }

  pub fn get_id<T>(&mut self, name: &str) -> Option<Id<T>> where T: Get {
    T::get_id(self, name)
  }

  pub fn get<T>(&self, id: Id<T>) -> Option<&T> where T: Get {
    T::get(self, id)
  }

  pub fn resource_manager(&mut self) -> &mut ResourceManager {
    &mut self.res_manager
  }
}

pub trait Get: Sized {
  fn get_id(scene: &mut Scene, name: &str) -> Option<Id<Self>>;
  fn get(scene: &Scene, id: Id<Self>) -> Option<&Self>;
}

impl Get for Model {
  fn get_id(scene: &mut Scene, name: &str) -> Option<Id<Self>> {
    match scene.model_cache.get(name).cloned() {
      id@Some(..) => {
        deb!("cache hit for model \"{}\"", name);
        id
      },
      None => {
        // cache miss; load then
        let path_str = format!("data/models/{}.obj", name);
        let path = Path::new(&path_str);

        deb!("cache miss for model \"{}\"", name);

        if path.exists() {
          match Model::load(&mut scene.res_manager, path) {
            Ok(model) => {
              let model_id: Id<Model> = (scene.models.len() as u32).into();

              // add the model to the list of loaded models
              scene.models.push(model);
              // add the model to the cache
              scene.model_cache.insert(name.to_owned(), model_id.clone());

              Some(model_id)
            },
            Err(e) => {
              err!("unable to load model '{}': '{:?}'", name, e);
              None
            }
          }
        } else { // TODO: add a manifest override to look in somewhere else
          err!("model '{}' cannot be found", name);
          None
        }
      }
    }
  }

  fn get(scene: &Scene, id: Id<Self>) -> Option<&Self> {
    scene.models.get(*id as usize)
  }
}
<commit_msg>Added model_entities to Scene (introduced type SceneModelEntity).<commit_after>use std::collections::HashMap;
use std::marker::PhantomData;
use std::ops::Deref;
use std::path::Path;

use anim::Cont;
use entity::Entity;
use model::Model;
use resource::ResourceManager;

/// A typed identifier.
#[derive(Debug)]
pub struct Id<T> {
  pub id: u32,
  _t: PhantomData<*const T>
}

impl<T> Id<T> {
  pub fn new(id: u32) -> Self {
    Id {
      id: id,
      _t: PhantomData
    }
  }
}

impl<T> Clone for Id<T> {
  fn clone(&self) -> Self {
    self.id.into()
  }
}

impl<T> Deref for Id<T> {
  type Target = u32;

  fn deref(&self) -> &Self::Target {
    &self.id
  }
}

impl<T> From<u32> for Id<T> {
  fn from(id: u32) -> Self {
    Id::new(id)
  }
}

/// The scene type.
///
/// This type gathers all the required objects a scene needs to correctly handle and render all
/// visual effects.
pub struct Scene {
  /// Resource manager; used to handle scarce resources.
  res_manager: ResourceManager,
  /// All models used in the scene.
  models: Vec<Model>,
  /// Model cache used to resolve Id based on instance name.
  model_cache: HashMap<String, Id<Model>>,
  /// Model entities used in the scene, containing `Id` to the models of the scene.
  model_entities: HashMap<String, SceneModelEntity>
}

impl Scene {
  pub fn new<P>(root: P) -> Self where P: AsRef<Path>{
    Scene {
      res_manager: ResourceManager::new(root),
      models: Vec::new(),
      model_cache: HashMap::new(),
      model_entities: HashMap::new()
    }
  }

  pub fn get_id<T>(&mut self, name: &str) -> Option<Id<T>> where T: Get {
    T::get_id(self, name)
  }

  pub fn get<T>(&self, id: Id<T>) -> Option<&T> where T: Get {
    T::get(self, id)
  }

  pub fn resource_manager(&mut self) -> &mut ResourceManager {
    &mut self.res_manager
  }
}

pub enum SceneModelEntity {
  Static(Entity<Id<Model>>),
  Dynamic(Cont<'static, Entity<Id<Model>>>)
}

pub trait Get: Sized {
  fn get_id(scene: &mut Scene, name: &str) -> Option<Id<Self>>;
  fn get(scene: &Scene, id: Id<Self>) -> Option<&Self>;
}

impl Get for Model {
  fn get_id(scene: &mut Scene, name: &str) -> Option<Id<Self>> {
    match scene.model_cache.get(name).cloned() {
      id@Some(..) => {
        deb!("cache hit for model \"{}\"", name);
        id
      },
      None => {
        // cache miss; load then
        let path_str = format!("data/models/{}.obj", name);
        let path = Path::new(&path_str);

        deb!("cache miss for model \"{}\"", name);

        if path.exists() {
          match Model::load(&mut scene.res_manager, path) {
            Ok(model) => {
              let model_id: Id<Model> = (scene.models.len() as u32).into();

              // add the model to the list of loaded models
              scene.models.push(model);
              // add the model to the cache
              scene.model_cache.insert(name.to_owned(), model_id.clone());

              Some(model_id)
            },
            Err(e) => {
              err!("unable to load model '{}': '{:?}'", name, e);
              None
            }
          }
        } else { // TODO: add a manifest override to look in somewhere else
          err!("model '{}' cannot be found", name);
          None
        }
      }
    }
  }

  fn get(scene: &Scene, id: Id<Self>) -> Option<&Self> {
    scene.models.get(*id as usize)
  }
}
<|endoftext|>


<commit_before>use vga_buffer;
use memory;
use multiboot2;
use interrupts;
use device;

/// Enable the NXE bit to allow NO_EXECUTE pages.
fn enable_nxe_bit() {
    use x86_64::registers::msr::{IA32_EFER, rdmsr, wrmsr};

    let nxe_bit = 1 << 11;
    unsafe {
        let efer = rdmsr(IA32_EFER);
        wrmsr(IA32_EFER, efer | nxe_bit);
    }
}

/// This enables the write protect bit in order to enable write protection on kernel mode.
fn enable_write_protect_bit() {
    use x86_64::registers::control_regs::{cr0, cr0_write, Cr0};

    unsafe { cr0_write(cr0() | Cr0::WRITE_PROTECT) };
}

#[no_mangle]
/// Entry point for the Rust code
pub extern "C" fn rust_main(multiboot_information_address: usize) {

    // clear the console screen
    vga_buffer::clear_screen();

    // print out a welcome message
    println!("kernel: botting");

    let boot_info = unsafe { multiboot2::load(multiboot_information_address) };

    // enable NXE bit, to allow define none executable pages.
    enable_nxe_bit();

    // set write protect bit in order to enable write protection on kernel mode.
    enable_write_protect_bit();

    // set up guard page and map the heap pages
    let mut memory_controller = memory::init(boot_info);

    // Initialize IDT
    interrupts::init(&mut memory_controller);

    // Initialize devices
    device::init(&mut memory_controller);

    //  Allocation test
    for i in 0..1000 {
        println!("\n\nTesting hole allocator: {}",i);
        format!("Some String");
    }

    // TODO Read ACPI tables, starts APs

    // Initialize all the non-core devices
    device::init_non_core();

    println!("It did not crash!");

    loop {}
}
<commit_msg>Remove the allocator test<commit_after>use vga_buffer;
use memory;
use multiboot2;
use interrupts;
use device;

/// Enable the NXE bit to allow NO_EXECUTE pages.
fn enable_nxe_bit() {
    use x86_64::registers::msr::{IA32_EFER, rdmsr, wrmsr};

    let nxe_bit = 1 << 11;
    unsafe {
        let efer = rdmsr(IA32_EFER);
        wrmsr(IA32_EFER, efer | nxe_bit);
    }
}

/// This enables the write protect bit in order to enable write protection on kernel mode.
fn enable_write_protect_bit() {
    use x86_64::registers::control_regs::{cr0, cr0_write, Cr0};

    unsafe { cr0_write(cr0() | Cr0::WRITE_PROTECT) };
}

#[no_mangle]
/// Entry point for the Rust code
pub extern "C" fn rust_main(multiboot_information_address: usize) {

    // clear the console screen
    vga_buffer::clear_screen();

    // print out a welcome message
    println!("kernel: botting");

    let boot_info = unsafe { multiboot2::load(multiboot_information_address) };

    // enable NXE bit, to allow define none executable pages.
    enable_nxe_bit();

    // set write protect bit in order to enable write protection on kernel mode.
    enable_write_protect_bit();

    // set up guard page and map the heap pages
    let mut memory_controller = memory::init(boot_info);

    // Initialize IDT
    interrupts::init(&mut memory_controller);

    // Initialize devices
    device::init(&mut memory_controller);

    // TODO Read ACPI tables, starts APs

    // Initialize all the non-core devices
    device::init_non_core();

    println!("It did not crash!");

    loop {}
}
<|endoftext|>


<commit_before>
use ::prelude::*;

pub enum TestSetEntry {
    Test(&'static Fn() -> ()),
    Set(&'static TestSet),
}

pub use self::TestSetEntry::Test;
pub use self::TestSetEntry::Set;

pub type TestsT = &'static [(TestSetEntry, &'static str)];

pub trait TestSet {
    const TESTS: TestsT;
}

fn run_test_set<T: TestSet>() {
//    println!("running tests for \"{}\"", T::name());
//    println!("tests for \"{}\" ... OK", T::name());
}

pub fn test_all() {

    /*::fmt::tests::all();
    ::ioports::ioports_tests::all();
    ::utility::utility_tests::all();
    ::mem::paging::tests::all();
    ::mem::buddy::buddy_tests::all();*/
}

/// Sample of tests subcrate.
#[cfg(os_test)]
mod sample_tests {
    use ::tests::*;

    struct SampleTestSet;

    fn foo() {
        assert!(0 == 0);
    }

    fn bar() {
        assert!(5 < 7);
    }

    impl TestSet for SampleTestSet {
        const TESTS: TestsT = &[
            (Test(&foo), "sample1"),
            (Test(&bar), "sample2"),
        ];
    }
}

<commit_msg>too difficult testing system<commit_after>
use ::prelude::*;

pub enum TestSetEntry {
    Test(&'static Fn() -> ()),
    Set(&'static TestSet),
}

impl TestSetEntry {
    pub fn run(&self) {
        match self {
            &Test(f) => {
                f()
            },
            &Set(s) => s.run(),
        }
    }
}

pub use self::TestSetEntry::Test;
pub use self::TestSetEntry::Set;

pub type TestsT = &'static [(TestSetEntry, &'static str)];

pub trait TestSet {
    const TESTS: TestsT;
}

//fn run_test_set<T: TestSet>() {
//    for entry in T::TESTS {
//        entry
//    }
//}

pub fn test_all() {

    /*::fmt::tests::all();
    ::ioports::ioports_tests::all();
    ::utility::utility_tests::all();
    ::mem::paging::tests::all();
    ::mem::buddy::buddy_tests::all();*/
}

/// Sample of tests subcrate.
#[cfg(os_test)]
mod sample_tests {
    use ::tests::*;

    struct SampleTestSet;

    fn foo() {
        assert!(0 == 0);
    }

    fn bar() {
        assert!(5 < 7);
    }

    impl TestSet for SampleTestSet {
        const TESTS: TestsT = &[
            (Test(&foo), "sample1"),
            (Test(&bar), "sample2"),
        ];
    }
}

<|endoftext|>


<commit_before>use std::fmt;
use std::borrow::Cow;

use attr::AttributeList;
use escape::Escaped;

#[derive(Clone, Debug)]
pub enum Token<'a> {
    StartTag {
        name: Cow<'a, str>,
        attrs: AttributeList<'a>,
        /// Marker indicating self-closing tags such as `<br />`
        self_closing: bool,
    },
    EndTag {
        name: Cow<'a, str>,
    },
    /// The text contained will be escaped on `Display`.
    Text(Cow<'a, str>),
    /// The text contained will be `Display`ed as-is.
    RawText(Cow<'a, str>),
}

impl<'a> Token<'a> {
    pub fn start_tag<S>(name: S, attrs: AttributeList<'a>) -> Token<'a>
        where S: Into<Cow<'a, str>>
    {
        Token::StartTag {
            name: name.into(),
            attrs: attrs,
            self_closing: false,
        }
    }

    pub fn end_tag<S>(name: S) -> Token<'a>
        where S: Into<Cow<'a, str>>
    {
        Token::EndTag { name: name.into() }
    }

    pub fn text<S>(s: S) -> Token<'a>
        where S: Into<Cow<'a, str>>
    {
        Token::Text(s.into())
    }

    pub fn raw_text<S>(s: S) -> Token<'a>
        where S: Into<Cow<'a, str>>
    {
        Token::RawText(s.into())
    }

    /// If `self` is a `StartTag`, returns the `Token` after setting
    /// `self_closing` to `true`; otherwise, it is a no-op.
    pub fn closed(self) -> Token<'a> {
        if let Token::StartTag { name, attrs, .. } = self {
            Token::StartTag {
                name: name,
                attrs: attrs,
                self_closing: true,
            }
        } else {
            self
        }
    }
}

impl<'a> fmt::Display for Token<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Token::StartTag { ref name, ref attrs, self_closing } => {
                try!(write!(f, "<{}", name));
                for attr in attrs.iter() {
                    try!(write!(f, " {}", attr));
                }
                if self_closing {
                    write!(f, " />")
                } else {
                    write!(f, ">")
                }
            }
            Token::EndTag { ref name } => write!(f, "</{}>", name),
            Token::Text(ref text) => write!(f, "{}", Escaped(text)),
            Token::RawText(ref text) => write!(f, "{}", text),
        }
    }
}
<commit_msg>Add Token::Comment variant + tests<commit_after>use std::fmt;
use std::borrow::Cow;

use attr::AttributeList;
use escape::Escaped;

#[derive(Clone, Debug)]
pub enum Token<'a> {
    StartTag {
        name: Cow<'a, str>,
        attrs: AttributeList<'a>,
        /// Marker indicating self-closing tags such as `<br />`
        self_closing: bool,
    },
    EndTag {
        name: Cow<'a, str>,
    },
    /// The text contained will be escaped on `Display`.
    Text(Cow<'a, str>),
    /// The text contained will be `Display`ed as-is.
    RawText(Cow<'a, str>),
    /// For text contained within `<!--` and `-->`
    Comment(Cow<'a, str>),
}

impl<'a> Token<'a> {
    pub fn start_tag<S>(name: S, attrs: AttributeList<'a>) -> Token<'a>
        where S: Into<Cow<'a, str>>
    {
        Token::StartTag {
            name: name.into(),
            attrs: attrs,
            self_closing: false,
        }
    }

    pub fn end_tag<S>(name: S) -> Token<'a>
        where S: Into<Cow<'a, str>>
    {
        Token::EndTag { name: name.into() }
    }

    pub fn text<S>(s: S) -> Token<'a>
        where S: Into<Cow<'a, str>>
    {
        Token::Text(s.into())
    }

    pub fn raw_text<S>(s: S) -> Token<'a>
        where S: Into<Cow<'a, str>>
    {
        Token::RawText(s.into())
    }

    pub fn comment<S>(s: S) -> Token<'a>
        where S: Into<Cow<'a, str>>
    {
        Token::Comment(s.into())
    }

    /// If `self` is a `StartTag`, returns the `Token` after setting
    /// `self_closing` to `true`; otherwise, it is a no-op.
    pub fn closed(self) -> Token<'a> {
        if let Token::StartTag { name, attrs, .. } = self {
            Token::StartTag {
                name: name,
                attrs: attrs,
                self_closing: true,
            }
        } else {
            self
        }
    }
}

impl<'a> fmt::Display for Token<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Token::StartTag { ref name, ref attrs, self_closing } => {
                try!(write!(f, "<{}", name));
                for attr in attrs.iter() {
                    try!(write!(f, " {}", attr));
                }
                if self_closing {
                    write!(f, " />")
                } else {
                    write!(f, ">")
                }
            }
            Token::EndTag { ref name } => write!(f, "</{}>", name),
            Token::Text(ref text) => write!(f, "{}", Escaped(text)),
            Token::RawText(ref text) => write!(f, "{}", text),
            Token::Comment(ref text) => write!(f, "<!--{}-->", text),
        }
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn token_variants() {
        use Token;
        use attr::AttributeList;

        let start_tag = Token::start_tag("tag", AttributeList::empty());
        assert_eq!(format!("{}", start_tag), "<tag>");

        let end_tag = Token::end_tag("tag");
        assert_eq!(format!("{}", end_tag), "</tag>");

        let text = Token::text("<bomb>");
        assert_eq!(format!("{}", text), "<bomb>");

        let raw_text = Token::raw_text("<bomb>");
        assert_eq!(format!("{}", raw_text), "<bomb>");

        let comment = Token::comment("Multi\nline\ncomment");
        assert_eq!(format!("{}", comment), "<!--Multi\nline\ncomment-->");
    }
}
<|endoftext|>


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

use crate::traits::*;

pub type NewRootContext = fn(context_id: u32) -> Box<dyn RootContext>;
pub type NewStreamContext = fn(context_id: u32, root_context_id: u32) -> Box<dyn StreamContext>;
pub type NewHttpContext = fn(context_id: u32, root_context_id: u32) -> Box<dyn HttpContext>;

#[repr(u32)]
#[derive(Debug)]
pub enum LogLevel {
    Trace = 0,
    Debug = 1,
    Info = 2,
    Warn = 3,
    Error = 4,
    Critical = 5,
}

#[repr(u32)]
#[derive(Debug)]
pub enum Action {
    Continue = 0,
    Pause = 1,
}

#[repr(u32)]
#[derive(Debug)]
pub enum Status {
    Ok = 0,
    NotFound = 1,
    BadArgument = 2,
    Empty = 7,
    CasMismatch = 8,
    InternalFailure = 10,
}

#[repr(u32)]
#[derive(Debug)]
pub enum BufferType {
    HttpRequestBody = 0,
    HttpResponseBody = 1,
    DownstreamData = 2,
    UpstreamData = 3,
    HttpCallResponseBody = 4,
}

#[repr(u32)]
#[derive(Debug)]
pub enum MapType {
    HttpRequestHeaders = 0,
    HttpRequestTrailers = 1,
    HttpResponseHeaders = 2,
    HttpResponseTrailers = 3,
    HttpCallResponseHeaders = 7,
    HttpCallResponseTrailers = 8,
}

#[repr(u32)]
#[derive(Debug)]
pub enum PeerType {
    Unknown = 0,
    Local = 1,
    Remote = 2,
}

pub type Bytes = Vec<u8>;
<commit_msg>Update MapType values to match updated Proxy-Wasm ABI v0.1.0. (#7)<commit_after>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::traits::*;

pub type NewRootContext = fn(context_id: u32) -> Box<dyn RootContext>;
pub type NewStreamContext = fn(context_id: u32, root_context_id: u32) -> Box<dyn StreamContext>;
pub type NewHttpContext = fn(context_id: u32, root_context_id: u32) -> Box<dyn HttpContext>;

#[repr(u32)]
#[derive(Debug)]
pub enum LogLevel {
    Trace = 0,
    Debug = 1,
    Info = 2,
    Warn = 3,
    Error = 4,
    Critical = 5,
}

#[repr(u32)]
#[derive(Debug)]
pub enum Action {
    Continue = 0,
    Pause = 1,
}

#[repr(u32)]
#[derive(Debug)]
pub enum Status {
    Ok = 0,
    NotFound = 1,
    BadArgument = 2,
    Empty = 7,
    CasMismatch = 8,
    InternalFailure = 10,
}

#[repr(u32)]
#[derive(Debug)]
pub enum BufferType {
    HttpRequestBody = 0,
    HttpResponseBody = 1,
    DownstreamData = 2,
    UpstreamData = 3,
    HttpCallResponseBody = 4,
}

#[repr(u32)]
#[derive(Debug)]
pub enum MapType {
    HttpRequestHeaders = 0,
    HttpRequestTrailers = 1,
    HttpResponseHeaders = 2,
    HttpResponseTrailers = 3,
    HttpCallResponseHeaders = 6,
    HttpCallResponseTrailers = 7,
}

#[repr(u32)]
#[derive(Debug)]
pub enum PeerType {
    Unknown = 0,
    Local = 1,
    Remote = 2,
}

pub type Bytes = Vec<u8>;
<|endoftext|>


<commit_before>// This file is part of Grust, GObject introspection bindings for Rust
//
// Copyright (C) 2013, 2014  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

// This module provides types that are intrinsic in GIR, so they do not
// get defined through other types. It should ultimately have a name defined
// for every basic type listed in the documentation:
// https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations#Default_Basic_Types
//
// Exceptions are:
// 1. Fixed-size integer types. These have straightforward machine-independent
//    counterparts in Rust.
// 2. Strings annotated as "utf8" or "filename". These types are not named
//    as such in the C API. There is no limitation for an introspected API
//    against providing its own "utf8" or "filename", so these types are
//    disambiguated in the generated code by qualifying their names with
//    a separate module, gstr.
//
// Rust aliases are needed for machine-dependent basic types used in GIR,
// since the GLib types are not necessarily identical to their Rust namesakes
// (the issue similarly addressed by libc::c_int and the like).
// GIR uses the GLib names for these types as well.
//
// Any other GLib-derived types used by the bindings require some name
// disambiguation with definitions for the same C types that are emitted
// in "raw" namespaces of the generated GLib API crates (which are dependent,
// as any others, on the grust crate, so we cannot refer to their types here
// without creating a circular build dependency). Those type names should
// not be defined so as to be pulled in by 'use grust::types::*'.

#![allow(non_camel_case_types)]

use libc;

pub type gboolean       = libc::c_int;
pub type gchar          = libc::c_char;
pub type gint           = libc::c_int;
pub type guint          = libc::c_uint;
pub type gsize          = libc::size_t;
pub type gpointer       = *mut   libc::c_void;
pub type gconstpointer  = *const libc::c_void;

pub static FALSE: gboolean = 0;
pub static TRUE : gboolean = 1;
<commit_msg>Removed a murky and obsolete comment<commit_after>// This file is part of Grust, GObject introspection bindings for Rust
//
// Copyright (C) 2013, 2014  Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

// This module provides types that are intrinsic in GIR, so they do not
// get defined through other types. It should ultimately have a name defined
// for every basic type listed in the documentation:
// https://wiki.gnome.org/Projects/GObjectIntrospection/Annotations#Default_Basic_Types
//
// Exceptions are:
// 1. Fixed-size integer types. These have straightforward machine-independent
//    counterparts in Rust.
// 2. Strings annotated as "utf8" or "filename". These types are not named
//    as such in the C API. There is no limitation for an introspected API
//    against providing its own "utf8" or "filename", so these types are
//    disambiguated in the generated code by qualifying their names with
//    a separate module, gstr.
//
// Rust aliases are needed for machine-dependent basic types used in GIR,
// since the GLib types are not necessarily identical to their Rust namesakes
// (the issue similarly addressed by libc::c_int and the like).
// GIR uses the GLib names for these types as well.

#![allow(non_camel_case_types)]

use libc;

pub type gboolean       = libc::c_int;
pub type gchar          = libc::c_char;
pub type gint           = libc::c_int;
pub type guint          = libc::c_uint;
pub type gsize          = libc::size_t;
pub type gpointer       = *mut   libc::c_void;
pub type gconstpointer  = *const libc::c_void;

pub static FALSE: gboolean = 0;
pub static TRUE : gboolean = 1;
<|endoftext|>