<commit_before>extern crate libc;

use self::libc::{c_char, c_uchar};

/// Creates and saves in secured Wallet identity that can be used to
/// issue and verify Identity Ledger transaction.
///
/// #Params
/// client_id: id of sovrin client instance.
/// command_id: command id to map of callback to user context.
/// identity_json: Identity information as json. For current moment it is NYM transaction
///   data with optional information for creation of sign key (DID, Verkey, Role, Alias, Seed and etc...).
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// String identifier of this Identity.
///
/// #Errors
/// No method specific errors.
/// See `SovrinError` docs for common errors description.
#[no_mangle]
pub  extern fn wallet_sovrin_create_identity(client_id: i32, command_id: i32,
                                             identity_json: *const c_char,
                                             cb: extern fn(xcommand_id: i32, err: i32,
                                                           identity_id: *const c_char)) {
    unimplemented!();
}

/// Returns public information for Identity stored in secured Wallet.
///
/// #Params
/// client_id: id of sovrin client instance.
/// command_id: command id to map of callback to user context.
/// identity_id: Id of Identity stored in secured Wallet.
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Public Identity information as json (DID, Verkey, Role, Alias and etc...).
///
/// #Errors
/// No method specific errors.
/// See `SovrinError` docs for common errors description.
#[no_mangle]
pub  extern fn wallet_sovrin_get_identity(client_id: i32, command_id: i32,
                                          identity_id: *const c_char,
                                          cb: extern fn(xcommand_id: i32, err: i32,
                                                        identity_json: *const c_char)) {
    unimplemented!();
}

/// Returns list of ids for Identities stored in secured Wallet.
///
/// #Params
/// client_id: id of sovrin client instance.
/// command_id: command id to map of callback to user context.
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// List of stored identity ids.
///
/// #Errors
/// No method specific errors.
/// See `SovrinError` docs for common errors description.
#[no_mangle]
pub  extern fn wallet_sovrin_get_identities(client_id: i32, command_id: i32,
                                            cb: extern fn(xcommand_id: i32, err: i32,
                                                          identity_ids: [*const c_char])) {
    unimplemented!();
}

/// Creates all necessary keys and objects depends on received schema and returns schema_id.
///
/// #Params
/// client_id: id of sovrin client instance.
/// command_id: command id to map of callback to user context.
/// schema_json: Schema as a json. Includes name, version, attributes, keys, accumulator and etc.
///     Every empty field in the schema will be filled with the right value.
///     For example: if schema have an empty public key value, function will generate it. If it's
///         not necessary, value for public key field should be None.
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Returns id of schema.
///
/// #Errors
/// No method specific errors.
/// See `AnoncredsError` docs for common errors description.
#[no_mangle]
pub extern fn wallet_anoncreds_create_schema(client_id: i32, command_id: i32,
                                             schema_json: *const c_char,
                                             cb: extern fn(xcommand_id: i32, err: i32,
                                                           schema_id: *const c_char)) {
    unimplemented!();
}

/// Creates and saves in secured Wallet received claim.
///
/// #Params
/// client_id: id of sovrin client instance.
/// command_id: command id to map of callback to user context.
/// schema_id: id of schema for which claim was generated.
/// claim_json: Claim as a json.
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Returns id of claim.
///
/// #Errors
/// No method specific errors.
/// See `AnoncredsError` docs for common errors description.
#[no_mangle]
pub extern fn wallet_anoncreds_create_claim(client_id: i32, command_id: i32,
                                            schema_id: *const c_char,
                                            claim_json: *const c_char,
                                            cb: extern fn(xcommand_id: i32, err: i32,
                                                          claim_id: *const c_char)) {
    unimplemented!();
}<commit_msg>* Added new methods to anoncreds wallet<commit_after>extern crate libc;

use self::libc::{c_char, c_uchar};

/// Creates and saves in secured Wallet identity that can be used to
/// issue and verify Identity Ledger transaction.
///
/// #Params
/// client_id: id of sovrin client instance.
/// command_id: command id to map of callback to user context.
/// identity_json: Identity information as json. For current moment it is NYM transaction
///   data with optional information for creation of sign key (DID, Verkey, Role, Alias, Seed and etc...).
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// String identifier of this Identity.
///
/// #Errors
/// No method specific errors.
/// See `SovrinError` docs for common errors description.
#[no_mangle]
pub  extern fn wallet_sovrin_create_identity(client_id: i32, command_id: i32,
                                             identity_json: *const c_char,
                                             cb: extern fn(xcommand_id: i32, err: i32,
                                                           identity_id: *const c_char)) {
    unimplemented!();
}

/// Returns public information for Identity stored in secured Wallet.
///
/// #Params
/// client_id: id of sovrin client instance.
/// command_id: command id to map of callback to user context.
/// identity_id: Id of Identity stored in secured Wallet.
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Public Identity information as json (DID, Verkey, Role, Alias and etc...).
///
/// #Errors
/// No method specific errors.
/// See `SovrinError` docs for common errors description.
#[no_mangle]
pub  extern fn wallet_sovrin_get_identity(client_id: i32, command_id: i32,
                                          identity_id: *const c_char,
                                          cb: extern fn(xcommand_id: i32, err: i32,
                                                        identity_json: *const c_char)) {
    unimplemented!();
}

/// Returns list of ids for Identities stored in secured Wallet.
///
/// #Params
/// client_id: id of sovrin client instance.
/// command_id: command id to map of callback to user context.
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// List of stored identity ids.
///
/// #Errors
/// No method specific errors.
/// See `SovrinError` docs for common errors description.
#[no_mangle]
pub  extern fn wallet_sovrin_get_identities(client_id: i32, command_id: i32,
                                            cb: extern fn(xcommand_id: i32, err: i32,
                                                          identity_ids: [*const c_char])) {
    unimplemented!();
}

/// Creates all necessary keys and objects depends on received schema and returns schema_id.
///
/// #Params
/// client_id: id of sovrin client instance.
/// command_id: command id to map of callback to user context.
/// schema_json: Schema as a json. Includes name, version, attributes, keys, accumulator and etc.
///     Every empty field in the schema will be filled with the right value.
///     For example: if schema have an empty public key value, function will generate it. If it's
///         not necessary, value for public key field should be None.
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Returns id of schema.
///
/// #Errors
/// No method specific errors.
/// See `AnoncredsError` docs for common errors description.
#[no_mangle]
pub extern fn wallet_anoncreds_create_schema(client_id: i32, command_id: i32,
                                             schema_json: *const c_char,
                                             cb: extern fn(xcommand_id: i32, err: i32,
                                                           schema_id: *const c_char)) {
    unimplemented!();
}

// Returns public fields of schema
pub extern fn wallet_anoncreds_get_schema(client_id: i32, command_id: i32,
                                          schema_id: *const c_char,
                                          cb: extern fn(xcommand_id: i32, err: i32,
                                                        schema_json: *const c_char)) {
    unimplemented!();
}

// Generates new issuer keys and crypto variables for stored schema
pub extern fn wallet_anoncreds_schema_update_issuer_key(client_id: i32, command_id: i32,
                                                        schema_id: *const c_char,
                                                        cb: extern fn(xcommand_id: i32, err: i32)) {
    unimplemented!();
}

/// Creates and saves in secured Wallet received claim.
///
/// #Params
/// client_id: id of sovrin client instance.
/// command_id: command id to map of callback to user context.
/// schema_id: id of schema for which claim was generated.
/// claim_json: Claim as a json.
/// cb: Callback that takes command result as parameter.
///
/// #Returns
/// Returns id of claim.
///
/// #Errors
/// No method specific errors.
/// See `AnoncredsError` docs for common errors description.
#[no_mangle]
pub extern fn wallet_anoncreds_create_claim(client_id: i32, command_id: i32,
                                            schema_id: *const c_char,
                                            claim_json: *const c_char,
                                            cb: extern fn(xcommand_id: i32, err: i32,
                                                          claim_id: *const c_char)) {
    unimplemented!();
}<|endoftext|>


<commit_before>extern crate rand;

use std::env;
use rand::distributions::{Normal, IndependentSample};

/// Prints a sequence of Normal deviates.
///
/// # Examples
///
/// ```bash
/// cargo run --bin normal <num_deviates> <mean> <variance>
/// ```
/// This will print `<num_deviates>` float point numbers, one per line, to
/// standard output. These numbers will have a Normal distribution with the
/// specified mean and variance.
///
/// `<num_deviates>` must be a positive integer, `<mean>` and `<variance>` may
/// be integers or floating point numbers but `<variance>` must be positive.
fn main() {
  let args: Vec<String> = env::args().collect();

  let n: u32 = args[1].parse::<u32>().unwrap();
  let mean: f64 = args[2].parse::<f64>().unwrap();
  let variance: f64 = args[3].parse::<f64>().unwrap();

  let mut rng = rand::thread_rng();
  let normal = Normal::new(mean, variance.sqrt());

  for _ in 0..n {
    let x = normal.ind_sample(&mut rng);
    println!("{}", x)
  }
}
<commit_msg>Add assertions about arguments to normal generation binary.<commit_after>extern crate rand;

use std::env;
use rand::distributions::{Normal, IndependentSample};

/// Prints a sequence of Normal deviates.
///
/// # Examples
///
/// ```bash
/// cargo run --bin normal <num_deviates> <mean> <variance>
/// ```
/// This will print `<num_deviates>` float point numbers, one per line, to
/// standard output. These numbers will have a Normal distribution with the
/// specified mean and variance.
///
/// `<num_deviates>` must be a positive integer, `<mean>` and `<variance>` may
/// be integers or floating point numbers but `<variance>` must be positive.
fn main() {
  let args: Vec<String> = env::args().collect();

  let n: u32 = args[1].parse().ok().expect("<num_deviates> must be an integer.");
  let mean: f64 = args[2].parse().ok().expect("<mean> must be a floating point number.");
  let variance: f64 = args[3].parse().ok().expect("<variance> must be a floating point number.");

  assert!(n > 0 && variance.is_sign_positive());

  let mut rng = rand::thread_rng();
  let normal = Normal::new(mean, variance.sqrt());

  for _ in 0..n {
    let x = normal.ind_sample(&mut rng);
    println!("{}", x)
  }
}
<|endoftext|>


