<commit_before>use std::collections::HashMap;

use msgpack;
use redis;
use rustc_serialize;
use std::ascii::AsciiExt;

#[derive(Debug, Clone, PartialEq)]
enum EncoderStatus {
    Normal,
    Id,
    Reference(String),
}

#[derive(Debug, Clone)]
pub struct Encoder {
    pub id: usize,
    pub id_field: String,
    pub features: HashMap<String, String>,
    pub attributes: Vec<String>,
    status: EncoderStatus,
}

impl Encoder {
    pub fn new() -> Self {
        Encoder {
            id: 0,
            id_field: "".to_string(),
            features: HashMap::new(),
            attributes: vec![],
            status: EncoderStatus::Normal,
        }
    }
}

#[derive(Debug)]
pub enum EncoderError {
    NotImplementedYet,
    MissingField,
    UnknownStruct(String),
    RedisError(redis::RedisError),
    MsgPackError(msgpack::encode::serialize::Error),
}

impl From<redis::RedisError> for EncoderError {
    fn from(e: redis::RedisError) -> EncoderError {
        EncoderError::RedisError(e)
    }
}

impl From<msgpack::encode::serialize::Error> for EncoderError {
    fn from(e: msgpack::encode::serialize::Error) -> EncoderError {
        EncoderError::MsgPackError(e)
    }
}

pub type EncodeResult<T> = Result<T, EncoderError>;

macro_rules! emit_fmt {
    ($enc: ident, $e: expr) => {{
        $enc.attributes.push(format!("{}", $e));
        Ok(())
    }}
}

impl rustc_serialize::Encoder for Encoder {
    type Error = EncoderError;

    fn emit_nil(&mut self) -> EncodeResult<()> {
        self.attributes.pop();
        Ok(())
    }

    fn emit_usize(&mut self, v: usize) -> EncodeResult<()> {
        let s = format!("{}", v);
        match self.status {
            EncoderStatus::Normal => self.attributes.push(s),
            EncoderStatus::Id => {
                if s != "0" {
                    self.features.insert("id".to_string(), s);
                }
                self.attributes.pop();
            }
            EncoderStatus::Reference(ref field) => {
                self.attributes.push(format!("{}_id", &*field.to_ascii_lowercase()));
                self.attributes.push(s);
            }
        }
        self.status = EncoderStatus::Normal;
        Ok(())
    }

    fn emit_u64(&mut self, v: u64) -> EncodeResult<()> { emit_fmt!(self, v) }
    fn emit_u32(&mut self, v: u32) -> EncodeResult<()> { emit_fmt!(self, v) }
    fn emit_u16(&mut self, v: u16) -> EncodeResult<()> { emit_fmt!(self, v) }
    fn emit_u8(&mut self, v: u8) -> EncodeResult<()> { emit_fmt!(self, v) }

    fn emit_isize(&mut self, v: isize) -> EncodeResult<()> { emit_fmt!(self, v) }
    fn emit_i64(&mut self, v: i64) -> EncodeResult<()> { emit_fmt!(self, v) }
    fn emit_i32(&mut self, v: i32) -> EncodeResult<()> { emit_fmt!(self, v) }
    fn emit_i16(&mut self, v: i16) -> EncodeResult<()> { emit_fmt!(self, v) }
    fn emit_i8(&mut self, v: i8) -> EncodeResult<()> { emit_fmt!(self, v) }

    fn emit_bool(&mut self, v: bool) -> EncodeResult<()> { emit_fmt!(self, if v { 1 } else { 0 }) }

    fn emit_f64(&mut self, v: f64) -> EncodeResult<()> { emit_fmt!(self, v) }
    fn emit_f32(&mut self, v: f32) -> EncodeResult<()> { emit_fmt!(self, v) }

    fn emit_char(&mut self, v: char) -> EncodeResult<()> { emit_fmt!(self, v) }

    fn emit_str(&mut self, v: &str) -> EncodeResult<()> { emit_fmt!(self, v) }

    fn emit_enum<F>(&mut self, _: &str, _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }

    fn emit_enum_variant<F>(&mut self,
        _: &str,
        _: usize,
        _: usize,
        _: F)
        -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }

    fn emit_enum_variant_arg<F>(&mut self, _: usize, _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }

    fn emit_enum_struct_variant<F>(&mut self,
                                   _: &str,
                                   _: usize,
                                   _: usize,
                                   _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }

    fn emit_enum_struct_variant_field<F>(&mut self,
                                         _: &str,
                                         _: usize,
                                         _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }

    fn emit_struct<F>(&mut self, name: &str, _: usize, f: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        if self.features.contains_key("name") {
            match name {
                "Reference" => self.status = EncoderStatus::Reference(try!(self.attributes.pop().ok_or(EncoderError::MissingField))),
                _ => return Err(EncoderError::UnknownStruct(name.to_string())),
            }
            f(self)
        } else {
            self.features.insert("name".to_string(), name.to_string());
            f(self)
        }
    }

    fn emit_struct_field<F>(&mut self, name: &str, _: usize, f: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        if self.status == EncoderStatus::Normal && name == "id" {
            self.status = EncoderStatus::Id;
        } else {
            self.attributes.push(name.to_string());
        }
        f(self)
    }

    fn emit_tuple<F>(&mut self, _: usize, _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }

    fn emit_tuple_arg<F>(&mut self, _: usize, _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }

    fn emit_tuple_struct<F>(&mut self, _: &str, _: usize, _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }
    fn emit_tuple_struct_arg<F>(&mut self, _: usize, _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }

    fn emit_option<F>(&mut self, f: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        f(self)
    }

    fn emit_option_none(&mut self) -> EncodeResult<()> {
        self.emit_nil()
    }

    fn emit_option_some<F>(&mut self, f: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        f(self)
    }

    fn emit_seq<F>(&mut self, _: usize, _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }

    fn emit_seq_elt<F>(&mut self, _: usize, _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }

    fn emit_map<F>(&mut self, _: usize, _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }

    fn emit_map_elt_key<F>(&mut self, _: usize, _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }

    fn emit_map_elt_val<F>(&mut self, _: usize, _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }
}

pub fn msgpack_encode<T: rustc_serialize::Encodable>(t: &T) -> Result<Vec<u8>, msgpack::encode::serialize::Error> {
    let mut buf = Vec::new();
    try!(t.encode(&mut msgpack::Encoder::new(&mut buf)));
    Ok(buf)
}
<commit_msg>Un-hardcode "id"<commit_after>use std::collections::HashMap;

use msgpack;
use redis;
use rustc_serialize;
use std::ascii::AsciiExt;

#[derive(Debug, Clone, PartialEq)]
enum EncoderStatus {
    Normal,
    Id,
    Reference(String),
}

#[derive(Debug, Clone)]
pub struct Encoder {
    pub id: usize,
    pub id_field: String,
    pub features: HashMap<String, String>,
    pub attributes: Vec<String>,
    status: EncoderStatus,
}

impl Encoder {
    pub fn new() -> Self {
        Encoder {
            id: 0,
            id_field: "".to_string(),
            features: HashMap::new(),
            attributes: vec![],
            status: EncoderStatus::Normal,
        }
    }
}

#[derive(Debug)]
pub enum EncoderError {
    NotImplementedYet,
    MissingField,
    UnknownStruct(String),
    RedisError(redis::RedisError),
    MsgPackError(msgpack::encode::serialize::Error),
}

impl From<redis::RedisError> for EncoderError {
    fn from(e: redis::RedisError) -> EncoderError {
        EncoderError::RedisError(e)
    }
}

impl From<msgpack::encode::serialize::Error> for EncoderError {
    fn from(e: msgpack::encode::serialize::Error) -> EncoderError {
        EncoderError::MsgPackError(e)
    }
}

pub type EncodeResult<T> = Result<T, EncoderError>;

macro_rules! emit_fmt {
    ($enc: ident, $e: expr) => {{
        $enc.attributes.push(format!("{}", $e));
        Ok(())
    }}
}

impl rustc_serialize::Encoder for Encoder {
    type Error = EncoderError;

    fn emit_nil(&mut self) -> EncodeResult<()> {
        self.attributes.pop();
        Ok(())
    }

    fn emit_usize(&mut self, v: usize) -> EncodeResult<()> {
        let s = format!("{}", v);
        match self.status {
            EncoderStatus::Normal => self.attributes.push(s),
            EncoderStatus::Id => {
                if s != "0" {
                    self.features.insert(self.id_field.clone(), s);
                }
                self.attributes.pop();
            }
            EncoderStatus::Reference(ref field) => {
                self.attributes.push(format!("{}_id", &*field.to_ascii_lowercase()));
                self.attributes.push(s);
            }
        }
        self.status = EncoderStatus::Normal;
        Ok(())
    }

    fn emit_u64(&mut self, v: u64) -> EncodeResult<()> { emit_fmt!(self, v) }
    fn emit_u32(&mut self, v: u32) -> EncodeResult<()> { emit_fmt!(self, v) }
    fn emit_u16(&mut self, v: u16) -> EncodeResult<()> { emit_fmt!(self, v) }
    fn emit_u8(&mut self, v: u8) -> EncodeResult<()> { emit_fmt!(self, v) }

    fn emit_isize(&mut self, v: isize) -> EncodeResult<()> { emit_fmt!(self, v) }
    fn emit_i64(&mut self, v: i64) -> EncodeResult<()> { emit_fmt!(self, v) }
    fn emit_i32(&mut self, v: i32) -> EncodeResult<()> { emit_fmt!(self, v) }
    fn emit_i16(&mut self, v: i16) -> EncodeResult<()> { emit_fmt!(self, v) }
    fn emit_i8(&mut self, v: i8) -> EncodeResult<()> { emit_fmt!(self, v) }

    fn emit_bool(&mut self, v: bool) -> EncodeResult<()> { emit_fmt!(self, if v { 1 } else { 0 }) }

    fn emit_f64(&mut self, v: f64) -> EncodeResult<()> { emit_fmt!(self, v) }
    fn emit_f32(&mut self, v: f32) -> EncodeResult<()> { emit_fmt!(self, v) }

    fn emit_char(&mut self, v: char) -> EncodeResult<()> { emit_fmt!(self, v) }

    fn emit_str(&mut self, v: &str) -> EncodeResult<()> { emit_fmt!(self, v) }

    fn emit_enum<F>(&mut self, _: &str, _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }

