<commit_before>
// Copyright 2017 The gltf Library 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. This file may not be copied, modified, or distributed
// except according to those terms.
use byteorder::{LE, ReadBytesExt};

use Error;

use std::{fmt, io};

/// Represents a Glb loader error.
#[derive(Debug)]
pub enum GlbError {
    /// Io error occured.
    IoError(::std::io::Error),
    /// Unsupported version.
    Version(u32),
    /// Magic says that file is not glTF.
    Magic([u8; 4]),
    /// Length specified in GLB header exceeeds that of slice.
    Length {
        /// length specified in GLB header.
        length: u32,
        /// Actual length of data read.
        length_read: usize,
    },
    /// Stream ended before we could read the chunk.
    ChunkLength {
        /// chunkType error happened at.
        ty: ChunkType,
        /// chunkLength.
        length: u32,
        /// Actual length of data read.
        length_read: usize,
    },
    /// Chunk of this chunkType was not expected.
    ChunkType(ChunkType),
    /// Unknown chunk type.
    UnknownChunkType([u8; 4]),
}

/// The contents of a .glb file.
#[derive(Clone, Debug)]
pub struct Glb<'a> {
    /// The header section of the `.glb` file.
    pub header: Header,
    /// The JSON section of the `.glb` file.
    pub json: &'a [u8],
    /// The optional BIN section of the `.glb` file.
    pub bin: Option<&'a [u8]>,
}

/// The header section of a .glb file.
#[derive(Copy, Clone, Debug)]
pub struct Header {
    /// Must be `b"glTF"`.
    pub magic: [u8; 4],
    /// Must be `2`.
    pub version: u32,
    /// Must match the length of the parent .glb file.
    pub length: u32,
}

/// GLB chunk type.
#[derive(Copy, Clone, Debug)]
pub enum ChunkType {
    /// JSON chunk.
    Json,
    /// BIN\0 chunk.
    Bin,
}

/// Chunk header with no data read yet.
#[derive(Copy, Clone, Debug)]
struct ChunkHeader {
    /// The length of the chunk data in byte excluding the header.
    length: u32,
    /// Chunk type.
    ty: ChunkType,
}

impl Header {
    fn from_reader<R: io::Read>(mut reader: R) -> Result<Self, GlbError> {
        use self::GlbError::IoError;
        let mut magic = [0; 4];
        reader.read_exact(&mut magic).map_err(IoError)?;
        // We only validate magic as we don't care for version and length of
        // contents, the caller does.  Let them decide what to do next with
        // regard to version and length.
        if &magic == b"glTF" {
            Ok(Self {
                magic,
                version: reader.read_u32::<LE>().map_err(IoError)?,
                length: reader.read_u32::<LE>().map_err(IoError)?,
            })
        } else {
            Err(GlbError::Magic(magic))
        }
    }
}

impl ChunkHeader {
    fn from_reader<R: io::Read>(mut reader: R) -> Result<Self, GlbError> {
        use self::GlbError::IoError;
        let length = reader.read_u32::<LE>().map_err(IoError)?;
        let mut ty = [0; 4];
        reader.read_exact(&mut ty).map_err(IoError)?;
        let ty = match &ty {
            b"JSON" => Ok(ChunkType::Json),
            b"BIN\0" => Ok(ChunkType::Bin),
            _ => Err(GlbError::UnknownChunkType(ty)),
        }?;
        Ok(Self { length, ty })
    }
}

impl<'a> Glb<'a> {
    /// Splits loaded GLB into its three chunks.
    ///
    /// * Mandatory GLB header.
    /// * Mandatory JSON chunk.
    /// * Optional BIN chunk.
    pub fn from_slice(mut data: &'a [u8]) -> Result<Self, Error> {
        let header = Header::from_reader(&mut data)
            .and_then(|header| if header.length as usize <= data.len() {
                Ok(header)
            } else {
                Err(GlbError::Length {
                    length: header.length,
                    length_read: data.len(),
                })
            })
            .map_err(Error::Glb)?;
        match header.version {
            2 => Self::from_v2(data)
                .map(|(json, bin)| Glb { header, json, bin })
                .map_err(Error::Glb),
            x => Err(Error::Glb(GlbError::Version(x)))
        }
    }

    /// Does the loading job for you.  Provided buf will be cleared before new
    /// data will be written.  When error happens, if only header was read, buf
    /// will not be mutated, otherwise, buf will be empty.
    pub fn from_reader<R: io::Read>(mut reader: R,
                                    buf: &'a mut Vec<u8>) -> Result<Self, Error> {
        let header = Header::from_reader(&mut reader).map_err(Error::Glb)?;
        match header.version {
            2 => {
                buf.clear();
                buf.reserve(header.length as usize);
                // SAFETY: We are doing unsafe operation on a user-supplied
                // container!  Make sure not to expose user to uninitialized
                // data if an error happens during reading.
                //
                // It is guaranteed by reserve's implementation that the reserve
                // call will make buf's capacity _at least_ header.length.
                //
                // We do not read contents of the Vec unless it is fully
                // initialized.
                unsafe { buf.set_len(header.length as usize) };
                if let Err(e) = reader.read(buf)
                    .map_err(GlbError::IoError)
                    .and_then(|len| if len == header.length as usize {
                        Ok(())
                    } else {
                        Err(GlbError::Length {
                            length: header.length,
                            length_read: len,
                        })
                    })
                {
                    // SAFETY: It is safe to not run destructors because u8 has
                    // none.
                    unsafe { buf.set_len(0) };
                    Err(Error::Glb(e))
                } else {
                    Self::from_v2(buf)
                       .map(|(json, bin)| Glb { header, json, bin })
                       .map_err(Error::Glb)
                }
            }
            x => Err(Error::Glb(GlbError::Version(x)))
        }
    }

    /// Loads GLB for glTF 2.
    fn from_v2(mut data: &'a [u8]) -> Result<(&'a [u8], Option<&'a [u8]>), GlbError> {
        let (json, mut data) = ChunkHeader::from_reader(&mut data)
            .and_then(|json_h| if let ChunkType::Json = json_h.ty {
                Ok(json_h)
            } else {
                Err(GlbError::ChunkType(json_h.ty))
            })
            .and_then(|json_h| if json_h.length as usize <= data.len() {
                Ok(json_h)
            } else {
                Err(GlbError::ChunkLength {
                    ty: json_h.ty,
                    length: json_h.length,
                    length_read: data.len(),
                })
            })
            // PANIC: We have verified that json_h.length is no greater than
            // that of data.len().
            .map(|json_h| data.split_at(json_h.length as usize))?;

        let bin = if data.len() > 0 {
            ChunkHeader::from_reader(&mut data)
                .and_then(|bin_h| if let ChunkType::Bin = bin_h.ty {
                    Ok(bin_h)
                } else {
                    Err(GlbError::ChunkType(bin_h.ty))
                })
                .and_then(|bin_h| if bin_h.length as usize <= data.len() {
                    Ok(bin_h)
                } else {
                    Err(GlbError::ChunkLength {
                        ty: bin_h.ty,
                        length: bin_h.length,
                        length_read: data.len(),
                    })
                })
                // PANIC: we have verified that bin_h.length is no greater than
                // that of data.len().
                .map(|bin_h| data.split_at(bin_h.length as usize))
                .map(|(x, _)| Some(x))?
        } else {
            None
        };
        Ok((json, bin))
    }
}

impl fmt::Display for GlbError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use std::error::Error;
        write!(f, "{}", self.description())
    }
}

impl ::std::error::Error for GlbError {
    fn description(&self) -> &str {
         match *self {
             GlbError::IoError(ref e) => e.description(),
             GlbError::Version(_) => "unsupported version",
             GlbError::Magic(_) => "not glTF magic",
             GlbError::Length { .. } => "could not completely read the object",
             GlbError::ChunkLength { ty, .. } => match ty {
                 ChunkType::Json => "JSON chunk length exceeds that of slice",
                 ChunkType::Bin => "BIN\\0 chunk length exceeds that of slice",
             },
             GlbError::ChunkType(ty) => match ty {
                 ChunkType::Json => "was not expecting JSON chunk",
                 ChunkType::Bin => "was not expecting BIN\\0 chunk",
             },
             GlbError::UnknownChunkType(_) => "unknown chunk type",
        }
    }
}
<commit_msg>Ignore header when setting up for contents<commit_after>
// Copyright 2017 The gltf Library 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. This file may not be copied, modified, or distributed
// except according to those terms.
use byteorder::{LE, ReadBytesExt};

use Error;

use std::{fmt, io};

/// Represents a Glb loader error.
#[derive(Debug)]
pub enum GlbError {
    /// Io error occured.
    IoError(::std::io::Error),
    /// Unsupported version.
    Version(u32),
    /// Magic says that file is not glTF.
    Magic([u8; 4]),
    /// Length specified in GLB header exceeeds that of slice.
    Length {
        /// length specified in GLB header.
        length: u32,
        /// Actual length of data read.
        length_read: usize,
    },
    /// Stream ended before we could read the chunk.
    ChunkLength {
        /// chunkType error happened at.
        ty: ChunkType,
        /// chunkLength.
        length: u32,
        /// Actual length of data read.
        length_read: usize,
    },
    /// Chunk of this chunkType was not expected.
    ChunkType(ChunkType),
    /// Unknown chunk type.
    UnknownChunkType([u8; 4]),
}

/// The contents of a .glb file.
#[derive(Clone, Debug)]
pub struct Glb<'a> {
    /// The header section of the `.glb` file.
    pub header: Header,
    /// The JSON section of the `.glb` file.
    pub json: &'a [u8],
    /// The optional BIN section of the `.glb` file.
    pub bin: Option<&'a [u8]>,
}

/// The header section of a .glb file.
#[derive(Copy, Clone, Debug)]
pub struct Header {
    /// Must be `b"glTF"`.
    pub magic: [u8; 4],
    /// Must be `2`.
    pub version: u32,
    /// Must match the length of the parent .glb file.
    pub length: u32,
}

/// GLB chunk type.
#[derive(Copy, Clone, Debug)]
pub enum ChunkType {
    /// JSON chunk.
    Json,
    /// BIN\0 chunk.
    Bin,
}

/// Chunk header with no data read yet.
#[derive(Copy, Clone, Debug)]
struct ChunkHeader {
    /// The length of the chunk data in byte excluding the header.
    length: u32,
    /// Chunk type.
    ty: ChunkType,
}

impl Header {
    fn from_reader<R: io::Read>(mut reader: R) -> Result<Self, GlbError> {
        use self::GlbError::IoError;
        let mut magic = [0; 4];
        reader.read_exact(&mut magic).map_err(IoError)?;
        // We only validate magic as we don't care for version and length of
        // contents, the caller does.  Let them decide what to do next with
        // regard to version and length.
        if &magic == b"glTF" {
            Ok(Self {
                magic,
                version: reader.read_u32::<LE>().map_err(IoError)?,
                length: reader.read_u32::<LE>().map_err(IoError)?,
            })
        } else {
            Err(GlbError::Magic(magic))
        }
    }

    fn size_of() -> usize { 12 }
}

impl ChunkHeader {
    fn from_reader<R: io::Read>(mut reader: R) -> Result<Self, GlbError> {
        use self::GlbError::IoError;
        let length = reader.read_u32::<LE>().map_err(IoError)?;
        let mut ty = [0; 4];
        reader.read_exact(&mut ty).map_err(IoError)?;
        let ty = match &ty {
            b"JSON" => Ok(ChunkType::Json),
            b"BIN\0" => Ok(ChunkType::Bin),
            _ => Err(GlbError::UnknownChunkType(ty)),
        }?;
        Ok(Self { length, ty })
    }
}

