<commit_before>// Copyright 2014 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

use std::ptr;
use std::slice;
use std::ffi;

use htslib;

pub struct Record {
    pub inner: *mut htslib::vcf::bcf1_t,
    pub header: *mut htslib::vcf::bcf_hdr_t,
    buffer: *mut ::libc::c_void,
}

impl Record {
    pub fn new() -> Self {
        let inner = unsafe { htslib::vcf::bcf_init() };
        Record { inner: inner, header: ptr::null_mut(), buffer: ptr::null_mut() }
    }

    #[inline]
    fn inner(&self) -> htslib::vcf::bcf1_t {
        unsafe { *self.inner }
    }

    pub fn rid(&self) -> Option<u32> {
        match self.inner().rid {
            -1  => None,
            rid => Some(rid as u32)
        }
    }

    // 0-based position.
    pub fn pos(&self) -> u32 {
        self.inner().pos as u32
    }

    pub fn alleles(&self) -> Vec<&[u8]> {
        unsafe { htslib::vcf::bcf_unpack(self.inner, htslib::vcf::BCF_UN_STR) };
        let n = self.inner().n_allele as usize;
        let dec = self.inner().d;
        let alleles = unsafe { slice::from_raw_parts(dec.allele, n) };
        (0..n).map(|i| unsafe { ffi::CStr::from_ptr(alleles[i]).to_bytes() }).collect()
    }

    pub fn qual(&self) -> f32 {
        self.inner().qual
    }

    /// Get the value of the given info tag.
    pub fn info<'a>(&'a mut self, tag: &'a [u8]) -> Info {
        Info { record: self, tag: tag }
    }

    pub fn sample_count(&self) -> u32 {
        self.inner().n_fmt_n_sample & 0xffffff
    }

    pub fn allele_count(&self) -> u16 {
        self.inner().n_allele
    }

    /// Get the value of the given format tag for each sample.
    pub fn format<'a>(&'a mut self, tag: &'a [u8]) -> Format {
        Format::new(self, tag)
    }
}

impl Drop for Record {
    fn drop(&mut self) {
        if !self.buffer.is_null() {
            unsafe { ::libc::free(self.buffer) };
        }
        unsafe { htslib::vcf::bcf_destroy(self.inner) };
    }
}

pub struct Info<'a> {
    record: &'a mut Record,
    tag: &'a [u8],
}

impl<'a> Info<'a> {
    fn data(&mut self, data_type: i32) -> Result<(usize, i32), TagError> {
        let mut n: i32 = 0;
        match unsafe {
            htslib::vcf::bcf_get_info_values(
                self.record.header,
                self.record.inner,
                ffi::CString::new(self.tag).unwrap().as_ptr() as *mut i8,
                &mut self.record.buffer,
                &mut n,
                data_type
            )
        } {
            -1 => Err(TagError::UndefinedTag),
            -2 => Err(TagError::UnexpectedType),
            -3 => Err(TagError::MissingTag),
            ret  => Ok((n as usize, ret)),
        }
    }

    pub fn integer(&mut self) -> Result<&[i32], TagError> {
        self.data(htslib::vcf::BCF_HT_INT).map(|(n, _)| {
            unsafe { slice::from_raw_parts(self.record.buffer as *mut i32, n) }
        })
    }

    pub fn float(&mut self) -> Result<&[f32], TagError> {
        self.data(htslib::vcf::BCF_HT_REAL).map(|(n, _)| {
            unsafe { slice::from_raw_parts(self.record.buffer as *mut f32, n) }
        })
    }

    pub fn flag(&mut self) -> Result<bool, TagError> {
        self.data(htslib::vcf::BCF_HT_FLAG).map(|(_, ret)| {
            ret == 1
        })
    }

    pub fn string(&mut self) -> Result<&[u8], TagError> {
        self.data(htslib::vcf::BCF_HT_STR).map(|(_, ret)| {
            unsafe { slice::from_raw_parts(self.record.buffer as *mut u8, ret as usize) }
        })
    }
}

// TODO implement format.
pub struct Format<'a> {
    record: &'a mut Record,
    tag: &'a [u8],
    inner: *mut htslib::vcf::bcf_fmt_t,
}

impl<'a> Format<'a> {
    fn new(record: &'a mut Record, tag: &'a [u8]) -> Format<'a> {
        let inner = unsafe { htslib::vcf::bcf_get_fmt(
            record.header,
            record.inner,
            ffi::CString::new(tag).unwrap().as_ptr() as *mut i8
        ) };
        Format { record: record, tag: tag, inner: inner }
    }

    fn values_per_sample(&self) -> usize {
        unsafe { (*self.inner).n as usize }
    }

    fn data(&mut self, data_type: i32) -> Result<(usize, i32), TagError> {
        let mut n: i32 = 0;
        match unsafe {
            htslib::vcf::bcf_get_format_values(
                self.record.header,
                self.record.inner,
                ffi::CString::new(self.tag).unwrap().as_ptr() as *mut i8,
                &mut self.record.buffer,
                &mut n,
                data_type
            )
        } {
            -1 => Err(TagError::UndefinedTag),
            -2 => Err(TagError::UnexpectedType),
            -3 => Err(TagError::MissingTag),
            ret  => Ok((n as usize, ret)),
        }
    }

    pub fn integer(&mut self) -> Result<Vec<&[i32]>, TagError> {
        self.data(htslib::vcf::BCF_HT_INT).map(|(n, _)| {
            unsafe {
                slice::from_raw_parts(self.record.buffer as *mut i32, n)
            }.chunks(self.values_per_sample()).collect()
        })
    }

    pub fn float(&mut self) -> Result<Vec<&[f32]>, TagError> {
        self.data(htslib::vcf::BCF_HT_REAL).map(|(n, _)| {
            unsafe {
                slice::from_raw_parts(self.record.buffer as *mut f32, n)
            }.chunks(self.values_per_sample()).collect()
        })
    }
}

pub enum TagError {
    UndefinedTag,
    UnexpectedType,
    MissingTag,
}
<commit_msg>Implement the Send trait for bcf records.<commit_after>// Copyright 2014 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

use std::ptr;
use std::slice;
use std::ffi;

use htslib;

pub struct Record {
    pub inner: *mut htslib::vcf::bcf1_t,
    pub header: *mut htslib::vcf::bcf_hdr_t,
    buffer: *mut ::libc::c_void,
}

impl Record {
    pub fn new() -> Self {
        let inner = unsafe { htslib::vcf::bcf_init() };
        Record { inner: inner, header: ptr::null_mut(), buffer: ptr::null_mut() }
    }

    #[inline]
    fn inner(&self) -> htslib::vcf::bcf1_t {
        unsafe { *self.inner }
    }

    pub fn rid(&self) -> Option<u32> {
        match self.inner().rid {
            -1  => None,
            rid => Some(rid as u32)
        }
    }

    // 0-based position.
    pub fn pos(&self) -> u32 {
        self.inner().pos as u32
    }

    pub fn alleles(&self) -> Vec<&[u8]> {
        unsafe { htslib::vcf::bcf_unpack(self.inner, htslib::vcf::BCF_UN_STR) };
        let n = self.inner().n_allele as usize;
        let dec = self.inner().d;
        let alleles = unsafe { slice::from_raw_parts(dec.allele, n) };
        (0..n).map(|i| unsafe { ffi::CStr::from_ptr(alleles[i]).to_bytes() }).collect()
    }

    pub fn qual(&self) -> f32 {
        self.inner().qual
    }

    /// Get the value of the given info tag.
    pub fn info<'a>(&'a mut self, tag: &'a [u8]) -> Info {
        Info { record: self, tag: tag }
    }

    pub fn sample_count(&self) -> u32 {
        self.inner().n_fmt_n_sample & 0xffffff
    }

    pub fn allele_count(&self) -> u16 {
        self.inner().n_allele
    }

    /// Get the value of the given format tag for each sample.
    pub fn format<'a>(&'a mut self, tag: &'a [u8]) -> Format {
        Format::new(self, tag)
    }
}

impl Drop for Record {
    fn drop(&mut self) {
        if !self.buffer.is_null() {
            unsafe { ::libc::free(self.buffer) };
        }
        unsafe { htslib::vcf::bcf_destroy(self.inner) };
    }
}

unsafe impl Send for Record {}

pub struct Info<'a> {
    record: &'a mut Record,
    tag: &'a [u8],
}

impl<'a> Info<'a> {
    fn data(&mut self, data_type: i32) -> Result<(usize, i32), TagError> {
        let mut n: i32 = 0;
        match unsafe {
            htslib::vcf::bcf_get_info_values(
                self.record.header,
                self.record.inner,
                ffi::CString::new(self.tag).unwrap().as_ptr() as *mut i8,
                &mut self.record.buffer,
                &mut n,
                data_type
            )
        } {
            -1 => Err(TagError::UndefinedTag),
            -2 => Err(TagError::UnexpectedType),
            -3 => Err(TagError::MissingTag),
            ret  => Ok((n as usize, ret)),
        }
    }

    pub fn integer(&mut self) -> Result<&[i32], TagError> {
        self.data(htslib::vcf::BCF_HT_INT).map(|(n, _)| {
            unsafe { slice::from_raw_parts(self.record.buffer as *mut i32, n) }
        })
    }

    pub fn float(&mut self) -> Result<&[f32], TagError> {
        self.data(htslib::vcf::BCF_HT_REAL).map(|(n, _)| {
            unsafe { slice::from_raw_parts(self.record.buffer as *mut f32, n) }
        })
    }

    pub fn flag(&mut self) -> Result<bool, TagError> {
        self.data(htslib::vcf::BCF_HT_FLAG).map(|(_, ret)| {
            ret == 1
        })
    }

    pub fn string(&mut self) -> Result<&[u8], TagError> {
        self.data(htslib::vcf::BCF_HT_STR).map(|(_, ret)| {
            unsafe { slice::from_raw_parts(self.record.buffer as *mut u8, ret as usize) }
        })
    }
}

// TODO implement format.
pub struct Format<'a> {
    record: &'a mut Record,
    tag: &'a [u8],
    inner: *mut htslib::vcf::bcf_fmt_t,
}

impl<'a> Format<'a> {
    fn new(record: &'a mut Record, tag: &'a [u8]) -> Format<'a> {
        let inner = unsafe { htslib::vcf::bcf_get_fmt(
            record.header,
            record.inner,
            ffi::CString::new(tag).unwrap().as_ptr() as *mut i8
        ) };
        Format { record: record, tag: tag, inner: inner }
    }

    fn values_per_sample(&self) -> usize {
        unsafe { (*self.inner).n as usize }
    }

    fn data(&mut self, data_type: i32) -> Result<(usize, i32), TagError> {
        let mut n: i32 = 0;
        match unsafe {
            htslib::vcf::bcf_get_format_values(
                self.record.header,
                self.record.inner,
                ffi::CString::new(self.tag).unwrap().as_ptr() as *mut i8,
                &mut self.record.buffer,
                &mut n,
                data_type
            )
        } {
            -1 => Err(TagError::UndefinedTag),
            -2 => Err(TagError::UnexpectedType),
            -3 => Err(TagError::MissingTag),
            ret  => Ok((n as usize, ret)),
        }
    }

    pub fn integer(&mut self) -> Result<Vec<&[i32]>, TagError> {
        self.data(htslib::vcf::BCF_HT_INT).map(|(n, _)| {
            unsafe {
                slice::from_raw_parts(self.record.buffer as *mut i32, n)
            }.chunks(self.values_per_sample()).collect()
        })
    }

    pub fn float(&mut self) -> Result<Vec<&[f32]>, TagError> {
        self.data(htslib::vcf::BCF_HT_REAL).map(|(n, _)| {
            unsafe {
                slice::from_raw_parts(self.record.buffer as *mut f32, n)
            }.chunks(self.values_per_sample()).collect()
        })
    }
}