    fn emit_enum_variant<F>(&mut self,
        _: &str,
        _: usize,
        _: usize,
        _: F)
        -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }

    fn emit_enum_variant_arg<F>(&mut self, _: usize, _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }

    fn emit_enum_struct_variant<F>(&mut self,
                                   _: &str,
                                   _: usize,
                                   _: usize,
                                   _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }

    fn emit_enum_struct_variant_field<F>(&mut self,
                                         _: &str,
                                         _: usize,
                                         _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }

    fn emit_struct<F>(&mut self, name: &str, _: usize, f: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        if self.features.contains_key("name") {
            match name {
                "Reference" => self.status = EncoderStatus::Reference(try!(self.attributes.pop().ok_or(EncoderError::MissingField))),
                _ => return Err(EncoderError::UnknownStruct(name.to_string())),
            }
            f(self)
        } else {
            self.features.insert("name".to_string(), name.to_string());
            f(self)
        }
    }

    fn emit_struct_field<F>(&mut self, name: &str, _: usize, f: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        if self.status == EncoderStatus::Normal && name == self.id_field {
            self.status = EncoderStatus::Id;
        } else {
            self.attributes.push(name.to_string());
        }
        f(self)
    }

    fn emit_tuple<F>(&mut self, _: usize, _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }

    fn emit_tuple_arg<F>(&mut self, _: usize, _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }

    fn emit_tuple_struct<F>(&mut self, _: &str, _: usize, _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }
    fn emit_tuple_struct_arg<F>(&mut self, _: usize, _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }

    fn emit_option<F>(&mut self, f: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        f(self)
    }

    fn emit_option_none(&mut self) -> EncodeResult<()> {
        self.emit_nil()
    }

    fn emit_option_some<F>(&mut self, f: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        f(self)
    }

    fn emit_seq<F>(&mut self, _: usize, _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }

    fn emit_seq_elt<F>(&mut self, _: usize, _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }

    fn emit_map<F>(&mut self, _: usize, _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }

    fn emit_map_elt_key<F>(&mut self, _: usize, _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }

    fn emit_map_elt_val<F>(&mut self, _: usize, _: F) -> EncodeResult<()> where
        F: FnOnce(&mut Encoder) -> EncodeResult<()>,
    {
        Err(EncoderError::NotImplementedYet)
    }
}

pub fn msgpack_encode<T: rustc_serialize::Encodable>(t: &T) -> Result<Vec<u8>, msgpack::encode::serialize::Error> {
    let mut buf = Vec::new();
    try!(t.encode(&mut msgpack::Encoder::new(&mut buf)));
    Ok(buf)
}
<|endoftext|>


<commit_before>use std::ptr;
use glib::Error;
use glib::object::{Object, Upcast, Wrapper, Ref};
use glib::types::{StaticType, Type};
use glib::translate::*;
use glib::glib_container::GlibContainer;
use secret_service::SecretService;
use secret_item::SecretItem;
use SecretResult;
use util::{lock_object, unlock_object};
use Lock;
use ffi;

/// SecretCollection represents a collection of secret items stored in the Secret Service.
/// A collection can be in a locked or unlocked state. Use `Lock::lock()` or `Lock::unlock()` to lock or unlock the collection.
/// Use `get_items()` to lookup the items in the collection. There may not be any items exposed when the collection is locked.
pub struct SecretCollection(Ref);

impl SecretCollection {

    /// Lookup which collection is assigned to this alias.
    /// Aliases help determine well known collections, such as 'default'.
    /// Returns the collection, or NULL if none assigned to the alias.
    pub fn for_alias(alias: &str) -> SecretResult<SecretCollection>{
        let mut err = ptr::null_mut();
        let ptr = unsafe{ffi::secret_collection_for_alias_sync(ptr::null_mut(), alias.to_glib_none().0, SECRET_COLLECTION_LOAD_ITEMS, ptr::null_mut(), &mut err)};
        if err.is_null(){
            Ok(unsafe { from_glib_full(ptr) })
        } else {
            Err(Error::wrap(err))
        }
    }

    /// Create a new collection in the secret service.
    /// If you specify an alias and a collection with that alias already exists, then a new collection will not be created. The previous one will be returned instead.
    /// Returns the created Collection.
    pub fn create(label: &str, alias: Option<&str>) -> SecretResult<SecretCollection> {
        let mut err = ptr::null_mut();
        let ptr = unsafe{ffi::secret_collection_create_sync(ptr::null_mut(), label.to_glib_none().0, alias.to_glib_none().0, 0, ptr::null_mut(), &mut err)};
        if err.is_null(){
            Ok(unsafe { from_glib_full(ptr) })
        } else {
            Err(Error::wrap(err))
        }
    }

    /// Get the created date and time of the collection.
    /// The return value is the number of seconds since the unix epoch, January 1st 1970.
    pub fn get_created(&self) -> u64 {
        unsafe {ffi::secret_collection_get_created(self.to_glib_none().0)}
    }

    /// Get the modified date and time of the collection.
    /// The return value is the number of seconds since the unix epoch, January 1st 1970.
    pub fn get_modified(&self) -> u64 {
        unsafe {ffi::secret_collection_get_modified(self.to_glib_none().0)}
    }

    /// Get the Secret Service object that this collection was created with.
    pub fn get_service(&self) -> SecretService { //TODO find out if this can return null
        unsafe {
            let ptr = ffi::secret_collection_get_service(self.to_glib_none().0);
            from_glib_none(ptr)
        }
    }

    /// Get if the items are currently loaded. Use `load_items()` to load them.
    pub fn are_items_loaded(&self) -> bool {
        let flags = unsafe {ffi::secret_collection_get_flags(self.to_glib_none().0)};
        flags & SECRET_COLLECTION_LOAD_ITEMS != 0
    }

    /// Get the label of this collection.
    pub fn get_label(&self) -> String {
        unsafe{
            let ptr = ffi::secret_collection_get_label(self.to_glib_none().0);
            from_glib_full(ptr)
        }
    }

    /// Get the SecretItems of the collection
    pub fn get_items(&self) -> Vec<SecretItem> {
        unsafe {
            let glist = ffi::secret_collection_get_items(self.to_glib_none().0);
            Vec::from_glib_full(glist)
        }
    }

    /// Ensure that the SecretCollection proxy has loaded all the items present in the Secret Service.
    pub fn load_items(&self) -> SecretResult<()>{
        unsafe {
            let mut err = ptr::null_mut();
            ffi::secret_collection_load_items_sync(self.to_glib_none().0, ptr::null_mut(), &mut err);
            if err.is_null() {
                Ok(())
            } else {
                Err(Error::wrap(err))
            }
        }
    }

    /// Assign the collection to this alias. Aliases help determine well known collections, such as 'default'.
    pub fn set_alias(&self, alias: &str) -> SecretResult<()>{
        unsafe {
            let mut err = ptr::null_mut();
            ffi::secret_service_set_alias_sync(ptr::null_mut(), alias.to_glib_none().0, self.to_glib_none().0, ptr::null_mut(), &mut err);
            if err.is_null() {
                Ok(())
            } else {
                Err(Error::wrap(err))
            }
        }
    }

    /// Check if the collection is currently locked.
    pub fn is_locked(&self) -> bool {
        let gbool = unsafe {
            ffi::secret_collection_get_locked(self.to_glib_none().0)
        };
        from_glib(gbool)
    }
}

impl StaticType for SecretCollection {
    fn static_type() -> Type{
        unsafe { from_glib(ffi::secret_collection_get_type()) }
    }
}

unsafe impl Upcast<Object> for SecretCollection { }

impl Wrapper for SecretCollection {
    type GlibType = ffi::SecretCollection;
    unsafe fn wrap(r: Ref) -> Self{
        SecretCollection(r)
    }

    fn as_ref(&self) -> &Ref{
        &self.0
    }

    fn unwrap(self) -> Ref{
        self.0
    }
}

impl Lock<SecretCollection> for SecretCollection {

    fn lock(&self) -> SecretResult<Vec<SecretCollection>>{
        lock_object::<SecretCollection>(self)
    }

    fn unlock(&self) -> SecretResult<Vec<SecretCollection>>{
        unlock_object::<SecretCollection>(self)
    }
}

#[allow(dead_code)]
const SECRET_COLLECTION_NONE: i32        = 0;
const SECRET_COLLECTION_LOAD_ITEMS: i32  = 1 << 1;
<commit_msg>Implement SecretCollection::delete<commit_after>use std::ptr;
use glib::Error;
use glib::object::{Object, Upcast, Wrapper, Ref};
use glib::types::{StaticType, Type};
use glib::translate::*;
use glib::glib_container::GlibContainer;
use secret_service::SecretService;
use secret_item::SecretItem;
use SecretResult;
use util::{lock_object, unlock_object};
use Lock;
use ffi;

/// SecretCollection represents a collection of secret items stored in the Secret Service.
/// A collection can be in a locked or unlocked state. Use `Lock::lock()` or `Lock::unlock()` to lock or unlock the collection.
/// Use `get_items()` to lookup the items in the collection. There may not be any items exposed when the collection is locked.
pub struct SecretCollection(Ref);

impl SecretCollection {

    /// Lookup which collection is assigned to this alias.
    /// Aliases help determine well known collections, such as 'default'.
    /// Returns the collection, or NULL if none assigned to the alias.
    pub fn for_alias(alias: &str) -> SecretResult<SecretCollection>{
        let mut err = ptr::null_mut();
        let ptr = unsafe{ffi::secret_collection_for_alias_sync(ptr::null_mut(), alias.to_glib_none().0, SECRET_COLLECTION_LOAD_ITEMS, ptr::null_mut(), &mut err)};
        if err.is_null(){
            Ok(unsafe { from_glib_full(ptr) })
        } else {
            Err(Error::wrap(err))
        }
    }

    /// Create a new collection in the secret service.
    /// If you specify an alias and a collection with that alias already exists, then a new collection will not be created. The previous one will be returned instead.
    /// Returns the created Collection.
    pub fn create(label: &str, alias: Option<&str>) -> SecretResult<SecretCollection> {
        let mut err = ptr::null_mut();
        let ptr = unsafe{ffi::secret_collection_create_sync(ptr::null_mut(), label.to_glib_none().0, alias.to_glib_none().0, 0, ptr::null_mut(), &mut err)};
        if err.is_null(){
            Ok(unsafe { from_glib_full(ptr) })
        } else {
            Err(Error::wrap(err))
        }
    }

    /// Delete this collection.
    /// The Secret Service may prompt the user.
    pub fn delete(&self) -> SecretResult<()>{
        let mut err = ptr::null_mut();
        unsafe{ffi::secret_collection_delete_sync(self.to_glib_none().0, ptr::null_mut(), &mut err)};
        if err.is_null(){
            Ok(())
        } else {
            Err(Error::wrap(err))
        }
    }

    /// Get the created date and time of the collection.
    /// The return value is the number of seconds since the unix epoch, January 1st 1970.
    pub fn get_created(&self) -> u64 {
        unsafe {ffi::secret_collection_get_created(self.to_glib_none().0)}
    }

    /// Get the modified date and time of the collection.
    /// The return value is the number of seconds since the unix epoch, January 1st 1970.
    pub fn get_modified(&self) -> u64 {
        unsafe {ffi::secret_collection_get_modified(self.to_glib_none().0)}
    }

    /// Get the Secret Service object that this collection was created with.
    pub fn get_service(&self) -> SecretService { //TODO find out if this can return null
        unsafe {
            let ptr = ffi::secret_collection_get_service(self.to_glib_none().0);
            from_glib_none(ptr)
        }
    }

    /// Get if the items are currently loaded. Use `load_items()` to load them.
    pub fn are_items_loaded(&self) -> bool {
        let flags = unsafe {ffi::secret_collection_get_flags(self.to_glib_none().0)};
        flags & SECRET_COLLECTION_LOAD_ITEMS != 0
    }