<commit_before>use std::ptr;

use super::{Block, ByteBuf};

enum Off {
    Left(usize),
    Right(usize),
}

pub struct Window<'a> {
    blocks: &'a [Block],
    off: Off,
    size: usize,
}

impl<'a> Window<'a> {
    pub fn as_bytes(&self) -> Option<&[u8]> {
        if self.size == 0 {
            return Some(&[]);
        }
        match self.blocks.len() == 1 {
            true => {
                let b = unsafe { self.blocks.get_unchecked(0) };
                let bytes = match self.off {
                    Off::Left(off) => b.as_bytes_range(b.read_pos() + off, self.size),
                    Off::Right(off) => b.as_bytes_range(b.write_pos() - off - self.size, self.size),
                };
                Some(bytes)
            }
            false => None,
        }
    }

    #[inline]
    pub fn to_bytes(&self) -> Vec<u8> {
        match self.off {
            Off::Left(off) => Self::to_bytes_left(self.blocks, off, self.size),
            Off::Right(off) => Self::to_bytes_right(self.blocks, off, self.size),
        }
    }

    fn to_bytes_left(blocks: &'a [Block], mut off: usize, mut size: usize) -> Vec<u8> {
        let mut bytes = Vec::with_capacity(size);
        unsafe { bytes.set_len(size) }
        let mut p_dst = bytes.as_mut_ptr();
        for block in blocks {
            off = block.read_pos() + off;
            let len = block.write_pos() - off;
            let p_src = block.ptr_at(off);
            if len >= size {
                unsafe {
                    ptr::copy_nonoverlapping(p_src, p_dst, size);
                }
                break;
            } else {
                unsafe {
                    ptr::copy_nonoverlapping(p_src, p_dst, len);
                    p_dst = p_dst.offset(len as isize);
                }
                size -= len;
                off = 0;
            }
        }
        bytes
    }

    fn to_bytes_right(blocks: &'a [Block], mut off: usize, mut size: usize) -> Vec<u8> {
        let mut bytes = Vec::with_capacity(size);
        unsafe { bytes.set_len(size) }
        let mut p_dst: *mut u8 = bytes.as_mut_ptr();
        p_dst = unsafe { p_dst.offset(size as isize) };
        for block in blocks.iter().rev() {
            off = block.write_pos() - off;
            let len = off - block.read_pos();
            if len >= size {
                let p_src = block.ptr_at(off - size);
                unsafe {
                    p_dst = p_dst.offset(-(size as isize));
                    ptr::copy_nonoverlapping(p_src, p_dst, size);
                }
                break;
            } else {
                let p_src = block.ptr_at(block.read_pos());
                unsafe {
                    p_dst = p_dst.offset(-(len as isize));
                    ptr::copy_nonoverlapping(p_src, p_dst, len);
                }
                size -= len;
                off = 0;
            }
        }
        bytes
    }

    #[inline]
    fn from_left(blocks: &'a [Block], off: usize, size: usize) -> Self {
        Window {
            blocks,
            off: Off::Left(off),
            size,
        }
    }

    #[inline]
    fn from_right(blocks: &'a [Block], off: usize, size: usize) -> Self {
        Window {
            blocks,
            off: Off::Right(off),
            size,
        }
    }

    #[inline]
    fn eq_left(&self, mut off: usize, mut other: &[u8]) -> bool {
        if self.size == other.len() {
            for block in self.blocks {
                off += block.read_pos();
                let len = block.write_pos() - off;
                if len >= other.len() {
                    let bytes = block.as_bytes_range(off, other.len());
                    return bytes == other;
                }
                let (left, right) = other.split_at(len);
                if block.as_bytes_range(off, len) != left {
                    return false;
                }
                other = right;
                off = 0;
            }
        }
        false
    }

    #[inline]
    fn eq_right(&self, mut off: usize, mut other: &[u8]) -> bool {
        if self.size == other.len() {
            for block in self.blocks.iter().rev() {
                off = block.write_pos() - off;
                let len = off - block.read_pos();
                if len >= other.len() {
                    let bytes = block.as_bytes_range(off - other.len(), other.len());
                    return bytes == other;
                }
                let (left, right) = other.split_at(other.len() - len);
                if block.as_bytes_range(block.read_pos(), len) != right {
                    return false;
                }
                other = left;
                off = 0;
            }
        }
        false
    }
}

impl<'a> PartialEq<&'a [u8]> for Window<'a> {
    fn eq(&self, other: &&[u8]) -> bool {
        match self.off {
            Off::Left(off) => self.eq_left(off, *other),
            Off::Right(off) => self.eq_right(off, *other),
        }
    }
}

impl<'a> PartialEq<Window<'a>> for &'a [u8] {
    fn eq(&self, other: &Window) -> bool {
        match other.off {
            Off::Left(off) => other.eq_left(off, self),
            Off::Right(off) => other.eq_right(off, self),
        }
    }
}

pub struct Windows<'a> {
    blocks: &'a [Block],
    off: usize,
    roff: usize,
    len: usize,
    size: usize, // window size
}

pub fn windows<'a>(buf: &'a ByteBuf, size: usize) -> Windows<'a> {
    let blocks: &[Block] = &buf.blocks[buf.idx..];
    let mut len = blocks.iter().fold(0, |n, b| n + b.len());
    len = if len >= size { len - size + 1 } else { 0 };
    Windows {
        blocks,
        off: 0,
        roff: 0,
        len,
        size,
    }
}

impl<'a> Iterator for Windows<'a> {
    type Item = Window<'a>;

    fn next(&mut self) -> Option<Self::Item> {
        if self.len == 0 {
            return None;
        }
        self.len -= 1;
        loop {
            match self.blocks.first() {
                Some(block) => if block.len() > self.off {
                    let window = Window::from_left(self.blocks, self.off, self.size);
                    self.off += 1;
                    return Some(window);
                },
                None => ::unreachable(),
            }
            self.blocks = &self.blocks[1..];
            self.off = 0;
        }
    }

    fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
        if n >= self.len {
            self.len = 0;
            return None;
        }
        let mut i = 0;
        for block in self.blocks {
            if n < block.len() {
                break;
            }
            n -= block.len();
            i += 1;
        }
        self.blocks = &self.blocks[i..];
        self.off = n;
        self.len -= n;
        self.next()
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.len, Some(self.len))
    }
}

impl<'a> DoubleEndedIterator for Windows<'a> {
    fn next_back(&mut self) -> Option<Self::Item> {
        if self.len == 0 {
            return None;
        }
        self.len -= 1;
        loop {
            match self.blocks.last() {
                Some(block) => if block.len() > self.roff {
                    let window = Window::from_right(self.blocks, self.roff, self.size);
                    self.roff += 1;
                    return Some(window);
                },
                None => ::unreachable(),
            }
            self.blocks = &self.blocks[..self.blocks.len() - 1];
            self.roff = 0;
        }
    }
}

impl<'a> ExactSizeIterator for Windows<'a> {
    #[inline]
    fn len(&self) -> usize {
        self.len
    }
}
<commit_msg>Rename Window::as_bytes to try_as_bytes and implement as_bytes to return Cow<[u8]><commit_after>use std::borrow::Cow;
use std::ptr;

use super::{Block, ByteBuf};

enum Off {
    Left(usize),
    Right(usize),
}

pub struct Window<'a> {
    blocks: &'a [Block],
    off: Off,
    size: usize,
}

impl<'a> Window<'a> {
    pub fn as_bytes(&self) -> Cow<[u8]> {
        if self.size == 0 {
            return Cow::Borrowed(&[]);
        }
        match self.blocks.len() == 1 {
            true => {
                let b = unsafe { self.blocks.get_unchecked(0) };
                let bytes = match self.off {
                    Off::Left(off) => b.as_bytes_range(b.read_pos() + off, self.size),
                    Off::Right(off) => b.as_bytes_range(b.write_pos() - off - self.size, self.size),
                };
                Cow::Borrowed(bytes)
            }
            false => Cow::Owned(self.to_bytes()),
        }
    }

    pub fn try_as_bytes(&self) -> Option<&[u8]> {
        if self.size == 0 {
            return Some(&[]);
        }
        match self.blocks.len() == 1 {
            true => {
                let b = unsafe { self.blocks.get_unchecked(0) };
                let bytes = match self.off {
                    Off::Left(off) => b.as_bytes_range(b.read_pos() + off, self.size),
                    Off::Right(off) => b.as_bytes_range(b.write_pos() - off - self.size, self.size),
                };
                Some(bytes)
            }
            false => None,
        }
    }

    #[inline]
    pub fn to_bytes(&self) -> Vec<u8> {
        match self.off {
            Off::Left(off) => Self::to_bytes_left(self.blocks, off, self.size),
            Off::Right(off) => Self::to_bytes_right(self.blocks, off, self.size),
        }
    }

    fn to_bytes_left(blocks: &'a [Block], mut off: usize, mut size: usize) -> Vec<u8> {
        let mut bytes = Vec::with_capacity(size);
        unsafe { bytes.set_len(size) }
        let mut p_dst = bytes.as_mut_ptr();
        for block in blocks {
            off = block.read_pos() + off;
            let len = block.write_pos() - off;
            let p_src = block.ptr_at(off);
            if len >= size {
                unsafe {
                    ptr::copy_nonoverlapping(p_src, p_dst, size);
                }
                break;
            } else {
                unsafe {
                    ptr::copy_nonoverlapping(p_src, p_dst, len);
                    p_dst = p_dst.offset(len as isize);
                }
                size -= len;
                off = 0;
            }
        }
        bytes
    }

    fn to_bytes_right(blocks: &'a [Block], mut off: usize, mut size: usize) -> Vec<u8> {
        let mut bytes = Vec::with_capacity(size);
        unsafe { bytes.set_len(size) }
        let mut p_dst: *mut u8 = bytes.as_mut_ptr();
        p_dst = unsafe { p_dst.offset(size as isize) };
        for block in blocks.iter().rev() {
            off = block.write_pos() - off;
            let len = off - block.read_pos();
            if len >= size {
                let p_src = block.ptr_at(off - size);
                unsafe {
                    p_dst = p_dst.offset(-(size as isize));
                    ptr::copy_nonoverlapping(p_src, p_dst, size);
                }
                break;
            } else {
                let p_src = block.ptr_at(block.read_pos());
                unsafe {
                    p_dst = p_dst.offset(-(len as isize));
                    ptr::copy_nonoverlapping(p_src, p_dst, len);
                }
                size -= len;
                off = 0;
            }
        }
        bytes
    }