pub enum TagError {
    UndefinedTag,
    UnexpectedType,
    MissingTag,
}
<|endoftext|>


<commit_before>use std::fmt;
use std::cmp;
use std::io::{self, Read, Take};
use httparse;

use {Result, Metadata};
use super::headers::{ContentLength, TransferEncoding};

pub trait IoExt: Sized {
    fn into_body_reader(self) -> Result<BodyReader<Self>>
        where Self: Read + Metadata
    {
        BodyReader::new(self)
    }
    fn max_length(self, max_len: u64) -> MaxLength<Self>
        where Self: Read
    {
        MaxLength::new(self, max_len)
    }
}
impl<T: Sized> IoExt for T {}

pub enum BodyReader<R> {
    Chunked(ChunkedBodyReader<R>),
    FixedLength(Take<R>),
    Raw(R),
}
impl<R> BodyReader<R>
    where R: Read + Metadata
{
    pub fn new(inner: R) -> Result<Self> {
        if let Some(h) = track_try!(inner.headers().parse::<ContentLength>()) {
            Ok(BodyReader::FixedLength(inner.take(h.len())))
        } else if let true = track_try!(inner.headers().parse::<TransferEncoding>()).is_some() {
            Ok(BodyReader::Chunked(ChunkedBodyReader::new(inner)))
        } else {
            Ok(BodyReader::Raw(inner))
        }
    }
    pub fn into_inner(self) -> R {
        match self {
            BodyReader::Chunked(r) => r.into_inner(),
            BodyReader::FixedLength(r) => r.into_inner(),
            BodyReader::Raw(r) => r,
        }
    }
}
impl<R: Read> Read for BodyReader<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        match *self {
            BodyReader::Chunked(ref mut r) => r.read(buf),
            BodyReader::FixedLength(ref mut r) => r.read(buf),
            BodyReader::Raw(ref mut r) => r.read(buf),
        }
    }
}
impl<R> fmt::Debug for BodyReader<R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            BodyReader::Chunked(_) => write!(f, "Chunked(_)"),
            BodyReader::FixedLength(_) => write!(f, "FixedLength(_)"),
            BodyReader::Raw(_) => write!(f, "Raw(_)"),
        }
    }
}

#[derive(Debug)]
pub struct ChunkedBodyReader<R> {
    inner: R,
    buf: [u8; 32],
    buf_offset: usize,
    chunk_remaining: Option<u64>,
    is_last: bool,
}
impl<R: Read> ChunkedBodyReader<R> {
    fn new(inner: R) -> Self {
        ChunkedBodyReader {
            inner: inner,
            buf: [0; 32],
            buf_offset: 0,
            chunk_remaining: None,
            is_last: false,
        }
    }
    pub fn into_inner(self) -> R {
        self.inner
    }
    fn fill_buf_byte(&mut self) -> io::Result<()> {
        if self.buf_offset == self.buf.len() {
            Err(io::Error::new(io::ErrorKind::InvalidData, "Chunk size is too large"))
        } else {
            let buf = &mut self.buf[self.buf_offset..][..1];
            if 0 == self.inner.read(buf)? {
                Err(io::Error::new(io::ErrorKind::UnexpectedEof,
                                   "Unexpected EOF while reading chunked HTTP body"))
            } else {
                self.buf_offset += 1;
                Ok(())
            }
        }
    }
}
impl<R: Read> Read for ChunkedBodyReader<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        if let Some(0) = self.chunk_remaining {
            while self.buf_offset != 2 {
                self.fill_buf_byte()?;
            }
            if &self.buf[0..2] == b"\r\n" {
                self.chunk_remaining = None;
                self.read(buf)
            } else {
                Err(io::Error::new(io::ErrorKind::InvalidData,
                                   r#"Chunk must be terminated with '\r\n'"#))
            }
        } else if let Some(remaining) = self.chunk_remaining {
            let size = cmp::min(remaining, buf.len() as u64) as usize;
            let read_size = self.inner.read(&mut buf[..size])?;
            self.chunk_remaining = Some(remaining - read_size as u64);
            Ok(read_size)
        } else if self.is_last {
            Ok(0)
        } else {
            loop {
                self.fill_buf_byte()?;
                match httparse::parse_chunk_size(&self.buf[..self.buf_offset]) {
                    Err(e) => return Err(io::Error::new(io::ErrorKind::InvalidData, e.to_string())),
                    Ok(httparse::Status::Partial) => {}
                    Ok(httparse::Status::Complete((_, chunk_size))) => {
                        self.buf_offset = 0;
                        self.chunk_remaining = Some(chunk_size);
                        self.is_last = chunk_size == 0;
                        return self.read(buf);
                    }
                }
            }
        }
    }
}

#[derive(Debug)]
pub struct MaxLength<R> {
    inner: R,
    read_bytes: u64,
    max_bytes: u64,
}
impl<R: Read> MaxLength<R> {
    pub fn new(inner: R, max_len: u64) -> Self {
        MaxLength {
            inner: inner,
            read_bytes: 0,
            max_bytes: max_len,
        }
    }
    pub fn into_inner(self) -> R {
        self.inner
    }
}
impl<R: Read> Read for MaxLength<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        if self.read_bytes == self.max_bytes {
            let message = format!("Maximum length ({} bytes) exceeded", self.max_bytes);
            Err(io::Error::new(io::ErrorKind::InvalidData, message))
        } else {
            let size = cmp::min(buf.len() as u64, self.max_bytes - self.read_bytes) as usize;
            let read_size = self.inner.read(&mut buf[..size])?;
            self.read_bytes += read_size as u64;
            Ok(read_size)
        }
    }
}
<commit_msg>Add branch to handle empty body request<commit_after>use std::fmt;
use std::cmp;
use std::io::{self, Read, Take};
use httparse;

use {Result, Metadata};
use super::headers::{ContentLength, TransferEncoding};

pub trait IoExt: Sized {
    fn into_body_reader(self) -> Result<BodyReader<Self>>
        where Self: Read + Metadata
    {
        BodyReader::new(self)
    }
    fn max_length(self, max_len: u64) -> MaxLength<Self>
        where Self: Read
    {
        MaxLength::new(self, max_len)
    }
}
impl<T: Sized> IoExt for T {}

pub enum BodyReader<R> {
    Chunked(ChunkedBodyReader<R>),
    FixedLength(Take<R>),
    Raw(R),
}
impl<R> BodyReader<R>
    where R: Read + Metadata
{
    pub fn new(inner: R) -> Result<Self> {
        if let Some(h) = track_try!(inner.headers().parse::<ContentLength>()) {
            Ok(BodyReader::FixedLength(inner.take(h.len())))
        } else if let true = track_try!(inner.headers().parse::<TransferEncoding>()).is_some() {
            Ok(BodyReader::Chunked(ChunkedBodyReader::new(inner)))
        } else if inner.is_request() {
            Ok(BodyReader::FixedLength(inner.take(0)))
        } else {
            Ok(BodyReader::Raw(inner))
        }
    }
    pub fn into_inner(self) -> R {
        match self {
            BodyReader::Chunked(r) => r.into_inner(),
            BodyReader::FixedLength(r) => r.into_inner(),
            BodyReader::Raw(r) => r,
        }
    }
}
impl<R: Read> Read for BodyReader<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        match *self {
            BodyReader::Chunked(ref mut r) => r.read(buf),
            BodyReader::FixedLength(ref mut r) => r.read(buf),
            BodyReader::Raw(ref mut r) => r.read(buf),
        }
    }
}
impl<R> fmt::Debug for BodyReader<R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            BodyReader::Chunked(_) => write!(f, "Chunked(_)"),
            BodyReader::FixedLength(_) => write!(f, "FixedLength(_)"),
            BodyReader::Raw(_) => write!(f, "Raw(_)"),
        }
    }
}

#[derive(Debug)]
pub struct ChunkedBodyReader<R> {
    inner: R,
    buf: [u8; 32],
    buf_offset: usize,
    chunk_remaining: Option<u64>,
    is_last: bool,
}
impl<R: Read> ChunkedBodyReader<R> {
    fn new(inner: R) -> Self {
        ChunkedBodyReader {
            inner: inner,
            buf: [0; 32],
            buf_offset: 0,
            chunk_remaining: None,
            is_last: false,
        }
    }
    pub fn into_inner(self) -> R {
        self.inner
    }
    fn fill_buf_byte(&mut self) -> io::Result<()> {
        if self.buf_offset == self.buf.len() {
            Err(io::Error::new(io::ErrorKind::InvalidData, "Chunk size is too large"))
        } else {
            let buf = &mut self.buf[self.buf_offset..][..1];
            if 0 == self.inner.read(buf)? {
                Err(io::Error::new(io::ErrorKind::UnexpectedEof,
                                   "Unexpected EOF while reading chunked HTTP body"))
            } else {
                self.buf_offset += 1;
                Ok(())
            }
        }
    }
}
impl<R: Read> Read for ChunkedBodyReader<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        if let Some(0) = self.chunk_remaining {
            while self.buf_offset != 2 {
                self.fill_buf_byte()?;
            }
            if &self.buf[0..2] == b"\r\n" {
                self.chunk_remaining = None;
                self.read(buf)
            } else {
                Err(io::Error::new(io::ErrorKind::InvalidData,
                                   r#"Chunk must be terminated with '\r\n'"#))
            }
        } else if let Some(remaining) = self.chunk_remaining {
            let size = cmp::min(remaining, buf.len() as u64) as usize;
            let read_size = self.inner.read(&mut buf[..size])?;
            self.chunk_remaining = Some(remaining - read_size as u64);
            Ok(read_size)
        } else if self.is_last {
            Ok(0)
        } else {
            loop {
                self.fill_buf_byte()?;
                match httparse::parse_chunk_size(&self.buf[..self.buf_offset]) {
                    Err(e) => return Err(io::Error::new(io::ErrorKind::InvalidData, e.to_string())),
                    Ok(httparse::Status::Partial) => {}
                    Ok(httparse::Status::Complete((_, chunk_size))) => {
                        self.buf_offset = 0;
                        self.chunk_remaining = Some(chunk_size);
                        self.is_last = chunk_size == 0;
                        return self.read(buf);
                    }
                }
            }
        }
    }
}

#[derive(Debug)]
pub struct MaxLength<R> {
    inner: R,
    read_bytes: u64,
    max_bytes: u64,
}
impl<R: Read> MaxLength<R> {
    pub fn new(inner: R, max_len: u64) -> Self {
        MaxLength {
            inner: inner,
            read_bytes: 0,
            max_bytes: max_len,
        }
    }
    pub fn into_inner(self) -> R {
        self.inner
    }
}
impl<R: Read> Read for MaxLength<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        if self.read_bytes == self.max_bytes {
            let message = format!("Maximum length ({} bytes) exceeded", self.max_bytes);
            Err(io::Error::new(io::ErrorKind::InvalidData, message))
        } else {
            let size = cmp::min(buf.len() as u64, self.max_bytes - self.read_bytes) as usize;
            let read_size = self.inner.read(&mut buf[..size])?;
            self.read_bytes += read_size as u64;
            Ok(read_size)
        }
    }
}
<|endoftext|>