impl<'a> Glb<'a> {
    /// Splits loaded GLB into its three chunks.
    ///
    /// * Mandatory GLB header.
    /// * Mandatory JSON chunk.
    /// * Optional BIN chunk.
    pub fn from_slice(mut data: &'a [u8]) -> Result<Self, Error> {
        let header = Header::from_reader(&mut data)
            .and_then(|header| if header.length as usize <= data.len() {
                Ok(header)
            } else {
                Err(GlbError::Length {
                    length: header.length,
                    length_read: data.len(),
                })
            })
            .map_err(Error::Glb)?;
        match header.version {
            2 => Self::from_v2(data)
                .map(|(json, bin)| Glb { header, json, bin })
                .map_err(Error::Glb),
            x => Err(Error::Glb(GlbError::Version(x)))
        }
    }

    /// Does the loading job for you.  Provided buf will be cleared before new
    /// data will be written.  When error happens, if only header was read, buf
    /// will not be mutated, otherwise, buf will be empty.
    pub fn from_reader<R: io::Read>(mut reader: R,
                                    buf: &'a mut Vec<u8>) -> Result<Self, Error> {
        let header = Header::from_reader(&mut reader).map_err(Error::Glb)?;
        match header.version {
            2 => {
                let glb_len = header.length - Header::size_of() as u32;
                buf.clear();
                buf.reserve(glb_len as usize);
                // SAFETY: We are doing unsafe operation on a user-supplied
                // container!  Make sure not to expose user to uninitialized
                // data if an error happens during reading.
                //
                // It is guaranteed by reserve's implementation that the reserve
                // call will make buf's capacity _at least_ buf_len.
                //
                // We do not read contents of the Vec unless it is fully
                // initialized.
                unsafe { buf.set_len(glb_len as usize) };
                if let Err(e) = reader.read(buf)
                    .map_err(GlbError::IoError)
                    .and_then(|len| if len == header.length as usize {
                        Ok(())
                    } else {
                        Err(GlbError::Length {
                            length: glb_len,
                            length_read: len,
                        })
                    })
                {
                    // SAFETY: It is safe to not run destructors because u8 has
                    // none.
                    unsafe { buf.set_len(0) };
                    Err(Error::Glb(e))
                } else {
                    Self::from_v2(buf)
                       .map(|(json, bin)| Glb { header, json, bin })
                       .map_err(Error::Glb)
                }
            }
            x => Err(Error::Glb(GlbError::Version(x)))
        }
    }

    /// Loads GLB for glTF 2.
    fn from_v2(mut data: &'a [u8]) -> Result<(&'a [u8], Option<&'a [u8]>), GlbError> {
        let (json, mut data) = ChunkHeader::from_reader(&mut data)
            .and_then(|json_h| if let ChunkType::Json = json_h.ty {
                Ok(json_h)
            } else {
                Err(GlbError::ChunkType(json_h.ty))
            })
            .and_then(|json_h| if json_h.length as usize <= data.len() {
                Ok(json_h)
            } else {
                Err(GlbError::ChunkLength {
                    ty: json_h.ty,
                    length: json_h.length,
                    length_read: data.len(),
                })
            })
            // PANIC: We have verified that json_h.length is no greater than
            // that of data.len().
            .map(|json_h| data.split_at(json_h.length as usize))?;

        let bin = if data.len() > 0 {
            ChunkHeader::from_reader(&mut data)
                .and_then(|bin_h| if let ChunkType::Bin = bin_h.ty {
                    Ok(bin_h)
                } else {
                    Err(GlbError::ChunkType(bin_h.ty))
                })
                .and_then(|bin_h| if bin_h.length as usize <= data.len() {
                    Ok(bin_h)
                } else {
                    Err(GlbError::ChunkLength {
                        ty: bin_h.ty,
                        length: bin_h.length,
                        length_read: data.len(),
                    })
                })
                // PANIC: we have verified that bin_h.length is no greater than
                // that of data.len().
                .map(|bin_h| data.split_at(bin_h.length as usize))
                .map(|(x, _)| Some(x))?
        } else {
            None
        };
        Ok((json, bin))
    }
}

impl fmt::Display for GlbError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use std::error::Error;
        write!(f, "{}", self.description())
    }
}

impl ::std::error::Error for GlbError {
    fn description(&self) -> &str {
         match *self {
             GlbError::IoError(ref e) => e.description(),
             GlbError::Version(_) => "unsupported version",
             GlbError::Magic(_) => "not glTF magic",
             GlbError::Length { .. } => "could not completely read the object",
             GlbError::ChunkLength { ty, .. } => match ty {
                 ChunkType::Json => "JSON chunk length exceeds that of slice",
                 ChunkType::Bin => "BIN\\0 chunk length exceeds that of slice",
             },
             GlbError::ChunkType(ty) => match ty {
                 ChunkType::Json => "was not expecting JSON chunk",
                 ChunkType::Bin => "was not expecting BIN\\0 chunk",
             },
             GlbError::UnknownChunkType(_) => "unknown chunk type",
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2017-2019 Rene van der Meer
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

//! Miscellaneous `embedded-hal` trait implementations.
//!
//! The `hal` module consists of a collection of `embedded-hal` trait
//! implementations for traits that aren't tied to a specific peripheral.
//!
//! This module is only included when either the `hal` or `hal-unproven` feature
//! flag is enabled.

use std::thread;
use std::time::{Duration, Instant};

use embedded_hal::blocking::delay::{DelayMs, DelayUs};
use embedded_hal::timer::CountDown;
use void::Void;

/// Implements the `embedded-hal` `DelayMs` and `DelayUs` traits.
#[derive(Debug, Default)]
pub struct Delay {}

impl Delay {
    /// Constructs a new `Delay`.
    pub fn new() -> Delay {
        Delay {}
    }
}

impl DelayMs<u8> for Delay {
    fn delay_ms(&mut self, ms: u8) {
        thread::sleep(Duration::from_millis(u64::from(ms)));
    }
}

impl DelayMs<u16> for Delay {
    fn delay_ms(&mut self, ms: u16) {
        thread::sleep(Duration::from_millis(u64::from(ms)));
    }
}

impl DelayMs<u32> for Delay {
    fn delay_ms(&mut self, ms: u32) {
        thread::sleep(Duration::from_millis(u64::from(ms)));
    }
}

impl DelayMs<u64> for Delay {
    fn delay_ms(&mut self, ms: u64) {
        thread::sleep(Duration::from_millis(ms));
    }
}

impl DelayUs<u8> for Delay {
    fn delay_us(&mut self, us: u8) {
        thread::sleep(Duration::from_micros(u64::from(us)));
    }
}

impl DelayUs<u16> for Delay {
    fn delay_us(&mut self, us: u16) {
        thread::sleep(Duration::from_micros(u64::from(us)));
    }
}

impl DelayUs<u32> for Delay {
    fn delay_us(&mut self, us: u32) {
        thread::sleep(Duration::from_micros(u64::from(us)));
    }
}

impl DelayUs<u64> for Delay {
    fn delay_us(&mut self, us: u64) {
        thread::sleep(Duration::from_micros(us));
    }
}

/// Implements the `embedded-hal` `CountDown` trait.
#[derive(Debug, Copy, Clone)]
pub struct Timer {
    now: Instant,
    duration: Duration,
}

impl Timer {
    /// Constructs a new `Timer`.
    pub fn new() -> Self {
        Self {
            now: Instant::now(),
            duration: Duration::from_micros(0),
        }
    }
}

impl Default for Timer {
    fn default() -> Self {
        Timer::new()
    }
}

pub struct Millisecond(pub u64);
pub struct Microsecond(pub u64);
pub struct Second(pub u64);

impl From<Millisecond> for Microsecond {
    fn from(item: Millisecond) -> Self {
        Microsecond(item.0 * 1_000)
    }
}

impl From<Second> for Microsecond {
    fn from(item: Second) -> Self {
        Microsecond(item.0 * 1_000_000)
    }
}

impl Microsecond {
    fn as_u64(&self) -> u64 {
        let &Microsecond(t) = self;
        t
    }
}

impl CountDown for Timer {
    type Time = Microsecond;

    /// Start the timer with a `timeout`
    fn start<T>(&mut self, timeout: T)
    where
        T: Into<Microsecond>,
    {
        self.duration = Duration::from_micros(timeout.into().as_u64());
        self.now = Instant::now();
    }

    /// Return `Ok` if the timer has wrapped
    /// Automatically clears the flag and restarts the time
    fn wait(&mut self) -> nb::Result<(), Void> {
        if self.now.elapsed() >= self.duration {
            Ok(())
        } else {
            Err(nb::Error::WouldBlock)
        }
    }
}
<commit_msg>Update documentation<commit_after>// Copyright (c) 2017-2019 Rene van der Meer
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

//! Miscellaneous `embedded-hal` trait implementations.
//!
//! The `hal` module consists of a collection of `embedded-hal` trait
//! implementations for traits that aren't tied to a specific peripheral.
//!
//! This module is only included when either the `hal` or `hal-unproven` feature
//! flag is enabled.

use std::thread;
use std::time::{Duration, Instant};

use embedded_hal::blocking::delay::{DelayMs, DelayUs};
use embedded_hal::timer::CountDown;
use void::Void;

/// Implements the `embedded-hal` `DelayMs` and `DelayUs` traits.
#[derive(Debug, Default)]
pub struct Delay {}

impl Delay {
    /// Constructs a new `Delay`.
    pub fn new() -> Delay {
        Delay {}
    }
}

impl DelayMs<u8> for Delay {
    fn delay_ms(&mut self, ms: u8) {
        thread::sleep(Duration::from_millis(u64::from(ms)));
    }
}

impl DelayMs<u16> for Delay {
    fn delay_ms(&mut self, ms: u16) {
        thread::sleep(Duration::from_millis(u64::from(ms)));
    }
}

impl DelayMs<u32> for Delay {
    fn delay_ms(&mut self, ms: u32) {
        thread::sleep(Duration::from_millis(u64::from(ms)));
    }
}

impl DelayMs<u64> for Delay {
    fn delay_ms(&mut self, ms: u64) {
        thread::sleep(Duration::from_millis(ms));
    }
}

impl DelayUs<u8> for Delay {
    fn delay_us(&mut self, us: u8) {
        thread::sleep(Duration::from_micros(u64::from(us)));
    }
}

impl DelayUs<u16> for Delay {
    fn delay_us(&mut self, us: u16) {
        thread::sleep(Duration::from_micros(u64::from(us)));
    }
}

impl DelayUs<u32> for Delay {
    fn delay_us(&mut self, us: u32) {
        thread::sleep(Duration::from_micros(u64::from(us)));
    }
}

impl DelayUs<u64> for Delay {
    fn delay_us(&mut self, us: u64) {
        thread::sleep(Duration::from_micros(us));
    }
}

/// Implements the `embedded-hal` `CountDown` trait.
#[derive(Debug, Copy, Clone)]
pub struct Timer {
    now: Instant,
    duration: Duration,
}

impl Timer {
    /// Constructs a new `Timer`.
    pub fn new() -> Self {
        Self {
            now: Instant::now(),
            duration: Duration::from_micros(0),
        }
    }
}

impl Default for Timer {
    fn default() -> Self {
        Timer::new()
    }
}

pub struct Millisecond(pub u64);
pub struct Microsecond(pub u64);
pub struct Second(pub u64);

impl From<Millisecond> for Microsecond {
    fn from(item: Millisecond) -> Self {
        Microsecond(item.0 * 1_000)
    }
}

impl From<Second> for Microsecond {
    fn from(item: Second) -> Self {
        Microsecond(item.0 * 1_000_000)
    }
}

impl Microsecond {
    fn as_u64(&self) -> u64 {
        self.0
    }
}

impl CountDown for Timer {
    type Time = Microsecond;

    /// Starts the timer with a `timeout`.
    fn start<T>(&mut self, timeout: T)
    where
        T: Into<Microsecond>,
    {
        self.duration = Duration::from_micros(timeout.into().as_u64());
        self.now = Instant::now();
    }

    /// Returns `Ok` if the timer has wrapped.
    fn wait(&mut self) -> nb::Result<(), Void> {
        if self.now.elapsed() >= self.duration {
            Ok(())
        } else {
            Err(nb::Error::WouldBlock)
        }
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! List of primitives.

use traits::{FromPointerReader, FromPointerBuilder, IndexMove, ListIter};
use private::layout::{ListReader, ListBuilder, PointerReader, PointerBuilder,
                      PrimitiveElement};
use Result;

#[derive(Clone, Copy)]
pub struct Owned<T> {
    marker: ::std::marker::PhantomData<T>,
}

impl <'a, T> ::traits::Owned<'a> for Owned<T> where T: PrimitiveElement {
    type Reader = Reader<'a, T>;
    type Builder = Builder<'a, T>;
}

#[derive(Clone, Copy)]
pub struct Reader<'a, T> where T: PrimitiveElement {
    marker : ::std::marker::PhantomData<T>,
    reader : ListReader<'a>
}

impl <'a, T : PrimitiveElement> Reader<'a, T> {
    pub fn new<'b>(reader : ListReader<'b>) -> Reader<'b, T> {
        Reader::<'b, T> { reader : reader, marker : ::std::marker::PhantomData }
    }

    pub fn len(&self) -> u32 { self.reader.len() }

    pub fn iter(self) -> ListIter<Reader<'a, T>, T>{
        let l = self.len();
        ListIter::new(self, l)
    }
}

impl <'a, T : PrimitiveElement> FromPointerReader<'a> for Reader<'a, T> {
    fn get_from_pointer(reader : &PointerReader<'a>) -> Result<Reader<'a, T>> {
        Ok(Reader { reader : try!(reader.get_list(T::element_size(), ::std::ptr::null())),
                    marker : ::std::marker::PhantomData })
    }
}

impl <'a, T: PrimitiveElement>  IndexMove<u32, T> for Reader<'a, T>{
    fn index_move(&self, index : u32) -> T {
        self.get(index)
    }
}

impl <'a, T : PrimitiveElement> Reader<'a, T> {
    pub fn get(&self, index : u32) -> T {
        assert!(index < self.len());
        PrimitiveElement::get(&self.reader, index)
    }
}

pub struct Builder<'a, T> where T: PrimitiveElement {
    marker : ::std::marker::PhantomData<T>,
    builder : ListBuilder<'a>
}