    /// Get the label of this collection.
    pub fn get_label(&self) -> String {
        unsafe{
            let ptr = ffi::secret_collection_get_label(self.to_glib_none().0);
            from_glib_full(ptr)
        }
    }

    /// Get the SecretItems of the collection
    pub fn get_items(&self) -> Vec<SecretItem> {
        unsafe {
            let glist = ffi::secret_collection_get_items(self.to_glib_none().0);
            Vec::from_glib_full(glist)
        }
    }

    /// Ensure that the SecretCollection proxy has loaded all the items present in the Secret Service.
    pub fn load_items(&self) -> SecretResult<()>{
        unsafe {
            let mut err = ptr::null_mut();
            ffi::secret_collection_load_items_sync(self.to_glib_none().0, ptr::null_mut(), &mut err);
            if err.is_null() {
                Ok(())
            } else {
                Err(Error::wrap(err))
            }
        }
    }

    /// Assign the collection to this alias. Aliases help determine well known collections, such as 'default'.
    pub fn set_alias(&self, alias: &str) -> SecretResult<()>{
        unsafe {
            let mut err = ptr::null_mut();
            ffi::secret_service_set_alias_sync(ptr::null_mut(), alias.to_glib_none().0, self.to_glib_none().0, ptr::null_mut(), &mut err);
            if err.is_null() {
                Ok(())
            } else {
                Err(Error::wrap(err))
            }
        }
    }

    /// Check if the collection is currently locked.
    pub fn is_locked(&self) -> bool {
        let gbool = unsafe {
            ffi::secret_collection_get_locked(self.to_glib_none().0)
        };
        from_glib(gbool)
    }
}

impl StaticType for SecretCollection {
    fn static_type() -> Type{
        unsafe { from_glib(ffi::secret_collection_get_type()) }
    }
}

unsafe impl Upcast<Object> for SecretCollection { }

impl Wrapper for SecretCollection {
    type GlibType = ffi::SecretCollection;
    unsafe fn wrap(r: Ref) -> Self{
        SecretCollection(r)
    }

    fn as_ref(&self) -> &Ref{
        &self.0
    }

    fn unwrap(self) -> Ref{
        self.0
    }
}

impl Lock<SecretCollection> for SecretCollection {

    fn lock(&self) -> SecretResult<Vec<SecretCollection>>{
        lock_object::<SecretCollection>(self)
    }

    fn unlock(&self) -> SecretResult<Vec<SecretCollection>>{
        unlock_object::<SecretCollection>(self)
    }
}

#[allow(dead_code)]
const SECRET_COLLECTION_NONE: i32        = 0;
const SECRET_COLLECTION_LOAD_ITEMS: i32  = 1 << 1;
<|endoftext|>


<commit_before>// Copyright 2015-2018 Benjamin Fry <benjaminfry@me.com>
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

//! `DnsResponse` wraps a `Message` and any associated connection details

use std::ops::{Deref, DerefMut};
use std::slice::{Iter, IterMut};

use smallvec::SmallVec;

use op::Message;

/// A DNS response object
///
/// For Most DNS requests, only one response is expected, the exception is a multicast request.
#[derive(Clone, Debug)]
pub struct DnsResponse(SmallVec<[Message; 1]>);

// TODO: when `impl Trait` lands in stable, remove this, and expose FlatMap over answers, et al.
impl DnsResponse {
    /// Get all the messages in the Response
    pub fn messages(&self) -> Iter<Message> {
        self.0.as_slice().iter()
    }

    /// Get all the messages in the Response
    pub fn messages_mut(&mut self) -> IterMut<Message> {
        self.0.as_mut_slice().iter_mut()
    }

    /// returns the number of messages in the response
    pub fn len(&self) -> usize {
        self.0.len()
    }
}

impl Deref for DnsResponse {
    type Target = Message;

    fn deref(&self) -> &Self::Target {
        debug_assert!(self.len() == 1, "There is more than one message in the response, this code path needs to deal with that");
        &self.0[0]
    }
}

impl DerefMut for DnsResponse {
    fn deref_mut(&mut self) -> &mut Self::Target {
        debug_assert!(self.len() == 1, "There is more than one message in the response, this code path needs to deal with that");
        &mut self.0[0]
    }
}

impl From<DnsResponse> for Message {
    fn from(mut response: DnsResponse) -> Message {
        // there should be no way to create an empty smallvec
        debug_assert!(response.len() == 1, "There is more than one message in the response, this code path needs to deal with that");
        response.0.remove(0)
    }
}

impl From<Message> for DnsResponse {
    fn from(message: Message) -> DnsResponse {
        DnsResponse(SmallVec::from([message]))
    }
}

impl From<SmallVec<[Message; 1]>> for DnsResponse {
    fn from(messages: SmallVec<[Message; 1]>) -> DnsResponse {
        debug_assert!(
            !messages.is_empty(),
            "There should be at least one message in any DnsResponse"
        );
        DnsResponse(messages)
    }
}
<commit_msg>remove panics on Deref(Message) from DnsResponse<commit_after>// Copyright 2015-2018 Benjamin Fry <benjaminfry@me.com>
//
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.

//! `DnsResponse` wraps a `Message` and any associated connection details

use std::ops::{Deref, DerefMut};
use std::slice::{Iter, IterMut};

use smallvec::SmallVec;

use op::Message;

// FIXME: see https://github.com/bluejekyll/trust-dns/issues/383 for removing vec of messages and instead returning a Stream
/// A DNS response object
///
/// For Most DNS requests, only one response is expected, the exception is a multicast request.
#[derive(Clone, Debug)]
pub struct DnsResponse(SmallVec<[Message; 1]>);

// TODO: when `impl Trait` lands in stable, remove this, and expose FlatMap over answers, et al.
impl DnsResponse {
    /// Get all the messages in the Response
    pub fn messages(&self) -> Iter<Message> {
        self.0.as_slice().iter()
    }

    /// Get all the messages in the Response
    pub fn messages_mut(&mut self) -> IterMut<Message> {
        self.0.as_mut_slice().iter_mut()
    }

    /// returns the number of messages in the response
    pub fn len(&self) -> usize {
        self.0.len()
    }
}

impl Deref for DnsResponse {
    type Target = Message;

    fn deref(&self) -> &Self::Target {
        &self.0[0]
    }
}

impl DerefMut for DnsResponse {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0[0]
    }
}

impl From<DnsResponse> for Message {
    fn from(mut response: DnsResponse) -> Message {
        response.0.remove(0)
    }
}

impl From<Message> for DnsResponse {
    fn from(message: Message) -> DnsResponse {
        DnsResponse(SmallVec::from([message]))
    }
}

impl From<SmallVec<[Message; 1]>> for DnsResponse {
    fn from(messages: SmallVec<[Message; 1]>) -> DnsResponse {
        debug_assert!(
            !messages.is_empty(),
            "There should be at least one message in any DnsResponse"
        );
        DnsResponse(messages)
    }
}
<|endoftext|>


<commit_before>use ::source::{Source, SourceError};

use handlebars::Handlebars;
use walkdir::{WalkDir, DirEntry};

pub struct DirectorySource {
    pub prefix: String,
    pub suffix: String
}

impl DirectorySource {
    pub fn new(prefix: &str, suffix: &str) -> DirectorySource {
        let mut prefix_owned = prefix.to_owned();
        // append tailing slash
        if ! prefix_owned.ends_with("/") {
            prefix_owned.push_str("/");
        }
        DirectorySource {
            prefix: prefix_owned,
            suffix: suffix.to_owned()
        }
    }
}

fn filter_file(entry: &DirEntry, suffix: &str) -> bool {
    entry.file_name().to_str()
        .map(|s| s.starts_with(".") || s.starts_with("#") || !s.ends_with(suffix))
        .unwrap_or(false)
}