<commit_before>use tileset::FlipContext;
use map::{Adjacents};
use sdl2::pixels::Color;

#[derive(Clone, Copy)]
pub enum CellState {
    Empty,
    Dirt,
    Stone,
    Wall
}

pub fn get_tileset_sprite(adjacents: &[bool; 8]) -> (u32, u32, FlipContext) {
    let adjacent_tiles = (
        adjacents[0],
        adjacents[1],
        adjacents[2],
        adjacents[3],
        adjacents[4],
        adjacents[5],
        adjacents[6],
        adjacents[7],
    );
    match adjacent_tiles {
        (
            _,     true,  _,
            true,         true,
            _,     true, _
        ) => {
            (5, 0, FlipContext::FlipNone)  // Standalone
        },
        (
            _,     true,  _,
            true,         true,
            _,     false, _
        ) => {
            (5, 1, FlipContext::FlipNone)  // Top nub
        },
        (
            _,     false,  _,
            true,         true,
            _,     false, _
        ) => {
            (5, 2, FlipContext::FlipNone)  // Vertical bar
        },
        (
            _,     false,  _,
            true,         true,
            _,     true, _
        ) => {
            (5, 3, FlipContext::FlipNone)  // Bottom nub
        },
        (
            _,     true,  _,
            true,         false,
            _,     true,  _
        ) => {
            (1, 3, FlipContext::FlipNone)  // Left nub
        },
        (
            _,     true,  _,
            false,        false,
            _,     true,  _
        ) => {
            (7, 1, FlipContext::FlipNone)  // Horizontal bar
        },
        (
            _,     true,  _,
            false,        true,
            _,     true,  _
        ) => {
            (1, 3, FlipContext::FlipHorizontal)  // Right nub
        },
        (
            _,     true,  _,
            true,         false,
            _,     false, false
        ) => {
            (1, 0, FlipContext::FlipNone)  // Top-left
        },
        (
            _,     false,  false,
            true,         false,
            _,     false, false
        ) => {
            (1, 1, FlipContext::FlipNone)  // Left
        },
        (
            _,     false, false,
            true,         false,
            _,     true , _
        ) => {
            (1, 2, FlipContext::FlipNone)  // Bottom-left
        },
        (
            _,     true,  _,
            false,        true,
            false, false, _
        ) => {
            (1, 0, FlipContext::FlipHorizontal)  // Top-right
        },
        (
            false,  false, _,
            false,         true,
            false,  false, _
        ) => {
            (1, 1, FlipContext::FlipHorizontal)  // Right
        },
        (
            false, false, _,
            false,        true,
            _,     true,  _
        ) => {
            (1, 2, FlipContext::FlipHorizontal)  // Bottom-right
        },
        (
            _, true,      _,
            _,            _,
            false, false, false
        ) => {
            (6, 1, FlipContext::FlipNone)  // Top
        },
        (
            false, false, false,
            _,            _,
            _, true,      _
        ) => {
            (6, 3, FlipContext::FlipNone)  // Bottom
        },
        (
            _,    true,   _,
            false,        false,
            false, false, true
        ) => {
            (3, 0, FlipContext::FlipHorizontal)  // T
        },
        (
            _,    true,  _,
            false,       false,
            true, false, false
        ) => {
            (3, 0, FlipContext::FlipNone)  // T
        },
        (
            true, false, false,
            false,       false,
            _, true,  false
        ) => {
            (3, 2, FlipContext::FlipNone)  // T
        },
        (
            false, false, true,
            false,        false,
            false, true,  _
        ) => {
            (3, 2, FlipContext::FlipHorizontal)  // T
        },
        (
            true,  false, false,
            false,        false,
            false, false, false
        ) => {
            (2, 0, FlipContext::FlipNone)  // Inside elbow top left
        },
        (
            false, false, true,
            false,        false,
            false, false, false
        ) => {
            (2, 0, FlipContext::FlipHorizontal)  // Inside elbow top right
        },
        (
            false, false, false,
            false,        false,
            true, false, false
        ) => {
            (2, 2, FlipContext::FlipNone)  // Inside elbow bottom left
        },
        (
            false, false, false,
            false,        false,
            false, false, true
        ) => {
            (2, 2, FlipContext::FlipHorizontal)  // Inside elbow bottom right
        },
        (
            false, false, true,
            false,        false,
            true, false, false
        ) => {
            (3, 1, FlipContext::FlipNone)  // Diagonal
        },
        (
            true,  false, false,
            false,        false,
            false, false, true,
        ) => {
            (3, 1, FlipContext::FlipHorizontal)  // Diagonal
        },
        (
            false, false, _,
            false,        true,
            true, false, _
        ) => {
            (4, 2, FlipContext::FlipNone)  // Side missing bottom corner
        },
        (
            _,    false, false,
            true,        false,
            _,    false, true
        ) => {
            (4, 2, FlipContext::FlipHorizontal)  // Side missing bottom corner
        },
        (
            true, false, _,
            false,        true,
            false, false, _
        ) => {
            (4, 0, FlipContext::FlipNone)  // Side missing top corner
        },
        (
            _,    false,  true,
            true,        false,
            _,    false, false,
        ) => {
            (4, 0, FlipContext::FlipHorizontal)  // Side missing top corner
        },
        (
            _,     true,  _,
            false,        false,
            true,  false, true,
        ) => {
            (6, 0, FlipContext::FlipNone)  // T
        },
        (
            true,  false, true,
            false,        false,
            _,     true,  _
        ) => {
            (7, 0, FlipContext::FlipNone)  // Inverse T
        },
        (
            true,  false, true,
            false,        false,
            _,     false, _
        ) => {
            (4, 3, FlipContext::FlipNone)  // T
        },
        (
            _,     false, _,
            false,        false,
            true,  false, true
        ) => {
            (4, 3, FlipContext::FlipVertical)  // T
        },
        (
            _,     true,  _,
            true,         false,
            _,     false, true
        ) => {
            (2, 3, FlipContext::FlipNone)  // Top-left bend
        },
        (
            _,      true,  _,
            false,         true,
            true,    false, _
        ) => {
            (2, 3, FlipContext::FlipHorizontal)  // Top-right bend
        },
        (
            _,     false, true,
            true,         false,
            _,     true , _
        ) => {
            (3, 3, FlipContext::FlipNone)  // Bottom-left
        },
        (
            true,  false, _,
            false,        true,
            _,      true , _
        ) => {
            (3, 3, FlipContext::FlipHorizontal)  // Bottom-left
        },
        (
            _, _, _,
            _,    _,
            _, _, _
        ) => {
            (6, 2, FlipContext::FlipNone)
        }
    }
}

impl CellState {
    pub fn is_passable(&self) -> bool {
        match *self {
            CellState::Empty | CellState::Dirt => true,
            _ => false
        }
    }

    pub fn get_color(&self) -> Color {
        let BLACK = Color::RGB(0, 0, 0);
        let BROWN = Color::RGB(100, 100, 0);
        let GREY = Color::RGB(100, 100, 100);
        let WHITE = Color::RGB(255, 255, 255);
        match *self {
            CellState::Dirt => BROWN,
            CellState::Stone => GREY,
            CellState::Wall => WHITE,
            CellState::Empty => BLACK
        }
    }

    pub fn get_sprite(&self, adjacents: &Adjacents) -> Option<(u32, u32, FlipContext)> {
        match *self {
            CellState::Dirt => {
                let adjacent_tile_states = adjacents.as_tile_states();
                let mut adjacent_tiles = [false; 8];
                for i in 0..8 {
                    adjacent_tiles[i] = match adjacent_tile_states[i] {
                        CellState::Empty => true,
                        _ => false
                    }
                };
                let (x, y, context) = get_tileset_sprite(&adjacent_tiles);
                Some((x + 8, y, context))
            },
            CellState::Stone => {
                let adjacent_tile_states = adjacents.as_tile_states();
                let mut adjacent_tiles = [false; 8];
                for i in 0..8 {
                    adjacent_tiles[i] = match adjacent_tile_states[i] {
                        CellState::Empty | CellState::Dirt => true,
                        _ => false
                    }
                };
                let (x, y, context) = get_tileset_sprite(&adjacent_tiles);
                Some((x + 8, y + 12, context))
            },
            CellState::Wall => Some((2, 5, FlipContext::FlipNone)),
            CellState::Empty => None
        }
    }
}

<commit_msg>Standard cell states<commit_after>use tileset::FlipContext;
use map::{Adjacents};
use sdl2::pixels::Color;

#[derive(Clone, Copy)]
pub enum CellState {
    Empty,
    Dirt,
    Stone,
    Wall
}