impl <'a, T> Builder<'a, T> where T: PrimitiveElement {
    pub fn new(builder : ListBuilder<'a>) -> Builder<'a, T> {
        Builder { builder : builder, marker : ::std::marker::PhantomData }
    }

    pub fn len(&self) -> u32 { self.builder.len() }

    pub fn set(&mut self, index : u32, value : T) {
        PrimitiveElement::set(&self.builder, index, value);
    }
}

impl <'a, T: PrimitiveElement> FromPointerBuilder<'a> for Builder<'a, T> {
    fn init_pointer(builder : PointerBuilder<'a>, size : u32) -> Builder<'a, T> {
        Builder { builder : builder.init_list(T::element_size(), size),
                  marker : ::std::marker::PhantomData }
    }
    fn get_from_pointer(builder : PointerBuilder<'a>) -> Result<Builder<'a, T>> {
        Ok(Builder { builder : try!(builder.get_list(T::element_size(), ::std::ptr::null())),
                     marker : ::std::marker::PhantomData })
    }
}

impl <'a, T : PrimitiveElement> Builder<'a, T> {
    pub fn get(&self, index : u32) -> T {
        assert!(index < self.len());
        PrimitiveElement::get_from_builder(&self.builder, index)
    }
}

impl <'a, T> ::traits::SetPointerBuilder<Builder<'a, T>> for Reader<'a, T>
    where T: PrimitiveElement
{
    fn set_pointer_builder<'b>(pointer: ::private::layout::PointerBuilder<'b>,
                               value: Reader<'a, T>) -> Result<()> {
        pointer.set_list(&value.reader)
    }
}

<commit_msg>style<commit_after>// Copyright (c) 2013-2015 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

//! List of primitives.

use std::{marker, ptr};

use traits::{FromPointerReader, FromPointerBuilder, IndexMove, ListIter};
use private::layout::{ListReader, ListBuilder, PointerReader, PointerBuilder,
                      PrimitiveElement};
use Result;

#[derive(Clone, Copy)]
pub struct Owned<T> {
    marker: marker::PhantomData<T>,
}

impl <'a, T> ::traits::Owned<'a> for Owned<T> where T: PrimitiveElement {
    type Reader = Reader<'a, T>;
    type Builder = Builder<'a, T>;
}

#[derive(Clone, Copy)]
pub struct Reader<'a, T> where T: PrimitiveElement {
    marker: marker::PhantomData<T>,
    reader: ListReader<'a>
}

impl <'a, T: PrimitiveElement> Reader<'a, T> {
    pub fn new<'b>(reader: ListReader<'b>) -> Reader<'b, T> {
        Reader::<'b, T> { reader: reader, marker: marker::PhantomData }
    }

    pub fn len(&self) -> u32 { self.reader.len() }

    pub fn iter(self) -> ListIter<Reader<'a, T>, T>{
        let l = self.len();
        ListIter::new(self, l)
    }
}

impl <'a, T: PrimitiveElement> FromPointerReader<'a> for Reader<'a, T> {
    fn get_from_pointer(reader: &PointerReader<'a>) -> Result<Reader<'a, T>> {
        Ok(Reader { reader: try!(reader.get_list(T::element_size(), ptr::null())),
                    marker: marker::PhantomData })
    }
}

impl <'a, T: PrimitiveElement>  IndexMove<u32, T> for Reader<'a, T>{
    fn index_move(&self, index: u32) -> T {
        self.get(index)
    }
}

impl <'a, T: PrimitiveElement> Reader<'a, T> {
    pub fn get(&self, index: u32) -> T {
        assert!(index < self.len());
        PrimitiveElement::get(&self.reader, index)
    }
}

pub struct Builder<'a, T> where T: PrimitiveElement {
    marker: marker::PhantomData<T>,
    builder: ListBuilder<'a>
}

impl <'a, T> Builder<'a, T> where T: PrimitiveElement {
    pub fn new(builder: ListBuilder<'a>) -> Builder<'a, T> {
        Builder { builder: builder, marker: marker::PhantomData }
    }

    pub fn len(&self) -> u32 { self.builder.len() }

    pub fn set(&mut self, index: u32, value: T) {
        PrimitiveElement::set(&self.builder, index, value);
    }
}

impl <'a, T: PrimitiveElement> FromPointerBuilder<'a> for Builder<'a, T> {
    fn init_pointer(builder: PointerBuilder<'a>, size: u32) -> Builder<'a, T> {
        Builder { builder: builder.init_list(T::element_size(), size),
                  marker: marker::PhantomData }
    }
    fn get_from_pointer(builder: PointerBuilder<'a>) -> Result<Builder<'a, T>> {
        Ok(Builder { builder: try!(builder.get_list(T::element_size(), ptr::null())),
                     marker: marker::PhantomData })
    }
}

impl <'a, T : PrimitiveElement> Builder<'a, T> {
    pub fn get(&self, index: u32) -> T {
        assert!(index < self.len());
        PrimitiveElement::get_from_builder(&self.builder, index)
    }
}

impl <'a, T> ::traits::SetPointerBuilder<Builder<'a, T>> for Reader<'a, T>
    where T: PrimitiveElement
{
    fn set_pointer_builder<'b>(pointer: PointerBuilder<'b>,
                               value: Reader<'a, T>) -> Result<()> {
        pointer.set_list(&value.reader)
    }
}

<|endoftext|>


<commit_before>use mio::*;
use mio::timer::Timer;
use mio_uds::{UnixListener,UnixStream};
use slab::Slab;
use std::fs;
use std::fmt;
use std::path::PathBuf;
use std::io::{self,ErrorKind};
use std::os::unix::fs::PermissionsExt;
use std::collections::HashMap;
use std::time::Duration;
use log;
use libc::pid_t;
use serde_json;

use sozu::network::{ProxyOrder,ServerMessage,ServerMessageStatus};
use sozu::channel::Channel;
use sozu_command::state::{HttpProxy,TlsProxy,ConfigState};
use sozu_command::data::{ConfigMessage,ConfigMessageAnswer,ConfigMessageStatus,ProxyType};
use sozu_command::config::Config;

pub mod orders;
pub mod client;

use self::client::{ConnReadError,CommandClient};

const SERVER: Token = Token(0);

#[derive(Copy,Clone,Debug,PartialEq,Eq,PartialOrd,Ord,Hash)]
pub struct FrontToken(pub usize);

impl From<usize> for FrontToken {
    fn from(val: usize) -> FrontToken {
        FrontToken(val)
    }
}

impl From<FrontToken> for usize {
    fn from(val: FrontToken) -> usize {
        val.0
    }
}

//#[derive(Serialize)]
pub struct Proxy {
  pub tag:           String,
  pub id:            u8,
  pub proxy_type:    ProxyType,
  pub channel:       Channel<ProxyOrder,ServerMessage>,
  pub state:         ConfigState,
  pub token:         Option<Token>,
  pub pid:           pid_t,
}

impl Proxy {
  pub fn new(tag: String, id: u8, pid: pid_t, proxy_type: ProxyType, ip_address: String, port: u16, channel: Channel<ProxyOrder,ServerMessage>) -> Proxy {
    let state = match proxy_type {
      ProxyType::HTTP  => ConfigState::Http(HttpProxy::new(ip_address, port)),
      ProxyType::HTTPS => ConfigState::Tls(TlsProxy::new(ip_address, port)),
      _                => unimplemented!(),
    };

    Proxy {
      tag:        tag,
      id:         id,
      proxy_type: proxy_type,
      channel:    channel,
      state:      state,
      token:      None,
      pid:        pid,
    }
  }
}

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

#[derive(Deserialize,Serialize,Debug)]
pub struct StoredProxy {
  pub tag:        String,
  pub proxy_type: ProxyType,
  pub state:      ConfigState,
}

impl StoredProxy {
  pub fn from_proxy(proxy: &Proxy) -> StoredProxy {
    StoredProxy {
      tag:        proxy.tag.clone(),
      proxy_type: proxy.proxy_type.clone(),
      state:      proxy.state.clone(),
    }
  }
}

#[derive(Deserialize,Serialize,Debug)]
pub struct ProxyConfiguration {
  id:      String,
  proxies: Vec<StoredProxy>,
}

pub type Tag = String;

struct CommandServer {
  sock:            UnixListener,
  buffer_size:     usize,
  max_buffer_size: usize,
  conns:           Slab<CommandClient,FrontToken>,
  proxies:         HashMap<Token, (Tag, Proxy)>,
  proxy_count:     usize,
  pub poll:        Poll,
  timer:           Timer<Token>,
}

impl CommandServer {
  fn accept(&mut self) -> io::Result<()> {
    debug!("server accepting socket");

    let acc = self.sock.accept();
    if let Ok(Some((sock, addr))) = acc {
      let conn = CommandClient::new(sock, self.buffer_size, self.max_buffer_size);
      let tok = self.conns.insert(conn)
        .ok().expect("could not add connection to slab");

      // Register the connection
      let token = self.from_front(tok);
      self.conns[tok].token = Some(token);
      let mut interest = Ready::hup();
      interest.insert(Ready::readable());
      interest.insert(Ready::writable());
      self.poll.register(&self.conns[tok].channel.sock, token, interest, PollOpt::edge())
        .ok().expect("could not register socket with event loop");

      let accept_interest = Ready::readable();
      self.poll.reregister(&self.sock, SERVER, accept_interest, PollOpt::edge());
      Ok(())
    } else {
      //FIXME: what do other cases mean, like Ok(None)?
      acc.map(|_| ())
    }
  }