impl Source for DirectorySource {
    fn load(&self, reg: &mut Handlebars) -> Result<(), SourceError> {
        let suffix_len = self.suffix.len();
        let prefix_len = self.prefix.len();

        info!("Loading templates from path {}", self.prefix);
        let walker = WalkDir::new(&self.prefix);
        for p in walker.min_depth(1).into_iter().filter(|e| e.is_ok() && !filter_file(e.as_ref().unwrap(), &self.suffix)).map(|e| e.unwrap()) {
            let tpl_path = p.path();
            let tpl_file_path = p.path().to_string_lossy();
            let tpl_name = &tpl_file_path[prefix_len .. tpl_file_path.len() - suffix_len];
            let tpl_canonical_name = tpl_name.replace("\\", "/");
            debug!("getting file {}", tpl_file_path);
            debug!("register template {}", tpl_name);
            try!(reg.register_template_file(&tpl_canonical_name, &tpl_path))
        }
        Ok(())
    }
}
<commit_msg>(feat) change path type to osstring [#62]<commit_after>use std::path::PathBuf;
use std::ffi::{OsString, OsStr};

use source::{Source, SourceError};

use handlebars::Handlebars;
use walkdir::{WalkDir, DirEntry};

pub struct DirectorySource {
    pub prefix: OsString,
    pub suffix: OsString,
}

impl DirectorySource {
    pub fn new<P>(prefix: P, suffix: P) -> DirectorySource
        where P: Into<PathBuf>
    {
        DirectorySource {
            prefix: prefix.into().into_os_string(),
            suffix: suffix.into().into_os_string(),
        }
    }
}

fn filter_file(entry: &DirEntry, suffix: &OsStr) -> bool {
    let path = entry.path();

    path.starts_with(".") || path.starts_with("#") || !path.ends_with(suffix)
}

impl Source for DirectorySource {
    fn load(&self, reg: &mut Handlebars) -> Result<(), SourceError> {
        let suffix_len = self.suffix.len();
        let prefix_len = self.prefix.len();

        info!("Loading templates from path {:?}", self.prefix);
        let walker = WalkDir::new(&self.prefix);
        for p in walker
                .min_depth(1)
                .into_iter()
                .filter(|e| e.is_ok() && !filter_file(e.as_ref().unwrap(), &self.suffix))
                .map(|e| e.unwrap()) {
            let tpl_path = p.path();
            let tpl_file_path = p.path().to_string_lossy();
            let tpl_name = &tpl_file_path[prefix_len..tpl_file_path.len() - suffix_len];
            let tpl_canonical_name = tpl_name.replace("\\", "/");
            debug!("getting file {:?}", tpl_file_path);
            debug!("register template {:?}", tpl_name);
            try!(reg.register_template_file(&tpl_canonical_name, &tpl_path))
        }
        Ok(())
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2015-2016 Ivo Wetzel

// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::net;
use std::fmt;
use std::thread;
use std::io::Error;
use std::sync::mpsc::{channel, Receiver, Sender, TryRecvError};
use super::super::traits::socket::Socket;

/// Non-blocking abstraction over a UDP socket.
///
/// The non-blocking behavior is implement by using a internal reader thread.
///
/// The implementation guarantees that the internal thread exits cleanly in
/// case of either the sockets shutdown or it getting dropped.
///
/// This will be subject to change when support for socket timeouts lands in
/// rust 1.4. We will most likely switch to a timeout based, synchronous read
/// loop by then.
pub struct UdpSocket {
    socket: net::UdpSocket,
    reader_thread: Option<thread::JoinHandle<()>>,
    udp_receiver: Receiver<(net::SocketAddr, Vec<u8>)>,
    close_sender: Sender<()>
}

impl UdpSocket {

    /// Tries to create a new UDP socket by binding to the specified address.
    pub fn new<T: net::ToSocketAddrs>(
        address: T, max_packet_size: usize

    ) -> Result<Self, Error> {

        // Create the send socket
        let sender = try!(net::UdpSocket::bind(address));

        // Clone the socket handle for use inside the reader thread
        let reader = try!(sender.try_clone());

        // Create communication channels
        let (s_udp, r_udp) = channel::<(net::SocketAddr, Vec<u8>)>();
        let (s_close, r_close) = channel::<()>();

        // Create Reader Thread
        let reader_thread = thread::spawn(move|| {

            // Allocate buffer for the maximum packet size
            let mut buffer = Vec::with_capacity(max_packet_size);
            for _ in 0..max_packet_size {
                buffer.push(0);
            }

            loop  {

                // Receive packets...
                if let Ok((len, src)) = reader.recv_from(&mut buffer) {

                    // ...until shutdown is received
                    if let Ok(_) = r_close.try_recv() {
                        break;

                    // Copy only the actual number of bytes and send them
                    // along with the source address
                    } else {
                        s_udp.send((
                            src,
                            buffer[..len].iter().cloned().collect()

                        )).ok();
                    }

                }

            }

        });

        // Return the combined structure
        Ok(UdpSocket {
            socket: sender,
            reader_thread: Some(reader_thread),
            udp_receiver: r_udp,
            close_sender: s_close
        })

    }

}

impl Socket for UdpSocket {

    /// Attempts to return a incoming packet on this socket without blocking.
    fn try_recv(&self) -> Result<(net::SocketAddr, Vec<u8>), TryRecvError> {
        self.udp_receiver.try_recv()
    }

    /// Send data on the socket to the given address. On success, returns the
    /// number of bytes written.
    fn send_to(
        &mut self, data: &[u8], addr: net::SocketAddr)

    -> Result<usize, Error> {
        self.socket.send_to(data, addr)
    }

    /// Returns the socket address of the underlying `net::UdpSocket`.
    fn local_addr(&self) -> Result<net::SocketAddr, Error> {
        self.socket.local_addr()
    }

    /// Shuts down the socket by stopping its internal reader thread.
    fn shutdown(&mut self) {

        // Only shutdown if we still got a reader thread
        if let Some(reader_thread) = self.reader_thread.take() {

            // Notify the reader thread to exit
            self.close_sender.send(()).unwrap();

            // Then send a empty packet to the reader socket
            // so its recv_from() unblocks
            let socket = net::UdpSocket::bind("0.0.0.0:0").expect(
                "Failed to create local socket for closure."
            );

            let empty_packet: [u8; 0] = [0; 0];
            socket.send_to(
                &empty_packet, self.local_addr().unwrap()

            ).expect("Failed to send closure packet.");

            // Finally wait for the reader thread to exit cleanly
            reader_thread.join().unwrap();

        }

    }

}

impl Drop for UdpSocket {
    fn drop(&mut self) {
        // Make sure to exit the internal thread cleanly
        self.shutdown();
    }
}

impl fmt::Debug for UdpSocket {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "UdpSocket({:?})", self.socket)
    }
}

<commit_msg>Set read timeout on udp sockets in order to allow for clean shutdown on windows.<commit_after>// Copyright (c) 2015-2016 Ivo Wetzel

// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::net;
use std::fmt;
use std::thread;
use std::time::Duration;
use std::io::Error;
use std::sync::mpsc::{channel, Receiver, Sender, TryRecvError};
use super::super::traits::socket::Socket;

/// Non-blocking abstraction over a UDP socket.
///
/// The non-blocking behavior is implement by using a internal reader thread.
pub struct UdpSocket {
    socket: net::UdpSocket,
    reader_thread: Option<thread::JoinHandle<()>>,
    udp_receiver: Receiver<(net::SocketAddr, Vec<u8>)>,
    close_sender: Sender<()>
}

impl UdpSocket {

    /// Tries to create a new UDP socket by binding to the specified address.
    pub fn new<T: net::ToSocketAddrs>(
        address: T, max_packet_size: usize

    ) -> Result<Self, Error> {

        // Create the send socket
        let sender = try!(net::UdpSocket::bind(address));

        // Clone the socket handle for use inside the reader thread
        let reader = try!(sender.try_clone());
        try!(reader.set_read_timeout(Some(Duration::from_millis(10))));

        // Create communication channels
        let (s_udp, r_udp) = channel::<(net::SocketAddr, Vec<u8>)>();
        let (s_close, r_close) = channel::<()>();

        // Create Reader Thread
        let reader_thread = thread::spawn(move|| {

            // Allocate buffer for the maximum packet size
            let mut buffer = Vec::with_capacity(max_packet_size);
            for _ in 0..max_packet_size {
                buffer.push(0);
            }

            loop {

                // Receive packets...
                if let Ok((len, src)) = reader.recv_from(&mut buffer) {

                    // Copy only the actual number of bytes and send them
                    // along with the source address
                    s_udp.send((
                        src,
                        buffer[..len].iter().cloned().collect()

                    )).ok();

                // ...until shutdown is received
                } else if let Ok(_) = r_close.try_recv() {
                    break;
                }

            }

        });

        // Return the combined structure
        Ok(UdpSocket {
            socket: sender,
            reader_thread: Some(reader_thread),
            udp_receiver: r_udp,
            close_sender: s_close
        })

    }

}

impl Socket for UdpSocket {

    /// Attempts to return a incoming packet on this socket without blocking.
    fn try_recv(&self) -> Result<(net::SocketAddr, Vec<u8>), TryRecvError> {
        self.udp_receiver.try_recv()
    }

    /// Send data on the socket to the given address. On success, returns the
    /// number of bytes written.
    fn send_to(
        &mut self, data: &[u8], addr: net::SocketAddr)

    -> Result<usize, Error> {
        self.socket.send_to(data, addr)
    }

    /// Returns the socket address of the underlying `net::UdpSocket`.
    fn local_addr(&self) -> Result<net::SocketAddr, Error> {
        self.socket.local_addr()
    }

    /// Shuts down the socket by stopping its internal reader thread.
    fn shutdown(&mut self) {

        // Only shutdown if we still got a reader thread
        if let Some(reader_thread) = self.reader_thread.take() {

            // Notify the reader thread to exit
            self.close_sender.send(()).unwrap();

            // Finally wait for the reader thread to exit cleanly
            reader_thread.join().unwrap();

        }

    }

}

impl Drop for UdpSocket {
    fn drop(&mut self) {
        // Make sure to exit the internal thread cleanly
        self.shutdown();
    }
}

impl fmt::Debug for UdpSocket {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "UdpSocket({:?})", self.socket)
    }
}

<|endoftext|>


<commit_before>//! JSON and serialization
//!
//! # What is JSON?
//!
//! JSON (JavaScript Object Notation) is a way to write data in JavaScript.  Like XML, it allows to
//! encode structured data in a text format that can be easily read by humans.  Its simple syntax
//! and native compatibility with JavaScript have made it a widely used format.
//!
//! Data types that can be encoded are JavaScript types (see the `serde_json:Value` enum for more
//! details):
//!
//! * `Boolean`: equivalent to rust's `bool`
//! * `I64`: equivalent to rust's `i64`
//! * `U64`: equivalent to rust's `u64`
//! * `F64`: equivalent to rust's `i64`
//! * `String`: equivalent to rust's `String`
//! * `Array`: equivalent to rust's `Vec<T>`, but also allowing objects of different types in the
//!    same array
//! * `Object`: equivalent to rust's `BTreeMap<String, serde_json::Value>`
//! * `Null`
//!
//! An object is a series of string keys mapping to values, in `"key": value` format.  Arrays are
//! enclosed in square brackets ([ ... ]) and objects in curly brackets ({ ... }).  A simple JSON
//! document encoding a person, his/her age, address and phone numbers could look like
//!
//! ```ignore
//! {
//!     "FirstName": "John",
//!     "LastName": "Doe",
//!     "Age": 43,
//!     "Address": {
//!         "Street": "Downing Street 10",
//!         "City": "London",
//!         "Country": "Great Britain"
//!     },
//!     "PhoneNumbers": [
//!         "+44 1234567",
//!         "+44 2345678"
//!     ]
//! }
//! ```
//!
//! # Type-based Serialization and Deserialization
//!
//! Serde provides a mechanism for low boilerplate serialization & deserialization of values to and
//! from JSON via the serialization API.  To be able to serialize a piece of data, it must implement
//! the `serde::Serialize` trait.  To be able to deserialize a piece of data, it must implement the
//! `serde::Deserialize` trait.  Serde provides provides an annotation to automatically generate
//! the code for these traits: `#[derive(Serialize, Deserialize)]`.
//!
//! The JSON API also provides an enum `serde_json::Value` and a method `to_value` to serialize
//! objects.  A `serde_json::Value` value can be serialized as a string or buffer using the
//! functions described above.  You can also use the `json::Serializer` object, which implements the
//! `Serializer` trait.
//!
//! # Examples of use
//!
//! ## Parsing a `str` to `Value` and reading the result
//!
//! ```rust
//! //#![feature(custom_derive, plugin)]
//! //#![plugin(serde_macros)]
//!
//! extern crate serde_json;
//!
//! use serde_json::Value;
//!
//! fn main() {
//!     let data: Value = serde_json::from_str("{\"foo\": 13, \"bar\": \"baz\"}").unwrap();
//!     println!("data: {:?}", data);
//!     // data: {"bar":"baz","foo":13}
//!     println!("object? {}", data.is_object());
//!     // object? true
//!
//!     let obj = data.as_object().unwrap();
//!     let foo = obj.get("foo").unwrap();
//!
//!     println!("array? {:?}", foo.as_array());
//!     // array? None
//!     println!("u64? {:?}", foo.as_u64());
//!     // u64? Some(13u64)
//!
//!     for (key, value) in obj.iter() {
//!         println!("{}: {}", key, match *value {
//!             Value::U64(v) => format!("{} (u64)", v),
//!             Value::String(ref v) => format!("{} (string)", v),
//!             _ => format!("other")
//!         });
//!     }
//!     // bar: baz (string)
//!     // foo: 13 (u64)
//! }
//! ```

#![deny(missing_docs)]

extern crate num;
extern crate serde;

pub use self::de::{
    Deserializer,
    from_iter,
    from_reader,
    from_slice,
    from_str,
};
pub use self::error::{Error, ErrorCode, Result};
pub use self::ser::{
    Serializer,
    to_writer,
    to_writer_pretty,
    to_vec,
    to_vec_pretty,
    to_string,
    to_string_pretty,
    escape_str,
};
pub use self::value::{Value, to_value, from_value};