pub fn get_tileset_sprite(adjacents: &[bool; 8]) -> (u32, u32, FlipContext) {
    let adjacent_tiles = (
        adjacents[0],
        adjacents[1],
        adjacents[2],
        adjacents[3],
        adjacents[4],
        adjacents[5],
        adjacents[6],
        adjacents[7],
    );
    match adjacent_tiles {
        // 0, 0 - Unused ramp
        // 0, 1 - Unused ramp
        (
            true,  false,  false,
            false,         false,
            true,  false,  true
        ) => {
            (0, 2, FlipContext::FlipNone)  // 3 corners
        },
        (
            false, false, true,
            false,        false,
            true, false, true,
        ) => {
            (0, 2, FlipContext::FlipHorizontal)  // 3 corners
        },
        (
            true,  false,  true,
            false,         false,
            true,  false,  false
        ) => {
            (0, 3, FlipContext::FlipNone)  // 3 corners
        },
        (
            true,  false, true,
            false,       false,
            false, false, true,
        ) => {
            (0, 3, FlipContext::FlipHorizontal)  // 3 corners
        },
        (
            _,     true,  _,
            true,         false,
            _,     false, false
        ) => {
            (1, 0, FlipContext::FlipNone)  // Top-left
        },
        (
            _,     true,  _,
            false,        true,
            false, false, _
        ) => {
            (1, 0, FlipContext::FlipHorizontal)  // Top-right
        },
        (
            _,     false,  false,
            true,         false,
            _,     false, false
        ) => {
            (1, 1, FlipContext::FlipNone)  // Left
        },
        (
            false,  false, _,
            false,         true,
            false,  false, _
        ) => {
            (1, 1, FlipContext::FlipHorizontal)  // Right
        },
        (
            _,     false, false,
            true,         false,
            _,     true , _
        ) => {
            (1, 2, FlipContext::FlipNone)  // Bottom-left
        },
        (
            false, false, _,
            false,        true,
            _,     true,  _
        ) => {
            (1, 2, FlipContext::FlipHorizontal)  // Bottom-right
        },
        (
            _,     true,  _,
            true,         false,
            _,     true,  _
        ) => {
            (1, 3, FlipContext::FlipNone)  // Left nub
        },
        (
            _,     true,  _,
            false,        true,
            _,     true,  _
        ) => {
            (1, 3, FlipContext::FlipHorizontal)  // Right nub
        },
        (
            true,  false, false,
            false,        false,
            false, false, false
        ) => {
            (2, 0, FlipContext::FlipNone)  // Inside elbow top left
        },
        (
            false, false, true,
            false,        false,
            false, false, false
        ) => {
            (2, 0, FlipContext::FlipHorizontal)  // Inside elbow top right
        },
        (
            true,  false, false,
            false,        false,
            true, false, false
        ) => {
            (2, 1, FlipContext::FlipNone)  // Left corners
        },
        (
            false, false, true,
            false,        false,
            false, false, true
        ) => {
            (2, 1, FlipContext::FlipHorizontal)  // Right corners
        },
        (
            false, false, false,
            false,        false,
            true, false, false
        ) => {
            (2, 2, FlipContext::FlipNone)  // Inside elbow bottom left
        },
        (
            false, false, false,
            false,        false,
            false, false, true
        ) => {
            (2, 2, FlipContext::FlipHorizontal)  // Inside elbow bottom right
        },
        (
            _,     true,  _,
            true,         false,
            _,     false, true
        ) => {
            (2, 3, FlipContext::FlipNone)  // Top-left bend
        },
        (
            _,      true,  _,
            false,         true,
            true,    false, _
        ) => {
            (2, 3, FlipContext::FlipHorizontal)  // Top-right bend
        },
        (
            _,    true,  _,
            false,       false,
            true, false, false
        ) => {
            (3, 0, FlipContext::FlipNone)  // T
        },
        (
            _,    true,   _,
            false,        false,
            false, false, true
        ) => {
            (3, 0, FlipContext::FlipHorizontal)  // T
        },
        (
            false, false, true,
            false,        false,
            true, false, false
        ) => {
            (3, 1, FlipContext::FlipNone)  // Diagonal
        },
        (
            true,  false, false,
            false,        false,
            false, false, true,
        ) => {
            (3, 1, FlipContext::FlipHorizontal)  // Diagonal
        },
        (
            true, false, false,
            false,       false,
            _,    true,   _
        ) => {
            (3, 2, FlipContext::FlipNone)  // T
        },
        (
            false, false, true,
            false,        false,
            _,     true,  _
        ) => {
            (3, 2, FlipContext::FlipHorizontal)  // T
        },
        (
            _,     false, true,
            true,         false,
            _,     true , _
        ) => {
            (3, 3, FlipContext::FlipNone)  // Bottom-left
        },
        (
            true,  false, _,
            false,        true,
            _,      true , _
        ) => {
            (3, 3, FlipContext::FlipHorizontal)  // Bottom-left
        },
        (
            true, false, _,
            false,        true,
            false, false, _
        ) => {
            (4, 0, FlipContext::FlipNone)  // Side missing top corner
        },
        (
            _,    false,  true,
            true,        false,
            _,    false, false,
        ) => {
            (4, 0, FlipContext::FlipHorizontal)  // Side missing top corner
        },
        (
            true, false, _,
            false,        true,
            true, false, _
        ) => {
            (4, 1, FlipContext::FlipNone)  // Right T
        },
        (
            _,     false, true,
            true,         false,
            _,     false, true,
        ) => {
            (4, 1, FlipContext::FlipHorizontal)  // Left T
        },
        (
            false, false, _,
            false,        true,
            true, false, _
        ) => {
            (4, 2, FlipContext::FlipNone)  // Side missing bottom corner
        },
        (
            _,    false, false,
            true,        false,
            _,    false, true
        ) => {
            (4, 2, FlipContext::FlipHorizontal)  // Side missing bottom corner
        },
        (
            true,  false, true,
            false,        false,
            false,     false, false
        ) => {
            (4, 3, FlipContext::FlipNone)  // T
        },
        (
            false, false, false,
            false,        false,
            true,  false, true
        ) => {
            (4, 3, FlipContext::FlipVertical)  // T
        },
        (
            _,     true,  _,
            true,         true,
            _,     true, _
        ) => {
            (5, 0, FlipContext::FlipNone)  // Standalone
        },
        (
            _,     true,  _,
            true,         true,
            _,     false, _
        ) => {
            (5, 1, FlipContext::FlipNone)  // Top nub
        },
        (
            _,     false,  _,
            true,         true,
            _,     false, _
        ) => {
            (5, 2, FlipContext::FlipNone)  // Vertical bar
        },
        (
            _,     false,  _,
            true,         true,
            _,     true, _
        ) => {
            (5, 3, FlipContext::FlipNone)  // Bottom nub
        },
        (
            _,     true,  _,
            false,        false,
            true,  false, true,
        ) => {
            (6, 0, FlipContext::FlipNone)  // T
        },
        (
            _, true,      _,
            _,            _,
            false, false, false
        ) => {
            (6, 1, FlipContext::FlipNone)  // Top
        },
        // Skip 6, 2 - centre block
        (
            false, false, false,
            _,            _,
            _, true,      _
        ) => {
            (6, 3, FlipContext::FlipNone)  // Bottom
        },
        (
            true,  false, true,
            false,        false,
            _,     true,  _
        ) => {
            (7, 0, FlipContext::FlipNone)  // Inverse T
        },
        (
            _,     true,  _,
            false,        false,
            _,     true,  _
        ) => {
            (7, 1, FlipContext::FlipNone)  // Horizontal bar
        },
        (
            true,  false, true,
            false,        false,
            true,  false, true
        ) => {
            (7, 2, FlipContext::FlipNone)  // +
        },
        (
            _, _, _,
            _,    _,
            _, _, _
        ) => {
            (6, 2, FlipContext::FlipNone)
        }
    }
}

impl CellState {
    pub fn is_passable(&self) -> bool {
        match *self {
            CellState::Empty | CellState::Dirt => true,
            _ => false
        }
    }

    pub fn get_color(&self) -> Color {
        let BLACK = Color::RGB(0, 0, 0);
        let BROWN = Color::RGB(100, 100, 0);
        let GREY = Color::RGB(100, 100, 100);
        let WHITE = Color::RGB(255, 255, 255);
        match *self {
            CellState::Dirt => BROWN,
            CellState::Stone => GREY,
            CellState::Wall => WHITE,
            CellState::Empty => BLACK
        }
    }

    pub fn get_sprite(&self, adjacents: &Adjacents) -> Option<(u32, u32, FlipContext)> {
        match *self {
            CellState::Dirt => {
                let adjacent_tile_states = adjacents.as_tile_states();
                let mut adjacent_tiles = [false; 8];
                for i in 0..8 {
                    adjacent_tiles[i] = match adjacent_tile_states[i] {
                        CellState::Empty => true,
                        _ => false
                    }
                };
                let (x, y, context) = get_tileset_sprite(&adjacent_tiles);
                Some((x + 8, y, context))
            },
            CellState::Stone => {
                let adjacent_tile_states = adjacents.as_tile_states();
                let mut adjacent_tiles = [false; 8];
                for i in 0..8 {
                    adjacent_tiles[i] = match adjacent_tile_states[i] {
                        CellState::Empty | CellState::Dirt => true,
                        _ => false
                    }
                };
                let (x, y, context) = get_tileset_sprite(&adjacent_tiles);
                Some((x + 8, y + 12, context))
            },
            CellState::Wall => Some((2, 5, FlipContext::FlipNone)),
            CellState::Empty => None
        }
    }
}

<|endoftext|>


<commit_before>extern crate mio;

use mio::tcp::*;
use mio::TryWrite;
use mio::util::Slab;
use std::net::SocketAddr;
use std::io::Result;
use mio::{EventSet, EventLoop, Token, Handler, PollOpt};
use std::thread;
use std::thread::JoinHandle;
use std::sync::{Arc, RwLock};
//use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::collections::VecDeque;

const CLIENT_TOKEN: mio::Token = mio::Token(1);

struct ClientInterface{
    socket: TcpStream,

    thread_handle: Option<JoinHandle<()>>,

    client: Arc<RwLock<ClientData>>
}

impl ClientInterface{
    fn new(event_loop: Arc<RwLock<EventLoop<ClientInterface>>>, socket: TcpStream, client: Arc<RwLock<ClientData>>) -> Arc<RwLock<ClientInterface>>{
        let interface = Arc::new(RwLock::new(ClientInterface{
            socket: socket,
            thread_handle: None,
            client: client
        }));

        let thread_interface = interface.clone();
        println!("Before");
        let handle = thread::spawn(move||{
            println!("Hello from thread!");

            loop{
                if let Ok(mut event_loop) = event_loop.write(){
                    if let Ok(mut client_interface) = thread_interface.write(){
                        event_loop.run_once(&mut client_interface, None);
                    }
                }
            }
        });

        println!("after");

        if let Ok(mut interface_mut) = interface.write(){
            interface_mut.thread_handle = Some(handle);
        }

        return interface;
    }

    fn register(&mut self, event_loop: &mut EventLoop<ClientInterface>, client_ref: &Arc<RwLock<ClientData>>){
        if let Ok(client) = client_ref.read(){
            event_loop.register(
                &self.socket,
                client.token,
                client.interest,
                PollOpt::edge() | PollOpt::oneshot()
            ).or_else(|e| {
                println!("Failed to register server! {:?}", e);
                Err(e)
            });
        }
    }

    fn reregister(&mut self, event_loop: &mut EventLoop<ClientInterface>, client_ref: Arc<RwLock<ClientData>>){
        if let Ok(client) = client_ref.read(){
            event_loop.reregister(&self.socket, client.token, client.interest, PollOpt::edge())
                .or_else(|e|{
                    println!("I am a sad panda, {:?}", e);
                    Err(e)
            });
        }
    }
}

pub struct ClientData{
    pub token: Token,

    interest: EventSet,

    send_queue: VecDeque<String>,
}

impl ClientData{
    fn new() -> ClientData{
        ClientData {
            send_queue: VecDeque::new(),
            token: CLIENT_TOKEN,
            interest: EventSet::readable() | EventSet::writable()
        }
    }
}

type RwArcClientInterface = Arc<RwLock<ClientInterface>>;

impl Handler for ClientInterface{
    type Timeout = ();
    type Message = ();

    fn tick(&mut self, _: &mut EventLoop<ClientInterface>) {
        println!("Begin client tick");

        println!("End client tick");
    }

    fn ready(&mut self, event_loop: &mut EventLoop<ClientInterface>, token: Token, events: EventSet) {
        assert!(token != Token(0), "Token 0, y?????");

        if events.is_error(){
            println!("Client received error for token {:?}", token);
            return;
        }

        if events.is_hup(){
            println!("Oh shit, did the server crash or some shit?!");
            return;
        }

        if events.is_writable(){
            println!("TIME TO TALK MOTHERFUCKER");

            if let Ok(mut client) = self.client.write(){
                if !client.send_queue.is_empty(){
                    if let Some(message) = client.send_queue.pop_front(){
                        match self.socket.try_write(message.as_bytes()){
                            Ok(Some(n)) => {
                                println!("Wrote {} bytes", n);
                            },
                            Ok(None) => {
                                println!("Nothing happened but it's okay I guess?");
                                client.send_queue.push_back(message);
                            },
                            Err(e) => {
                                println!("Oh fuck me god fucking damn it fucking shit fuck: {:?}", e);
                                client.send_queue.push_back(message);
                            }
                        };
                    }
                    else{
                        println!("Failed to pop message from queue!");
                    }
                }
                else{
                    println!("WTF do you mean there's no messages for me?");
                }
            }
        }

        if events.is_readable(){
            println!("OH shit, what've you got to say?");
        }

        let client_rereg = self.client.clone();
        self.reregister(event_loop, client_rereg);
        //self.debug.fetch_add(1, Ordering::SeqCst);
    }

    fn notify(&mut self, _: &mut EventLoop<Self>, _: Self::Message) {
        println!("Received notify!");
    }