  fn dispatch(&mut self, token: FrontToken, v: Vec<ConfigMessage>) {
    for message in &v {
      self.handle_client_message(token, message);
    }
  }

  fn new(srv: UnixListener, proxies_map: HashMap<String, Vec<Proxy>>, buffer_size: usize, max_buffer_size: usize, poll: Poll) -> CommandServer {
    //FIXME: verify this
    poll.register(&srv, Token(0), Ready::readable(), PollOpt::edge() | PollOpt::oneshot()).unwrap();

    let mut proxies = HashMap::new();

    let mut token_count = 0;
    for (tag, mut proxy_list) in proxies_map {
      for proxy in proxy_list.drain(..) {
        token_count += 1;
        poll.register(&proxy.channel.sock, Token(token_count), Ready::all(), PollOpt::edge()).unwrap();
        proxies.insert(Token(token_count), (tag.clone(), proxy));
      }
    }
    //let mut timer = timer::Builder::default().tick_duration(Duration::from_millis(1000)).build();
    //FIXME: registering the timer makes the timer thread spin too much
    let mut timer = timer::Timer::default();
    //poll.register(&timer, Token(1), Ready::readable(), PollOpt::edge()).unwrap();
    timer.set_timeout(Duration::from_millis(700), Token(0));
    CommandServer {
      sock:            srv,
      buffer_size:     buffer_size,
      max_buffer_size: max_buffer_size,
      conns:           Slab::with_capacity(128),
      proxies:       proxies,
      proxy_count:  token_count,
      poll:            poll,
      timer:           timer,
    }
  }

  pub fn to_front(&self, token: Token) -> FrontToken {
    FrontToken(token.0 - self.proxy_count - 1)
  }

  pub fn from_front(&self, token: FrontToken) -> Token {
    Token(token.0 + self.proxy_count + 1)
  }

}

type Message = ();

impl CommandServer {
  pub fn run(&mut self) {
    let mut events = Events::with_capacity(1024);
    let poll_timeout = Some(Duration::from_millis(1000));
    loop {
      self.poll.poll(&mut events, poll_timeout).unwrap();
      for event in events.iter() {
        self.ready(event.token(), event.kind());
      }
    }
  }

  fn ready(&mut self, token: Token, events: Ready) {
    //trace!("ready: {:?} -> {:?}", token, events);
    match token {
      Token(0) => {
        if events.is_readable() {
          self.accept().unwrap();
        } else {
          error!("received writable for token 0");
        }
      },
      Token(i) if i < self.proxy_count + 1 => {
        let mut messages = {
          let &mut (ref tag, ref mut proxy) =  self.proxies.get_mut(&Token(i)).unwrap();
          proxy.channel.handle_events(events);
          proxy.channel.run();

          let mut messages = Vec::new();
          loop {
            let msg = proxy.channel.read_message();
            if msg.is_none() {
              break;
            } else {
              messages.push(msg.unwrap());
            }
          }

          messages
        };

        for msg in messages.drain(..) {
          self.proxy_handle_message(Token(i), msg);
        }

        {
          let &mut (ref tag, ref mut proxy) =  self.proxies.get_mut(&Token(i)).unwrap();
          proxy.channel.run();
        }

      },
      _ => {
        let conn_token = self.to_front(token);
        if self.conns.contains(conn_token) {
          self.conns[conn_token].channel.handle_events(events);
          self.conns[conn_token].channel.run();

          //FIXME: handle deconnection
          loop {
            let message = self.conns[conn_token].channel.read_message();

            // if the message was too large, we grow the buffer and retry to read if possible
            if message.is_none() {
              if self.conns[conn_token].channel.readiness.is_hup() {
                break;
              }

              if (self.conns[conn_token].channel.interest & self.conns[conn_token].channel.readiness).is_readable() {
                self.conns[conn_token].channel.run();
                continue;
              } else {
                break;
              }
            }

            let message = message.unwrap();
            self.handle_client_message(conn_token, &message);

          }

          self.conns[conn_token].channel.run();

          if self.conns[conn_token].channel.readiness.is_hup() {
            self.poll.deregister(&self.conns[conn_token].channel.sock);
            self.conns.remove(conn_token);
            trace!("closed client [{}]", token.0);
          }
        }
      }
    }
  }

  fn proxy_handle_message(&mut self, token: Token, msg: ServerMessage) {
    println!("got answer msg: {:?}", msg);
    let answer = ConfigMessageAnswer {
      id: msg.id.clone(),
      status: match msg.status {
        ServerMessageStatus::Error(_)   => ConfigMessageStatus::Error,
        ServerMessageStatus::Ok         => ConfigMessageStatus::Ok,
        ServerMessageStatus::Processing => ConfigMessageStatus::Processing,
      },
      message: match msg.status {
                 ServerMessageStatus::Error(s) => s.clone(),
                 _                             => String::new(),
               },
    };
    info!("sending: {:?}", answer);
    for client in self.conns.iter_mut() {
      if let Some(index) = client.has_message_id(&msg.id) {
        client.write_message(&answer);
        client.remove_message_id(index);
      }
    }
  }

}

pub fn start(config: Config, proxies: HashMap<String, Vec<Proxy>>) {
  let buffer_size     = config.command_buffer_size.unwrap_or(10000);
  let max_buffer_size = config.max_command_buffer_size.unwrap_or(buffer_size * 2);
  let saved_state     = config.saved_state.clone();

  let event_loop = Poll::new().unwrap();
  let addr = PathBuf::from(&config.command_socket);
  if let Err(e) = fs::remove_file(&addr) {
    match e.kind() {
      ErrorKind::NotFound => {},
      _ => {
        log!(log::LogLevel::Error, "could not delete previous socket at {:?}: {:?}", addr, e);
        return;
      }
    }
  }
  match UnixListener::bind(&addr) {
    Ok(srv) => {
      if let Err(e) =  fs::set_permissions(&addr, fs::Permissions::from_mode(0o600)) {
        log!( log::LogLevel::Error, "could not set the unix socket permissions: {:?}", e);
        fs::remove_file(&addr);
        return;
      }

      let mut server = CommandServer::new(srv, proxies, buffer_size, max_buffer_size, event_loop);

      server.load_static_application_configuration(&config);

      saved_state.as_ref().map(|state_path| {
        server.load_state("INITIALIZATION", state_path);
      });

      info!("listen for connections");
      server.run();
      //event_loop.run(&mut CommandServer::new(srv, proxies, buffer_size, max_buffer_size)).unwrap()
    },
      Err(e) => {
        log!(log::LogLevel::Error, "could not create unix socket: {:?}", e);
      }
  }
}
<commit_msg>do not stop sending messages on Processing, other are coming next<commit_after>use mio::*;
use mio::timer::Timer;
use mio_uds::{UnixListener,UnixStream};
use slab::Slab;
use std::fs;
use std::fmt;
use std::path::PathBuf;
use std::io::{self,ErrorKind};
use std::os::unix::fs::PermissionsExt;
use std::collections::HashMap;
use std::time::Duration;
use log;
use libc::pid_t;
use serde_json;

use sozu::network::{ProxyOrder,ServerMessage,ServerMessageStatus};
use sozu::channel::Channel;
use sozu_command::state::{HttpProxy,TlsProxy,ConfigState};
use sozu_command::data::{ConfigMessage,ConfigMessageAnswer,ConfigMessageStatus,ProxyType};
use sozu_command::config::Config;

pub mod orders;
pub mod client;

use self::client::{ConnReadError,CommandClient};

const SERVER: Token = Token(0);

#[derive(Copy,Clone,Debug,PartialEq,Eq,PartialOrd,Ord,Hash)]
pub struct FrontToken(pub usize);

impl From<usize> for FrontToken {
    fn from(val: usize) -> FrontToken {
        FrontToken(val)
    }
}

impl From<FrontToken> for usize {
    fn from(val: FrontToken) -> usize {
        val.0
    }
}

//#[derive(Serialize)]
pub struct Proxy {
  pub tag:           String,
  pub id:            u8,
  pub proxy_type:    ProxyType,
  pub channel:       Channel<ProxyOrder,ServerMessage>,
  pub state:         ConfigState,
  pub token:         Option<Token>,
  pub pid:           pid_t,
}

impl Proxy {
  pub fn new(tag: String, id: u8, pid: pid_t, proxy_type: ProxyType, ip_address: String, port: u16, channel: Channel<ProxyOrder,ServerMessage>) -> Proxy {
    let state = match proxy_type {
      ProxyType::HTTP  => ConfigState::Http(HttpProxy::new(ip_address, port)),
      ProxyType::HTTPS => ConfigState::Tls(TlsProxy::new(ip_address, port)),
      _                => unimplemented!(),
    };

    Proxy {
      tag:        tag,
      id:         id,
      proxy_type: proxy_type,
      channel:    channel,
      state:      state,
      token:      None,
      pid:        pid,
    }
  }
}

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

#[derive(Deserialize,Serialize,Debug)]
pub struct StoredProxy {
  pub tag:        String,
  pub proxy_type: ProxyType,
  pub state:      ConfigState,
}

impl StoredProxy {
  pub fn from_proxy(proxy: &Proxy) -> StoredProxy {
    StoredProxy {
      tag:        proxy.tag.clone(),
      proxy_type: proxy.proxy_type.clone(),
      state:      proxy.state.clone(),
    }
  }
}

#[derive(Deserialize,Serialize,Debug)]
pub struct ProxyConfiguration {
  id:      String,
  proxies: Vec<StoredProxy>,
}

pub type Tag = String;

struct CommandServer {
  sock:            UnixListener,
  buffer_size:     usize,
  max_buffer_size: usize,
  conns:           Slab<CommandClient,FrontToken>,
  proxies:         HashMap<Token, (Tag, Proxy)>,
  proxy_count:     usize,
  pub poll:        Poll,
  timer:           Timer<Token>,
}

impl CommandServer {
  fn accept(&mut self) -> io::Result<()> {
    debug!("server accepting socket");

    let acc = self.sock.accept();
    if let Ok(Some((sock, addr))) = acc {
      let conn = CommandClient::new(sock, self.buffer_size, self.max_buffer_size);
      let tok = self.conns.insert(conn)
        .ok().expect("could not add connection to slab");

      // Register the connection
      let token = self.from_front(tok);
      self.conns[tok].token = Some(token);
      let mut interest = Ready::hup();
      interest.insert(Ready::readable());
      interest.insert(Ready::writable());
      self.poll.register(&self.conns[tok].channel.sock, token, interest, PollOpt::edge())
        .ok().expect("could not register socket with event loop");

      let accept_interest = Ready::readable();
      self.poll.reregister(&self.sock, SERVER, accept_interest, PollOpt::edge());
      Ok(())
    } else {
      //FIXME: what do other cases mean, like Ok(None)?
      acc.map(|_| ())
    }
  }

  fn dispatch(&mut self, token: FrontToken, v: Vec<ConfigMessage>) {
    for message in &v {
      self.handle_client_message(token, message);
    }
  }