pub mod builder;
pub mod de;
pub mod error;
pub mod ser;
pub mod value;
<commit_msg>Fix typo in documentation of Value::F64<commit_after>//! JSON and serialization
//!
//! # What is JSON?
//!
//! JSON (JavaScript Object Notation) is a way to write data in JavaScript.  Like XML, it allows to
//! encode structured data in a text format that can be easily read by humans.  Its simple syntax
//! and native compatibility with JavaScript have made it a widely used format.
//!
//! Data types that can be encoded are JavaScript types (see the `serde_json:Value` enum for more
//! details):
//!
//! * `Boolean`: equivalent to rust's `bool`
//! * `I64`: equivalent to rust's `i64`
//! * `U64`: equivalent to rust's `u64`
//! * `F64`: equivalent to rust's `f64`
//! * `String`: equivalent to rust's `String`
//! * `Array`: equivalent to rust's `Vec<T>`, but also allowing objects of different types in the
//!    same array
//! * `Object`: equivalent to rust's `BTreeMap<String, serde_json::Value>`
//! * `Null`
//!
//! An object is a series of string keys mapping to values, in `"key": value` format.  Arrays are
//! enclosed in square brackets ([ ... ]) and objects in curly brackets ({ ... }).  A simple JSON
//! document encoding a person, his/her age, address and phone numbers could look like
//!
//! ```ignore
//! {
//!     "FirstName": "John",
//!     "LastName": "Doe",
//!     "Age": 43,
//!     "Address": {
//!         "Street": "Downing Street 10",
//!         "City": "London",
//!         "Country": "Great Britain"
//!     },
//!     "PhoneNumbers": [
//!         "+44 1234567",
//!         "+44 2345678"
//!     ]
//! }
//! ```
//!
//! # Type-based Serialization and Deserialization
//!
//! Serde provides a mechanism for low boilerplate serialization & deserialization of values to and
//! from JSON via the serialization API.  To be able to serialize a piece of data, it must implement
//! the `serde::Serialize` trait.  To be able to deserialize a piece of data, it must implement the
//! `serde::Deserialize` trait.  Serde provides provides an annotation to automatically generate
//! the code for these traits: `#[derive(Serialize, Deserialize)]`.
//!
//! The JSON API also provides an enum `serde_json::Value` and a method `to_value` to serialize
//! objects.  A `serde_json::Value` value can be serialized as a string or buffer using the
//! functions described above.  You can also use the `json::Serializer` object, which implements the
//! `Serializer` trait.
//!
//! # Examples of use
//!
//! ## Parsing a `str` to `Value` and reading the result
//!
//! ```rust
//! //#![feature(custom_derive, plugin)]
//! //#![plugin(serde_macros)]
//!
//! extern crate serde_json;
//!
//! use serde_json::Value;
//!
//! fn main() {
//!     let data: Value = serde_json::from_str("{\"foo\": 13, \"bar\": \"baz\"}").unwrap();
//!     println!("data: {:?}", data);
//!     // data: {"bar":"baz","foo":13}
//!     println!("object? {}", data.is_object());
//!     // object? true
//!
//!     let obj = data.as_object().unwrap();
//!     let foo = obj.get("foo").unwrap();
//!
//!     println!("array? {:?}", foo.as_array());
//!     // array? None
//!     println!("u64? {:?}", foo.as_u64());
//!     // u64? Some(13u64)
//!
//!     for (key, value) in obj.iter() {
//!         println!("{}: {}", key, match *value {
//!             Value::U64(v) => format!("{} (u64)", v),
//!             Value::String(ref v) => format!("{} (string)", v),
//!             _ => format!("other")
//!         });
//!     }
//!     // bar: baz (string)
//!     // foo: 13 (u64)
//! }
//! ```

#![deny(missing_docs)]

extern crate num;
extern crate serde;

pub use self::de::{
    Deserializer,
    from_iter,
    from_reader,
    from_slice,
    from_str,
};
pub use self::error::{Error, ErrorCode, Result};
pub use self::ser::{
    Serializer,
    to_writer,
    to_writer_pretty,
    to_vec,
    to_vec_pretty,
    to_string,
    to_string_pretty,
    escape_str,
};
pub use self::value::{Value, to_value, from_value};

pub mod builder;
pub mod de;
pub mod error;
pub mod ser;
pub mod value;
<|endoftext|>


<commit_before>// use std::iter::Iterator;

// Symbol Tables
pub trait ST<K, V> {
    /// create a symbol table
    fn new() -> Self;
    /// put key-value pair into the table
    /// (remove key from table if value is null)
    /// a[key] = val;
    fn put(&mut self, key: K, val: V);
    /// value paired with key
    /// (null if key is absent)
    /// a[key]
    fn get(&self, key: &K) -> Option<&V>;
    // FIXME: helper for a[key] =  val
    // fn get_mut(&mut self, key: &K) -> Option<&mut V>;
    /// remove key (and its value) from table
    fn delete(&mut self, key: &K);
    /// is there a value paired with key?
    fn contains(&self, key: &K) -> bool {
        self.get(key).is_none()
    }
    /// is the table empty?
    fn is_empty(&self) -> bool;
    /// number of key-value pairs in the table
    fn size(&self) -> usize;
    // all the keys in the table
    // fn keys() -> Iterator<Item=K>;
}

pub trait OrderedST<K, V>: ST<K, V> {
    /// smallest key
    fn min(&self) -> Option<&K>;

    /// largest key
    fn max(&self) -> Option<&K>;

    /// largest key less than or equal to key
    fn floor(&self, key: &K) -> Option<&K>;

    /// smallest key greater than or equal to key
    fn ceiling(&self, key: &K) -> Option<&K>;

    /// number of keys less than key
    fn rank(&self, key: &K) -> usize;

    /// key of rank k
    fn select(&self, k: usize) -> Option<&K>;

    /// delete smallest key
    fn delete_min(&mut self);

    /// delete largest key
    fn delete_max(&mut self);

    /// number of keys in [lo..hi]
    fn size_of_key_range(&self, lo: &K, hi: &K) -> usize {
        self.rank(hi) - self.rank(lo) + 1
    }
}

pub mod linked_st;

pub mod ordered_array_st;

pub mod binary_search_tree;
<commit_msg>symbol_tables: fix error in .contains()<commit_after>// use std::iter::Iterator;

// Symbol Tables
pub trait ST<K, V> {
    /// create a symbol table
    fn new() -> Self;
    /// put key-value pair into the table
    /// (remove key from table if value is null)
    /// a[key] = val;
    fn put(&mut self, key: K, val: V);
    /// value paired with key
    /// (null if key is absent)
    /// a[key]
    fn get(&self, key: &K) -> Option<&V>;
    // FIXME: helper for a[key] =  val
    // fn get_mut(&mut self, key: &K) -> Option<&mut V>;
    /// remove key (and its value) from table
    fn delete(&mut self, key: &K);
    /// is there a value paired with key?
    fn contains(&self, key: &K) -> bool {
        self.get(key).is_some()
    }
    /// is the table empty?
    fn is_empty(&self) -> bool;
    /// number of key-value pairs in the table
    fn size(&self) -> usize;
    // all the keys in the table
    // fn keys() -> Iterator<Item=K>;
}

pub trait OrderedST<K, V>: ST<K, V> {
    /// smallest key
    fn min(&self) -> Option<&K>;

    /// largest key
    fn max(&self) -> Option<&K>;

    /// largest key less than or equal to key
    fn floor(&self, key: &K) -> Option<&K>;

    /// smallest key greater than or equal to key
    fn ceiling(&self, key: &K) -> Option<&K>;

    /// number of keys less than key
    fn rank(&self, key: &K) -> usize;

    /// key of rank k
    fn select(&self, k: usize) -> Option<&K>;

    /// delete smallest key
    fn delete_min(&mut self);

    /// delete largest key
    fn delete_max(&mut self);

    /// number of keys in [lo..hi]
    fn size_of_key_range(&self, lo: &K, hi: &K) -> usize {
        self.rank(hi) - self.rank(lo) + 1
    }
}

pub mod linked_st;

pub mod ordered_array_st;

pub mod binary_search_tree;
<|endoftext|>


<commit_before>#![cfg(feature = "with-deprecated")]
#![deprecated(since = "0.1.4",
              note = "replaced with `BiLock` in many cases, otherwise slated \
                      for removal due to confusion")]

use std::prelude::v1::*;
use std::sync::Arc;
use std::cell::UnsafeCell;

// One critical piece of this module's contents are the `TaskRc<A>` handles.
// The purpose of this is to conceptually be able to store data in a task,
// allowing it to be accessed within multiple futures at once. For example if
// you have some concurrent futures working, they may all want mutable access to
// some data. We already know that when the futures are being poll'ed that we're
// entirely synchronized (aka `&mut Task`), so you shouldn't require an
// `Arc<Mutex<T>>` to share as the synchronization isn't necessary!
//
// So the idea here is that you insert data into a task via `Task::insert`, and
// a handle to that data is then returned to you. That handle can later get
// presented to the task itself to actually retrieve the underlying data. The
// invariant is that the data can only ever be accessed with the task present,
// and the lifetime of the actual data returned is connected to the lifetime of
// the task itself.
//
// Conceptually I at least like to think of this as "dynamically adding more
// struct fields to a `Task`". Each call to insert creates a new "name" for the
// struct field, a `TaskRc<A>`, and then you can access the fields of a struct
// with the struct itself (`Task`) as well as the name of the field
// (`TaskRc<A>`). If that analogy doesn't make sense then oh well, it at least
// helped me!
//
// So anyway, we do some interesting trickery here to actually get it to work.
// Each `TaskRc<A>` handle stores `Arc<UnsafeCell<A>>`. So it turns out, we're
// not even adding data to the `Task`! Each `TaskRc<A>` contains a reference
// to this `Arc`, and `TaskRc` handles can be cloned which just bumps the
// reference count on the `Arc` itself.
//
// As before, though, you can present the `Arc` to a `Task` and if they
// originated from the same place you're allowed safe access to the internals.
// We allow but shared and mutable access without the `Sync` bound on the data,
// crucially noting that a `Task` itself is not `Sync`.
//
// So hopefully I've convinced you of this point that the `get` and `get_mut`
// methods below are indeed safe. The data is always valid as it's stored in an
// `Arc`, and access is only allowed with the proof of the associated `Task`.
// One thing you might be asking yourself though is what exactly is this "proof
// of a task"? Right now it's a `usize` corresponding to the `Task`'s
// `TaskHandle` arc allocation.
//
// Wait a minute, isn't that the ABA problem! That is, we create a task A, add
// some data to it, destroy task A, do some work, create a task B, and then ask
// to get the data from task B. In this case though the point of the
// `task_inner` "proof" field is simply that there's some non-`Sync` token
// proving that you can get access to the data. So while weird, this case should
// still be safe, as the data's not stored in the task itself.

/// A reference to a piece of data that's accessible only within a specific
/// `Task`.
///
/// This data is `Send` even when `A` is not `Sync`, because the data stored
/// within is accessed in a single-threaded way. The thread accessing it may
/// change over time, if the task migrates, so `A` must be `Send`.
pub struct TaskRc<A> {
    task_id: usize,
    ptr: Arc<UnsafeCell<A>>,
}

// for safety here, see docs at the top of this module
unsafe impl<A: Send> Send for TaskRc<A> {}
unsafe impl<A: Sync> Sync for TaskRc<A> {}