    #[inline]
    fn from_left(blocks: &'a [Block], off: usize, size: usize) -> Self {
        Window {
            blocks,
            off: Off::Left(off),
            size,
        }
    }

    #[inline]
    fn from_right(blocks: &'a [Block], off: usize, size: usize) -> Self {
        Window {
            blocks,
            off: Off::Right(off),
            size,
        }
    }

    #[inline]
    fn eq_left(&self, mut off: usize, mut other: &[u8]) -> bool {
        if self.size == other.len() {
            for block in self.blocks {
                off += block.read_pos();
                let len = block.write_pos() - off;
                if len >= other.len() {
                    let bytes = block.as_bytes_range(off, other.len());
                    return bytes == other;
                }
                let (left, right) = other.split_at(len);
                if block.as_bytes_range(off, len) != left {
                    return false;
                }
                other = right;
                off = 0;
            }
        }
        false
    }

    #[inline]
    fn eq_right(&self, mut off: usize, mut other: &[u8]) -> bool {
        if self.size == other.len() {
            for block in self.blocks.iter().rev() {
                off = block.write_pos() - off;
                let len = off - block.read_pos();
                if len >= other.len() {
                    let bytes = block.as_bytes_range(off - other.len(), other.len());
                    return bytes == other;
                }
                let (left, right) = other.split_at(other.len() - len);
                if block.as_bytes_range(block.read_pos(), len) != right {
                    return false;
                }
                other = left;
                off = 0;
            }
        }
        false
    }
}

impl<'a> PartialEq<&'a [u8]> for Window<'a> {
    fn eq(&self, other: &&[u8]) -> bool {
        match self.off {
            Off::Left(off) => self.eq_left(off, *other),
            Off::Right(off) => self.eq_right(off, *other),
        }
    }
}

impl<'a> PartialEq<Window<'a>> for &'a [u8] {
    fn eq(&self, other: &Window) -> bool {
        match other.off {
            Off::Left(off) => other.eq_left(off, self),
            Off::Right(off) => other.eq_right(off, self),
        }
    }
}

pub struct Windows<'a> {
    blocks: &'a [Block],
    off: usize,
    roff: usize,
    len: usize,
    size: usize, // window size
}

pub fn windows<'a>(buf: &'a ByteBuf, size: usize) -> Windows<'a> {
    let blocks: &[Block] = &buf.blocks[buf.idx..];
    let mut len = blocks.iter().fold(0, |n, b| n + b.len());
    len = if len >= size { len - size + 1 } else { 0 };
    Windows {
        blocks,
        off: 0,
        roff: 0,
        len,
        size,
    }
}

impl<'a> Iterator for Windows<'a> {
    type Item = Window<'a>;

    fn next(&mut self) -> Option<Self::Item> {
        if self.len == 0 {
            return None;
        }
        self.len -= 1;
        loop {
            match self.blocks.first() {
                Some(block) => if block.len() > self.off {
                    let window = Window::from_left(self.blocks, self.off, self.size);
                    self.off += 1;
                    return Some(window);
                },
                None => ::unreachable(),
            }
            self.blocks = &self.blocks[1..];
            self.off = 0;
        }
    }

    fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
        if n >= self.len {
            self.len = 0;
            return None;
        }
        let mut i = 0;
        for block in self.blocks {
            if n < block.len() {
                break;
            }
            n -= block.len();
            i += 1;
        }
        self.blocks = &self.blocks[i..];
        self.off = n;
        self.len -= n;
        self.next()
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.len, Some(self.len))
    }
}

impl<'a> DoubleEndedIterator for Windows<'a> {
    fn next_back(&mut self) -> Option<Self::Item> {
        if self.len == 0 {
            return None;
        }
        self.len -= 1;
        loop {
            match self.blocks.last() {
                Some(block) => if block.len() > self.roff {
                    let window = Window::from_right(self.blocks, self.roff, self.size);
                    self.roff += 1;
                    return Some(window);
                },
                None => ::unreachable(),
            }
            self.blocks = &self.blocks[..self.blocks.len() - 1];
            self.roff = 0;
        }
    }
}

impl<'a> ExactSizeIterator for Windows<'a> {
    #[inline]
    fn len(&self) -> usize {
        self.len
    }
}
<|endoftext|>


<commit_before>// Copyright (C) 2018 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: Apache-2.0

use crate::{firmware::Metadata, runtime_settings::RuntimeSettings, update_package::UpdatePackage};

use failure::bail;
use log::debug;
use reqwest::{
    header::{HeaderMap, HeaderName, CONTENT_TYPE, RANGE, USER_AGENT},
    Client, StatusCode,
};
use serde_derive::Serialize;
use std::{path::Path, time::Duration};

#[cfg(test)]
pub(crate) mod tests;

pub(crate) struct Api<'a> {
    server: &'a str,
}

#[derive(Debug)]
pub(crate) enum ProbeResponse {
    NoUpdate,
    Update(UpdatePackage),
    ExtraPoll(i64),
}

impl<'a> Api<'a> {
    pub(crate) fn new(server: &'a str) -> Api<'a> {
        Api { server }
    }

    fn client(&self) -> Result<Client, failure::Error> {
        let mut headers = HeaderMap::new();

        headers.insert(USER_AGENT, "updatehub/next".parse()?);
        headers.insert(CONTENT_TYPE, "application/json".parse()?);
        headers.insert(
            HeaderName::from_static("api-content-type"),
            "application/vnd.updatehub-v1+json".parse()?,
        );

        Ok(Client::builder()
            .timeout(Duration::from_secs(10))
            .default_headers(headers)
            .build()?)
    }

    pub fn probe(
        &self,
        runtime_settings: &RuntimeSettings,
        firmware: &Metadata,
    ) -> Result<ProbeResponse, failure::Error> {
        let mut response = self
            .client()?
            .post(&format!("{}/upgrades", &self.server))
            .header(
                HeaderName::from_static("api-retries"),
                runtime_settings.retries(),
            )
            .json(firmware)
            .send()?;

        match response.status() {
            StatusCode::NOT_FOUND => Ok(ProbeResponse::NoUpdate),
            StatusCode::OK => {
                match response
                    .headers()
                    .get("add-extra-poll")
                    .and_then(|extra_poll| extra_poll.to_str().ok())
                    .and_then(|extra_poll| extra_poll.parse().ok())
                {
                    Some(extra_poll) => Ok(ProbeResponse::ExtraPoll(extra_poll)),
                    None => Ok(ProbeResponse::Update(UpdatePackage::parse(
                        &response.text()?,
                    )?)),
                }
            }
            _ => bail!("Invalid response. Status: {}", response.status()),
        }
    }

    pub fn download_object(
        &self,
        product_uid: &str,
        package_uid: &str,
        download_dir: &Path,
        object: &str,
    ) -> Result<(), failure::Error> {
        use std::fs::{create_dir_all, OpenOptions};

        // FIXME: Discuss the need of packages inside the route
        let mut client = self.client()?.get(&format!(
            "{}/products/{}/packages/{}/objects/{}",
            &self.server, product_uid, package_uid, object
        ));

        let path = download_dir;
        if !&path.exists() {
            debug!("Creating directory to store the downloads.");
            create_dir_all(&path)?;
        }

        let file = path.join(object);
        if file.exists() {
            client = client.header(RANGE, format!("bytes={}-", file.metadata()?.len() - 1));
        }

        let mut file = OpenOptions::new().create(true).append(true).open(&file)?;
        let mut response = client.send()?;
        if response.status().is_success() {
            response.copy_to(&mut file)?;
            return Ok(());
        }

        bail!("Couldn't download the object {}", object)
    }

    pub fn report(
        &self,
        state: &str,
        firmware: &'a Metadata,
        package_uid: &str,
        previous_state: Option<&str>,
        error_message: Option<String>,
    ) -> Result<(), failure::Error> {
        #[derive(Serialize)]
        #[serde(rename_all = "kebab-case")]
        struct Payload<'a> {
            status: &'a str,
            #[serde(flatten)]
            firmware: &'a Metadata,
            package_uid: &'a str,
            #[serde(skip_serializing_if = "Option::is_none")]
            previous_state: Option<&'a str>,
            #[serde(skip_serializing_if = "Option::is_none")]
            error_message: Option<String>,
        }

        let payload = Payload {
            status: state,
            firmware,
            package_uid,
            previous_state,
            error_message,
        };

        self.client()?
            .post(&format!("{}/report", &self.server))
            .json(&payload)
            .send()?;
        Ok(())
    }
}
<commit_msg>client: report: Use serde rename to adjust payload<commit_after>// Copyright (C) 2018 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: Apache-2.0

use crate::{firmware::Metadata, runtime_settings::RuntimeSettings, update_package::UpdatePackage};

use failure::bail;
use log::debug;
use reqwest::{
    header::{HeaderMap, HeaderName, CONTENT_TYPE, RANGE, USER_AGENT},
    Client, StatusCode,
};
use serde_derive::Serialize;
use std::{path::Path, time::Duration};

#[cfg(test)]
pub(crate) mod tests;

pub(crate) struct Api<'a> {
    server: &'a str,
}

#[derive(Debug)]
pub(crate) enum ProbeResponse {
    NoUpdate,
    Update(UpdatePackage),
    ExtraPoll(i64),
}