  fn new(srv: UnixListener, proxies_map: HashMap<String, Vec<Proxy>>, buffer_size: usize, max_buffer_size: usize, poll: Poll) -> CommandServer {
    //FIXME: verify this
    poll.register(&srv, Token(0), Ready::readable(), PollOpt::edge() | PollOpt::oneshot()).unwrap();

    let mut proxies = HashMap::new();

    let mut token_count = 0;
    for (tag, mut proxy_list) in proxies_map {
      for proxy in proxy_list.drain(..) {
        token_count += 1;
        poll.register(&proxy.channel.sock, Token(token_count), Ready::all(), PollOpt::edge()).unwrap();
        proxies.insert(Token(token_count), (tag.clone(), proxy));
      }
    }
    //let mut timer = timer::Builder::default().tick_duration(Duration::from_millis(1000)).build();
    //FIXME: registering the timer makes the timer thread spin too much
    let mut timer = timer::Timer::default();
    //poll.register(&timer, Token(1), Ready::readable(), PollOpt::edge()).unwrap();
    timer.set_timeout(Duration::from_millis(700), Token(0));
    CommandServer {
      sock:            srv,
      buffer_size:     buffer_size,
      max_buffer_size: max_buffer_size,
      conns:           Slab::with_capacity(128),
      proxies:       proxies,
      proxy_count:  token_count,
      poll:            poll,
      timer:           timer,
    }
  }

  pub fn to_front(&self, token: Token) -> FrontToken {
    FrontToken(token.0 - self.proxy_count - 1)
  }

  pub fn from_front(&self, token: FrontToken) -> Token {
    Token(token.0 + self.proxy_count + 1)
  }

}

type Message = ();

impl CommandServer {
  pub fn run(&mut self) {
    let mut events = Events::with_capacity(1024);
    let poll_timeout = Some(Duration::from_millis(1000));
    loop {
      self.poll.poll(&mut events, poll_timeout).unwrap();
      for event in events.iter() {
        self.ready(event.token(), event.kind());
      }
    }
  }

  fn ready(&mut self, token: Token, events: Ready) {
    //trace!("ready: {:?} -> {:?}", token, events);
    match token {
      Token(0) => {
        if events.is_readable() {
          self.accept().unwrap();
        } else {
          error!("received writable for token 0");
        }
      },
      Token(i) if i < self.proxy_count + 1 => {
        let mut messages = {
          let &mut (ref tag, ref mut proxy) =  self.proxies.get_mut(&Token(i)).unwrap();
          proxy.channel.handle_events(events);
          proxy.channel.run();

          let mut messages = Vec::new();
          loop {
            let msg = proxy.channel.read_message();
            if msg.is_none() {
              break;
            } else {
              messages.push(msg.unwrap());
            }
          }

          messages
        };

        for msg in messages.drain(..) {
          self.proxy_handle_message(Token(i), msg);
        }

        {
          let &mut (ref tag, ref mut proxy) =  self.proxies.get_mut(&Token(i)).unwrap();
          proxy.channel.run();
        }

      },
      _ => {
        let conn_token = self.to_front(token);
        if self.conns.contains(conn_token) {
          self.conns[conn_token].channel.handle_events(events);
          self.conns[conn_token].channel.run();

          //FIXME: handle deconnection
          loop {
            let message = self.conns[conn_token].channel.read_message();

            // if the message was too large, we grow the buffer and retry to read if possible
            if message.is_none() {
              if self.conns[conn_token].channel.readiness.is_hup() {
                break;
              }

              if (self.conns[conn_token].channel.interest & self.conns[conn_token].channel.readiness).is_readable() {
                self.conns[conn_token].channel.run();
                continue;
              } else {
                break;
              }
            }

            let message = message.unwrap();
            self.handle_client_message(conn_token, &message);

          }

          self.conns[conn_token].channel.run();

          if self.conns[conn_token].channel.readiness.is_hup() {
            self.poll.deregister(&self.conns[conn_token].channel.sock);
            self.conns.remove(conn_token);
            trace!("closed client [{}]", token.0);
          }
        }
      }
    }
  }

  fn proxy_handle_message(&mut self, token: Token, msg: ServerMessage) {
    println!("got answer msg: {:?}", msg);
    let answer = ConfigMessageAnswer {
      id: msg.id.clone(),
      status: match msg.status {
        ServerMessageStatus::Error(_)   => ConfigMessageStatus::Error,
        ServerMessageStatus::Ok         => ConfigMessageStatus::Ok,
        ServerMessageStatus::Processing => ConfigMessageStatus::Processing,
      },
      message: match msg.status {
                 ServerMessageStatus::Error(s) => s.clone(),
                 _                             => String::new(),
               },
    };
    info!("sending: {:?}", answer);
    for client in self.conns.iter_mut() {
      if let Some(index) = client.has_message_id(&msg.id) {
        client.write_message(&answer);
        if answer.status != ConfigMessageStatus::Processing {
          client.remove_message_id(index);
        }
      }
      client.channel.run();
    }
  }

}

pub fn start(config: Config, proxies: HashMap<String, Vec<Proxy>>) {
  let buffer_size     = config.command_buffer_size.unwrap_or(10000);
  let max_buffer_size = config.max_command_buffer_size.unwrap_or(buffer_size * 2);
  let saved_state     = config.saved_state.clone();

  let event_loop = Poll::new().unwrap();
  let addr = PathBuf::from(&config.command_socket);
  if let Err(e) = fs::remove_file(&addr) {
    match e.kind() {
      ErrorKind::NotFound => {},
      _ => {
        log!(log::LogLevel::Error, "could not delete previous socket at {:?}: {:?}", addr, e);
        return;
      }
    }
  }
  match UnixListener::bind(&addr) {
    Ok(srv) => {
      if let Err(e) =  fs::set_permissions(&addr, fs::Permissions::from_mode(0o600)) {
        log!( log::LogLevel::Error, "could not set the unix socket permissions: {:?}", e);
        fs::remove_file(&addr);
        return;
      }

      let mut server = CommandServer::new(srv, proxies, buffer_size, max_buffer_size, event_loop);

      server.load_static_application_configuration(&config);

      saved_state.as_ref().map(|state_path| {
        server.load_state("INITIALIZATION", state_path);
      });

      info!("listen for connections");
      server.run();
      //event_loop.run(&mut CommandServer::new(srv, proxies, buffer_size, max_buffer_size)).unwrap()
    },
      Err(e) => {
        log!(log::LogLevel::Error, "could not create unix socket: {:?}", e);
      }
  }
}
<|endoftext|>


<commit_before>use texture::{Texture2dBinder, TextureCubeMapBinder};

pub trait TextureUnit {
    fn idx() -> u32;
}

// TODO: Use a macro, or const generic parameters:
// https://github.com/rust-lang/rfcs/issues/273
// https://github.com/rust-lang/rfcs/issues/1038
pub struct TextureUnit0;
pub struct TextureUnit1;
pub struct TextureUnit2;
pub struct TextureUnit3;
pub struct TextureUnit4;
pub struct TextureUnit5;
pub struct TextureUnit6;
pub struct TextureUnit7;

impl TextureUnit for TextureUnit0 { fn idx() -> u32 { 0 } }
impl TextureUnit for TextureUnit1 { fn idx() -> u32 { 1 } }
impl TextureUnit for TextureUnit2 { fn idx() -> u32 { 2 } }
impl TextureUnit for TextureUnit3 { fn idx() -> u32 { 3 } }
impl TextureUnit for TextureUnit4 { fn idx() -> u32 { 4 } }
impl TextureUnit for TextureUnit5 { fn idx() -> u32 { 5 } }
impl TextureUnit for TextureUnit6 { fn idx() -> u32 { 6 } }
impl TextureUnit for TextureUnit7 { fn idx() -> u32 { 7 } }

// NOTE: Ensure the number of each texture unit matches its index in the tuple
pub struct TextureUnits(pub TextureUnit0, pub TextureUnit1, pub TextureUnit2,
                        pub TextureUnit3, pub TextureUnit4, pub TextureUnit5,
                        pub TextureUnit6, pub TextureUnit7);

impl TextureUnits {
    pub unsafe fn current() -> TextureUnits {
        TextureUnits(TextureUnit0, TextureUnit1, TextureUnit2, TextureUnit3,
                     TextureUnit4, TextureUnit5, TextureUnit6, TextureUnit7)
    }
}

pub struct TextureUnitBinding {
    pub texture_2d: Texture2dBinder,
    pub texture_cube_map: TextureCubeMapBinder
}
<commit_msg>Add `TextureUnit.active()`<commit_after>use gl;
use gl::types::*;
use texture::{Texture2dBinder, TextureCubeMapBinder};
use types::GLError;

pub trait TextureUnit {
    fn idx() -> u32;