impl<A> TaskRc<A> {
    /// Inserts a new piece of task-local data into this task, returning a
    /// reference to it.
    ///
    /// Ownership of the data will be transferred to the task, and the data will
    /// be destroyed when the task itself is destroyed. The returned value can
    /// be passed to the `with` method to get a reference back to the original
    /// data.
    ///
    /// Note that the returned handle is cloneable and copyable and can be sent
    /// to other futures which will be associated with the same task. All
    /// futures will then have access to this data when passed the reference
    /// back.
    ///
    /// # Panics
    ///
    /// This function will panic if a task is not currently running.
    pub fn new(a: A) -> TaskRc<A> {
        super::with(|task, _| {
            TaskRc {
                task_id: task.id,
                ptr: Arc::new(UnsafeCell::new(a)),
            }
        })
    }

    /// Operate with a reference to the underlying data.
    ///
    /// This method should be passed a handle previously returned by
    /// `Task::insert`. That handle, when passed back into this method, will
    /// retrieve a reference to the original data.
    ///
    /// # Panics
    ///
    /// This method will panic if a task is not currently running or if `self`
    /// does not belong to the task that is currently running. That is, if
    /// another task generated the `data` handle passed in, this method will
    /// panic.
    pub fn with<F, R>(&self, f: F) -> R
        where F: FnOnce(&A) -> R
    {
        // for safety here, see docs at the top of this module
        super::with(|task, _| {
            assert!(self.task_id == task.id,
                    "TaskRc being accessed on task it does not belong to");
            f(unsafe { &*self.ptr.get() })
        })
    }
}

impl<A> Clone for TaskRc<A> {
    fn clone(&self) -> TaskRc<A> {
        TaskRc {
            task_id: self.task_id,
            ptr: self.ptr.clone(),
        }
    }
}
<commit_msg>Fix warnings on 1.10.0<commit_after>#![cfg(feature = "with-deprecated")]
#![allow(deprecated)]
#![deprecated(since = "0.1.4",
              note = "replaced with `BiLock` in many cases, otherwise slated \
                      for removal due to confusion")]

use std::prelude::v1::*;
use std::sync::Arc;
use std::cell::UnsafeCell;

// One critical piece of this module's contents are the `TaskRc<A>` handles.
// The purpose of this is to conceptually be able to store data in a task,
// allowing it to be accessed within multiple futures at once. For example if
// you have some concurrent futures working, they may all want mutable access to
// some data. We already know that when the futures are being poll'ed that we're
// entirely synchronized (aka `&mut Task`), so you shouldn't require an
// `Arc<Mutex<T>>` to share as the synchronization isn't necessary!
//
// So the idea here is that you insert data into a task via `Task::insert`, and
// a handle to that data is then returned to you. That handle can later get
// presented to the task itself to actually retrieve the underlying data. The
// invariant is that the data can only ever be accessed with the task present,
// and the lifetime of the actual data returned is connected to the lifetime of
// the task itself.
//
// Conceptually I at least like to think of this as "dynamically adding more
// struct fields to a `Task`". Each call to insert creates a new "name" for the
// struct field, a `TaskRc<A>`, and then you can access the fields of a struct
// with the struct itself (`Task`) as well as the name of the field
// (`TaskRc<A>`). If that analogy doesn't make sense then oh well, it at least
// helped me!
//
// So anyway, we do some interesting trickery here to actually get it to work.
// Each `TaskRc<A>` handle stores `Arc<UnsafeCell<A>>`. So it turns out, we're
// not even adding data to the `Task`! Each `TaskRc<A>` contains a reference
// to this `Arc`, and `TaskRc` handles can be cloned which just bumps the
// reference count on the `Arc` itself.
//
// As before, though, you can present the `Arc` to a `Task` and if they
// originated from the same place you're allowed safe access to the internals.
// We allow but shared and mutable access without the `Sync` bound on the data,
// crucially noting that a `Task` itself is not `Sync`.
//
// So hopefully I've convinced you of this point that the `get` and `get_mut`
// methods below are indeed safe. The data is always valid as it's stored in an
// `Arc`, and access is only allowed with the proof of the associated `Task`.
// One thing you might be asking yourself though is what exactly is this "proof
// of a task"? Right now it's a `usize` corresponding to the `Task`'s
// `TaskHandle` arc allocation.
//
// Wait a minute, isn't that the ABA problem! That is, we create a task A, add
// some data to it, destroy task A, do some work, create a task B, and then ask
// to get the data from task B. In this case though the point of the
// `task_inner` "proof" field is simply that there's some non-`Sync` token
// proving that you can get access to the data. So while weird, this case should
// still be safe, as the data's not stored in the task itself.

/// A reference to a piece of data that's accessible only within a specific
/// `Task`.
///
/// This data is `Send` even when `A` is not `Sync`, because the data stored
/// within is accessed in a single-threaded way. The thread accessing it may
/// change over time, if the task migrates, so `A` must be `Send`.
pub struct TaskRc<A> {
    task_id: usize,
    ptr: Arc<UnsafeCell<A>>,
}

// for safety here, see docs at the top of this module
unsafe impl<A: Send> Send for TaskRc<A> {}
unsafe impl<A: Sync> Sync for TaskRc<A> {}

impl<A> TaskRc<A> {
    /// Inserts a new piece of task-local data into this task, returning a
    /// reference to it.
    ///
    /// Ownership of the data will be transferred to the task, and the data will
    /// be destroyed when the task itself is destroyed. The returned value can
    /// be passed to the `with` method to get a reference back to the original
    /// data.
    ///
    /// Note that the returned handle is cloneable and copyable and can be sent
    /// to other futures which will be associated with the same task. All
    /// futures will then have access to this data when passed the reference
    /// back.
    ///
    /// # Panics
    ///
    /// This function will panic if a task is not currently running.
    pub fn new(a: A) -> TaskRc<A> {
        super::with(|task, _| {
            TaskRc {
                task_id: task.id,
                ptr: Arc::new(UnsafeCell::new(a)),
            }
        })
    }

    /// Operate with a reference to the underlying data.
    ///
    /// This method should be passed a handle previously returned by
    /// `Task::insert`. That handle, when passed back into this method, will
    /// retrieve a reference to the original data.
    ///
    /// # Panics
    ///
    /// This method will panic if a task is not currently running or if `self`
    /// does not belong to the task that is currently running. That is, if
    /// another task generated the `data` handle passed in, this method will
    /// panic.
    pub fn with<F, R>(&self, f: F) -> R
        where F: FnOnce(&A) -> R
    {
        // for safety here, see docs at the top of this module
        super::with(|task, _| {
            assert!(self.task_id == task.id,
                    "TaskRc being accessed on task it does not belong to");
            f(unsafe { &*self.ptr.get() })
        })
    }
}

impl<A> Clone for TaskRc<A> {
    fn clone(&self) -> TaskRc<A> {
        TaskRc {
            task_id: self.task_id,
            ptr: self.ptr.clone(),
        }
    }
}
<|endoftext|>


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

<%namespace name="helpers" file="/helpers.mako.rs" />

<%helpers:shorthand name="font" sub_properties="font-style font-variant font-weight font-stretch
                                                font-size line-height font-family
                                                ${'font-size-adjust' if product == 'gecko' else ''}
                                                ${'font-kerning' if product == 'gecko' else ''}
                                                ${'font-variant-caps' if product == 'gecko' else ''}
                                                ${'font-variant-position' if product == 'gecko' else ''}
                                                ${'font-language-override' if product == 'none' else ''}"
                    spec="https://drafts.csswg.org/css-fonts-3/#propdef-font">
    use properties::longhands::{font_style, font_variant, font_weight, font_stretch};
    use properties::longhands::{font_size, line_height};
    % if product == "gecko":
    use properties::longhands::{font_size_adjust, font_kerning, font_variant_caps, font_variant_position};
    % endif
    % if product == "none":
    use properties::longhands::font_language_override;
    % endif
    use properties::longhands::font_family::SpecifiedValue as FontFamily;

    pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
        let mut nb_normals = 0;
        let mut style = None;
        let mut variant = None;
        let mut weight = None;
        let mut stretch = None;
        let size;
        loop {
            // Special-case 'normal' because it is valid in each of
            // font-style, font-weight, font-variant and font-stretch.
            // Leaves the values to None, 'normal' is the initial value for each of them.
            if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
                nb_normals += 1;
                continue;
            }
            if style.is_none() {
                if let Ok(value) = input.try(|input| font_style::parse(context, input)) {
                    style = Some(value);
                    continue
                }
            }
            if weight.is_none() {
                if let Ok(value) = input.try(|input| font_weight::parse(context, input)) {
                    weight = Some(value);
                    continue
                }
            }
            if variant.is_none() {
                if let Ok(value) = input.try(|input| font_variant::parse(context, input)) {
                    variant = Some(value);
                    continue
                }
            }
            if stretch.is_none() {
                if let Ok(value) = input.try(|input| font_stretch::parse(context, input)) {
                    stretch = Some(value);
                    continue
                }
            }
            size = Some(try!(font_size::parse(context, input)));
            break
        }
        #[inline]
        fn count<T>(opt: &Option<T>) -> u8 {
            if opt.is_some() { 1 } else { 0 }
        }
        if size.is_none() || (count(&style) + count(&weight) + count(&variant) + count(&stretch) + nb_normals) > 4 {
            return Err(())
        }
        let line_height = if input.try(|input| input.expect_delim('/')).is_ok() {
            Some(try!(line_height::parse(context, input)))
        } else {
            None
        };
        let family = FontFamily::parse(input)?;
        Ok(Longhands {
            % for name in "style variant weight stretch size".split():
                font_${name}: unwrap_or_initial!(font_${name}, ${name}),
            % endfor
            line_height: unwrap_or_initial!(line_height),
            font_family: family,
            % if product == "gecko":
                % for name in "size_adjust kerning variant_caps variant_position".split():
                    font_${name}: font_${name}::get_initial_specified_value(),
                % endfor
            % endif
            % if product == "none":
                font_language_override: font_language_override::get_initial_specified_value(),
            % endif
        })
    }

    // This may be a bit off, unsure, possibly needs changes
    impl<'a> ToCss for LonghandsToSerialize<'a>  {
        fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
            self.font_style.to_css(dest)?;
            dest.write_str(" ")?;
            self.font_variant.to_css(dest)?;
            dest.write_str(" ")?;
            self.font_weight.to_css(dest)?;
            dest.write_str(" ")?;
            self.font_stretch.to_css(dest)?;
            dest.write_str(" ")?;

            self.font_size.to_css(dest)?;
            match *self.line_height {
                line_height::SpecifiedValue::Normal => {},
                _ => {
                    dest.write_str("/")?;
                    self.line_height.to_css(dest)?;
                }
            }

            dest.write_str(" ")?;
            self.font_family.to_css(dest)
        }
    }
</%helpers:shorthand>
<commit_msg>Serialize font to "" on some nondefault properties<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

<%namespace name="helpers" file="/helpers.mako.rs" />