impl<'a> Api<'a> {
    pub(crate) fn new(server: &'a str) -> Api<'a> {
        Api { server }
    }

    fn client(&self) -> Result<Client, failure::Error> {
        let mut headers = HeaderMap::new();

        headers.insert(USER_AGENT, "updatehub/next".parse()?);
        headers.insert(CONTENT_TYPE, "application/json".parse()?);
        headers.insert(
            HeaderName::from_static("api-content-type"),
            "application/vnd.updatehub-v1+json".parse()?,
        );

        Ok(Client::builder()
            .timeout(Duration::from_secs(10))
            .default_headers(headers)
            .build()?)
    }

    pub fn probe(
        &self,
        runtime_settings: &RuntimeSettings,
        firmware: &Metadata,
    ) -> Result<ProbeResponse, failure::Error> {
        let mut response = self
            .client()?
            .post(&format!("{}/upgrades", &self.server))
            .header(
                HeaderName::from_static("api-retries"),
                runtime_settings.retries(),
            )
            .json(firmware)
            .send()?;

        match response.status() {
            StatusCode::NOT_FOUND => Ok(ProbeResponse::NoUpdate),
            StatusCode::OK => {
                match response
                    .headers()
                    .get("add-extra-poll")
                    .and_then(|extra_poll| extra_poll.to_str().ok())
                    .and_then(|extra_poll| extra_poll.parse().ok())
                {
                    Some(extra_poll) => Ok(ProbeResponse::ExtraPoll(extra_poll)),
                    None => Ok(ProbeResponse::Update(UpdatePackage::parse(
                        &response.text()?,
                    )?)),
                }
            }
            _ => bail!("Invalid response. Status: {}", response.status()),
        }
    }

    pub fn download_object(
        &self,
        product_uid: &str,
        package_uid: &str,
        download_dir: &Path,
        object: &str,
    ) -> Result<(), failure::Error> {
        use std::fs::{create_dir_all, OpenOptions};

        // FIXME: Discuss the need of packages inside the route
        let mut client = self.client()?.get(&format!(
            "{}/products/{}/packages/{}/objects/{}",
            &self.server, product_uid, package_uid, object
        ));

        let path = download_dir;
        if !&path.exists() {
            debug!("Creating directory to store the downloads.");
            create_dir_all(&path)?;
        }

        let file = path.join(object);
        if file.exists() {
            client = client.header(RANGE, format!("bytes={}-", file.metadata()?.len() - 1));
        }

        let mut file = OpenOptions::new().create(true).append(true).open(&file)?;
        let mut response = client.send()?;
        if response.status().is_success() {
            response.copy_to(&mut file)?;
            return Ok(());
        }

        bail!("Couldn't download the object {}", object)
    }

    pub fn report(
        &self,
        state: &str,
        firmware: &'a Metadata,
        package_uid: &str,
        previous_state: Option<&str>,
        error_message: Option<String>,
    ) -> Result<(), failure::Error> {
        #[derive(Serialize)]
        #[serde(rename_all = "kebab-case")]
        struct Payload<'a> {
            #[serde(rename = "status")]
            state: &'a str,
            #[serde(flatten)]
            firmware: &'a Metadata,
            package_uid: &'a str,
            #[serde(skip_serializing_if = "Option::is_none")]
            previous_state: Option<&'a str>,
            #[serde(skip_serializing_if = "Option::is_none")]
            error_message: Option<String>,
        }

        let payload = Payload {
            state,
            firmware,
            package_uid,
            previous_state,
            error_message,
        };

        self.client()?
            .post(&format!("{}/report", &self.server))
            .json(&payload)
            .send()?;
        Ok(())
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 The vulkano developers
// 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. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

//! Synchronization primitives for Vulkan objects.
//!
//! In Vulkan, you have to manually ensure two things:
//!
//! - That a buffer or an image are not read and written simultaneously (similarly to the CPU).
//! - That writes to a buffer or an image are propagated to other queues by inserting memory
//!   barriers.
//!
//! But don't worry ; this is automatically enforced by this library (as long as you don't use
//! any unsafe function). See the `memory` module for more info.
//!

use std::ops;
use std::sync::Arc;
use device::Queue;
use vk;

pub use self::event::Event;
pub use self::fence::Fence;
pub use self::fence::FenceWaitError;
pub use self::future::DummyFuture;
pub use self::future::GpuFuture;
pub use self::future::SemaphoreSignalFuture;
pub use self::future::FenceSignalFuture;
pub use self::future::JoinFuture;
pub use self::semaphore::Semaphore;

mod event;
mod fence;
mod future;
mod semaphore;

/// Base trait for objects that can be used as resources and must be synchronized.
// TODO: remove
pub unsafe trait Resource {
    /// Returns in which queue family or families this resource can be used.
    fn sharing_mode(&self) -> &SharingMode;

    /// Returns true if the `gpu_access` function should be passed a fence.
    #[inline]
    fn requires_fence(&self) -> bool {
        true
    }

    /// Returns true if the `gpu_access` function should be passed a semaphore.
    #[inline]
    fn requires_semaphore(&self) -> bool {
        true
    }
}

/// Declares in which queue(s) a resource can be used.
///
/// When you create a buffer or an image, you have to tell the Vulkan library in which queue
/// families it will be used. The vulkano library requires you to tell in which queue famiily
/// the resource will be used, even for exclusive mode.
#[derive(Debug, Clone, PartialEq, Eq)]
// TODO: remove
pub enum SharingMode {
    /// The resource is used is only one queue family.
    Exclusive(u32),
    /// The resource is used in multiple queue families. Can be slower than `Exclusive`.
    Concurrent(Vec<u32>),       // TODO: Vec is too expensive here
}

impl<'a> From<&'a Arc<Queue>> for SharingMode {
    #[inline]
    fn from(queue: &'a Arc<Queue>) -> SharingMode {
        SharingMode::Exclusive(queue.family().id())
    }
}

impl<'a> From<&'a [&'a Arc<Queue>]> for SharingMode {
    #[inline]
    fn from(queues: &'a [&'a Arc<Queue>]) -> SharingMode {
        SharingMode::Concurrent(queues.iter().map(|queue| {
            queue.family().id()
        }).collect())
    }
}

/// Declares in which queue(s) a resource can be used.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Sharing<I> where I: Iterator<Item = u32> {
    /// The resource is used is only one queue family.
    Exclusive,
    /// The resource is used in multiple queue families. Can be slower than `Exclusive`.
    Concurrent(I),
}

macro_rules! pipeline_stages {
    ($($elem:ident => $val:expr,)+) => (
        #[derive(Debug, Copy, Clone)]
        #[allow(missing_docs)]
        pub struct PipelineStages {
            $(
                pub $elem: bool,
            )+
        }

        impl PipelineStages {
            /// Builds an `PipelineStages` struct with none of the stages set.
            pub fn none() -> PipelineStages {
                PipelineStages {
                    $(
                        $elem: false,
                    )+
                }
            }
        }

        impl ops::BitOr for PipelineStages {
            type Output = PipelineStages;

            #[inline]
            fn bitor(self, rhs: PipelineStages) -> PipelineStages {
                PipelineStages {
                    $(
                        $elem: self.$elem || rhs.$elem,
                    )+
                }
            }
        }

        impl ops::BitOrAssign for PipelineStages {
            #[inline]
            fn bitor_assign(&mut self, rhs: PipelineStages) {
                $(
                    self.$elem = self.$elem || rhs.$elem;
                )+
            }
        }

        #[doc(hidden)]
        impl Into<vk::PipelineStageFlagBits> for PipelineStages {
            #[inline]
            fn into(self) -> vk::PipelineStageFlagBits {
                let mut result = 0;
                $(
                    if self.$elem { result |= $val }
                )+
                result
            }
        }
    );
}

pipeline_stages!{
    top_of_pipe => vk::PIPELINE_STAGE_TOP_OF_PIPE_BIT,
    draw_indirect => vk::PIPELINE_STAGE_DRAW_INDIRECT_BIT,
    vertex_input => vk::PIPELINE_STAGE_VERTEX_INPUT_BIT,
    vertex_shader => vk::PIPELINE_STAGE_VERTEX_SHADER_BIT,
    tessellation_control_shader => vk::PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT,
    tessellation_evaluation_shader => vk::PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT,
    geometry_shader => vk::PIPELINE_STAGE_GEOMETRY_SHADER_BIT,
    fragment_shader => vk::PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
    early_fragment_tests => vk::PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
    late_fragment_tests => vk::PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
    color_attachment_output => vk::PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
    compute_shader => vk::PIPELINE_STAGE_COMPUTE_SHADER_BIT,
    transfer => vk::PIPELINE_STAGE_TRANSFER_BIT,
    bottom_of_pipe => vk::PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
    host => vk::PIPELINE_STAGE_HOST_BIT,
    all_graphics => vk::PIPELINE_STAGE_ALL_GRAPHICS_BIT,
    all_commands => vk::PIPELINE_STAGE_ALL_COMMANDS_BIT,
}

macro_rules! access_flags {
    ($($elem:ident => $val:expr,)+) => (
        #[derive(Debug, Copy, Clone)]
        #[allow(missing_docs)]
        pub struct AccessFlagBits {
            $(
                pub $elem: bool,
            )+
        }

        impl AccessFlagBits {
            /// Builds an `AccessFlagBits` struct with all bits set.
            pub fn all() -> AccessFlagBits {
                AccessFlagBits {
                    $(
                        $elem: true,
                    )+
                }
            }

            /// Builds an `AccessFlagBits` struct with none of the bits set.
            pub fn none() -> AccessFlagBits {
                AccessFlagBits {
                    $(
                        $elem: false,
                    )+
                }
            }
        }

        impl ops::BitOr for AccessFlagBits {
            type Output = AccessFlagBits;

            #[inline]
            fn bitor(self, rhs: AccessFlagBits) -> AccessFlagBits {
                AccessFlagBits {
                    $(
                        $elem: self.$elem || rhs.$elem,
                    )+
                }
            }
        }

        impl ops::BitOrAssign for AccessFlagBits {
            #[inline]
            fn bitor_assign(&mut self, rhs: AccessFlagBits) {
                $(
                    self.$elem = self.$elem || rhs.$elem;
                )+
            }
        }

        #[doc(hidden)]
        impl Into<vk::AccessFlagBits> for AccessFlagBits {
            #[inline]
            fn into(self) -> vk::AccessFlagBits {
                let mut result = 0;
                $(
                    if self.$elem { result |= $val }
                )+
                result
            }
        }
    );
}