    fn active(&mut self) -> TextureUnitBinding {
        unsafe { gl::ActiveTexture(gl::TEXTURE0 + (Self::idx() as GLenum)); }
        dbg_gl_error! {
            GLError::InvalidEnum => "`texture` is out of bounds (expected to be GL_TEXTUREi, 0 <= i < GL_MAX_TEXTURE_IMAGE_UNITS)",
            _ => "Unknown error"
        }
        TextureUnitBinding {
            texture_2d: Texture2dBinder,
            texture_cube_map: TextureCubeMapBinder
        }
    }
}

// TODO: Use a macro, or const generic parameters:
// https://github.com/rust-lang/rfcs/issues/273
// https://github.com/rust-lang/rfcs/issues/1038
pub struct TextureUnit0;
pub struct TextureUnit1;
pub struct TextureUnit2;
pub struct TextureUnit3;
pub struct TextureUnit4;
pub struct TextureUnit5;
pub struct TextureUnit6;
pub struct TextureUnit7;

impl TextureUnit for TextureUnit0 { fn idx() -> u32 { 0 } }
impl TextureUnit for TextureUnit1 { fn idx() -> u32 { 1 } }
impl TextureUnit for TextureUnit2 { fn idx() -> u32 { 2 } }
impl TextureUnit for TextureUnit3 { fn idx() -> u32 { 3 } }
impl TextureUnit for TextureUnit4 { fn idx() -> u32 { 4 } }
impl TextureUnit for TextureUnit5 { fn idx() -> u32 { 5 } }
impl TextureUnit for TextureUnit6 { fn idx() -> u32 { 6 } }
impl TextureUnit for TextureUnit7 { fn idx() -> u32 { 7 } }

// NOTE: Ensure the number of each texture unit matches its index in the tuple
pub struct TextureUnits(pub TextureUnit0, pub TextureUnit1, pub TextureUnit2,
                        pub TextureUnit3, pub TextureUnit4, pub TextureUnit5,
                        pub TextureUnit6, pub TextureUnit7);

impl TextureUnits {
    pub unsafe fn current() -> TextureUnits {
        TextureUnits(TextureUnit0, TextureUnit1, TextureUnit2, TextureUnit3,
                     TextureUnit4, TextureUnit5, TextureUnit6, TextureUnit7)
    }
}

pub struct TextureUnitBinding {
    pub texture_2d: Texture2dBinder,
    pub texture_cube_map: TextureCubeMapBinder
}
<|endoftext|>


<commit_before>extern crate rdkafka;

extern crate futures;
extern crate rand;

mod test_utils;

use futures::*;

use rdkafka::config::{ClientConfig, TopicConfig};
use rdkafka::consumer::{Consumer, CommitMode, EmptyConsumerContext};
use rdkafka::consumer::stream_consumer::StreamConsumer;
use rdkafka::producer::FutureProducer;
use rdkafka::topic_partition_list::TopicPartitionList;
use rdkafka::message::ToBytes;

use test_utils::{rand_test_group, rand_test_topic};

use std::collections::HashMap;

fn produce_messages<P, K, J, Q>(topic_name: &str, count: i32, value_fn: &P, key_fn: &K, partition: Option<i32>)
    -> HashMap<(i32, i64), i32>
    where P: Fn(i32) -> J,
          K: Fn(i32) -> Q,
          J: ToBytes,
          Q: ToBytes {
    // Produce some messages
    let producer = ClientConfig::new()
        .set("bootstrap.servers", "localhost:9092")
        .create::<FutureProducer>()
        .expect("Producer creation error");

    producer.start();

    let topic_config = TopicConfig::new()
        .set("produce.offset.report", "true")
        .set("message.timeout.ms", "5000")
        .finalize();

    let topic = producer.get_topic(&topic_name, &topic_config)
        .expect("Topic creation error");

    let futures = (0..count)
        .map(|id| {
            let future = topic.send_copy(partition, Some(&value_fn(id)), Some(&key_fn(id)))
                .expect("Production failed");
            (id, future)
        }).collect::<Vec<_>>();

    let mut message_map = HashMap::new();
    for (id, future) in futures {
        match future.wait() {
            Ok(report) => match report.result() {
                Err(e) => panic!("Delivery failed: {}", e),
                Ok((partition, offset)) => message_map.insert((partition, offset), id),
            },
            Err(e) => panic!("Waiting for future failed: {}", e)
        };
    }

    message_map
}

// Create consumer
fn create_simple_stream_consumer(topic_name: &str) -> StreamConsumer<EmptyConsumerContext> {
    let mut consumer = ClientConfig::new()
        .set("group.id", &rand_test_group())
        .set("bootstrap.servers", "localhost:9092")
        .set("enable.partition.eof", "false")
        .set("session.timeout.ms", "6000")
        .set("enable.auto.commit", "false")
        .set_default_topic_config(
            TopicConfig::new()
                .set("auto.offset.reset", "earliest")
                .finalize()
        )
        .create::<StreamConsumer<_>>()
        .expect("Consumer creation failed");
    consumer.subscribe(&vec![topic_name]).unwrap();
    consumer
}

fn value_fn(id: i32) -> String {
    format!("Message {}", id)
}

fn key_fn(id: i32) -> String {
    format!("Key {}", id)
}

// All produced messages should be consumed.
#[test]
fn test_produce_consume_base() {
    let topic_name = rand_test_topic();
    let message_map = produce_messages(&topic_name, 100, &value_fn, &key_fn, None);
    let mut consumer = create_simple_stream_consumer(&topic_name);

    let _consumer_future = consumer.start()
        .take(100)
        .for_each(|message| {
            match message {
                Ok(m) => {
                    let id = message_map.get(&(m.partition(), m.offset())).unwrap();
                    assert_eq!(m.payload_view::<str>().unwrap().unwrap(), value_fn(*id));
                    assert_eq!(m.key_view::<str>().unwrap().unwrap(), key_fn(*id));
                    //consumer.commit_message(&m, CommitMode::Async).unwrap();
                },
                e => panic!("Error receiving message: {:?}", e)
            };
            Ok(())
        })
        .wait();
}

// All messages should go to the same partition.
#[test]
fn test_produce_partition() {
    let topic_name = rand_test_topic();
    let message_map = produce_messages(&topic_name, 100, &value_fn, &key_fn, Some(0));

    let res = message_map.iter()
        .filter(|&(&(partition, _), _)| partition == 0)
        .count();

    assert_eq!(res, 100);
}

// Test metadata.
#[test]
fn test_metadata() {
    let topic_name = rand_test_topic();
    produce_messages(&topic_name, 1, &value_fn, &key_fn, Some(0));
    produce_messages(&topic_name, 1, &value_fn, &key_fn, Some(1));
    produce_messages(&topic_name, 1, &value_fn, &key_fn, Some(2));
    let consumer = create_simple_stream_consumer(&topic_name);

    let metadata = consumer.fetch_metadata(5000).unwrap();

    let topic_metadata = metadata.topics().iter()
        .find(|m| m.name() == topic_name).unwrap();

    let mut ids = topic_metadata.partitions().iter().map(|p| p.id()).collect::<Vec<_>>();
    ids.sort();

    assert_eq!(ids, vec![0, 1, 2]);
    // assert_eq!(topic_metadata.error(), None);
    assert_eq!(topic_metadata.partitions().len(), 3);
    assert_eq!(topic_metadata.partitions()[0].leader(), 0);
    assert_eq!(topic_metadata.partitions()[1].leader(), 0);
    assert_eq!(topic_metadata.partitions()[2].leader(), 0);
    assert_eq!(topic_metadata.partitions()[0].replicas(), &[0]);
    assert_eq!(topic_metadata.partitions()[0].isr(), &[0]);
}

// Test consumer commit and watermarks.
#[test]
fn test_consumer_commit() {
    let topic_name = rand_test_topic();
    produce_messages(&topic_name, 10, &value_fn, &key_fn, Some(0));
    produce_messages(&topic_name, 11, &value_fn, &key_fn, Some(1));
    produce_messages(&topic_name, 12, &value_fn, &key_fn, Some(2));
    let mut consumer = create_simple_stream_consumer(&topic_name);

    let _consumer_future = consumer.start()
        .take(33)
        .for_each(|message| {
            match message {
                Ok(m) => {
                    if m.partition() == 1 {
                        consumer.commit_message(&m, CommitMode::Async).unwrap();
                    }
                },
                e => panic!("Error receiving message: {:?}", e)
            };
            Ok(())
        })
        .wait();

    assert_eq!(consumer.fetch_watermarks(&topic_name, 0, 5000).unwrap(), (0, 10));
    assert_eq!(consumer.fetch_watermarks(&topic_name, 1, 5000).unwrap(), (0, 11));
    assert_eq!(consumer.fetch_watermarks(&topic_name, 2, 5000).unwrap(), (0, 12));

    let mut assignment = TopicPartitionList::new();
    assignment.add_topic_with_partitions_and_offsets(&topic_name, &vec![(0, -1001), (1, -1001), (2, -1001)]);
    assert_eq!(assignment, consumer.assignment().unwrap());

    let mut committed = TopicPartitionList::new();
    committed.add_topic_with_partitions_and_offsets(&topic_name, &vec![(0, -1001), (1, 11), (2, -1001)]);
    assert_eq!(committed, consumer.committed(5000).unwrap());

    let mut position = TopicPartitionList::new();
    position.add_topic_with_partitions_and_offsets(&topic_name, &vec![(0, 10), (1, 11), (2, 12)]);
    assert_eq!(position, consumer.position().unwrap());
}

// Test subscription.
#[test]
fn test_subscription() {
    let topic_name = rand_test_topic();
    produce_messages(&topic_name, 10, &value_fn, &key_fn, None);
    let mut consumer = create_simple_stream_consumer(&topic_name);

    let _consumer_future = consumer.start().take(10).wait();

    let subscription = TopicPartitionList::with_topics(&vec![&topic_name]);
    assert_eq!(subscription, consumer.subscription().unwrap());
}
<commit_msg>Code cleanup<commit_after>extern crate rdkafka;
extern crate futures;
extern crate rand;

mod test_utils;

use futures::*;

use rdkafka::config::{ClientConfig, TopicConfig};
use rdkafka::consumer::{Consumer, CommitMode, EmptyConsumerContext};
use rdkafka::consumer::stream_consumer::StreamConsumer;
use rdkafka::producer::FutureProducer;
use rdkafka::topic_partition_list::TopicPartitionList;
use rdkafka::message::ToBytes;

use test_utils::{rand_test_group, rand_test_topic};

use std::collections::HashMap;

fn produce_messages<P, K, J, Q>(topic_name: &str, count: i32, value_fn: &P, key_fn: &K, partition: Option<i32>)
    -> HashMap<(i32, i64), i32>
    where P: Fn(i32) -> J,
          K: Fn(i32) -> Q,
          J: ToBytes,
          Q: ToBytes {
    // Produce some messages
    let producer = ClientConfig::new()
        .set("bootstrap.servers", "localhost:9092")
        .create::<FutureProducer>()
        .expect("Producer creation error");

    producer.start();

    let topic_config = TopicConfig::new()
        .set("produce.offset.report", "true")
        .set("message.timeout.ms", "5000")
        .finalize();

    let topic = producer.get_topic(&topic_name, &topic_config)
        .expect("Topic creation error");

    let futures = (0..count)
        .map(|id| {
            let future = topic.send_copy(partition, Some(&value_fn(id)), Some(&key_fn(id)))
                .expect("Production failed");
            (id, future)
        }).collect::<Vec<_>>();

    let mut message_map = HashMap::new();
    for (id, future) in futures {
        match future.wait() {
            Ok(report) => match report.result() {
                Err(e) => panic!("Delivery failed: {}", e),
                Ok((partition, offset)) => message_map.insert((partition, offset), id),
            },
            Err(e) => panic!("Waiting for future failed: {}", e)
        };
    }

    message_map
}

// Create consumer
fn create_stream_consumer(topic_name: &str) -> StreamConsumer<EmptyConsumerContext> {
    let mut consumer = ClientConfig::new()
        .set("group.id", &rand_test_group())
        .set("bootstrap.servers", "localhost:9092")
        .set("enable.partition.eof", "false")
        .set("session.timeout.ms", "6000")
        .set("enable.auto.commit", "false")
        .set_default_topic_config(
            TopicConfig::new()
                .set("auto.offset.reset", "earliest")
                .finalize()
        )
        .create::<StreamConsumer<_>>()
        .expect("Consumer creation failed");
    consumer.subscribe(&vec![topic_name]).unwrap();
    consumer
}

fn value_fn(id: i32) -> String {
    format!("Message {}", id)
}

fn key_fn(id: i32) -> String {
    format!("Key {}", id)
}

// All produced messages should be consumed.
#[test]
fn test_produce_consume_base() {
    let topic_name = rand_test_topic();
    let message_map = produce_messages(&topic_name, 100, &value_fn, &key_fn, None);
    let mut consumer = create_stream_consumer(&topic_name);

    let _consumer_future = consumer.start()
        .take(100)
        .for_each(|message| {
            match message {
                Ok(m) => {
                    let id = message_map.get(&(m.partition(), m.offset())).unwrap();
                    assert_eq!(m.payload_view::<str>().unwrap().unwrap(), value_fn(*id));
                    assert_eq!(m.key_view::<str>().unwrap().unwrap(), key_fn(*id));
                },
                e => panic!("Error receiving message: {:?}", e)
            };
            Ok(())
        })
        .wait();
}

// All messages should go to the same partition.
#[test]
fn test_produce_partition() {
    let topic_name = rand_test_topic();
    let message_map = produce_messages(&topic_name, 100, &value_fn, &key_fn, Some(0));

    let res = message_map.iter()
        .filter(|&(&(partition, _), _)| partition == 0)
        .count();

    assert_eq!(res, 100);
}

#[test]
fn test_metadata() {
    let topic_name = rand_test_topic();
    produce_messages(&topic_name, 1, &value_fn, &key_fn, Some(0));
    produce_messages(&topic_name, 1, &value_fn, &key_fn, Some(1));
    produce_messages(&topic_name, 1, &value_fn, &key_fn, Some(2));
    let consumer = create_stream_consumer(&topic_name);

    let metadata = consumer.fetch_metadata(5000).unwrap();

    let topic_metadata = metadata.topics().iter()
        .find(|m| m.name() == topic_name).unwrap();

    let mut ids = topic_metadata.partitions().iter().map(|p| p.id()).collect::<Vec<_>>();
    ids.sort();

    assert_eq!(ids, vec![0, 1, 2]);
    // assert_eq!(topic_metadata.error(), None);
    assert_eq!(topic_metadata.partitions().len(), 3);
    assert_eq!(topic_metadata.partitions()[0].leader(), 0);
    assert_eq!(topic_metadata.partitions()[1].leader(), 0);
    assert_eq!(topic_metadata.partitions()[2].leader(), 0);
    assert_eq!(topic_metadata.partitions()[0].replicas(), &[0]);
    assert_eq!(topic_metadata.partitions()[0].isr(), &[0]);
}

#[test]
fn test_consumer_commit() {
    let topic_name = rand_test_topic();
    produce_messages(&topic_name, 10, &value_fn, &key_fn, Some(0));
    produce_messages(&topic_name, 11, &value_fn, &key_fn, Some(1));
    produce_messages(&topic_name, 12, &value_fn, &key_fn, Some(2));
    let mut consumer = create_stream_consumer(&topic_name);

    let _consumer_future = consumer.start()
        .take(33)
        .for_each(|message| {
            match message {
                Ok(m) => {
                    if m.partition() == 1 {
                        consumer.commit_message(&m, CommitMode::Async).unwrap();
                    }
                },
                e => panic!("Error receiving message: {:?}", e)
            };
            Ok(())
        })
        .wait();

    assert_eq!(consumer.fetch_watermarks(&topic_name, 0, 5000).unwrap(), (0, 10));
    assert_eq!(consumer.fetch_watermarks(&topic_name, 1, 5000).unwrap(), (0, 11));
    assert_eq!(consumer.fetch_watermarks(&topic_name, 2, 5000).unwrap(), (0, 12));

    let mut assignment = TopicPartitionList::new();
    assignment.add_topic_with_partitions_and_offsets(&topic_name, &vec![(0, -1001), (1, -1001), (2, -1001)]);
    assert_eq!(assignment, consumer.assignment().unwrap());

    let mut committed = TopicPartitionList::new();
    committed.add_topic_with_partitions_and_offsets(&topic_name, &vec![(0, -1001), (1, 11), (2, -1001)]);
    assert_eq!(committed, consumer.committed(5000).unwrap());

    let mut position = TopicPartitionList::new();
    position.add_topic_with_partitions_and_offsets(&topic_name, &vec![(0, 10), (1, 11), (2, 12)]);
    assert_eq!(position, consumer.position().unwrap());
}

#[test]
fn test_subscription() {
    let topic_name = rand_test_topic();
    produce_messages(&topic_name, 10, &value_fn, &key_fn, None);
    let mut consumer = create_stream_consumer(&topic_name);

    let _consumer_future = consumer.start().take(10).wait();

    let subscription = TopicPartitionList::with_topics(&vec![&topic_name]);
    assert_eq!(subscription, consumer.subscription().unwrap());
}
<|endoftext|>


<commit_before>// Copyright 2018 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Implementation for iOS
use crate::Error;

// TODO: Make extern once extern_types feature is stabilized. See:
//   https://github.com/rust-lang/rust/issues/43467
#[repr(C)]
struct SecRandom([u8; 0]);

#[link(name = "Security", kind = "framework")]
extern "C" {
    static kSecRandomDefault: *const SecRandom;

    fn SecRandomCopyBytes(rnd: *const SecRandom, count: usize, bytes: *mut u8) -> i32;
}

pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
    let ret = unsafe { SecRandomCopyBytes(kSecRandomDefault, dest.len(), dest.as_mut_ptr()) };
    if ret == -1 {
        Err(Error::IOS_SEC_RANDOM)
    } else {
        Ok(())
    }
}
<commit_msg>ios: Don't use SecRandom type<commit_after>// Copyright 2018 Developers of the Rand project.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Implementation for iOS
use crate::Error;
use core::{ffi::c_void, ptr::null};