    fn timeout(&mut self, _: &mut EventLoop<Self>, _: Self::Timeout) {
        println!("Received timeout");
    }
    fn interrupted(&mut self, _: &mut EventLoop<Self>) {
        println!("Interrupted! :O");
    }
}

#[test]
fn connect(){
    let addr = "127.0.0.1:6969".parse().unwrap();

    let mut socket = TcpStream::connect(&addr);
    if socket.is_ok(){

        println!("Starting thing");
        let mut event_loop = Arc::new(RwLock::new(EventLoop::new().ok().expect("Failed to create event loop!")));
        let mut client = Arc::new(RwLock::new(ClientData::new()));

        let interface_event_loop = event_loop.clone();
        let mut client_interface = ClientInterface::new(interface_event_loop, socket.unwrap(), client.clone());
        println!("Starting debug loop");

        if let Ok(mut event_loop_ref) = event_loop.write(){
            if let Ok(mut interface) = client_interface.write(){
                interface.register(&mut event_loop_ref, &client);
            }
        }

        if let Ok(mut client_ref) = client.write(){
            client_ref.send_queue.push_front(String::from("Hello, world!"));
        }

        loop{
            // if client.debug.load(Ordering::Relaxed) > 0{
            //     break;
            // }
        }

        println!("Done with this shit");
    }
    else{
        println!("Failed to open socket! {:?}", socket.unwrap_err());
    }
}

#[cfg(test)]
mod test {
    use mio::tcp::*;
    use mio::TryWrite;
    use std::net::SocketAddr;
    //use lag_client::Client;

}
<commit_msg>wrapped all of the stuff up into a nice Client struct<commit_after>extern crate mio;

use mio::tcp::*;
use mio::TryWrite;
use mio::util::Slab;
use std::net::SocketAddr;
use std::io::Result;
use mio::{EventSet, EventLoop, Token, Handler, PollOpt};
use std::thread;
use std::thread::JoinHandle;
use std::sync::{Arc, RwLock};
//use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::collections::VecDeque;

const CLIENT_TOKEN: mio::Token = mio::Token(1);

/// Contains data related to the client
pub struct ClientData{
    pub token: Token,

    interest: EventSet,

    send_queue: VecDeque<String>,
}

impl ClientData{
    fn new() -> ClientData{
        ClientData {
            send_queue: VecDeque::new(),
            token: CLIENT_TOKEN,
            interest: EventSet::readable() | EventSet::writable()
        }
    }
}

/// Maintains a reference to the client, the socket, and the thread join handle
struct ClientInterface{
    socket: TcpStream,

    thread_handle: Option<JoinHandle<()>>,

    client: Arc<RwLock<ClientData>>
}

impl ClientInterface{
    fn new(event_loop: Arc<RwLock<EventLoop<ClientInterface>>>, socket: TcpStream, client: Arc<RwLock<ClientData>>) -> Arc<RwLock<ClientInterface>>{
        let interface = Arc::new(RwLock::new(ClientInterface{
            socket: socket,
            thread_handle: None,
            client: client
        }));

        let thread_interface = interface.clone();
        println!("Before");
        let handle = thread::spawn(move||{
            println!("Hello from thread!");

            loop{
                if let Ok(mut event_loop) = event_loop.write(){
                    if let Ok(mut client_interface) = thread_interface.write(){
                        event_loop.run_once(&mut client_interface, None);
                    }
                }
            }
        });

        println!("after");

        if let Ok(mut interface_mut) = interface.write(){
            interface_mut.thread_handle = Some(handle);
        }

        return interface;
    }

    fn register(&mut self, event_loop: &mut EventLoop<ClientInterface>, client_ref: &Arc<RwLock<ClientData>>){
        if let Ok(client) = client_ref.read(){
            event_loop.register(
                &self.socket,
                client.token,
                client.interest,
                PollOpt::edge() | PollOpt::oneshot()
            ).or_else(|e| {
                println!("Failed to register server! {:?}", e);
                Err(e)
            });
        }
    }

    fn reregister(&mut self, event_loop: &mut EventLoop<ClientInterface>, client_ref: Arc<RwLock<ClientData>>){
        if let Ok(client) = client_ref.read(){
            event_loop.reregister(&self.socket, client.token, client.interest, PollOpt::edge())
                .or_else(|e|{
                    println!("I am a sad panda, {:?}", e);
                    Err(e)
            });
        }
    }
}

impl Handler for ClientInterface{
    type Timeout = ();
    type Message = ();

    fn tick(&mut self, _: &mut EventLoop<ClientInterface>) {
        println!("Begin client tick");

        println!("End client tick");
    }

    fn ready(&mut self, event_loop: &mut EventLoop<ClientInterface>, token: Token, events: EventSet) {
        assert!(token != Token(0), "Token 0, y?????");

        if events.is_error(){
            println!("Client received error for token {:?}", token);
            return;
        }

        if events.is_hup(){
            println!("Oh shit, did the server crash or some shit?!");
            return;
        }

        if events.is_writable(){
            println!("TIME TO TALK MOTHERFUCKER");

            if let Ok(mut client) = self.client.write(){
                if !client.send_queue.is_empty(){
                    if let Some(message) = client.send_queue.pop_front(){
                        match self.socket.try_write(message.as_bytes()){
                            Ok(Some(n)) => {
                                println!("Wrote {} bytes", n);
                            },
                            Ok(None) => {
                                println!("Nothing happened but it's okay I guess?");
                                client.send_queue.push_back(message);
                            },
                            Err(e) => {
                                println!("Oh fuck me god fucking damn it fucking shit fuck: {:?}", e);
                                client.send_queue.push_back(message);
                            }
                        };
                    }
                    else{
                        println!("Failed to pop message from queue!");
                    }
                }
                else{
                    println!("WTF do you mean there's no messages for me?");
                }
            }
        }

        if events.is_readable(){
            println!("OH shit, what've you got to say?");
        }

        let client_rereg = self.client.clone();
        self.reregister(event_loop, client_rereg);
        //self.debug.fetch_add(1, Ordering::SeqCst);
    }

    fn notify(&mut self, _: &mut EventLoop<Self>, _: Self::Message) {
        println!("Received notify!");
    }

    fn timeout(&mut self, _: &mut EventLoop<Self>, _: Self::Timeout) {
        println!("Received timeout");
    }
    fn interrupted(&mut self, _: &mut EventLoop<Self>) {
        println!("Interrupted! :O");
    }
}

pub struct Client{
    data: Arc<RwLock<ClientData>>,
    interface: Arc<RwLock<ClientInterface>>,
    event_loop: Arc<RwLock<EventLoop<ClientInterface>>>
}

impl Client{
    /// Connect to the given socket and register with a threaded event loop
    pub fn connect(socket: TcpStream) -> Client{
        let event_loop = Arc::new(RwLock::new(EventLoop::new().ok().expect("Failed to create event loop!")));
        let client_data = Arc::new(RwLock::new(ClientData::new()));

        let interface_event_loop = event_loop.clone();
        let client_interface = ClientInterface::new(interface_event_loop, socket, client_data.clone());

        let mut client = Client{
            data: client_data,
            interface: client_interface,
            event_loop: event_loop
        };

        client.register();

        return client;
    }

    /// Register with the event loop
    fn register(&mut self){
        if let Ok(mut event_loop) = self.event_loop.write(){
            if let Ok(mut interface) = self.interface.write(){
                interface.register(&mut event_loop, &self.data);
            }
        }
    }
}

#[test]
fn connect(){
    let addr = "127.0.0.1:6969".parse().unwrap();

    let mut socket = TcpStream::connect(&addr);
    if socket.is_ok(){
        println!("Starting thing");

        let mut client = Client::connect(socket.unwrap());

        // if let Ok(mut client_ref) = client.write(){
        //     client_ref.send_queue.push_front(String::from("Hello, world!"));
        // }

        //loop{
            // if client.debug.load(Ordering::Relaxed) > 0{
            //     break;
            // }
        //}

        //println!("Done with this shit");
    }
    else{
        println!("Failed to open socket! {:?}", socket.unwrap_err());
    }
}

#[cfg(test)]
mod test {
    use mio::tcp::*;
    use mio::TryWrite;
    use std::net::SocketAddr;
    //use lag_client::Client;

}
<|endoftext|>


<commit_before>extern crate tokio;
extern crate futures;
use self::tokio::{Service, client};
use self::tokio::tcp::TcpStream;
use self::tokio::reactor::*;
use self::tokio::io::{TryWrite, TryRead, Readiness, Transport};
use self::tokio::proto::pipeline;
use self::tokio::proto::pipeline::{Server, Frame};
use self::futures::{Future};
use std::io;

use super::parse::{Command, CommandParser};

pub struct Client {}
impl Client {
    pub fn start() {
        let reactor = Reactor::default().unwrap();

        let stream = TcpStream::connect(&"127.0.0.1:6667".parse().unwrap()).unwrap();
        let server = Server::new(tokio::simple_service(|r| {
            Ok(CommandParser::new(b"NICK nickmass".to_vec()).parse())
        })
        , IrcTransport::new(stream)).unwrap();
        let handle = &reactor.handle();

        handle.schedule(server);

        reactor.run().unwrap();
    }
}

enum ServiceError {
    Transport(TransportError),
    Service,
}

impl From<pipeline::Error<TransportError>> for ServiceError {
    fn from(e: pipeline::Error<TransportError>) -> Self {
        ServiceError::Service
    }
}
impl From<TransportError> for ServiceError {
    fn from(e: TransportError) -> Self {
        ServiceError::Transport(e)
    }
}

enum TransportError {
    Something,
    Bad
}

struct IrcService {}
impl IrcService {
    fn new() -> IrcService {
        IrcService {}
    }
}

impl Service for IrcService {
    type Req = String;
    type Resp = Command;
    type Error = ServiceError;
    type Fut = Box<Future<Item = Self::Resp, Error = Self::Error>>;

    fn call(&self, req: String) -> Self::Fut {
        println!("Req: {:?}", req);
    }
}

struct IrcTransport<T> {
    stream: T,
    read_buf: Vec<u8>,
    write_buf: Vec<u8>,
}

impl<T: TryRead + TryWrite + Readiness> IrcTransport<T> {
    fn new(stream: T) -> IrcTransport<T> {
        let mut write_buf = Vec::new();
        write_buf.append(&mut b"USER nickmass 8 * :Nick Massey\r\n".to_vec());
        write_buf.append(&mut b"NICK nickmass\r\n".to_vec());
        IrcTransport { stream: stream, read_buf: Vec::new(), write_buf: write_buf }
    }
}

impl<T> Readiness for IrcTransport<T> {
    fn is_readable(&self) -> bool {
        true
    }

    fn is_writable(&self) -> bool {
        true
    }
}

impl<T: TryRead + TryWrite + Readiness> Transport for IrcTransport<T> {
    type In = Command;
    type Out = String;

    fn read(&mut self) -> io::Result<Option<Self::Out>> {
        let mut buf = Vec::new();
        if let Some(bytes) = try!(self.stream.try_read(&mut buf)) {
            if bytes > 0 {
                println!("read");
                println!("{}", ::std::str::from_utf8(&*buf).unwrap());
                buf.truncate(bytes);
                let mut count = 0;
                for i in &*buf {
                    count += 1;
                    if *i == 0x10 {
                        break;
                    }
                }

                let remainder = buf.split_off(count);
                self.read_buf.append(&mut buf);
                if self.read_buf.len() > 0 {
                    println!("{}", ::std::str::from_utf8(&*self.read_buf).unwrap());
                    return Ok(Some(String::from_utf8(self.read_buf.clone()).unwrap()));
                }
                self.read_buf = remainder;
            }
        }
        Ok(None)
    }