access_flags!{
    indirect_command_read => vk::ACCESS_INDIRECT_COMMAND_READ_BIT,
    index_read => vk::ACCESS_INDEX_READ_BIT,
    vertex_attribute_read => vk::ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
    uniform_read => vk::ACCESS_UNIFORM_READ_BIT,
    input_attachment_read => vk::ACCESS_INPUT_ATTACHMENT_READ_BIT,
    shader_read => vk::ACCESS_SHADER_READ_BIT,
    shader_write => vk::ACCESS_SHADER_WRITE_BIT,
    color_attachment_read => vk::ACCESS_COLOR_ATTACHMENT_READ_BIT,
    color_attachment_write => vk::ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
    depth_stencil_attachment_read => vk::ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
    depth_stencil_attachment_write => vk::ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
    transfer_read => vk::ACCESS_TRANSFER_READ_BIT,
    transfer_write => vk::ACCESS_TRANSFER_WRITE_BIT,
    host_read => vk::ACCESS_HOST_READ_BIT,
    host_write => vk::ACCESS_HOST_WRITE_BIT,
    memory_read => vk::ACCESS_MEMORY_READ_BIT,
    memory_write => vk::ACCESS_MEMORY_WRITE_BIT,
}
<commit_msg>Remove useless type<commit_after>// Copyright (c) 2016 The vulkano developers
// 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. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

//! Synchronization primitives for Vulkan objects.
//!
//! In Vulkan, you have to manually ensure two things:
//!
//! - That a buffer or an image are not read and written simultaneously (similarly to the CPU).
//! - That writes to a buffer or an image are propagated to other queues by inserting memory
//!   barriers.
//!
//! But don't worry ; this is automatically enforced by this library (as long as you don't use
//! any unsafe function). See the `memory` module for more info.
//!

use std::ops;
use std::sync::Arc;
use device::Queue;
use vk;

pub use self::event::Event;
pub use self::fence::Fence;
pub use self::fence::FenceWaitError;
pub use self::future::DummyFuture;
pub use self::future::GpuFuture;
pub use self::future::SemaphoreSignalFuture;
pub use self::future::FenceSignalFuture;
pub use self::future::JoinFuture;
pub use self::semaphore::Semaphore;

mod event;
mod fence;
mod future;
mod semaphore;

/// Declares in which queue(s) a resource can be used.
///
/// When you create a buffer or an image, you have to tell the Vulkan library in which queue
/// families it will be used. The vulkano library requires you to tell in which queue famiily
/// the resource will be used, even for exclusive mode.
#[derive(Debug, Clone, PartialEq, Eq)]
// TODO: remove
pub enum SharingMode {
    /// The resource is used is only one queue family.
    Exclusive(u32),
    /// The resource is used in multiple queue families. Can be slower than `Exclusive`.
    Concurrent(Vec<u32>),       // TODO: Vec is too expensive here
}

impl<'a> From<&'a Arc<Queue>> for SharingMode {
    #[inline]
    fn from(queue: &'a Arc<Queue>) -> SharingMode {
        SharingMode::Exclusive(queue.family().id())
    }
}

impl<'a> From<&'a [&'a Arc<Queue>]> for SharingMode {
    #[inline]
    fn from(queues: &'a [&'a Arc<Queue>]) -> SharingMode {
        SharingMode::Concurrent(queues.iter().map(|queue| {
            queue.family().id()
        }).collect())
    }
}

/// Declares in which queue(s) a resource can be used.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Sharing<I> where I: Iterator<Item = u32> {
    /// The resource is used is only one queue family.
    Exclusive,
    /// The resource is used in multiple queue families. Can be slower than `Exclusive`.
    Concurrent(I),
}

macro_rules! pipeline_stages {
    ($($elem:ident => $val:expr,)+) => (
        #[derive(Debug, Copy, Clone)]
        #[allow(missing_docs)]
        pub struct PipelineStages {
            $(
                pub $elem: bool,
            )+
        }

        impl PipelineStages {
            /// Builds an `PipelineStages` struct with none of the stages set.
            pub fn none() -> PipelineStages {
                PipelineStages {
                    $(
                        $elem: false,
                    )+
                }
            }
        }

        impl ops::BitOr for PipelineStages {
            type Output = PipelineStages;

            #[inline]
            fn bitor(self, rhs: PipelineStages) -> PipelineStages {
                PipelineStages {
                    $(
                        $elem: self.$elem || rhs.$elem,
                    )+
                }
            }
        }

        impl ops::BitOrAssign for PipelineStages {
            #[inline]
            fn bitor_assign(&mut self, rhs: PipelineStages) {
                $(
                    self.$elem = self.$elem || rhs.$elem;
                )+
            }
        }

        #[doc(hidden)]
        impl Into<vk::PipelineStageFlagBits> for PipelineStages {
            #[inline]
            fn into(self) -> vk::PipelineStageFlagBits {
                let mut result = 0;
                $(
                    if self.$elem { result |= $val }
                )+
                result
            }
        }
    );
}

pipeline_stages!{
    top_of_pipe => vk::PIPELINE_STAGE_TOP_OF_PIPE_BIT,
    draw_indirect => vk::PIPELINE_STAGE_DRAW_INDIRECT_BIT,
    vertex_input => vk::PIPELINE_STAGE_VERTEX_INPUT_BIT,
    vertex_shader => vk::PIPELINE_STAGE_VERTEX_SHADER_BIT,
    tessellation_control_shader => vk::PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT,
    tessellation_evaluation_shader => vk::PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT,
    geometry_shader => vk::PIPELINE_STAGE_GEOMETRY_SHADER_BIT,
    fragment_shader => vk::PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
    early_fragment_tests => vk::PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
    late_fragment_tests => vk::PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
    color_attachment_output => vk::PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
    compute_shader => vk::PIPELINE_STAGE_COMPUTE_SHADER_BIT,
    transfer => vk::PIPELINE_STAGE_TRANSFER_BIT,
    bottom_of_pipe => vk::PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
    host => vk::PIPELINE_STAGE_HOST_BIT,
    all_graphics => vk::PIPELINE_STAGE_ALL_GRAPHICS_BIT,
    all_commands => vk::PIPELINE_STAGE_ALL_COMMANDS_BIT,
}

macro_rules! access_flags {
    ($($elem:ident => $val:expr,)+) => (
        #[derive(Debug, Copy, Clone)]
        #[allow(missing_docs)]
        pub struct AccessFlagBits {
            $(
                pub $elem: bool,
            )+
        }

        impl AccessFlagBits {
            /// Builds an `AccessFlagBits` struct with all bits set.
            pub fn all() -> AccessFlagBits {
                AccessFlagBits {
                    $(
                        $elem: true,
                    )+
                }
            }

            /// Builds an `AccessFlagBits` struct with none of the bits set.
            pub fn none() -> AccessFlagBits {
                AccessFlagBits {
                    $(
                        $elem: false,
                    )+
                }
            }
        }

        impl ops::BitOr for AccessFlagBits {
            type Output = AccessFlagBits;

            #[inline]
            fn bitor(self, rhs: AccessFlagBits) -> AccessFlagBits {
                AccessFlagBits {
                    $(
                        $elem: self.$elem || rhs.$elem,
                    )+
                }
            }
        }

        impl ops::BitOrAssign for AccessFlagBits {
            #[inline]
            fn bitor_assign(&mut self, rhs: AccessFlagBits) {
                $(
                    self.$elem = self.$elem || rhs.$elem;
                )+
            }
        }

        #[doc(hidden)]
        impl Into<vk::AccessFlagBits> for AccessFlagBits {
            #[inline]
            fn into(self) -> vk::AccessFlagBits {
                let mut result = 0;
                $(
                    if self.$elem { result |= $val }
                )+
                result
            }
        }
    );
}

access_flags!{
    indirect_command_read => vk::ACCESS_INDIRECT_COMMAND_READ_BIT,
    index_read => vk::ACCESS_INDEX_READ_BIT,
    vertex_attribute_read => vk::ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
    uniform_read => vk::ACCESS_UNIFORM_READ_BIT,
    input_attachment_read => vk::ACCESS_INPUT_ATTACHMENT_READ_BIT,
    shader_read => vk::ACCESS_SHADER_READ_BIT,
    shader_write => vk::ACCESS_SHADER_WRITE_BIT,
    color_attachment_read => vk::ACCESS_COLOR_ATTACHMENT_READ_BIT,
    color_attachment_write => vk::ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
    depth_stencil_attachment_read => vk::ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
    depth_stencil_attachment_write => vk::ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
    transfer_read => vk::ACCESS_TRANSFER_READ_BIT,
    transfer_write => vk::ACCESS_TRANSFER_WRITE_BIT,
    host_read => vk::ACCESS_HOST_READ_BIT,
    host_write => vk::ACCESS_HOST_WRITE_BIT,
    memory_read => vk::ACCESS_MEMORY_READ_BIT,
    memory_write => vk::ACCESS_MEMORY_WRITE_BIT,
}
<|endoftext|>


<commit_before><commit_msg>Use premultiplied alpha for brush primitives.<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2016 The vulkano developers
// 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. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

use std::sync::Arc;

use buffer::Buffer;
use buffer::BufferViewRef;
use buffer::TrackedBuffer;
use command_buffer::cmd::CommandsListSink;
use descriptor::descriptor_set::DescriptorSet;
use descriptor::descriptor_set::TrackedDescriptorSet;
use descriptor::descriptor_set::UnsafeDescriptorSetLayout;
use descriptor::descriptor_set::DescriptorPool;
use descriptor::descriptor_set::sys::UnsafeDescriptorSet;
use descriptor::descriptor_set::sys::DescriptorWrite;
use descriptor::pipeline_layout::PipelineLayoutRef;
use image::TrackedImageView;
use image::sys::Layout;
use sync::AccessFlagBits;
use sync::PipelineStages;

/// A simple immutable descriptor set.
///
/// It is named "simple" because creating such a descriptor set allocates from a pool, and because
/// it can't be modified once created. It is sufficient for most usages, but in some situations
/// you may wish to use something more optimized instead.
///
/// In order to build a `SimpleDescriptorSet`, you need to use a `SimpleDescriptorSetBuilder`. But
/// the easiest way is to use the `simple_descriptor_set!` macro.
///
/// The template parameter of the `SimpleDescriptorSet` is very complex, and you shouldn't try to
/// express it explicitely. If you want to store your descriptor set in a struct or in a `Vec` for
/// example, you are encouraged to turn `SimpleDescriptorSet` into a `Box<DescriptorSet>` or a
/// `Arc<DescriptorSet>`.
///
/// # Example
// TODO:
pub struct SimpleDescriptorSet<R> {
    inner: UnsafeDescriptorSet,
    resources: R,
}