#[link(name = "Security", kind = "framework")]
extern "C" {
    fn SecRandomCopyBytes(rnd: *const c_void, count: usize, bytes: *mut u8) -> i32;
}

pub fn getrandom_inner(dest: &mut [u8]) -> Result<(), Error> {
    // Apple's documentation guarantees kSecRandomDefault is a synonym for NULL.
    let ret = unsafe { SecRandomCopyBytes(null(), dest.len(), dest.as_mut_ptr()) };
    if ret == -1 {
        Err(Error::IOS_SEC_RANDOM)
    } else {
        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::time::Duration;

use game::Color;
use types::NumMoves;
use search;

pub use self::mode::Mode;

mod mode;

#[deriving(Clone)]
pub struct State {
    pub search_state: Option<search::State>,
    pub mode: Mode,
    pub start_search_time: Option<u64>,
    pub start_move_time: Option<u64>,
    pub time_data: Option<TimeData>,
}
impl State {
    pub fn new() -> State {
        State {
            search_state: None,
            mode: Mode::new(),
            start_search_time: None,
            start_move_time: None,
            time_data: None,
        }
    }
}

#[deriving(Copy, Clone)]
pub enum TimeData {
    TimeLeft(TimeLeftData),
    ExactTime(Duration),
}

#[deriving(Copy, Clone)]
pub struct TimeLeftData {
    pub w_time: Option<Duration>,
    pub b_time: Option<Duration>,
    pub w_inc: Option<Duration>,
    pub b_inc: Option<Duration>,
    pub moves_to_go: Option<NumMoves>,
}
impl TimeLeftData {
    pub fn time(&self, c: Color) -> Option<Duration> {
        match c {
            Color::White => self.w_time,
            Color::Black => self.b_time,
        }
    }
    pub fn set_time(&mut self, c: Color, val: Option<Duration>) {
        match c {
            Color::White => self.w_time = val,
            Color::Black => self.b_time = val,
        }
    }
    pub fn inc(&self, c: Color) -> Option<Duration> {
        match c {
            Color::White => self.w_inc,
            Color::Black => self.b_inc,
        }
    }
    pub fn set_inc(&mut self, c: Color, val: Option<Duration>) {
        match c {
            Color::White => self.w_inc = val,
            Color::Black => self.b_inc = val,
        }
    }
}
<commit_msg>Add field ucinewgame_support to uci::state::State.<commit_after>use std::time::Duration;

use game::Color;
use types::NumMoves;
use search;

pub use self::mode::Mode;

mod mode;

#[deriving(Clone)]
pub struct State {
    pub search_state: Option<search::State>,
    pub mode: Mode,
    pub start_search_time: Option<u64>,
    pub start_move_time: Option<u64>,
    pub time_data: Option<TimeData>,
    pub ucinewgame_support: bool,
}
impl State {
    pub fn new() -> State {
        State {
            search_state: None,
            mode: Mode::new(),
            start_search_time: None,
            start_move_time: None,
            time_data: None,
            ucinewgame_support: false,
        }
    }
}

#[deriving(Copy, Clone)]
pub enum TimeData {
    TimeLeft(TimeLeftData),
    ExactTime(Duration),
}

#[deriving(Copy, Clone)]
pub struct TimeLeftData {
    pub w_time: Option<Duration>,
    pub b_time: Option<Duration>,
    pub w_inc: Option<Duration>,
    pub b_inc: Option<Duration>,
    pub moves_to_go: Option<NumMoves>,
}
impl TimeLeftData {
    pub fn time(&self, c: Color) -> Option<Duration> {
        match c {
            Color::White => self.w_time,
            Color::Black => self.b_time,
        }
    }
    pub fn set_time(&mut self, c: Color, val: Option<Duration>) {
        match c {
            Color::White => self.w_time = val,
            Color::Black => self.b_time = val,
        }
    }
    pub fn inc(&self, c: Color) -> Option<Duration> {
        match c {
            Color::White => self.w_inc,
            Color::Black => self.b_inc,
        }
    }
    pub fn set_inc(&mut self, c: Color, val: Option<Duration>) {
        match c {
            Color::White => self.w_inc = val,
            Color::Black => self.b_inc = val,
        }
    }
}
<|endoftext|>


<commit_before>#![crate_name = "irc"]
#![crate_type = "dylib"]
#![license = "MIT/ASL2"]
#![feature(if_let, slicing_syntax, globs, phase, macro_rules)]

#![allow(dead_code, deprecated)]
#![deny(unused_must_use, warnings, unused_variables, unused_mut)]

#[cfg(test)] extern crate test;
#[phase(plugin, link)] extern crate log;
extern crate time;
extern crate serialize;

pub use self::message::IrcMessage;

pub use self::connection::IrcConnection;
pub use self::connection::IrcConnectionCommand;

pub use self::event::IrcEvent;

pub use self::watchers::{
    RegisterError,
    RegisterErrorType,

    JoinResult,
    JoinSuccess,
    JoinError,

    WhoResult,
    WhoRecord,
    WhoSuccess,
    WhoError,

    BundlerManager,
    JoinBundlerTrigger,
    WhoBundlerTrigger,
};

pub use self::irccase::{
    IrcAsciiExt,
    OwnedIrcAsciiExt,
};

pub use self::state::{
    User,
    UserId,

    Channel,
    ChannelId,

    State,
    MessageEndpoint,
};

mod numerics;
mod connection;
mod message;
mod watchers;
mod core_plugins;

#[experimental = "Subject to all types of change"]
/// Experimental message types
pub mod message_types;

#[experimental = "Subject to being moved"]
/// Experimental utility code
pub mod util;

#[experimental = "Subject to being moved"]
/// Experimental parsing code
pub mod parse;

/// Event types
mod event;

/// IRC case manipulation
mod irccase;

/// IRC state tracker
mod state;<commit_msg>Remove license crate attribute from source file<commit_after>#![crate_name = "irc"]
#![crate_type = "dylib"]
#![feature(if_let, slicing_syntax, globs, phase, macro_rules)]

#![allow(dead_code, deprecated)]
#![deny(unused_must_use, warnings, unused_variables, unused_mut)]

#[cfg(test)] extern crate test;
#[phase(plugin, link)] extern crate log;
extern crate time;
extern crate serialize;

pub use self::message::IrcMessage;

pub use self::connection::IrcConnection;
pub use self::connection::IrcConnectionCommand;

pub use self::event::IrcEvent;

pub use self::watchers::{
    RegisterError,
    RegisterErrorType,

    JoinResult,
    JoinSuccess,
    JoinError,

    WhoResult,
    WhoRecord,
    WhoSuccess,
    WhoError,

    BundlerManager,
    JoinBundlerTrigger,
    WhoBundlerTrigger,
};

pub use self::irccase::{
    IrcAsciiExt,
    OwnedIrcAsciiExt,
};

pub use self::state::{
    User,
    UserId,

    Channel,
    ChannelId,

    State,
    MessageEndpoint,
};

mod numerics;
mod connection;
mod message;
mod watchers;
mod core_plugins;

#[experimental = "Subject to all types of change"]
/// Experimental message types
pub mod message_types;

#[experimental = "Subject to being moved"]
/// Experimental utility code
pub mod util;

#[experimental = "Subject to being moved"]
/// Experimental parsing code
pub mod parse;

/// Event types
mod event;

/// IRC case manipulation
mod irccase;

/// IRC state tracker
mod state;<|endoftext|>


<commit_before>
/// Implemented by contexts that contains color.
pub trait RelativeColor<'a> {
    /// Multiplies with red, green, blue and alpha values.
    fn mul_rgba(&'a self, r: f32, g: f32, b: f32, a: f32) -> Self;
}

<commit_msg>Implemented default behaviour for `RelativeColor`<commit_after>use {
    CanColor,
    Color,
    HasColor,
};

/// Implemented by contexts that contains color.
pub trait RelativeColor<'a> {
    /// Multiplies with red, green, blue and alpha values.
    fn mul_rgba(&'a self, r: f32, g: f32, b: f32, a: f32) -> Self;
}

impl<
    'a,
    T: HasColor<'a, Color> + CanColor<'a, T, Color>
> RelativeColor<'a> for T {
    #[inline(always)]
    fn mul_rgba(&'a self, r: f32, g: f32, b: f32, a: f32) -> T {
        let color = self.get_color();
        self.color([color[0] * r, color[1] * g, color[2] * b, color[3] * a])
    }
}

<|endoftext|>


<commit_before>//! DaZeus IRC bot bindings for rust
#![feature(io, std_misc, net, collections)]

extern crate "rustc-serialize" as serialize;
extern crate unix_socket;

pub use self::event::*;
pub use self::response::*;
pub use self::request::*;
pub use self::scope::*;
use self::handlers::{Reader, Writer, Handler};
use self::util::Connection;
use std::collections::HashMap;
use std::io::{Read, Write, BufStream};
use std::sync::Future;
use std::sync::mpsc::{Sender, Receiver, channel};
use std::thread;

mod event;
mod handlers;
mod request;
mod response;
mod scope;
pub mod error;
pub mod util;

/// Methods that need to be implemented for sending commands to the server
trait Commander {
    fn subscribe(&mut self, events: &str, callback: &Fn(Event)) -> Future<Response>;
    fn subscribe_command(&mut self, command: &str, callback: &Fn(Event)) -> Future<Response>;
    fn networks(&self) -> Future<Response>;
    fn channels(&self, network: &str) -> Future<Response>;
    fn message(&self, network: &str, channel: &str, message: &str) -> Future<Response>;
    fn notice(&self, network: &str, channel: &str, message: &str) -> Future<Response>;
    fn ctcp(&self, network: &str, channel: &str, message: &str) -> Future<Response>;
    fn ctcp_reply(&self, network: &str, channel: &str, message: &str) -> Future<Response>;
    fn action(&self, network: &str, channel: &str, message: &str) -> Future<Response>;
    fn reply(&self, network: &str, channel: &str, message: &str) -> Future<Response>;
    fn send_names(&self, network: &str, channel: &str) -> Future<Response>;
    fn names(&self, network: &str, channel: &str) -> Future<Event>;
    fn send_whois(&self, network: &str, nick: &str) -> Future<Response>;
    fn whois(&self, network: &str, nick: &str) -> Future<Event>;
    fn join(&self, network: &str, channel: &str) -> Future<Response>;
    fn part(&self, network: &str, channel: &str) -> Future<Response>;
    fn nick(&self, network: &str) -> Future<Response>;
    fn handshake(&self, name: &str, version: &str, config: Option<&str>) -> Future<Response>;
    fn get_config(&self, group: &str, name: &str) -> Future<Response>;
    fn get_property(&self, name: &str, scope: Scope) -> Future<Response>;
    fn set_property(&self, name: &str, value: &str, scope: Scope) -> Future<Response>;
    fn unset_property(&self, name: &str, name: &str, scope: Scope) -> Future<Response>;
    fn get_property_keys(&self, prefix: &str, scope: Scope) -> Future<Response>;
    fn set_permission(&self, permission: &str, allow: bool, scope: Scope) -> Future<Response>;
    fn has_permission(&self, permission: &str, default: bool, scope: Scope) -> Future<Response>;
    fn unset_permission(&self, permission: &str, scope: Scope) -> Future<Response>;
}

/// The base DaZeus struct
pub struct DaZeus<'a> {
    event_rx: Receiver<Event>,
    request_tx: Sender<(Request, Sender<Response>)>,
    listeners: HashMap<EventType, Vec<&'a Fn(Event)>>,
}