    fn write(&mut self, req: Self::In) -> io::Result<Option<()>>{
        self.write_buf.append(&mut req.to_cmd().into_bytes());
        if self.write_buf.len() > 0 {
            if let Some(bytes) = try!(self.stream.try_write(&*self.write_buf)) {
                println!("{}", ::std::str::from_utf8(&*self.write_buf).unwrap());
                self.write_buf = self.write_buf.split_off(bytes);
                return Ok(Some(()));
            }
        }
        Ok(None)
    }

    fn flush(&mut self) -> io::Result<Option<()>>{
        Ok(None)
    }
}
<commit_msg>Parse in transport<commit_after>extern crate tokio;
extern crate futures;
use self::tokio::{Service, client};
use self::tokio::tcp::TcpStream;
use self::tokio::reactor::*;
use self::tokio::io::{TryWrite, TryRead, Readiness, Transport};
use self::tokio::proto::pipeline;
use self::tokio::proto::pipeline::{Server, Frame};
use self::futures::{Future};
use std::io;

use super::parse::{Command, CommandParser};

pub struct Client {}
impl Client {
    pub fn start() {
        let reactor = Reactor::default().unwrap();

        let stream = TcpStream::connect(&"127.0.0.1:6667".parse().unwrap()).unwrap();
        let server = Server::new(
            /*
            tokio::simple_service(|r| {
                Ok(CommandParser::new(b"NICK nickmass".to_vec()).parse())
            })
            */
            IrcService::new()
            , IrcTransport::new(stream)).unwrap();
        let handle = &reactor.handle();

        handle.schedule(server);

        reactor.run().unwrap();
    }
}

enum ServiceError {
    Transport(TransportError),
    Service,
}

impl From<pipeline::Error<TransportError>> for ServiceError {
    fn from(e: pipeline::Error<TransportError>) -> Self {
        ServiceError::Service
    }
}
impl From<TransportError> for ServiceError {
    fn from(e: TransportError) -> Self {
        ServiceError::Transport(e)
    }
}

enum TransportError {
    Something,
    Bad
}

struct IrcService {}
impl IrcService {
    fn new() -> IrcService {
        IrcService {}
    }
}

impl Service for IrcService {
    type Req = Command;
    type Resp = Command;
    type Error = ServiceError;
    type Fut = Box<Future<Item = Self::Resp, Error = Self::Error>>;

    fn call(&self, req: Command) -> Self::Fut {
        println!("Req: {:?}", req.to_cmd());
        futures::finished(CommandParser::new(b"NICK nickmass".to_vec()).parse()).boxed()
    }
}

struct IrcTransport<T> {
    stream: T,
    read_buf: Vec<u8>,
    write_buf: Vec<u8>,
}

impl<T: TryRead + TryWrite + Readiness> IrcTransport<T> {
    fn new(stream: T) -> IrcTransport<T> {
        let mut write_buf = Vec::new();
        write_buf.append(&mut b"USER nickmass 8 * :Nick Massey\r\n".to_vec());
        write_buf.append(&mut b"NICK nickmass\r\n".to_vec());
        IrcTransport { stream: stream, read_buf: Vec::new(), write_buf: write_buf }
    }
}

impl<T> Readiness for IrcTransport<T> {
    fn is_readable(&self) -> bool {
        true
    }

    fn is_writable(&self) -> bool {
        true
    }
}

impl<T: TryRead + TryWrite + Readiness> Transport for IrcTransport<T> {
    type In = Command;
    type Out = Command;

    fn read(&mut self) -> io::Result<Option<Self::Out>> {
        let mut buf = Vec::new();
        if let Some(bytes) = try!(self.stream.try_read(&mut buf)) {
            if bytes > 0 {
                println!("read");
                println!("{}", ::std::str::from_utf8(&*buf).unwrap());
                buf.truncate(bytes);
                let mut count = 0;
                for i in &*buf {
                    count += 1;
                    if *i == 0x10 {
                        break;
                    }
                }

                let remainder = buf.split_off(count);
                self.read_buf.append(&mut buf);
                if self.read_buf.len() > 0 {
                    println!("{}", ::std::str::from_utf8(&*self.read_buf).unwrap());
                    return Ok(Some(CommandParser::new(self.read_buf.clone()).parse()));
                }
                self.read_buf = remainder;
            }
        }
        Ok(None)
    }

    fn write(&mut self, req: Self::In) -> io::Result<Option<()>>{
        self.write_buf.append(&mut req.to_cmd().into_bytes());
        if self.write_buf.len() > 0 {
            if let Some(bytes) = try!(self.stream.try_write(&*self.write_buf)) {
                println!("{}", ::std::str::from_utf8(&*self.write_buf).unwrap());
                self.write_buf = self.write_buf.split_off(bytes);
                return Ok(Some(()));
            }
        }
        Ok(None)
    }