impl<R> SimpleDescriptorSet<R> {
    /// Returns the layout used to create this descriptor set.
    #[inline]
    pub fn set_layout(&self) -> &Arc<UnsafeDescriptorSetLayout> {
        self.inner.layout()
    }
}

unsafe impl<R> DescriptorSet for SimpleDescriptorSet<R> {
    #[inline]
    fn inner(&self) -> &UnsafeDescriptorSet {
        &self.inner
    }
}

unsafe impl<R> TrackedDescriptorSet for SimpleDescriptorSet<R>
    where R: SimpleDescriptorSetResourcesCollection
{
    #[inline]
    fn add_transition<'a>(&'a self, sink: &mut CommandsListSink<'a>) {
        self.resources.add_transition(sink)
    }
}

/// Builds a descriptor set in the form of a `SimpleDescriptorSet` object.
// TODO: more doc
#[macro_export]
macro_rules! simple_descriptor_set {
    ($layout:expr, $set_num:expr, {$($name:ident: $val:expr),*$(,)*}) => ({
        use $crate::descriptor::descriptor_set::SimpleDescriptorSetBuilder;
        use $crate::descriptor::descriptor_set::SimpleDescriptorSetBufferExt;

        let builder = SimpleDescriptorSetBuilder::new($layout, $set_num);

        $(
            let builder = $val.add_me(builder, stringify!($name));
        )*

        builder.build()
    });
}

/// Prototype of a `SimpleDescriptorSet`.
///
/// > **Note**: You are encouraged to use the `simple_descriptor_set!` macro instead of
/// > manipulating these internals.
///
/// # Example
// TODO: example here
pub struct SimpleDescriptorSetBuilder<L, R> {
    layout: L,
    set_id: usize,
    writes: Vec<DescriptorWrite>,
    resources: R,
}

impl<L> SimpleDescriptorSetBuilder<L, ()> where L: PipelineLayoutRef {
    /// Builds a new prototype for a `SimpleDescriptorSet`. Requires a reference to a pipeline
    /// layout, and the id of the set within the layout.
    ///
    /// # Panic
    ///
    /// - Panics if the set id is out of range.
    ///
    pub fn new(layout: L, set_id: usize) -> SimpleDescriptorSetBuilder<L, ()> {
        assert!(layout.desc().num_sets() > set_id);

        SimpleDescriptorSetBuilder {
            layout: layout,
            set_id: set_id,
            writes: Vec::new(),
            resources: (),
        }
    }
}

impl<L, R> SimpleDescriptorSetBuilder<L, R> where L: PipelineLayoutRef {
    /// Builds a `SimpleDescriptorSet` from the builder.
    pub fn build(self) -> SimpleDescriptorSet<R> {
        // TODO: check that we filled everything
        // TODO: don't create a pool every time
        let pool = Arc::new(DescriptorPool::raw(self.layout.device()).unwrap());       // FIXME: error
        let set_layout = self.layout.descriptor_set_layout(self.set_id).unwrap();       // FIXME: error

        let set = unsafe {
            let mut set = UnsafeDescriptorSet::uninitialized_raw(&pool, set_layout).unwrap();      // FIXME: error
            set.write(self.writes.into_iter());
            set
        };

        SimpleDescriptorSet {
            inner: set,
            resources: self.resources,
        }
    }
}

/// Trait implemented on buffer values that can be appended to a simple descriptor set builder.
pub unsafe trait SimpleDescriptorSetBufferExt<L, R> {
    type Out;

    // TODO: return Result
    fn add_me(self, i: SimpleDescriptorSetBuilder<L, R>, name: &str)
              -> SimpleDescriptorSetBuilder<L, Self::Out>;
}

unsafe impl<L, R, T> SimpleDescriptorSetBufferExt<L, R> for T
    where T: TrackedBuffer, L: PipelineLayoutRef
{
    type Out = (R, SimpleDescriptorSetBuf<T>);

    fn add_me(self, i: SimpleDescriptorSetBuilder<L, R>, name: &str)
              -> SimpleDescriptorSetBuilder<L, Self::Out>
    {
        let (set_id, binding_id) = i.layout.desc().descriptor_by_name(name).unwrap();    // TODO: Result instead
        assert_eq!(set_id, i.set_id);       // TODO: Result instead
        let desc = i.layout.desc().descriptor(set_id, binding_id).unwrap();     // TODO: Result instead

        //i.writes.push(DescriptorWrite:);

        SimpleDescriptorSetBuilder {
            layout: i.layout,
            set_id: i.set_id,
            writes: i.writes,
            resources: (i.resources, SimpleDescriptorSetBuf {
                buffer: self,
                write: !desc.readonly,
                stage: PipelineStages::none(),      // FIXME:
                access: AccessFlagBits::none(),     // FIXME:
            })
        }
    }
}

/// Internal trait related to the `SimpleDescriptorSet` system.
pub unsafe trait SimpleDescriptorSetResourcesCollection {
    #[inline]
    fn add_transition<'a>(&'a self, sink: &mut CommandsListSink<'a>);
}

unsafe impl SimpleDescriptorSetResourcesCollection for () {
    #[inline]
    fn add_transition<'a>(&'a self, _: &mut CommandsListSink<'a>) {
    }
}

/// Internal object related to the `SimpleDescriptorSet` system.
pub struct SimpleDescriptorSetBuf<B> {
    buffer: B,
    write: bool,
    stage: PipelineStages,
    access: AccessFlagBits,
}

unsafe impl<B> SimpleDescriptorSetResourcesCollection for SimpleDescriptorSetBuf<B>
    where B: TrackedBuffer
{
    #[inline]
    fn add_transition<'a>(&'a self, sink: &mut CommandsListSink<'a>) {
        sink.add_buffer_transition(&self.buffer, 0, self.buffer.size(), self.write);
    }
}

/// Internal object related to the `SimpleDescriptorSet` system.
pub struct SimpleDescriptorSetBufView<V> where V: BufferViewRef {
    view: V,
    write: bool,
    stage: PipelineStages,
    access: AccessFlagBits,
}

unsafe impl<V> SimpleDescriptorSetResourcesCollection for SimpleDescriptorSetBufView<V>
    where V: BufferViewRef, V::Buffer: TrackedBuffer
{
    #[inline]
    fn add_transition<'a>(&'a self, sink: &mut CommandsListSink<'a>) {
        sink.add_buffer_transition(&self.view.view().buffer(), 0, self.view.view().buffer().size(), self.write);
    }
}

/// Internal object related to the `SimpleDescriptorSet` system.
pub struct SimpleDescriptorSetImg<I> {
    image: I,
    write: bool,
    first_mipmap: u32,
    num_mipmaps: u32,
    first_layer: u32,
    num_layers: u32,
    layout: Layout,
    stage: PipelineStages,
    access: AccessFlagBits,
}

unsafe impl<I> SimpleDescriptorSetResourcesCollection for SimpleDescriptorSetImg<I>
    where I: TrackedImageView
{
    #[inline]
    fn add_transition<'a>(&'a self, sink: &mut CommandsListSink<'a>) {
        /*sink.add_image_transition(&self.image, self.first_layer, self.num_layers,
                                  self.first_mipmap, self.num_mipmaps, self.write,
                                  self.layout);*/
                                  // TODO:
        unimplemented!()
    }
}

unsafe impl<A, B> SimpleDescriptorSetResourcesCollection for (A, B)
    where A: SimpleDescriptorSetResourcesCollection,
          B: SimpleDescriptorSetResourcesCollection
{
    #[inline]
    fn add_transition<'a>(&'a self, sink: &mut CommandsListSink<'a>) {
        self.0.add_transition(sink);
        self.1.add_transition(sink);
    }
}
<commit_msg>Fix image transition<commit_after>// Copyright (c) 2016 The vulkano developers
// 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. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

use std::sync::Arc;

use buffer::Buffer;
use buffer::BufferViewRef;
use buffer::TrackedBuffer;
use command_buffer::cmd::CommandsListSink;
use descriptor::descriptor_set::DescriptorSet;
use descriptor::descriptor_set::TrackedDescriptorSet;
use descriptor::descriptor_set::UnsafeDescriptorSetLayout;
use descriptor::descriptor_set::DescriptorPool;
use descriptor::descriptor_set::sys::UnsafeDescriptorSet;
use descriptor::descriptor_set::sys::DescriptorWrite;
use descriptor::pipeline_layout::PipelineLayoutRef;
use image::TrackedImageView;
use image::sys::Layout;
use sync::AccessFlagBits;
use sync::PipelineStages;

/// A simple immutable descriptor set.
///
/// It is named "simple" because creating such a descriptor set allocates from a pool, and because
/// it can't be modified once created. It is sufficient for most usages, but in some situations
/// you may wish to use something more optimized instead.
///
/// In order to build a `SimpleDescriptorSet`, you need to use a `SimpleDescriptorSetBuilder`. But
/// the easiest way is to use the `simple_descriptor_set!` macro.
///
/// The template parameter of the `SimpleDescriptorSet` is very complex, and you shouldn't try to
/// express it explicitely. If you want to store your descriptor set in a struct or in a `Vec` for
/// example, you are encouraged to turn `SimpleDescriptorSet` into a `Box<DescriptorSet>` or a
/// `Arc<DescriptorSet>`.
///
/// # Example
// TODO:
pub struct SimpleDescriptorSet<R> {
    inner: UnsafeDescriptorSet,
    resources: R,
}

impl<R> SimpleDescriptorSet<R> {
    /// Returns the layout used to create this descriptor set.
    #[inline]
    pub fn set_layout(&self) -> &Arc<UnsafeDescriptorSetLayout> {
        self.inner.layout()
    }
}

unsafe impl<R> DescriptorSet for SimpleDescriptorSet<R> {
    #[inline]
    fn inner(&self) -> &UnsafeDescriptorSet {
        &self.inner
    }
}

unsafe impl<R> TrackedDescriptorSet for SimpleDescriptorSet<R>
    where R: SimpleDescriptorSetResourcesCollection
{
    #[inline]
    fn add_transition<'a>(&'a self, sink: &mut CommandsListSink<'a>) {
        self.resources.add_transition(sink)
    }
}