<%helpers:shorthand name="font" sub_properties="font-style font-variant font-weight font-stretch
                                                font-size line-height font-family
                                                ${'font-size-adjust' if product == 'gecko' or data.testing else ''}
                                                ${'font-kerning' if product == 'gecko' or data.testing else ''}
                                                ${'font-variant-caps' if product == 'gecko' or data.testing else ''}
                                                ${'font-variant-position' if product == 'gecko' or data.testing else ''}
                                                ${'font-language-override' if data.testing else ''}"
                    spec="https://drafts.csswg.org/css-fonts-3/#propdef-font">
    use properties::longhands::{font_style, font_variant, font_weight, font_stretch};
    use properties::longhands::{font_size, line_height};
    % if product == "gecko" or data.testing:
    use properties::longhands::{font_size_adjust, font_kerning, font_variant_caps, font_variant_position};
    % endif
    % if data.testing:
    use properties::longhands::font_language_override;
    % endif
    use properties::longhands::font_family::SpecifiedValue as FontFamily;

    pub fn parse_value(context: &ParserContext, input: &mut Parser) -> Result<Longhands, ()> {
        let mut nb_normals = 0;
        let mut style = None;
        let mut variant = None;
        let mut weight = None;
        let mut stretch = None;
        let size;
        loop {
            // Special-case 'normal' because it is valid in each of
            // font-style, font-weight, font-variant and font-stretch.
            // Leaves the values to None, 'normal' is the initial value for each of them.
            if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
                nb_normals += 1;
                continue;
            }
            if style.is_none() {
                if let Ok(value) = input.try(|input| font_style::parse(context, input)) {
                    style = Some(value);
                    continue
                }
            }
            if weight.is_none() {
                if let Ok(value) = input.try(|input| font_weight::parse(context, input)) {
                    weight = Some(value);
                    continue
                }
            }
            if variant.is_none() {
                if let Ok(value) = input.try(|input| font_variant::parse(context, input)) {
                    variant = Some(value);
                    continue
                }
            }
            if stretch.is_none() {
                if let Ok(value) = input.try(|input| font_stretch::parse(context, input)) {
                    stretch = Some(value);
                    continue
                }
            }
            size = Some(try!(font_size::parse(context, input)));
            break
        }
        #[inline]
        fn count<T>(opt: &Option<T>) -> u8 {
            if opt.is_some() { 1 } else { 0 }
        }
        if size.is_none() || (count(&style) + count(&weight) + count(&variant) + count(&stretch) + nb_normals) > 4 {
            return Err(())
        }
        let line_height = if input.try(|input| input.expect_delim('/')).is_ok() {
            Some(try!(line_height::parse(context, input)))
        } else {
            None
        };
        let family = FontFamily::parse(input)?;
        Ok(Longhands {
            % for name in "style variant weight stretch size".split():
                font_${name}: unwrap_or_initial!(font_${name}, ${name}),
            % endfor
            line_height: unwrap_or_initial!(line_height),
            font_family: family,
            % if product == "gecko" or data.testing:
                % for name in "size_adjust kerning variant_caps variant_position".split():
                    font_${name}: font_${name}::get_initial_specified_value(),
                % endfor
            % endif
            % if data.testing:
                font_language_override: font_language_override::get_initial_specified_value(),
            % endif
        })
    }

    // This may be a bit off, unsure, possibly needs changes
    impl<'a> ToCss for LonghandsToSerialize<'a>  {
        fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {

    % if product == "gecko" or data.testing:
        % for name in "size_adjust kerning variant_caps variant_position".split():
            if self.font_${name} != &font_${name}::get_initial_specified_value() {
                return Ok(());
            }
        % endfor
    % endif

    % if data.testing:
            if self.font_language_override != &font_language_override::get_initial_specified_value() {
                return Ok(());
            }
    % endif

    % for name in "style variant weight stretch".split():
            self.font_${name}.to_css(dest)?;
            dest.write_str(" ")?;
    % endfor

            self.font_size.to_css(dest)?;

            match *self.line_height {
                line_height::SpecifiedValue::Normal => {},
                _ => {
                    dest.write_str("/")?;
                    self.line_height.to_css(dest)?;
                }
            }

            dest.write_str(" ")?;
            self.font_family.to_css(dest)?;

            Ok(())
        }
    }
</%helpers:shorthand>
<|endoftext|>


<commit_before>use std::boxed::FnBox;
use std::sync::{Arc, Mutex};
use std::thread::{self, JoinHandle, spawn};

use world_state;

pub struct ExampleResultInner {
    _description: String,
}

impl ExampleResultInner {
    pub fn new(description: String) -> ExampleResultInner {
        ExampleResultInner {
            _description: description,
        }
    }
}

pub type ExampleResult = Result<ExampleResultInner, ExampleResultInner>;
pub type ExampleRecoveryBlock = Box<FnBox() -> thread::Result<()> + Send + 'static>;

pub struct Example {
    description: String,
    block: ExampleRecoveryBlock,
}

impl Example {
    pub fn new(description: String, block: ExampleRecoveryBlock) -> Example {
        Example {
            description: description,
            block: block,
        }
    }

    pub fn spawn(self, state: Arc<Mutex<world_state::WorldState>>) -> JoinHandle<ExampleResult> {
        spawn(move || self.run(state))
    }

    fn run(self, state: Arc<Mutex<world_state::WorldState>>) -> ExampleResult {
        let block_result = (self.block)();

        let result = match block_result {
            Err(_) => Err(ExampleResultInner::new(self.description)),
            Ok(_) => Ok(ExampleResultInner::new(self.description)),
        };

        Example::report_result(&result, state);

        result
    }

    fn report_result(result: &ExampleResult, state: Arc<Mutex<world_state::WorldState>>) {
        let ref reporter = state.lock().unwrap().reporter;

        let reporting_result = if result.is_err() {
            reporter.example_failed()
        } else {
            reporter.example_passed()
        };

        if reporting_result.is_err() {
            panic!("work out what to do here");
        }
    }
}
<commit_msg>Expose ExampleGroupResultInner description.<commit_after>use std::boxed::FnBox;
use std::sync::{Arc, Mutex};
use std::thread::{self, JoinHandle, spawn};

use world_state;

pub struct ExampleResultInner {
    pub description: String,
}

impl ExampleResultInner {
    pub fn new(description: String) -> ExampleResultInner {
        ExampleResultInner {
            description: description,
        }
    }
}

pub type ExampleResult = Result<ExampleResultInner, ExampleResultInner>;
pub type ExampleRecoveryBlock = Box<FnBox() -> thread::Result<()> + Send + 'static>;

pub struct Example {
    description: String,
    block: ExampleRecoveryBlock,
}

impl Example {
    pub fn new(description: String, block: ExampleRecoveryBlock) -> Example {
        Example {
            description: description,
            block: block,
        }
    }

    pub fn spawn(self, state: Arc<Mutex<world_state::WorldState>>) -> JoinHandle<ExampleResult> {
        spawn(move || self.run(state))
    }

    fn run(self, state: Arc<Mutex<world_state::WorldState>>) -> ExampleResult {
        let block_result = (self.block)();

        let result = match block_result {
            Err(_) => Err(ExampleResultInner::new(self.description)),
            Ok(_) => Ok(ExampleResultInner::new(self.description)),
        };

        Example::report_result(&result, state);

        result
    }

    fn report_result(result: &ExampleResult, state: Arc<Mutex<world_state::WorldState>>) {
        let ref reporter = state.lock().unwrap().reporter;

        let reporting_result = if result.is_err() {
            reporter.example_failed()
        } else {
            reporter.example_passed()
        };

        if reporting_result.is_err() {
            panic!("work out what to do here");
        }
    }
}
<|endoftext|>


<commit_before>//! Features and intervals for gene annotations.

use std::collections::HashMap;

use bio::io::Strand;

use self::error::FeatureError;

pub mod error {

    use std::error::Error;
    use std::fmt;

    #[derive(Debug)]
    pub enum FeatureError {
        InvalidCoords,
    }

    impl Error for FeatureError {
        fn description(&self) -> &str {
            match *self {
                FeatureError::InvalidCoords => "interval start coordinate larger than its end coordinate"
            }
        }

        fn cause(&self) -> Option<&Error> {
            None
        }
    }

    impl fmt::Display for FeatureError {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            write!(f, "FeatureError: {}", self.description())
        }
    }
}

/// Interface for features with start and end coordinates.
///
/// The intervals represented here are zero-based, half open intervals.
/// Coordinates start from zero and start coordinates must be less than
/// or equal to the end coordinates.
pub trait Interval: Sized {

    /// Start coordinate of the interval.
    fn start(&self) -> u64;

    /// End coordinate of the interval.
    fn end(&self) -> u64;

    /// Name of the interval.
    fn name(&self) -> Option<&str>;

    /// Name setter that returns the implementor itself.
    ///
    /// This function is expected to mutate the implementing type.
    fn with_name<T: Into<String>>(self, name: T) -> Self;

    /// Coordinate setter that returns the implementor itself.
    ///
    /// This function is expected to mutate the implementing type.
    fn with_coords(self, start: u64, end: u64) -> Self;

    /// Performs various validation of the interval.
    fn validate(self) -> Result<Self, FeatureError> {
        self.validate_coords()
    }

    /// The number of bases covered by the interval.
    fn span(&self) -> u64 {
        self.end() - self.start()
    }

    /// Whether two intervals have an intersection or not.
    fn overlaps(&self, other: &Self) -> bool {
        (other.start() <= self.start() && self.start() <= other.end()) ||
        (other.start() <= self.end() && self.end() <= other.end())
    }

    /// Whether one interval completely contains the other.
    fn envelops(&self, other: &Self) -> bool {
        self.start() <= other.start() && self.end() >= other.end()
    }

    /// Whether two intervals cover a contiguous region without any overlaps.
    fn adjacent(&self, other: &Self) -> bool {
        self.end() == other.start() || self.start() == other.end()
    }

    /// Performs validation of the interval coordinates.
    ///
    /// If the validation fails, an error message is returned within
    /// the `Result` type.
    fn validate_coords(self) -> Result<Self, FeatureError> {
        if self.start() > self.end() {
            return Err(FeatureError::InvalidCoords)
        }

        Ok(self)
    }
}

/// Macro for default function implementations of interval types.
macro_rules! impl_interval {
    ($struct_ty:ty) => (

        impl Interval for $struct_ty {

            /// Name of the interval.
            fn name(&self) -> Option<&str> {
                self.name.as_ref().map(|n| n.as_str())
            }

            /// Start coordinate of the interval.
            fn start(&self) -> u64 {
                self.start
            }

            /// End coordinate of the interval.
            fn end(&self) -> u64 {
                self.end
            }

            fn with_name<T>(mut self, name: T) -> $struct_ty
                where T: Into<String>
            {
                self.name = Some(name.into());
                self
            }

            fn with_coords(mut self, start: u64, end: u64) -> $struct_ty {
                self.start = start;
                self.end = end;
                self
            }
        }

    );
}

/// Default implementation of the `Interval` trait.
///
/// This struct also provides static methods for creating exons, transcripts, and genes.
#[derive(Debug, Default)]
pub struct Feature {
    start: u64,
    end: u64,
    name: Option<String>,
}

impl Feature {