impl<'a> DaZeus<'a> {
    /// Create a new instance of DaZeus from the given connection
    pub fn from_conn(conn: Connection) -> DaZeus<'a> {
        let clone = conn.try_clone().unwrap();
        DaZeus::new(conn, clone)
    }

    /// Create a new instance of DaZeus from the given connection, making use of a buffered stream
    pub fn from_conn_buff(conn: Connection) -> DaZeus<'a> {
        let clone = conn.try_clone().unwrap();
        DaZeus::new(BufStream::new(conn), BufStream::new(clone))
    }

    /// Create a new instance from a Read and Send, note that both need to point to the same socket
    pub fn new<R: Read + Send + 'static, W: Write + Send + 'static>(read: R, write: W) -> DaZeus<'a> {
        let (read_tx, read_rx) = channel();
        let (write_tx, write_rx) = channel();
        let mut reader = Reader::new(read, read_tx);
        let mut writer = Writer::new(write, write_rx);

        let (event_tx, event_rx) = channel();
        let (request_tx, request_rx) = channel();
        let mut handler = Handler::new(write_tx, event_tx);

        thread::spawn(move || { reader.run(); });
        thread::spawn(move || { writer.run(); });
        thread::spawn(move || { handler.run(read_rx, request_rx); });

        DaZeus { event_rx: event_rx, request_tx: request_tx, listeners: HashMap::new() }
    }

    /// Send a new Json packet to DaZeus
    pub fn send(&self, data: Request) -> Future<Response> {
        let (response_tx, response_rx) = channel();
        match self.request_tx.send((data, response_tx)) {
            Err(e) => panic!(e),
            Ok(_) => (),
        }
        Future::from_receiver(response_rx)
    }

    /// Handle an event received
    fn handle_event(&self, event: Event) {
        if self.listeners.contains_key(&event.event) {
            let listeners = self.listeners.get(&event.event).unwrap();
            for listener in listeners {
                (**listener)(event.clone());
            }
        }
    }

    /// Loop wait for messages to receive in a blocking way
    pub fn listen(&self) {
        loop {
            match self.event_rx.recv() {
                Ok(event) => self.handle_event(event),
                Err(err) => panic!(err)
            }
        }
    }
}
<commit_msg>Updated event listeners<commit_after>//! DaZeus IRC bot bindings for rust
#![feature(io, std_misc, net, collections)]

extern crate "rustc-serialize" as serialize;
extern crate unix_socket;

pub use self::event::*;
pub use self::response::*;
pub use self::request::*;
pub use self::scope::*;
use self::handlers::{Reader, Writer, Handler};
use self::util::Connection;
use std::collections::HashMap;
use std::io::{Read, Write, BufStream};
use std::sync::Future;
use std::sync::mpsc::{Sender, Receiver, channel};
use std::thread;

mod event;
mod handlers;
mod request;
mod response;
mod scope;
pub mod error;
pub mod util;

/// Methods that need to be implemented for sending commands to the server
pub trait Commander {
    fn subscribe(&mut self, event: &str, callback: &Fn(Event)) -> Future<Response>;
    fn subscribe_command(&mut self, command: &str, callback: &Fn(Event)) -> Future<Response>;
    fn networks(&self) -> Future<Response>;
    fn channels(&self, network: &str) -> Future<Response>;
    fn message(&self, network: &str, channel: &str, message: &str) -> Future<Response>;
    fn notice(&self, network: &str, channel: &str, message: &str) -> Future<Response>;
    fn ctcp(&self, network: &str, channel: &str, message: &str) -> Future<Response>;
    fn ctcp_reply(&self, network: &str, channel: &str, message: &str) -> Future<Response>;
    fn action(&self, network: &str, channel: &str, message: &str) -> Future<Response>;
    fn reply(&self, network: &str, channel: &str, message: &str) -> Future<Response>;
    fn send_names(&self, network: &str, channel: &str) -> Future<Response>;
    fn names(&self, network: &str, channel: &str) -> Future<Event>;
    fn send_whois(&self, network: &str, nick: &str) -> Future<Response>;
    fn whois(&self, network: &str, nick: &str) -> Future<Event>;
    fn join(&self, network: &str, channel: &str) -> Future<Response>;
    fn part(&self, network: &str, channel: &str) -> Future<Response>;
    fn nick(&self, network: &str) -> Future<Response>;
    fn handshake(&self, name: &str, version: &str, config: Option<&str>) -> Future<Response>;
    fn get_config(&self, group: &str, name: &str) -> Future<Response>;
    fn get_property(&self, name: &str, scope: Scope) -> Future<Response>;
    fn set_property(&self, name: &str, value: &str, scope: Scope) -> Future<Response>;
    fn unset_property(&self, name: &str, name: &str, scope: Scope) -> Future<Response>;
    fn get_property_keys(&self, prefix: &str, scope: Scope) -> Future<Response>;
    fn set_permission(&self, permission: &str, allow: bool, scope: Scope) -> Future<Response>;
    fn has_permission(&self, permission: &str, default: bool, scope: Scope) -> Future<Response>;
    fn unset_permission(&self, permission: &str, scope: Scope) -> Future<Response>;
}

/// The base DaZeus struct
pub struct DaZeus<'a> {
    event_rx: Receiver<Event>,
    request_tx: Sender<(Request, Sender<Response>)>,
    listeners: HashMap<EventType, Vec<&'a Fn(Event)>>,
}

impl<'a> DaZeus<'a> {
    /// Create a new instance of DaZeus from the given connection
    pub fn from_conn(conn: Connection) -> DaZeus<'a> {
        let clone = conn.try_clone().unwrap();
        DaZeus::new(conn, clone)
    }

    /// Create a new instance of DaZeus from the given connection, making use of a buffered stream
    pub fn from_conn_buff(conn: Connection) -> DaZeus<'a> {
        let clone = conn.try_clone().unwrap();
        DaZeus::new(BufStream::new(conn), BufStream::new(clone))
    }

    /// Create a new instance from a Read and Send, note that both need to point to the same socket
    pub fn new<R: Read + Send + 'static, W: Write + Send + 'static>(read: R, write: W) -> DaZeus<'a> {
        let (read_tx, read_rx) = channel();
        let (write_tx, write_rx) = channel();
        let mut reader = Reader::new(read, read_tx);
        let mut writer = Writer::new(write, write_rx);

        let (event_tx, event_rx) = channel();
        let (request_tx, request_rx) = channel();
        let mut handler = Handler::new(write_tx, event_tx);

        thread::spawn(move || { reader.run(); });
        thread::spawn(move || { writer.run(); });
        thread::spawn(move || { handler.run(read_rx, request_rx); });

        DaZeus { event_rx: event_rx, request_tx: request_tx, listeners: HashMap::new() }
    }

    /// Send a new Json packet to DaZeus
    pub fn send(&self, data: Request) -> Future<Response> {
        let (response_tx, response_rx) = channel();
        match self.request_tx.send((data, response_tx)) {
            Err(e) => panic!(e),
            Ok(_) => (),
        }
        Future::from_receiver(response_rx)
    }

    /// Handle an event received
    fn handle_event(&self, event: Event) {
        if self.listeners.contains_key(&event.event) {
            let listeners = self.listeners.get(&event.event).unwrap();
            for listener in listeners {
                (**listener)(event.clone());
            }
        }
    }

    /// Loop wait for messages to receive in a blocking way
    pub fn listen(&self) {
        loop {
            match self.event_rx.recv() {
                Ok(event) => self.handle_event(event),
                Err(err) => panic!(err)
            }
        }
    }

    /// Subscribe to an event type and call the callback function every time such an event occurs
    pub fn subscribe(&mut self, event: EventType, callback: &'a Fn(Event)) -> Future<Response> {
        let request = match event {
            EventType::Command(ref cmd) => Request::SubscribeCommand(cmd.clone(), None),
            _ => Request::Subscribe(event.to_string()),
        };

        if !self.listeners.contains_key(&event) {
            self.listeners.insert(event.clone(), Vec::new());
        }

        // borrow listeners only for adding the listener callback
        {
            let mut listeners = self.listeners.get_mut(&event).unwrap();
            listeners.push(callback);
        }

        // because we can't have a mutable borrow when borrowing immutable over here
        self.send(request)
    }

    /// Subscribe to a command and call the callback function every time such a command occurs
    pub fn subscribe_command(&mut self, command: &str, callback: &'a Fn(Event)) -> Future<Response> {
        self.subscribe(EventType::Command(String::from_str(command)), callback)
    }
}
<|endoftext|>


<commit_before>#![allow(dead_code, bad_style)]

pub const ENOMEM: i32 = 12;
pub const celix_thread_default : (i32,i32) = (0,0);

include!(concat!(env!("OUT_DIR"), "/celix_bind.rs"));
include!(concat!(env!("OUT_DIR"), "/constants.rs"));

// macros for functions needed by celix
<commit_msg>Fixed const value<commit_after>#![allow(dead_code, bad_style)]

pub const ENOMEM: i32 = 12;
pub const celix_thread_default : celix_thread_t = celix_thread_t {
    threadInitialized: 0,
    thread: 0,
};

include!(concat!(env!("OUT_DIR"), "/celix_bind.rs"));
include!(concat!(env!("OUT_DIR"), "/constants.rs"));

// TODO: macros for functions needed by celix
<|endoftext|>