/// Builds a descriptor set in the form of a `SimpleDescriptorSet` object.
// TODO: more doc
#[macro_export]
macro_rules! simple_descriptor_set {
    ($layout:expr, $set_num:expr, {$($name:ident: $val:expr),*$(,)*}) => ({
        use $crate::descriptor::descriptor_set::SimpleDescriptorSetBuilder;
        use $crate::descriptor::descriptor_set::SimpleDescriptorSetBufferExt;

        let builder = SimpleDescriptorSetBuilder::new($layout, $set_num);

        $(
            let builder = $val.add_me(builder, stringify!($name));
        )*

        builder.build()
    });
}

/// Prototype of a `SimpleDescriptorSet`.
///
/// > **Note**: You are encouraged to use the `simple_descriptor_set!` macro instead of
/// > manipulating these internals.
///
/// # Example
// TODO: example here
pub struct SimpleDescriptorSetBuilder<L, R> {
    layout: L,
    set_id: usize,
    writes: Vec<DescriptorWrite>,
    resources: R,
}

impl<L> SimpleDescriptorSetBuilder<L, ()> where L: PipelineLayoutRef {
    /// Builds a new prototype for a `SimpleDescriptorSet`. Requires a reference to a pipeline
    /// layout, and the id of the set within the layout.
    ///
    /// # Panic
    ///
    /// - Panics if the set id is out of range.
    ///
    pub fn new(layout: L, set_id: usize) -> SimpleDescriptorSetBuilder<L, ()> {
        assert!(layout.desc().num_sets() > set_id);

        SimpleDescriptorSetBuilder {
            layout: layout,
            set_id: set_id,
            writes: Vec::new(),
            resources: (),
        }
    }
}

impl<L, R> SimpleDescriptorSetBuilder<L, R> where L: PipelineLayoutRef {
    /// Builds a `SimpleDescriptorSet` from the builder.
    pub fn build(self) -> SimpleDescriptorSet<R> {
        // TODO: check that we filled everything
        // TODO: don't create a pool every time
        let pool = Arc::new(DescriptorPool::raw(self.layout.device()).unwrap());       // FIXME: error
        let set_layout = self.layout.descriptor_set_layout(self.set_id).unwrap();       // FIXME: error

        let set = unsafe {
            let mut set = UnsafeDescriptorSet::uninitialized_raw(&pool, set_layout).unwrap();      // FIXME: error
            set.write(self.writes.into_iter());
            set
        };

        SimpleDescriptorSet {
            inner: set,
            resources: self.resources,
        }
    }
}

/// Trait implemented on buffer values that can be appended to a simple descriptor set builder.
pub unsafe trait SimpleDescriptorSetBufferExt<L, R> {
    type Out;

    // TODO: return Result
    fn add_me(self, i: SimpleDescriptorSetBuilder<L, R>, name: &str)
              -> SimpleDescriptorSetBuilder<L, Self::Out>;
}

unsafe impl<L, R, T> SimpleDescriptorSetBufferExt<L, R> for T
    where T: TrackedBuffer, L: PipelineLayoutRef
{
    type Out = (R, SimpleDescriptorSetBuf<T>);

    fn add_me(self, i: SimpleDescriptorSetBuilder<L, R>, name: &str)
              -> SimpleDescriptorSetBuilder<L, Self::Out>
    {
        let (set_id, binding_id) = i.layout.desc().descriptor_by_name(name).unwrap();    // TODO: Result instead
        assert_eq!(set_id, i.set_id);       // TODO: Result instead
        let desc = i.layout.desc().descriptor(set_id, binding_id).unwrap();     // TODO: Result instead

        //i.writes.push(DescriptorWrite:);

        SimpleDescriptorSetBuilder {
            layout: i.layout,
            set_id: i.set_id,
            writes: i.writes,
            resources: (i.resources, SimpleDescriptorSetBuf {
                buffer: self,
                write: !desc.readonly,
                stage: PipelineStages::none(),      // FIXME:
                access: AccessFlagBits::none(),     // FIXME:
            })
        }
    }
}

/// Internal trait related to the `SimpleDescriptorSet` system.
pub unsafe trait SimpleDescriptorSetResourcesCollection {
    #[inline]
    fn add_transition<'a>(&'a self, sink: &mut CommandsListSink<'a>);
}

unsafe impl SimpleDescriptorSetResourcesCollection for () {
    #[inline]
    fn add_transition<'a>(&'a self, _: &mut CommandsListSink<'a>) {
    }
}

/// Internal object related to the `SimpleDescriptorSet` system.
pub struct SimpleDescriptorSetBuf<B> {
    buffer: B,
    write: bool,
    stage: PipelineStages,
    access: AccessFlagBits,
}

unsafe impl<B> SimpleDescriptorSetResourcesCollection for SimpleDescriptorSetBuf<B>
    where B: TrackedBuffer
{
    #[inline]
    fn add_transition<'a>(&'a self, sink: &mut CommandsListSink<'a>) {
        sink.add_buffer_transition(&self.buffer, 0, self.buffer.size(), self.write);
    }
}

/// Internal object related to the `SimpleDescriptorSet` system.
pub struct SimpleDescriptorSetBufView<V> where V: BufferViewRef {
    view: V,
    write: bool,
    stage: PipelineStages,
    access: AccessFlagBits,
}

unsafe impl<V> SimpleDescriptorSetResourcesCollection for SimpleDescriptorSetBufView<V>
    where V: BufferViewRef, V::Buffer: TrackedBuffer
{
    #[inline]
    fn add_transition<'a>(&'a self, sink: &mut CommandsListSink<'a>) {
        sink.add_buffer_transition(&self.view.view().buffer(), 0, self.view.view().buffer().size(), self.write);
    }
}

/// Internal object related to the `SimpleDescriptorSet` system.
pub struct SimpleDescriptorSetImg<I> {
    image: I,
    write: bool,
    first_mipmap: u32,
    num_mipmaps: u32,
    first_layer: u32,
    num_layers: u32,
    layout: Layout,
    stage: PipelineStages,
    access: AccessFlagBits,
}

unsafe impl<I> SimpleDescriptorSetResourcesCollection for SimpleDescriptorSetImg<I>
    where I: TrackedImageView
{
    #[inline]
    fn add_transition<'a>(&'a self, sink: &mut CommandsListSink<'a>) {
        // FIXME: adjust layers & mipmaps with the view's parameters
        sink.add_image_transition(&self.image.image(), self.first_layer, self.num_layers,
                                  self.first_mipmap, self.num_mipmaps, self.write,
                                  self.layout);
    }
}

unsafe impl<A, B> SimpleDescriptorSetResourcesCollection for (A, B)
    where A: SimpleDescriptorSetResourcesCollection,
          B: SimpleDescriptorSetResourcesCollection
{
    #[inline]
    fn add_transition<'a>(&'a self, sink: &mut CommandsListSink<'a>) {
        self.0.add_transition(sink);
        self.1.add_transition(sink);
    }
}
<|endoftext|>


<commit_before>#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Dimensions {
    pub pixels: (u32,u32),
    pub scale: f64,
}

impl Dimensions {
    pub fn points(&self) -> (f64, f64) {
    	let (width, height) = self.pixels;
        (width as f64 / self.scale, height as f64 / self.scale)
    }

    pub fn approx_equal_point_size(lhs: Dimensions, rhs:Dimensions) -> bool {
    	let (l_width, l_height) = lhs.points();
    	let (r_width, r_height) = rhs.points();
    	(l_width - r_width).abs() < 0.01 && (l_height - r_height).abs() < 0.01
    }
}
<commit_msg>Notes<commit_after>#[derive(Copy, Clone, Debug, PartialEq)]
pub struct Dimensions {
    pub pixels: (u32,u32),
    pub scale: f64,
}

impl Dimensions {
    pub fn points(&self) -> (f64, f64) {
    	let (width, height) = self.pixels;
        (width as f64 / self.scale, height as f64 / self.scale)
    }

    pub fn approx_equal_point_size(lhs: Dimensions, rhs:Dimensions) -> bool {
    	let (l_width, l_height) = lhs.points();
    	let (r_width, r_height) = rhs.points();
    	(l_width - r_width).abs() < 0.01 && (l_height - r_height).abs() < 0.01
    }
}

<|endoftext|>


<commit_before>use html5ever::rcdom::{Handle, RcDom};
use html5ever::rcdom::NodeEnum::{Element, Text};
use super::Entry;

pub fn find_entry_elements(dom: &mut RcDom) -> Vec<Option<Entry>> {
    let mut entries = vec![];
    walk_tree(&dom.document, String::from(""), &mut entries);
    entries
}