    /// Creates a gene interval with default values.
    ///
    /// A gene interval is a container for transcript intervals.
    ///
    /// # Examples
    ///
    /// ```
    /// let gene = Feature::gene();
    ///
    /// assert_eq!(gene.transcript().len(), 0);
    /// assert_eq!(gene.start(), 0);
    /// assert_eq!(gene.end(), 0);
    /// assert_eq!(gene.name(), None);
    /// ```
    pub fn gene() -> Gene {
        Gene::default()
    }

    /// Creates a transcript interval with default values.
    ///
    /// A transcript interval is a container for exon intervals.
    ///
    /// # Examples
    ///
    /// ```
    /// use bio::io::Strand;
    ///
    /// let transcript = Feature::transcript();
    ///
    /// assert_eq!(transcript.exons().len(), 0);
    /// assert_eq!(transcript.strand(), &Strand::Unknown)
    /// assert_eq!(transcript.start(), 0);
    /// assert_eq!(transcript.end(), 0);
    /// assert_eq!(transcript.name(), None);
    /// ```
    pub fn transcript() -> Transcript {
        Transcript::default()
    }

    /// Creates an exon interval with default values.
    ///
    /// # Examples
    ///
    /// ```
    /// let exon = Feature::exon();
    ///
    /// assert_eq!(exon.start(), 0);
    /// assert_eq!(exon.end(), 0);
    /// assert_eq!(exon.name(), None);
    /// ```
    pub fn exon() -> Exon {
        Exon::default()
    }
}

impl_interval!(Feature);

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

    #[test]
    fn default() {
        let fx = Feature::default();
        assert_eq!(fx.start(), 0);
        assert_eq!(fx.end(), 0);
        assert!(fx.validate().is_ok());
    }

    #[test]
    fn with_name() {
        let fx1 = Feature::default()
            .with_name("fx1");
        assert_eq!(fx1.start(), 0);
        assert_eq!(fx1.end(), 0);
        assert_eq!(fx1.name(), Some("fx1"));

        let fx2 = Feature::default()
            .with_name("fx2".to_owned());
        assert_eq!(fx2.start(), 0);
        assert_eq!(fx2.end(), 0);
        assert_eq!(fx2.name(), Some("fx2"));
    }

    #[test]
    fn with_coords() {
        let fx = Feature::default()
            .with_coords(1, 3);
        assert_eq!(fx.start(), 1);
        assert_eq!(fx.end(), 3);
        assert_eq!(fx.name(), None);
    }

    #[test]
    fn with_multiples() {
        let fx = Feature::default()
            .with_name("fx")
            .with_coords(20, 30);
        assert_eq!(fx.start(), 20);
        assert_eq!(fx.end(), 30);
        assert_eq!(fx.name(), Some("fx"));
    }
}

/// Gene annotation.
#[derive(Debug, Default)]
pub struct Gene {
    name: Option<String>,
    start: u64,
    end: u64,
    transcripts: HashMap<String, Transcript>,
}

impl Gene {

    pub fn transcripts(&self) -> &HashMap<String, Transcript> {
        &self.transcripts
    }
}

impl_interval!(Gene);

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

    #[test]
    fn default() {
        let gene = Feature::gene();
        assert_eq!(gene.start(), 0);
        assert_eq!(gene.end(), 0);
        assert_eq!(gene.name(), None);
        assert_eq!(gene.transcripts().len(), 0);
    }
}

/// Transcript annotation.
#[derive(Debug)]
pub struct Transcript {
    name: Option<String>,
    strand: Strand,
    start: u64,
    end: u64,
    cds_start: Option<u64>,
    cds_end: Option<u64>,
    exons: Vec<Exon>,
}

impl Transcript {

    pub fn strand(&self) -> &Strand {
        &self.strand
    }

    pub fn with_strand(mut self, strand: Strand) -> Transcript {
        self.strand = strand;
        self
    }

    pub fn cds_start(&self) -> Option<u64> {
        self.cds_start
    }

    pub fn with_cds_start(mut self, cds_start: u64) -> Transcript {
        self.cds_start = Some(cds_start);
        self
    }

    pub fn cds_end(&self) -> Option<u64> {
        self.cds_end
    }

    pub fn with_cds_end(mut self, cds_end: u64) -> Transcript {
        self.cds_end = Some(cds_end);
        self
    }

    pub fn exons(&self) -> &Vec<Exon> {
        &self.exons
    }

    pub fn with_exons(mut self, exons: Vec<Exon>) -> Transcript {
        self.exons = exons;
        self
    }

    pub fn insert_exon(&mut self, exon: Exon) {
        self.exons.push(exon);
    }
}

impl Default for Transcript {

    fn default() -> Transcript {
        Transcript {
            name: None,
            strand: Strand::Unknown,
            start: 0,
            end: 0,
            cds_start: None,
            cds_end: None,
            exons: Vec::new(),
        }
    }
}

impl_interval!(Transcript);

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

    #[test]
    fn default() {
        let trx = Feature::transcript();
        assert_eq!(trx.start(), 0);
        assert_eq!(trx.end(), 0);
        assert_eq!(trx.name(), None);
        assert_eq!(trx.strand(), &Strand::Unknown);
        assert_eq!(trx.cds_start(), None);
        assert_eq!(trx.cds_end(), None);
        assert_eq!(trx.exons().len(), 0);
    }

    #[test]
    fn with_strand() {
        let trx = Feature::transcript()
            .with_strand(Strand::Forward);
        assert_eq!(trx.strand(), &Strand::Forward);
    }

    #[test]
    fn with_cds_start() {
        let trx = Feature::transcript()
            .with_cds_start(20);
        assert_eq!(trx.cds_start(), Some(20));
    }

    #[test]
    fn with_cds_end() {
        let trx = Feature::transcript()
            .with_cds_end(40);
        assert_eq!(trx.cds_end(), Some(40))
    }

    #[test]
    fn with_exons() {
        let trx = Feature::transcript()
            .with_exons(vec![
                Exon::new(1, 2, Some("ex1")),
                Exon::new(10, 20, Some("ex2")),
                Exon::new(100, 200, Some("ex3")),
            ]);
        assert_eq!(trx.exons().len(), 3);
    }

    #[test]
    fn insert_exon() {
        let mut trx = Feature::transcript();
        assert_eq!(trx.exons().len(), 0);
        trx.insert_exon(Exon::new(1, 2, Some("ex")));
        assert_eq!(trx.exons().len(), 1);
    }
}

/// Exon annotation.
#[derive(Debug, Default)]
pub struct Exon {
    name: Option<String>,
    start: u64,
    end: u64,
}

impl Exon {

    fn new<T>(start: u64, end: u64, name: Option<T>) -> Exon
        where T: Into<String>
    {
        Exon { start: start, end: end,
               name: name.map(|n| n.into()) }
    }
}

impl_interval!(Exon);

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

    #[test]
    fn default() {
        let exon = Feature::exon();
        assert_eq!(exon.start(), 0);
        assert_eq!(exon.end(), 0);
        assert_eq!(exon.name(), None);
    }
}
<commit_msg>Use interval struct from rust-bio<commit_after>//! Interval-based annotation features.

use bio::utils::{Interval, IntervalError};

pub trait NamedInterval: Sized {

    /// Underlying interval struct.
    fn interval(&self) -> &Interval<u64>;

    /// Name of the interval.
    fn name(&self) -> Option<&str>;

    /// Name setter that returns the implementor itself.
    ///
    /// This function is expected to mutate the implementing type.
    fn with_name<T: Into<String>>(self, name: T) -> Self;

    /// Coordinate setter that returns the implementor itself.
    ///
    /// This function is expected to mutate the implementing type.
    fn with_coords(self, start: u64, end: u64) -> Result<Self, IntervalError>;

    /// Start coordinate of the interval.
    fn start(&self) -> u64 {
        self.interval().start
    }

    /// End coordinate of the interval.
    fn end(&self) -> u64 {
        self.interval().end
    }

    /// The number of bases covered by the interval.
    fn span(&self) -> u64 {
        self.end() - self.start()
    }

    /// Whether two intervals have an intersection or not.
    fn overlaps(&self, other: &Self) -> bool {
        (other.start() <= self.start() && self.start() <= other.end()) ||
        (other.start() <= self.end() && self.end() <= other.end())
    }

    /// Whether one interval completely contains the other.
    fn envelops(&self, other: &Self) -> bool {
        self.start() <= other.start() && self.end() >= other.end()
    }

    /// Whether two intervals cover a contiguous region without any overlaps.
    fn adjacent(&self, other: &Self) -> bool {
        self.end() == other.start() || self.start() == other.end()
    }
}

/// Macro for default function implementations of interval types.
macro_rules! impl_ninterval {
    ($struct_ty:ty) => (

        impl NamedInterval for $struct_ty {

            /// Name of the interval.
            fn name(&self) -> Option<&str> {
                self.name.as_ref().map(|n| n.as_str())
            }

            fn with_name<T>(mut self, name: T) -> $struct_ty
                where T: Into<String>
            {
                self.name = Some(name.into());
                self
            }

            fn interval(&self) -> &Interval<u64> {
                &self.interval
            }

            fn with_coords(mut self, start: u64, end: u64) -> Result<$struct_ty, IntervalError> {
                Interval::new(start..end)
                    .map(|iv| {
                        self.interval = iv;
                        self
                    })
            }
        }

    );
}

/// Default implementation of the `Interval` trait.
///
/// This struct also provides static methods for creating exons, transcripts, and genes.
#[derive(Debug)]
pub struct Feature {
    interval: Interval<u64>,
    name: Option<String>,
}

impl Default for Feature {

    fn default() -> Feature {
        Feature { interval: Interval::new(0..0).unwrap(), name: None }
    }
}

impl_ninterval!(Feature);

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

    #[test]
    fn default() {
        let fx = Feature::default();
        assert_eq!(fx.start(), 0);
        assert_eq!(fx.end(), 0);
        assert_eq!(fx.name(), None);
    }

    #[test]
    fn with_name() {
        let fx1 = Feature::default()
            .with_name("fx1");
        assert_eq!(fx1.start(), 0);
        assert_eq!(fx1.end(), 0);
        assert_eq!(fx1.name(), Some("fx1"));

        let fx2 = Feature::default()
            .with_name("fx2".to_owned());
        assert_eq!(fx2.start(), 0);
        assert_eq!(fx2.end(), 0);
        assert_eq!(fx2.name(), Some("fx2"));
    }

    #[test]
    fn with_coords() {
        let fxm = Feature::default()
            .with_coords(1, 3);
        assert!(fxm.is_ok());
        let fx = fxm.unwrap();
        assert_eq!(fx.start(), 1);
        assert_eq!(fx.end(), 3);
        assert_eq!(fx.name(), None);
    }

    #[test]
    fn with_coords_err() {
        let fxm = Feature::default()
            .with_coords(3, 1);
        assert!(fxm.is_err());
    }

    #[test]
    fn with_multiples() {
        let fxm = Feature::default()
            .with_coords(20, 30)
            .map(|f| f.with_name("fx"));
        assert!(fxm.is_ok());
        let fx = fxm.unwrap();
        assert_eq!(fx.start(), 20);
        assert_eq!(fx.end(), 30);
        assert_eq!(fx.name(), Some("fx"));
    }
}
<|endoftext|>