    fn flush(&mut self) -> io::Result<Option<()>>{
        Ok(None)
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix formatting<commit_after><|endoftext|>


<commit_before>use std::path::Path;

use bytes::Bytes;

#[derive(Debug, Clone, PartialEq, PartialOrd, Ord, Eq, Hash)]
pub struct Text(pub(crate) Bytes);

impl Text {
    pub fn as_str(&self) -> &str {
        unsafe { std::str::from_utf8_unchecked(self.0.as_ref()) }
    }
}

impl From<String> for Text {
    fn from(value: String) -> Self {
        Text(value.into())
    }
}

impl<'a> From<&'a str> for Text {
    fn from(value: &'a str) -> Self {
        Text(value.into())
    }
}

impl AsRef<str> for Text {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl AsRef<Path> for Text {
    fn as_ref(&self) -> &Path {
        self.as_str().as_ref()
    }
}
<commit_msg>refactor: make Text field private<commit_after>use std::path::Path;

use bytes::Bytes;

#[derive(Debug, Clone, PartialEq, PartialOrd, Ord, Eq, Hash)]
pub struct Text(Bytes);

impl Text {
    pub fn as_str(&self) -> &str {
        unsafe { std::str::from_utf8_unchecked(self.0.as_ref()) }
    }
}

impl From<String> for Text {
    fn from(value: String) -> Self {
        Text(value.into())
    }
}

impl<'a> From<&'a str> for Text {
    fn from(value: &'a str) -> Self {
        Text(value.into())
    }
}

impl AsRef<str> for Text {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl AsRef<Path> for Text {
    fn as_ref(&self) -> &Path {
        self.as_str().as_ref()
    }
}
<|endoftext|>


<commit_before>use std::env;
use std::fs;
use std::fs::File;
use std::io;
use std::io::BufReader;
use std::io::BufWriter;
use std::io::Read;
use std::io::Write;
use std::io::Seek;
use std::path::Path;
use std::process::Command;

extern crate tools;
use tools::find_source_file;
use tools::file_format::analysis::{read_analysis, read_source, read_jumps};
use tools::format::format_file_data;
use tools::config;
use tools::languages;
use languages::FormatAs;

use tools::output::{PanelItem, PanelSection};

fn format_documentation(input_fname: &str, output_fname: &str) {
    let _ = Command::new("pandoc")
        .arg("--css")
        .arg("/static/css/pandoc.css")
        .arg("-o")
        .arg(output_fname)
        .arg("-w")
        .arg("html")
        .arg(input_fname)
        .status();
}

fn main() {
    let args: Vec<_> = env::args().collect();
    let (base_args, fname_args) = args.split_at(3);

    let cfg = config::load(&base_args[1], false);
    println!("Config file read");

    let tree_name = &base_args[2];
    let tree_config = cfg.trees.get(tree_name).unwrap();

    let jumps_fname = format!("{}/jumps", tree_config.paths.index_path);
    //let jumps : std::collections::HashMap<String, tools::analysis::Jump> = std::collections::HashMap::new();
    let jumps = read_jumps(&jumps_fname);
    println!("Jumps read");

    let (blame_commit, head_oid) = match &tree_config.git {
        &Some(ref git) => {
            let head_oid = git.repo.refname_to_id("HEAD").unwrap();
            let blame_oid = git.blame_repo.refname_to_id("HEAD").unwrap();
            let blame_commit = Some(git.blame_repo.find_commit(blame_oid).unwrap());
            (blame_commit, Some(head_oid))
        },
        &None => (None, None),
    };
    let blame_commit_ref = match blame_commit { Some(ref bc) => Some(bc), None => None };

    for path in fname_args {
        println!("File {}", path);

        let output_fname = format!("{}/file/{}", tree_config.paths.index_path, path);
        let source_fname = find_source_file(path, &tree_config.paths.files_path, &tree_config.paths.objdir_path);

        let format = languages::select_formatting(path);
        match format {
            FormatAs::FormatDoc(_) => {
                let _ = format_documentation(&source_fname, &output_fname);
                continue;
            },
            _ => {},
        };

        let output_file = File::create(output_fname).unwrap();
        let mut writer = BufWriter::new(output_file);

        let source_file = match File::open(source_fname.clone()) {
            Ok(f) => f,
            Err(_) => {
                println!("Unable to open file");
                continue;
            },
        };

        let p = Path::new(&source_fname);
        let metadata = fs::symlink_metadata(p).unwrap();
        if metadata.file_type().is_symlink() {
            let dest = fs::read_link(p).unwrap();
            write!(writer, "Symlink to {}", dest.to_str().unwrap()).unwrap();
            continue;
        }

        let mut reader = BufReader::new(&source_file);

        match format {
            FormatAs::Binary => {
                let _ = io::copy(&mut reader, &mut writer);
                continue;
            },
            _ => {},
        };

        let analysis_fname = format!("{}/analysis/{}", tree_config.paths.index_path, path);
        let analysis = read_analysis(&analysis_fname, &read_source);

        let mut input = String::new();
        match reader.read_to_string(&mut input) {
            Ok(_) => {},
            Err(_) => {
                let mut bytes = Vec::new();
                reader.seek(std::io::SeekFrom::Start(0)).unwrap();
                match reader.read_to_end(&mut bytes) {
                    Ok(_) => {
                        input.push_str(&bytes.iter().map(|c| *c as char).collect::<String>());
                    },
                    Err(e) => {
                        println!("Unable to read file: {:?}", e);
                        continue;
                    }
                }
            }
        }

        let panel = if path.contains("__GENERATED__") {
            vec![]
        } else if let Some(oid) = head_oid {
            vec![PanelSection {
                name: "Revision control".to_owned(),
                items: vec![PanelItem {
                    title: "Permalink".to_owned(),
                    link: format!("/{}/rev/{}/{}", tree_name, oid, path),
                    update_link_lineno: true,
                }, PanelItem {
                    title: "Log".to_owned(),
                    link: format!("https://hg.mozilla.org/mozilla-central/log/tip/{}", path),
                    update_link_lineno: false,
                }, PanelItem {
                    title: "Blame".to_owned(),
                    link: "javascript:alert('Hover over the gray bar on the left to see blame information.')".to_owned(),
                    update_link_lineno: false,
                }],
            }]
        } else {
            vec![]
        };

        format_file_data(&cfg,
                         tree_name,
                         &panel,
                         None,
                         blame_commit_ref,
                         path,
                         input,
                         &jumps,
                         &analysis,
                         &mut writer).unwrap();
    }
}
<commit_msg>Add link to Raw file<commit_after>use std::env;
use std::fs;
use std::fs::File;
use std::io;
use std::io::BufReader;
use std::io::BufWriter;
use std::io::Read;
use std::io::Write;
use std::io::Seek;
use std::path::Path;
use std::process::Command;

extern crate tools;
use tools::find_source_file;
use tools::file_format::analysis::{read_analysis, read_source, read_jumps};
use tools::format::format_file_data;
use tools::config;
use tools::languages;
use languages::FormatAs;

use tools::output::{PanelItem, PanelSection};

fn format_documentation(input_fname: &str, output_fname: &str) {
    let _ = Command::new("pandoc")
        .arg("--css")
        .arg("/static/css/pandoc.css")
        .arg("-o")
        .arg(output_fname)
        .arg("-w")
        .arg("html")
        .arg(input_fname)
        .status();
}

fn main() {
    let args: Vec<_> = env::args().collect();
    let (base_args, fname_args) = args.split_at(3);

    let cfg = config::load(&base_args[1], false);
    println!("Config file read");

    let tree_name = &base_args[2];
    let tree_config = cfg.trees.get(tree_name).unwrap();

    let jumps_fname = format!("{}/jumps", tree_config.paths.index_path);
    //let jumps : std::collections::HashMap<String, tools::analysis::Jump> = std::collections::HashMap::new();
    let jumps = read_jumps(&jumps_fname);
    println!("Jumps read");

    let (blame_commit, head_oid) = match &tree_config.git {
        &Some(ref git) => {
            let head_oid = git.repo.refname_to_id("HEAD").unwrap();
            let blame_oid = git.blame_repo.refname_to_id("HEAD").unwrap();
            let blame_commit = Some(git.blame_repo.find_commit(blame_oid).unwrap());
            (blame_commit, Some(head_oid))
        },
        &None => (None, None),
    };
    let blame_commit_ref = match blame_commit { Some(ref bc) => Some(bc), None => None };

    for path in fname_args {
        println!("File {}", path);

        let output_fname = format!("{}/file/{}", tree_config.paths.index_path, path);
        let source_fname = find_source_file(path, &tree_config.paths.files_path, &tree_config.paths.objdir_path);

        let format = languages::select_formatting(path);
        match format {
            FormatAs::FormatDoc(_) => {
                let _ = format_documentation(&source_fname, &output_fname);
                continue;
            },
            _ => {},
        };

        let output_file = File::create(output_fname).unwrap();
        let mut writer = BufWriter::new(output_file);

        let source_file = match File::open(source_fname.clone()) {
            Ok(f) => f,
            Err(_) => {
                println!("Unable to open file");
                continue;
            },
        };

        let p = Path::new(&source_fname);
        let metadata = fs::symlink_metadata(p).unwrap();
        if metadata.file_type().is_symlink() {
            let dest = fs::read_link(p).unwrap();
            write!(writer, "Symlink to {}", dest.to_str().unwrap()).unwrap();
            continue;
        }

        let mut reader = BufReader::new(&source_file);

        match format {
            FormatAs::Binary => {
                let _ = io::copy(&mut reader, &mut writer);
                continue;
            },
            _ => {},
        };

        let analysis_fname = format!("{}/analysis/{}", tree_config.paths.index_path, path);
        let analysis = read_analysis(&analysis_fname, &read_source);

        let mut input = String::new();
        match reader.read_to_string(&mut input) {
            Ok(_) => {},
            Err(_) => {
                let mut bytes = Vec::new();
                reader.seek(std::io::SeekFrom::Start(0)).unwrap();
                match reader.read_to_end(&mut bytes) {
                    Ok(_) => {
                        input.push_str(&bytes.iter().map(|c| *c as char).collect::<String>());
                    },
                    Err(e) => {
                        println!("Unable to read file: {:?}", e);
                        continue;
                    }
                }
            }
        }

        let panel = if path.contains("__GENERATED__") {
            vec![]
        } else if let Some(oid) = head_oid {
            vec![PanelSection {
                name: "Revision control".to_owned(),
                items: vec![PanelItem {
                    title: "Permalink".to_owned(),
                    link: format!("/{}/rev/{}/{}", tree_name, oid, path),
                    update_link_lineno: true,
                }, PanelItem {
                    title: "Log".to_owned(),
                    link: format!("https://hg.mozilla.org/mozilla-central/log/tip/{}", path),
                    update_link_lineno: false,
                 }, PanelItem {
                    title: "Raw".to_owned(),
                    link: format!("https://hg.mozilla.org/mozilla-central/raw-file/{}/{}", oid, path),
                    update_link_lineno: false,
                }, PanelItem {
                    title: "Blame".to_owned(),
                    link: "javascript:alert('Hover over the gray bar on the left to see blame information.')".to_owned(),
                    update_link_lineno: false,
                }],
            }]
        } else {
            vec![]
        };

        format_file_data(&cfg,
                         tree_name,
                         &panel,
                         None,
                         blame_commit_ref,
                         path,
                         input,
                         &jumps,
                         &analysis,
                         &mut writer).unwrap();
    }
}
<|endoftext|>


<commit_before>/* Copyright 2015 Jordan Miner
 *
 * Licensed under the MIT license <LICENSE or
 * http://opensource.org/licenses/MIT>. This file may not be copied,
 * modified, or distributed except according to those terms.
 */

use std::ptr;
use iup_sys::*;
use super::{Control, UnwrapHandle};
use super::handle_rc::HandleRc;
use super::attributes::{
    OrientationAttribute,
    set_str_attribute,
    get_str_attribute_slice,
};

pub trait Container : Control {
    fn append(&self, new_child: &Control) -> Result<(), ()> {
        unsafe {
            if IupAppend(self.handle(), new_child.handle()) == ptr::null_mut() {
                Err(())
            } else {
                Ok(())
            }
        }
    }

    fn insert(&self, ref_child: Option<&Control>, new_child: &Control) -> Result<(), ()> {
        unsafe {
            let ref_child = ref_child.map(|c| c.handle()).unwrap_or(ptr::null_mut());
            if IupInsert(self.handle(), ref_child, new_child.handle()) == ptr::null_mut() {
                Err(())
            } else {
                Ok(())
            }
        }
    }

    /// Returns the number of children of the specified control.
    ///
    /// Warning: Since children are stored as a linked list, getting the count is O(n).
    fn child_count(&self) -> usize {
        unsafe {
            IupGetChildCount(self.handle()) as usize
        }
    }
}

pub trait NonDialogContainer : Container {
    fn refresh_children(&self) {
        unsafe {
            IupRefreshChildren(self.handle());
        }
    }
}

// Be sure that the Vec is not dropped before the *mut *mut Ihandle is used.
fn wrapper_to_handles(controls: Option<&[&::Control]>)
-> (Option<Vec<*mut Ihandle>>, *mut *mut Ihandle)
{
    let mut controls: Option<Vec<_>> = controls.map(|slice| {
        let mut v: Vec<*mut Ihandle> = slice.iter().map(|c| c.handle()).collect();
        v.push(ptr::null_mut()); // array has to be null terminated
        v
    });
    let p = controls.as_mut().map(|v| v.as_mut_ptr()).unwrap_or(ptr::null_mut());
    (controls, p)
}

#[derive(Clone)]
pub struct Fill(HandleRc);

impl Fill {
    pub fn new() -> Fill {
        unsafe {
            ::iup_open();
            let handle = IupFill();
            Fill(HandleRc::new(handle))
        }
    }
}

impl_control_traits!(Fill);

#[macro_export]
macro_rules! fill { // This is a macro for consistency, even though it could just be a function.
    () => { Fill::new() };
}

#[derive(Clone)]
pub struct Hbox(HandleRc);

impl Hbox {
    pub fn new(children: Option<&[&::Control]>) -> Hbox {
        unsafe {
            ::iup_open();
            let (_children, children_handles) = wrapper_to_handles(children);
            Hbox::from_handles(children_handles)
        }
    }

    pub unsafe fn from_handles(children: *mut *mut Ihandle) -> Hbox {
        let handle = IupHboxv(children);
        Hbox(HandleRc::new(handle))
    }
}

impl_control_traits!(Hbox);

impl Container for Hbox {}

#[macro_export]
macro_rules! hbox {
    ($($c:expr),*) => {
        {
            use std::ptr;
            let mut handles = Vec::new();
            $(
                // The control has to be stored in a binding to ensure it isn't dropped before
                // it is added as a child of the container. (Otherwise, the control is destroyed.)
                let c = $c;
                handles.push(c.handle());
            )*
            handles.push(ptr::null_mut());
            unsafe { Hbox::from_handles(handles.as_mut_ptr()) }
        }
    };
    ($($c:expr,)*) => { hbox!($($c),*) };
}

#[derive(Clone)]
pub struct Vbox(HandleRc);

impl Vbox {
    pub fn new(children: Option<&[&::Control]>) -> Vbox {
        unsafe {
            ::iup_open();
            let (_children, children_handles) = wrapper_to_handles(children);
            Vbox::from_handles(children_handles)
        }
    }

    pub unsafe fn from_handles(children: *mut *mut Ihandle) -> Vbox {
        let handle = IupVboxv(children);
        Vbox(HandleRc::new(handle))
    }
}

impl_control_traits!(Vbox);

impl Container for Vbox {}

#[macro_export]
macro_rules! vbox {
    ($($c:expr),*) => {
        {
            use std::ptr;
            let mut handles = Vec::new();
            $(
                // The control has to be stored in a binding to ensure it isn't dropped before
                // it is added as a child of the container. (Otherwise, the control is destroyed.)
                let c = $c;
                handles.push(c.handle());
            )*
            handles.push(ptr::null_mut());
            unsafe { Vbox::from_handles(handles.as_mut_ptr()) }
        }
    };
    ($($c:expr,)*) => { vbox!($($c),*) };
}

pub enum NumDiv {
    Fixed(u32),
    Auto,
}

#[derive(Clone)]
pub struct GridBox(HandleRc);

impl GridBox {
    pub fn new(children: Option<&[&::Control]>) -> GridBox {
        unsafe {
            ::iup_open();
            let (_children, children_handles) = wrapper_to_handles(children);
            GridBox::from_handles(children_handles)
        }
    }

    pub unsafe fn from_handles(children: *mut *mut Ihandle) -> GridBox {
        let handle = IupGridBoxv(children);
        GridBox(HandleRc::new(handle))
    }

    pub fn alignment_lin(&self, line: u32) -> ::VAlignment {
        unsafe {
            let attr = format!("ALIGNMENTLIN{}", line);
            ::VAlignment::from_str(get_str_attribute_slice(self.handle(), &attr).as_bytes())
        }
    }

    pub fn set_alignment_lin(&self, line: u32, alignment: ::VAlignment) {
        set_str_attribute(self.handle(), &format!("ALIGNMENTLIN{}", line), alignment.to_str());
    }

    pub fn alignment_lin_all(&self) -> ::VAlignment {
        unsafe {
            let s = get_str_attribute_slice(self.handle(), "ALIGNMENTLIN");
            ::VAlignment::from_str(s.as_bytes())
        }
    }

    pub fn set_alignment_lin_all(&self, alignment: ::VAlignment) {
        set_str_attribute(self.handle(), "ALIGNMENTLIN", alignment.to_str());
    }

    pub fn alignment_col(&self, column: u32) -> ::HAlignment {
        unsafe {
            let attr = format!("ALIGNMENTCOL{}", column);
            ::HAlignment::from_str(get_str_attribute_slice(self.handle(), &attr).as_bytes())
        }
    }

    pub fn set_alignment_col(&self, column: u32, alignment: ::HAlignment) {
        set_str_attribute(self.handle(), &format!("ALIGNMENTCOL{}", column), alignment.to_str());
    }

    pub fn alignment_col_all(&self) -> ::HAlignment {
        unsafe {
            let s = get_str_attribute_slice(self.handle(), "ALIGNMENTCOL");
            ::HAlignment::from_str(s.as_bytes())
        }
    }

    pub fn set_alignment_col_all(&self, alignment: ::HAlignment) {
        set_str_attribute(self.handle(), "ALIGNMENTCOL", alignment.to_str());
    }

    pub fn num_div(&self) -> NumDiv {
        unsafe {
            let s = get_str_attribute_slice(self.handle(), "NUMDIV");
            if s.as_bytes() == b"-1" {
                NumDiv::Auto
            } else {
                NumDiv::Fixed(s.parse().expect("could not convert NUMDIV to an integer"))
            }
        }
    }

    pub fn set_num_div(&self, num: NumDiv) {
        match num {
            NumDiv::Fixed(i) => set_str_attribute(self.handle(), "NUMDIV", &i.to_string()),
            NumDiv::Auto => set_str_attribute(self.handle(), "NUMDIV", "AUTO"),
        }
    }

    pub fn num_lin(&self) -> u32 {
        unsafe {
            let s = get_str_attribute_slice(self.handle(), "NUMLIN");
            s.parse().expect("could not convert NUMLIN to an integer")
        }
    }

    pub fn num_col(&self) -> u32 {
        unsafe {
            let s = get_str_attribute_slice(self.handle(), "NUMCOL");
            s.parse().expect("could not convert NUMLIN to an integer")
        }
    }
}

impl_control_traits!(GridBox);

impl Container for GridBox {}

impl OrientationAttribute for GridBox {}

#[macro_export]
macro_rules! grid_box {
    ($($c:expr),*) => {
        {
            use std::ptr;
            let mut handles = Vec::new();
            $(
                // The control has to be stored in a binding to ensure it isn't dropped before
                // it is added as a child of the container. (Otherwise, the control is destroyed.)
                let c = $c;
                handles.push(c.handle());
            )*
            handles.push(ptr::null_mut());
            unsafe { GridBox::from_handles(handles.as_mut_ptr()) }
        }
    };
    ($($c:expr,)*) => { grid_box!($($c),*) };
}
<commit_msg>Derive Debug on NumDiv (and other traits)<commit_after>/* Copyright 2015 Jordan Miner
 *
 * Licensed under the MIT license <LICENSE or
 * http://opensource.org/licenses/MIT>. This file may not be copied,
 * modified, or distributed except according to those terms.
 */

use std::ptr;
use iup_sys::*;
use super::{Control, UnwrapHandle};
use super::handle_rc::HandleRc;
use super::attributes::{
    OrientationAttribute,
    set_str_attribute,
    get_str_attribute_slice,
};

pub trait Container : Control {
    fn append(&self, new_child: &Control) -> Result<(), ()> {
        unsafe {
            if IupAppend(self.handle(), new_child.handle()) == ptr::null_mut() {
                Err(())
            } else {
                Ok(())
            }
        }
    }

    fn insert(&self, ref_child: Option<&Control>, new_child: &Control) -> Result<(), ()> {
        unsafe {
            let ref_child = ref_child.map(|c| c.handle()).unwrap_or(ptr::null_mut());
            if IupInsert(self.handle(), ref_child, new_child.handle()) == ptr::null_mut() {
                Err(())
            } else {
                Ok(())
            }
        }
    }

    /// Returns the number of children of the specified control.
    ///
    /// Warning: Since children are stored as a linked list, getting the count is O(n).
    fn child_count(&self) -> usize {
        unsafe {
            IupGetChildCount(self.handle()) as usize
        }
    }
}

pub trait NonDialogContainer : Container {
    fn refresh_children(&self) {
        unsafe {
            IupRefreshChildren(self.handle());
        }
    }
}

// Be sure that the Vec is not dropped before the *mut *mut Ihandle is used.
fn wrapper_to_handles(controls: Option<&[&::Control]>)
-> (Option<Vec<*mut Ihandle>>, *mut *mut Ihandle)
{
    let mut controls: Option<Vec<_>> = controls.map(|slice| {
        let mut v: Vec<*mut Ihandle> = slice.iter().map(|c| c.handle()).collect();
        v.push(ptr::null_mut()); // array has to be null terminated
        v
    });
    let p = controls.as_mut().map(|v| v.as_mut_ptr()).unwrap_or(ptr::null_mut());
    (controls, p)
}

#[derive(Clone)]
pub struct Fill(HandleRc);

impl Fill {
    pub fn new() -> Fill {
        unsafe {
            ::iup_open();
            let handle = IupFill();
            Fill(HandleRc::new(handle))
        }
    }
}

impl_control_traits!(Fill);

#[macro_export]
macro_rules! fill { // This is a macro for consistency, even though it could just be a function.
    () => { Fill::new() };
}

#[derive(Clone)]
pub struct Hbox(HandleRc);

impl Hbox {
    pub fn new(children: Option<&[&::Control]>) -> Hbox {
        unsafe {
            ::iup_open();
            let (_children, children_handles) = wrapper_to_handles(children);
            Hbox::from_handles(children_handles)
        }
    }

    pub unsafe fn from_handles(children: *mut *mut Ihandle) -> Hbox {
        let handle = IupHboxv(children);
        Hbox(HandleRc::new(handle))
    }
}

impl_control_traits!(Hbox);

impl Container for Hbox {}

#[macro_export]
macro_rules! hbox {
    ($($c:expr),*) => {
        {
            use std::ptr;
            let mut handles = Vec::new();
            $(
                // The control has to be stored in a binding to ensure it isn't dropped before
                // it is added as a child of the container. (Otherwise, the control is destroyed.)
                let c = $c;
                handles.push(c.handle());
            )*
            handles.push(ptr::null_mut());
            unsafe { Hbox::from_handles(handles.as_mut_ptr()) }
        }
    };
    ($($c:expr,)*) => { hbox!($($c),*) };
}

#[derive(Clone)]
pub struct Vbox(HandleRc);

impl Vbox {
    pub fn new(children: Option<&[&::Control]>) -> Vbox {
        unsafe {
            ::iup_open();
            let (_children, children_handles) = wrapper_to_handles(children);
            Vbox::from_handles(children_handles)
        }
    }

    pub unsafe fn from_handles(children: *mut *mut Ihandle) -> Vbox {
        let handle = IupVboxv(children);
        Vbox(HandleRc::new(handle))
    }
}

impl_control_traits!(Vbox);

impl Container for Vbox {}

#[macro_export]
macro_rules! vbox {
    ($($c:expr),*) => {
        {
            use std::ptr;
            let mut handles = Vec::new();
            $(
                // The control has to be stored in a binding to ensure it isn't dropped before
                // it is added as a child of the container. (Otherwise, the control is destroyed.)
                let c = $c;
                handles.push(c.handle());
            )*
            handles.push(ptr::null_mut());
            unsafe { Vbox::from_handles(handles.as_mut_ptr()) }
        }
    };
    ($($c:expr,)*) => { vbox!($($c),*) };
}

#[derive(Debug, Copy, Clone, PartialEq)]
pub enum NumDiv {
    Fixed(u32),
    Auto,
}

#[derive(Clone)]
pub struct GridBox(HandleRc);

impl GridBox {
    pub fn new(children: Option<&[&::Control]>) -> GridBox {
        unsafe {
            ::iup_open();
            let (_children, children_handles) = wrapper_to_handles(children);
            GridBox::from_handles(children_handles)
        }
    }

    pub unsafe fn from_handles(children: *mut *mut Ihandle) -> GridBox {
        let handle = IupGridBoxv(children);
        GridBox(HandleRc::new(handle))
    }

    pub fn alignment_lin(&self, line: u32) -> ::VAlignment {
        unsafe {
            let attr = format!("ALIGNMENTLIN{}", line);
            ::VAlignment::from_str(get_str_attribute_slice(self.handle(), &attr).as_bytes())
        }
    }

    pub fn set_alignment_lin(&self, line: u32, alignment: ::VAlignment) {
        set_str_attribute(self.handle(), &format!("ALIGNMENTLIN{}", line), alignment.to_str());
    }

    pub fn alignment_lin_all(&self) -> ::VAlignment {
        unsafe {
            let s = get_str_attribute_slice(self.handle(), "ALIGNMENTLIN");
            ::VAlignment::from_str(s.as_bytes())
        }
    }

    pub fn set_alignment_lin_all(&self, alignment: ::VAlignment) {
        set_str_attribute(self.handle(), "ALIGNMENTLIN", alignment.to_str());
    }

    pub fn alignment_col(&self, column: u32) -> ::HAlignment {
        unsafe {
            let attr = format!("ALIGNMENTCOL{}", column);
            ::HAlignment::from_str(get_str_attribute_slice(self.handle(), &attr).as_bytes())
        }
    }

    pub fn set_alignment_col(&self, column: u32, alignment: ::HAlignment) {
        set_str_attribute(self.handle(), &format!("ALIGNMENTCOL{}", column), alignment.to_str());
    }

    pub fn alignment_col_all(&self) -> ::HAlignment {
        unsafe {
            let s = get_str_attribute_slice(self.handle(), "ALIGNMENTCOL");
            ::HAlignment::from_str(s.as_bytes())
        }
    }

    pub fn set_alignment_col_all(&self, alignment: ::HAlignment) {
        set_str_attribute(self.handle(), "ALIGNMENTCOL", alignment.to_str());
    }

    pub fn num_div(&self) -> NumDiv {
        unsafe {
            let s = get_str_attribute_slice(self.handle(), "NUMDIV");
            if s.as_bytes() == b"-1" {
                NumDiv::Auto
            } else {
                NumDiv::Fixed(s.parse().expect("could not convert NUMDIV to an integer"))
            }
        }
    }

    pub fn set_num_div(&self, num: NumDiv) {
        match num {
            NumDiv::Fixed(i) => set_str_attribute(self.handle(), "NUMDIV", &i.to_string()),
            NumDiv::Auto => set_str_attribute(self.handle(), "NUMDIV", "AUTO"),
        }
    }

    pub fn num_lin(&self) -> u32 {
        unsafe {
            let s = get_str_attribute_slice(self.handle(), "NUMLIN");
            s.parse().expect("could not convert NUMLIN to an integer")
        }
    }

    pub fn num_col(&self) -> u32 {
        unsafe {
            let s = get_str_attribute_slice(self.handle(), "NUMCOL");
            s.parse().expect("could not convert NUMLIN to an integer")
        }
    }
}

impl_control_traits!(GridBox);

impl Container for GridBox {}

impl OrientationAttribute for GridBox {}

#[macro_export]
macro_rules! grid_box {
    ($($c:expr),*) => {
        {
            use std::ptr;
            let mut handles = Vec::new();
            $(
                // The control has to be stored in a binding to ensure it isn't dropped before
                // it is added as a child of the container. (Otherwise, the control is destroyed.)
                let c = $c;
                handles.push(c.handle());
            )*
            handles.push(ptr::null_mut());
            unsafe { GridBox::from_handles(handles.as_mut_ptr()) }
        }
    };
    ($($c:expr,)*) => { grid_box!($($c),*) };
}
<|endoftext|>