pub fn walk_tree(h: &Handle, context: String, entries: &mut Vec<Option<Entry>>) {
    let mut current_context: Option<String> = None;

    for e in &h.borrow().children {
        if let Element(ref name, _, ref attrs) = e.borrow().node {
            let tag = &(*name.local.to_ascii_lowercase());
            if let Some(class_attr) = attrs.iter()
                .find(|x| x.name == qualname!("", "class"))
                .and_then(|c| Some(c.clone().value.to_string())) {

                match (tag, class_attr.as_str()) {
                    ("h3", "impl") => {
                        entries.push(Entry::new(e.clone(),
                                                "Method",
                                                extract_entry_name(e, "in-band"),
                                                true))
                    }

                    ("h4", "method") | ("h3", "method") => {
                        if let Some(entry_name) = extract_entry_name(e, "fnname") {
                            entries.push(Entry::new(e.clone(),
                                                    "Method",
                                                    Some(format!("{}::{}", context, entry_name)),
                                                    false))
                        }
                    }

                    ("h3", "method stab") => {
                        if let Some(entry_name) = extract_entry_name(e, "fnname") {
                            entries.push(Entry::new(e.clone(),
                                                    "Method",
                                                    Some(format!("{}::{}", context, entry_name)),
                                                    false))
                        }
                    }

                    ("span", "variant") => {
                        if let Some(entry_name_with_parenthesis) =
                            extract_entry_name(e, "invisible") {
                            let entry_name = entry_name_with_parenthesis.split('(')
                                .nth(0)
                                .expect("split did not have any elements?");

                            entries.push(Entry::new(e.clone(),
                                                    "Variant",
                                                    Some(format!("{}::{}", context, entry_name)),
                                                    false))
                        }
                    }

                    ("span", "structfield") => {
                        if let Some(field_and_type) = extract_entry_name(e, "invisible") {
                            let entry_name = field_and_type.split(':')
                                .nth(0)
                                .expect("split did not have any elements?");

                            entries.push(Entry::new(e.clone(),
                                                    "Field",
                                                    Some(format!("{}::{}", context, entry_name)),
                                                    false))
                        }
                    }

                    ("h4", "type") => {
                        if let Some(entry_name) = extract_entry_name(e, "type") {
                            entries.push(Entry::new(e.clone(),
                                                    "Type",
                                                    Some(format!("{}::{}", context, entry_name)),
                                                    false))
                        }
                    }

                    ("section", "content") => {
                        if extract_entry_name(e, "constant").is_some() {
                            entries.push(Entry::new(e.clone(),
                                                    "Constant",
                                                    extract_entry_name(e, "in-band"),
                                                    false))
                        } else if extract_entry_name(e, "enum").is_some() {
                            current_context = extract_entry_name(e, "in-band");
                            entries.push(Entry::new(e.clone(), "Enum", current_context.clone(), false))
                        } else if extract_entry_name(e, "macro").is_some() {
                            entries.push(Entry::new(e.clone(),
                                                    "Macro",
                                                    extract_entry_name(e, "in-band"),
                                                    false))
                        } else if extract_entry_name(e, "trait").is_some() {
                            current_context = extract_entry_name(e, "in-band");
                            entries.push(Entry::new(e.clone(),
                                                    "Trait",
                                                    current_context.clone(),
                                                    false))
                        } else if extract_entry_name(e, "mod").is_some() {
                            entries.push(Entry::new(e.clone(),
                                                    "Module",
                                                    extract_entry_name(e, "in-band"),
                                                    false))
                        } else if extract_entry_name(e, "struct").is_some() {
                            current_context = extract_entry_name(e, "in-band");
                            entries.push(Entry::new(e.clone(),
                                                    "Struct",
                                                    current_context.clone(),
                                                    false))
                        } else if extract_entry_name(e, "fn").is_some() {
                            entries.push(Entry::new(e.clone(),
                                                    "Function",
                                                    extract_entry_name(e, "in-band"),
                                                    false))
                        }
                    }

                    (_, _) => {}
                }
            }
        }

        walk_tree(e,
                  current_context.clone().unwrap_or(context.clone()),
                  entries);
    }
}

pub fn extract_entry_name(e: &Handle, element_class: &str) -> Option<String> {
    let ignore_first_text_element =
        !["invisible", "type", "fnname"].iter().any(|&x| x == element_class);
    find_element_with_class(e, element_class).and_then(|x| get_text(&x, ignore_first_text_element))
}

fn find_element_with_class(h: &Handle, class_value: &str) -> Option<Handle> {
    for e in &h.borrow().children {
        if let Element(_, _, ref attrs) = e.borrow().node {
            if attrs.iter()
                .find(|attr| attr.name == qualname!("", "class"))
                .and_then(|attr| Some(attr.value.to_string() == class_value))
                .unwrap_or(false) {
                return Some(e.clone());
            }
        }

        // recurse down and check children
        if let Some(x) = find_element_with_class(e, class_value) {
            return Some(x);
        }
    }
    None
}

fn get_text(h: &Handle, ignore_first_text_element: bool) -> Option<String> {
    let mut text_tokens = Vec::new();
    let node = h.borrow();

    // get all text from current and all descendent elements: hallo heise! -> hallo heise !
    for e in &node.children {
        match e.borrow().node {
            Text(ref t) => text_tokens.push(t.to_string()),

            // if node is not a text node, recurse down
            _ => {
                if let Some(s) = get_text(e, false) {
                    text_tokens.push(s)
                }
            }
        }
    }

    // adjust extracted text: mainly remove white space and some unicode characters
    if text_tokens.is_empty() {
        None
    } else {
        if ignore_first_text_element {
            text_tokens.remove(0);
        }
        Some(String::from(text_tokens.join(" ").trim())
            .replace("\u{a0}", "")
            .replace(" >", ">")
            .replace(" <", "<")
            .replace(" ::", "::")
            .replace(":: ", "::")
            .replace("  ", " "))
    }
}
<commit_msg>Remove unnecessary case<commit_after>use html5ever::rcdom::{Handle, RcDom};
use html5ever::rcdom::NodeEnum::{Element, Text};
use super::Entry;

pub fn find_entry_elements(dom: &mut RcDom) -> Vec<Option<Entry>> {
    let mut entries = vec![];
    walk_tree(&dom.document, String::from(""), &mut entries);
    entries
}

pub fn walk_tree(h: &Handle, context: String, entries: &mut Vec<Option<Entry>>) {
    let mut current_context: Option<String> = None;

    for e in &h.borrow().children {
        if let Element(ref name, _, ref attrs) = e.borrow().node {
            let tag = &(*name.local.to_ascii_lowercase());
            if let Some(class_attr) = attrs.iter()
                .find(|x| x.name == qualname!("", "class"))
                .and_then(|c| Some(c.clone().value.to_string())) {

                match (tag, class_attr.as_str()) {
                    ("h3", "impl") => {
                        entries.push(Entry::new(e.clone(),
                                                "Method",
                                                extract_entry_name(e, "in-band"),
                                                true))
                    }

                    ("h4", "method") | ("h3", "method") => {
                        if let Some(entry_name) = extract_entry_name(e, "fnname") {
                            entries.push(Entry::new(e.clone(),
                                                    "Method",
                                                    Some(format!("{}::{}", context, entry_name)),
                                                    false))
                        }
                    }

                    ("span", "variant") => {
                        if let Some(entry_name_with_parenthesis) =
                            extract_entry_name(e, "invisible") {
                            let entry_name = entry_name_with_parenthesis.split('(')
                                .nth(0)
                                .expect("split did not have any elements?");

                            entries.push(Entry::new(e.clone(),
                                                    "Variant",
                                                    Some(format!("{}::{}", context, entry_name)),
                                                    false))
                        }
                    }

                    ("span", "structfield") => {
                        if let Some(field_and_type) = extract_entry_name(e, "invisible") {
                            let entry_name = field_and_type.split(':')
                                .nth(0)
                                .expect("split did not have any elements?");

                            entries.push(Entry::new(e.clone(),
                                                    "Field",
                                                    Some(format!("{}::{}", context, entry_name)),
                                                    false))
                        }
                    }

                    ("h4", "type") => {
                        if let Some(entry_name) = extract_entry_name(e, "type") {
                            entries.push(Entry::new(e.clone(),
                                                    "Type",
                                                    Some(format!("{}::{}", context, entry_name)),
                                                    false))
                        }
                    }

                    ("section", "content") => {
                        if extract_entry_name(e, "constant").is_some() {
                            entries.push(Entry::new(e.clone(),
                                                    "Constant",
                                                    extract_entry_name(e, "in-band"),
                                                    false))
                        } else if extract_entry_name(e, "enum").is_some() {
                            current_context = extract_entry_name(e, "in-band");
                            entries.push(Entry::new(e.clone(), "Enum", current_context.clone(), false))
                        } else if extract_entry_name(e, "macro").is_some() {
                            entries.push(Entry::new(e.clone(),
                                                    "Macro",
                                                    extract_entry_name(e, "in-band"),
                                                    false))
                        } else if extract_entry_name(e, "trait").is_some() {
                            current_context = extract_entry_name(e, "in-band");
                            entries.push(Entry::new(e.clone(),
                                                    "Trait",
                                                    current_context.clone(),
                                                    false))
                        } else if extract_entry_name(e, "mod").is_some() {
                            entries.push(Entry::new(e.clone(),
                                                    "Module",
                                                    extract_entry_name(e, "in-band"),
                                                    false))
                        } else if extract_entry_name(e, "struct").is_some() {
                            current_context = extract_entry_name(e, "in-band");
                            entries.push(Entry::new(e.clone(),
                                                    "Struct",
                                                    current_context.clone(),
                                                    false))
                        } else if extract_entry_name(e, "fn").is_some() {
                            entries.push(Entry::new(e.clone(),
                                                    "Function",
                                                    extract_entry_name(e, "in-band"),
                                                    false))
                        }
                    }

                    (_, _) => {}
                }
            }
        }

        walk_tree(e,
                  current_context.clone().unwrap_or(context.clone()),
                  entries);
    }
}

pub fn extract_entry_name(e: &Handle, element_class: &str) -> Option<String> {
    let ignore_first_text_element =
        !["invisible", "type", "fnname"].iter().any(|&x| x == element_class);
    find_element_with_class(e, element_class).and_then(|x| get_text(&x, ignore_first_text_element))
}

fn find_element_with_class(h: &Handle, class_value: &str) -> Option<Handle> {
    for e in &h.borrow().children {
        if let Element(_, _, ref attrs) = e.borrow().node {
            if attrs.iter()
                .find(|attr| attr.name == qualname!("", "class"))
                .and_then(|attr| Some(attr.value.to_string() == class_value))
                .unwrap_or(false) {
                return Some(e.clone());
            }
        }

        // recurse down and check children
        if let Some(x) = find_element_with_class(e, class_value) {
            return Some(x);
        }
    }
    None
}

fn get_text(h: &Handle, ignore_first_text_element: bool) -> Option<String> {
    let mut text_tokens = Vec::new();
    let node = h.borrow();

    // get all text from current and all descendent elements: hallo heise! -> hallo heise !
    for e in &node.children {
        match e.borrow().node {
            Text(ref t) => text_tokens.push(t.to_string()),

            // if node is not a text node, recurse down
            _ => {
                if let Some(s) = get_text(e, false) {
                    text_tokens.push(s)
                }
            }
        }
    }

    // adjust extracted text: mainly remove white space and some unicode characters
    if text_tokens.is_empty() {
        None
    } else {
        if ignore_first_text_element {
            text_tokens.remove(0);
        }
        Some(String::from(text_tokens.join(" ").trim())
            .replace("\u{a0}", "")
            .replace(" >", ">")
            .replace(" <", "<")
            .replace(" ::", "::")
            .replace(":: ", "::")
            .replace("  ", " "))
    }
}
<|endoftext|>