<commit_before>#![feature(tuple_indexing)]
#![feature(unsafe_destructor)]

extern crate "ogg-sys" as ogg_sys;
extern crate "vorbis-sys" as vorbis_sys;
extern crate "vorbisfile-sys" as vorbisfile_sys;
extern crate libc;

/// Allows you to decode a sound file stream into packets.
pub struct Decoder<R> where R: Reader + Seek {
    // further informations are boxed so that a pointer can be passed to callbacks
    data: Box<DecoderData<R>>,
    // the OggVorbis_File struct has no internal thread-safety
    nosync: std::kinds::marker::NoSync,
}

///
pub struct PacketsIter<'a, R: 'a + Reader + Seek>(&'a mut DecoderData<R>);

/// Errors that can happen while decoding
#[deriving(Show, PartialEq, Eq)]
pub enum VorbisError {
    ReadError(std::io::IoError),
    NotVorbis,
    VersionMismatch,
    BadHeader,
    InitialFileHeadersCorrupt,
}

impl std::error::Error for VorbisError {
    fn description(&self) -> &str {
        match self {
            &ReadError(_) => "A read from media returned an error",
            &NotVorbis => "Bitstream does not contain any Vorbis data",
            &VersionMismatch => "Vorbis version mismatch",
            &BadHeader => "Invalid Vorbis bitstream header",
            &InitialFileHeadersCorrupt => "Initial file headers are corrupt",
        }
    }

    fn cause(&self) -> Option<&std::error::Error> {
        match self {
            &ReadError(ref err) => Some(err as &std::error::Error+'static),
            _ => None
        }
    }
}

impl std::error::FromError<std::io::IoError> for VorbisError {
    fn from_error(err: std::io::IoError) -> VorbisError {
        ReadError(err)
    }
}

struct DecoderData<R> where R: Reader + Seek {
    vorbis: vorbisfile_sys::OggVorbis_File,
    reader: R,
    current_logical_bitstream: libc::c_int,
    read_error: Option<std::io::IoError>,
}

/// Packet of data.
///
/// Each sample is an `i16` ranging from I16_MIN to I16_MAX.
///
/// The channels are interleaved in the data. For example if you have two channels, you will
/// get a sample from channel 1, then a sample from channel 2, than a sample from channel 1, etc.
#[deriving(Clone, Show)]
pub struct Packet {
    pub data: Vec<i16>,
    pub channels: u16,
    pub rate: u64,
    pub bitrate_upper: u64,
    pub bitrate_nominal: u64,
    pub bitrate_lower: u64,
    pub bitrate_window: u64,
}

impl<R> Decoder<R> where R: Reader + Seek {
    pub fn new(input: R) -> Result<Decoder<R>, VorbisError> {
        extern fn read_func<R>(ptr: *mut libc::c_void, size: libc::size_t, nmemb: libc::size_t,
            datasource: *mut libc::c_void) -> libc::size_t where R: Reader + Seek
        {
            use std::c_vec::CVec;

            let mut ptr = ptr as *mut u8;

            let data: &mut DecoderData<R> = unsafe { std::mem::transmute(datasource) };

            loop {
                let mut buffer: CVec<u8> = unsafe { CVec::new(std::mem::transmute(ptr),
                    size as uint * nmemb as uint) };
                let buffer = buffer.as_mut_slice();

                match data.reader.read(buffer) {
                    Ok(0) => continue,
                    Ok(nb) => {
                        if buffer.len() == nb {
                            return nmemb;
                        } else {
                            unsafe { ptr = ptr.offset(nb as int) };
                        }
                    },
                    Err(ref e) if e.kind == std::io::EndOfFile => {
                        return 0
                    },
                    Err(e) => {
                        data.read_error = Some(e);
                        return 0;
                    }
                };
            }
        }

        extern fn seek_func<R>(datasource: *mut libc::c_void, offset: ogg_sys::ogg_int64_t,
            whence: libc::c_int) -> libc::c_int where R: Reader + Seek
        {
            let data: &mut DecoderData<R> = unsafe { std::mem::transmute(datasource) };

            let result = match whence {
                libc::SEEK_SET => data.reader.seek(offset, std::io::SeekSet),
                libc::SEEK_CUR => data.reader.seek(offset, std::io::SeekCur),
                libc::SEEK_END => data.reader.seek(offset, std::io::SeekEnd),
                _ => unreachable!()
            };

            match result {
                Ok(_) => 0,
                Err(_) => -1
            }
        }

        extern fn tell_func<R>(datasource: *mut libc::c_void) -> libc::c_long
            where R: Reader + Seek
        {
            let data: &mut DecoderData<R> = unsafe { std::mem::transmute(datasource) };
            data.reader.tell().unwrap_or(-1) as libc::c_long
        }

        let callbacks = {
            let mut callbacks: vorbisfile_sys::ov_callbacks = unsafe { std::mem::zeroed() };
            callbacks.read_func = read_func::<R>;
            callbacks.seek_func = seek_func::<R>;
            callbacks.tell_func = tell_func::<R>;
            callbacks
        };

        let mut data = DecoderData {
            vorbis: unsafe { std::mem::uninitialized() },
            reader: input,
            current_logical_bitstream: 0,
            read_error: None,
        };

        // initializing
        unsafe {
            let data_ptr = &mut data as *mut DecoderData<R>;
            let data_ptr = data_ptr as *mut libc::c_void;
            try!(check_errors(vorbisfile_sys::ov_open_callbacks(data_ptr, &mut data.vorbis,
                std::ptr::null(), 0, callbacks)));
        }

        Ok(Decoder {
            data: box data,
            nosync: std::kinds::marker::NoSync,
        })
    }

    pub fn packets(&mut self) -> PacketsIter<R> {
        PacketsIter(&mut *self.data)
    }
}

impl<'a, R> Iterator<Result<Packet, VorbisError>> for PacketsIter<'a, R> where R: 'a + Reader + Seek {
    fn next(&mut self) -> Option<Result<Packet, VorbisError>> {
        let mut buffer = Vec::from_elem(2048, 0i16);
        let buffer_len = buffer.len() * 2;

        match unsafe {
            vorbisfile_sys::ov_read(&mut self.0.vorbis, buffer.as_mut_ptr() as *mut i8,
                buffer_len as libc::c_int, 0, 2, 1, &mut self.0.current_logical_bitstream)
        } {
            0 => {
                match self.0.read_error.take() {
                    Some(err) => Some(Err(ReadError(err))),
                    None => None,
                }
            },

            err if err < 0 => {
                match check_errors(err as libc::c_int) {
                    Err(e) => Some(Err(e)),
                    Ok(_) => unreachable!()
                }
            },

            len => {
                buffer.truncate(len as uint);

                let infos = unsafe { vorbisfile_sys::ov_info(&mut self.0.vorbis,
                    self.0.current_logical_bitstream) };

                let infos: &vorbis_sys::vorbis_info = unsafe { std::mem::transmute(infos) };

                Some(Ok(Packet {
                    data: buffer,
                    channels: infos.channels as u16,
                    rate: infos.rate as u64,
                    bitrate_upper: infos.bitrate_upper as u64,
                    bitrate_nominal: infos.bitrate_nominal as u64,
                    bitrate_lower: infos.bitrate_lower as u64,
                    bitrate_window: infos.bitrate_window as u64,
                }))
            }
        }
    }
}

#[unsafe_destructor]
impl<R> Drop for Decoder<R> where R: Reader + Seek {
    fn drop(&mut self) {
        unsafe {
            vorbisfile_sys::ov_clear(&mut self.data.vorbis);
        }
    }
}

fn check_errors(code: libc::c_int) -> Result<(), VorbisError> {
    match code {
        0 => Ok(()),

        vorbis_sys::OV_ENOTVORBIS => Err(NotVorbis),
        vorbis_sys::OV_EVERSION => Err(VersionMismatch),
        vorbis_sys::OV_EBADHEADER => Err(BadHeader),
        vorbis_sys::OV_EINVAL => Err(InitialFileHeadersCorrupt),

        vorbis_sys::OV_EREAD => unimplemented!(),

        // indicates a bug or heap/stack corruption
        vorbis_sys::OV_EFAULT => panic!("Internal libvorbis error"),
        _ => panic!("Unknown vorbis error")
    }
}
<commit_msg>Fix segfault while reading<commit_after>#![feature(tuple_indexing)]
#![feature(unsafe_destructor)]

extern crate "ogg-sys" as ogg_sys;
extern crate "vorbis-sys" as vorbis_sys;
extern crate "vorbisfile-sys" as vorbisfile_sys;
extern crate libc;

/// Allows you to decode a sound file stream into packets.
pub struct Decoder<R> where R: Reader + Seek {
    // further informations are boxed so that a pointer can be passed to callbacks
    data: Box<DecoderData<R>>,
    // the OggVorbis_File struct has no internal thread-safety
    nosync: std::kinds::marker::NoSync,
}

///
pub struct PacketsIter<'a, R: 'a + Reader + Seek>(&'a mut DecoderData<R>);

/// Errors that can happen while decoding
#[deriving(Show, PartialEq, Eq)]
pub enum VorbisError {
    ReadError(std::io::IoError),
    NotVorbis,
    VersionMismatch,
    BadHeader,
    InitialFileHeadersCorrupt,
}

impl std::error::Error for VorbisError {
    fn description(&self) -> &str {
        match self {
            &ReadError(_) => "A read from media returned an error",
            &NotVorbis => "Bitstream does not contain any Vorbis data",
            &VersionMismatch => "Vorbis version mismatch",
            &BadHeader => "Invalid Vorbis bitstream header",
            &InitialFileHeadersCorrupt => "Initial file headers are corrupt",
        }
    }

    fn cause(&self) -> Option<&std::error::Error> {
        match self {
            &ReadError(ref err) => Some(err as &std::error::Error+'static),
            _ => None
        }
    }
}

impl std::error::FromError<std::io::IoError> for VorbisError {
    fn from_error(err: std::io::IoError) -> VorbisError {
        ReadError(err)
    }
}

struct DecoderData<R> where R: Reader + Seek {
    vorbis: vorbisfile_sys::OggVorbis_File,
    reader: R,
    current_logical_bitstream: libc::c_int,
    read_error: Option<std::io::IoError>,
}

/// Packet of data.
///
/// Each sample is an `i16` ranging from I16_MIN to I16_MAX.
///
/// The channels are interleaved in the data. For example if you have two channels, you will
/// get a sample from channel 1, then a sample from channel 2, than a sample from channel 1, etc.
#[deriving(Clone, Show)]
pub struct Packet {
    pub data: Vec<i16>,
    pub channels: u16,
    pub rate: u64,
    pub bitrate_upper: u64,
    pub bitrate_nominal: u64,
    pub bitrate_lower: u64,
    pub bitrate_window: u64,
}

impl<R> Decoder<R> where R: Reader + Seek {
    pub fn new(input: R) -> Result<Decoder<R>, VorbisError> {
        extern fn read_func<R>(ptr: *mut libc::c_void, size: libc::size_t, nmemb: libc::size_t,
            datasource: *mut libc::c_void) -> libc::size_t where R: Reader + Seek
        {
            use std::c_vec::CVec;

            let mut ptr = ptr as *mut u8;

            let data: &mut DecoderData<R> = unsafe { std::mem::transmute(datasource) };

            loop {
                let mut buffer: CVec<u8> = unsafe { CVec::new(ptr, size as uint * nmemb as uint) };
                let buffer = buffer.as_mut_slice();

                match data.reader.read(buffer) {
                    Ok(0) => continue,
                    Ok(nb) => {
                        if buffer.len() == nb {
                            return nmemb;
                        } else {
                            unsafe { ptr = ptr.offset(nb as int) };
                        }
                    },
                    Err(ref e) if e.kind == std::io::EndOfFile => {
                        return 0
                    },
                    Err(e) => {
                        data.read_error = Some(e);
                        return 0;
                    }
                };
            }
        }

        extern fn seek_func<R>(datasource: *mut libc::c_void, offset: ogg_sys::ogg_int64_t,
            whence: libc::c_int) -> libc::c_int where R: Reader + Seek
        {
            let data: &mut DecoderData<R> = unsafe { std::mem::transmute(datasource) };

            let result = match whence {
                libc::SEEK_SET => data.reader.seek(offset, std::io::SeekSet),
                libc::SEEK_CUR => data.reader.seek(offset, std::io::SeekCur),
                libc::SEEK_END => data.reader.seek(offset, std::io::SeekEnd),
                _ => unreachable!()
            };

            match result {
                Ok(_) => 0,
                Err(_) => -1
            }
        }

        extern fn tell_func<R>(datasource: *mut libc::c_void) -> libc::c_long
            where R: Reader + Seek
        {
            let data: &mut DecoderData<R> = unsafe { std::mem::transmute(datasource) };
            data.reader.tell().unwrap_or(-1) as libc::c_long
        }

        let callbacks = {
            let mut callbacks: vorbisfile_sys::ov_callbacks = unsafe { std::mem::zeroed() };
            callbacks.read_func = read_func::<R>;
            callbacks.seek_func = seek_func::<R>;
            callbacks.tell_func = tell_func::<R>;
            callbacks
        };

        let mut data = box DecoderData {
            vorbis: unsafe { std::mem::uninitialized() },
            reader: input,
            current_logical_bitstream: 0,
            read_error: None,
        };

        // initializing
        unsafe {
            let data_ptr = &mut *data as *mut DecoderData<R>;
            let data_ptr = data_ptr as *mut libc::c_void;
            try!(check_errors(vorbisfile_sys::ov_open_callbacks(data_ptr, &mut data.vorbis,
                std::ptr::null(), 0, callbacks)));
        }

        Ok(Decoder {
            data: data,
            nosync: std::kinds::marker::NoSync,
        })
    }

    pub fn packets(&mut self) -> PacketsIter<R> {
        PacketsIter(&mut *self.data)
    }
}

impl<'a, R> Iterator<Result<Packet, VorbisError>> for PacketsIter<'a, R> where R: 'a + Reader + Seek {
    fn next(&mut self) -> Option<Result<Packet, VorbisError>> {
        let mut buffer = Vec::from_elem(2048, 0i16);
        let buffer_len = buffer.len() * 2;

        match unsafe {
            vorbisfile_sys::ov_read(&mut self.0.vorbis, buffer.as_mut_ptr() as *mut i8,
                buffer_len as libc::c_int, 0, 2, 1, &mut self.0.current_logical_bitstream)
        } {
            0 => {
                match self.0.read_error.take() {
                    Some(err) => Some(Err(ReadError(err))),
                    None => None,
                }
            },

            err if err < 0 => {
                match check_errors(err as libc::c_int) {
                    Err(e) => Some(Err(e)),
                    Ok(_) => unreachable!()
                }
            },

            len => {
                buffer.truncate(len as uint);

                let infos = unsafe { vorbisfile_sys::ov_info(&mut self.0.vorbis,
                    self.0.current_logical_bitstream) };

                let infos: &vorbis_sys::vorbis_info = unsafe { std::mem::transmute(infos) };

                Some(Ok(Packet {
                    data: buffer,
                    channels: infos.channels as u16,
                    rate: infos.rate as u64,
                    bitrate_upper: infos.bitrate_upper as u64,
                    bitrate_nominal: infos.bitrate_nominal as u64,
                    bitrate_lower: infos.bitrate_lower as u64,
                    bitrate_window: infos.bitrate_window as u64,
                }))
            }
        }
    }
}

#[unsafe_destructor]
impl<R> Drop for Decoder<R> where R: Reader + Seek {
    fn drop(&mut self) {
        unsafe {
            vorbisfile_sys::ov_clear(&mut self.data.vorbis);
        }
    }
}

fn check_errors(code: libc::c_int) -> Result<(), VorbisError> {
    match code {
        0 => Ok(()),

        vorbis_sys::OV_ENOTVORBIS => Err(NotVorbis),
        vorbis_sys::OV_EVERSION => Err(VersionMismatch),
        vorbis_sys::OV_EBADHEADER => Err(BadHeader),
        vorbis_sys::OV_EINVAL => Err(InitialFileHeadersCorrupt),

        vorbis_sys::OV_EREAD => unimplemented!(),

        // indicates a bug or heap/stack corruption
        vorbis_sys::OV_EFAULT => panic!("Internal libvorbis error"),
        _ => panic!("Unknown vorbis error")
    }
}
<|endoftext|>


<commit_before>use std::io;
use std::thread;
use std::sync::Arc;
use std::sync::atomic::AtomicUsize;
use std::sync::mpsc::{channel, Sender, Receiver};
use std::clone::Clone;

pub mod pop;

use pop::population::Population;
use pop::population::manager::PopulationManager;
use pop::individual::Individual;
use pop::individual::manager::IndividualManager;
use pop::individual::chromosome::Chromosome;

pub trait ErrorsLayout {
    type CE: Sync + Send;
    type IE: Sync + Send;
    type IME: Sync + Send;
    type PE: Sync + Send;
    type PME: Sync + Send;
}

pub trait AlgorithmLayout: 'static {
    type EL: ErrorsLayout;
    type C: Chromosome<E = <Self::EL as ErrorsLayout>::CE>;
    type I: Individual<C = Self::C, E = <Self::EL as ErrorsLayout>::IE>;
    type IM: IndividualManager<I = Self::I, E = <Self::EL as ErrorsLayout>::IME>;
    type P: Population<I = Self::I, E = <Self::EL as ErrorsLayout>::PE>;
    type PM: PopulationManager<P = Self::P, IM = Self::IM, E = <Self::EL as ErrorsLayout>::PME>;
}

#[derive(Debug)]
pub enum Error<EL> where EL: ErrorsLayout {
    SpawnSlave(io::Error),
    Chromosome(EL::CE),
    Individual(EL::IE),
    IndividualManager(EL::IME),
    Population(EL::PE),
    PopulationManager(EL::PME),
}

enum Command<AL> where AL: AlgorithmLayout {
    PopulationInitialize(Arc<AL::PM>, Arc<AtomicUsize>),
    Stop,
}

impl<AL> Clone for Command<AL> where AL: AlgorithmLayout {
    fn clone(&self) -> Self {
        match *self {
            Command::PopulationInitialize(ref population_manager, ref sync_counter) =>
                Command::PopulationInitialize(population_manager.clone(), sync_counter.clone()),
            Command::Stop =>
                Command::Stop,
        }
    }
}

enum Report<AL> where AL: AlgorithmLayout {
    PopulationInitialized(AL::P),
    StopAck,
}

struct Slave<AL> where AL: AlgorithmLayout {
    thread: Option<thread::JoinHandle<()>>,
    tx: Sender<Command<AL>>,
    rx: Receiver<Result<Report<AL>, Error<AL::EL>>>,
}

impl<AL> Slave<AL> where AL: AlgorithmLayout {
    fn spawn(slave_id: usize) -> Result<Slave<AL>, io::Error> {
        let (master_tx, slave_rx) = channel();
        let (slave_tx, master_rx) = channel();
        let maybe_thread = thread::Builder::new()
            .name(format!("gen_lsb slave #{}", slave_id))
            .spawn(move || slave_loop(slave_rx, slave_tx));
        Ok(Slave {
            thread: Some(try!(maybe_thread)),
            tx: master_tx,
            rx: master_rx,
        })
    }
}

impl<AL> Drop for Slave<AL> where AL: AlgorithmLayout {
    fn drop(&mut self) {
        if let Some(thread) = self.thread.take() {
            self.tx.send(Command::Stop).unwrap();
            loop {
                match self.rx.recv().unwrap() {
                    Ok(Report::StopAck) => {
                        thread.join().unwrap();
                        break;
                    },
                    Ok(_) =>
                        continue,
                    Err(_err) =>
                        unreachable!(),
                }
            }
        }
    }
}

fn slave_loop<AL>(rx: Receiver<Command<AL>>, tx: Sender<Result<Report<AL>, Error<AL::EL>>>) where AL: AlgorithmLayout {
    loop {
        match rx.recv().unwrap() {
            Command::PopulationInitialize(population_manager, sync_counter) => {
                let result = slave_population_init::<AL>(population_manager, sync_counter);
                tx.send(result.map(|r| Report::PopulationInitialized(r))).unwrap();
            },
            Command::Stop => {
                tx.send(Ok(Report::StopAck)).unwrap();
                break;
            },
        }
    }
}

fn slave_population_init<AL>(population_manager: Arc<AL::PM>, sync_counter: Arc<AtomicUsize>) ->
    Result<AL::P, Error<AL::EL>> where AL: AlgorithmLayout
{
    let mut individual_manager =
        try!(population_manager.make_individual_manager().map_err(|e| Error::PopulationManager(e)));
    population_manager.init(&mut individual_manager, sync_counter).map_err(|e| Error::PopulationManager(e))
}

#[derive(Debug)]
pub enum RunResult<I> {
    FoundBest(I),
    PopLimitExceeded,
}

pub struct Algorithm<AL> where AL: AlgorithmLayout {
    population_manager: Arc<AL::PM>,
    slaves: Vec<Slave<AL>>,
}

impl<AL> Algorithm<AL> where AL: AlgorithmLayout {
    pub fn new(population_manager: AL::PM, slaves_count: usize) -> Result<Algorithm<AL>, Error<AL::EL>> {
        Ok(Algorithm {
            population_manager: Arc::new(population_manager),
            slaves: try!((0 .. slaves_count).map(|i| Slave::spawn(i).map_err(|e| Error::SpawnSlave(e))).collect()),
        })
    }

    pub fn run(&mut self) -> Result<RunResult<AL::I>, Error<AL::EL>> {
        let init_command =
            Command::PopulationInitialize(self.population_manager.clone(), Arc::new(AtomicUsize::new(0)));
        let _population_parts = try!(self.spread_sync(init_command));

        Ok(RunResult::PopLimitExceeded)
    }

    fn spread_sync(&self, cmd: Command<AL>) -> Result<Vec<Report<AL>>, Error<AL::EL>> {
        for slave in self.slaves.iter() {
            slave.tx.send(cmd.clone()).unwrap();
        }
        self.slaves.iter().map(|s| s.rx.recv().unwrap()).collect()
    }
}

#[cfg(test)]
mod tests {
}
<commit_msg>finally parallel initial population generation with no panics<commit_after>use std::io;
use std::thread;
use std::sync::Arc;
use std::sync::atomic::AtomicUsize;
use std::sync::mpsc::{channel, Sender, Receiver};
use std::clone::Clone;

pub mod pop;

use pop::population::Population;
use pop::population::manager::PopulationManager;
use pop::individual::Individual;
use pop::individual::manager::IndividualManager;
use pop::individual::chromosome::Chromosome;

pub trait ErrorsLayout {
    type CE: Sync + Send;
    type IE: Sync + Send;
    type IME: Sync + Send;
    type PE: Sync + Send;
    type PME: Sync + Send;
}

pub trait AlgorithmLayout: 'static {
    type EL: ErrorsLayout;
    type C: Chromosome<E = <Self::EL as ErrorsLayout>::CE>;
    type I: Individual<C = Self::C, E = <Self::EL as ErrorsLayout>::IE>;
    type IM: IndividualManager<I = Self::I, E = <Self::EL as ErrorsLayout>::IME>;
    type P: Population<I = Self::I, E = <Self::EL as ErrorsLayout>::PE>;
    type PM: PopulationManager<P = Self::P, IM = Self::IM, E = <Self::EL as ErrorsLayout>::PME>;
}

#[derive(Debug)]
pub enum Error<EL> where EL: ErrorsLayout {
    SpawnSlave(io::Error),
    Chromosome(EL::CE),
    Individual(EL::IE),
    IndividualManager(EL::IME),
    Population(EL::PE),
    PopulationManager(EL::PME),
    UnexpectedEmptyPopulation,
    Several(Vec<Error<EL>>),
}

enum Command<AL> where AL: AlgorithmLayout {
    PopulationInitialize(Arc<AL::PM>, Arc<AtomicUsize>),
    Stop,
}

impl<AL> Clone for Command<AL> where AL: AlgorithmLayout {
    fn clone(&self) -> Self {
        match *self {
            Command::PopulationInitialize(ref population_manager, ref sync_counter) =>
                Command::PopulationInitialize(population_manager.clone(), sync_counter.clone()),
            Command::Stop =>
                Command::Stop,
        }
    }
}

enum Report<AL> where AL: AlgorithmLayout {
    PopulationInitialized(AL::P),
    StopAck,
}

impl<AL> Report<AL> where AL: AlgorithmLayout {
    fn population_results(self) -> AL::P {
        match self {
            Report::PopulationInitialized(population) => population,
            _ => unreachable!(),
        }
    }
}

struct Slave<AL> where AL: AlgorithmLayout {
    thread: Option<thread::JoinHandle<()>>,
    tx: Sender<Command<AL>>,
    rx: Receiver<Result<Report<AL>, Error<AL::EL>>>,
    last_report: Option<Report<AL>>,
}

impl<AL> Slave<AL> where AL: AlgorithmLayout {
    fn spawn(slave_id: usize) -> Result<Slave<AL>, io::Error> {
        let (master_tx, slave_rx) = channel();
        let (slave_tx, master_rx) = channel();
        let maybe_thread = thread::Builder::new()
            .name(format!("gen_lsb slave #{}", slave_id))
            .spawn(move || slave_loop(slave_rx, slave_tx));
        Ok(Slave {
            thread: Some(try!(maybe_thread)),
            tx: master_tx,
            rx: master_rx,
            last_report: None,
        })
    }
}

impl<AL> Drop for Slave<AL> where AL: AlgorithmLayout {
    fn drop(&mut self) {
        if let Some(thread) = self.thread.take() {
            self.tx.send(Command::Stop).unwrap();
            loop {
                match self.rx.recv().unwrap() {
                    Ok(Report::StopAck) => {
                        thread.join().unwrap();
                        break;
                    },
                    Ok(_) =>
                        continue,
                    Err(_err) =>
                        unreachable!(),
                }
            }
        }
    }
}

fn slave_loop<AL>(rx: Receiver<Command<AL>>, tx: Sender<Result<Report<AL>, Error<AL::EL>>>) where AL: AlgorithmLayout {
    loop {
        match rx.recv().unwrap() {
            Command::PopulationInitialize(population_manager, sync_counter) => {
                let result = slave_population_init::<AL>(population_manager, sync_counter);
                tx.send(result.map(|r| Report::PopulationInitialized(r))).unwrap();
            },
            Command::Stop => {
                tx.send(Ok(Report::StopAck)).unwrap();
                break;
            },
        }
    }
}

fn slave_population_init<AL>(population_manager: Arc<AL::PM>, sync_counter: Arc<AtomicUsize>) ->
    Result<AL::P, Error<AL::EL>> where AL: AlgorithmLayout
{
    let mut individual_manager =
        try!(population_manager.make_individual_manager().map_err(|e| Error::PopulationManager(e)));
    population_manager.init(&mut individual_manager, sync_counter).map_err(|e| Error::PopulationManager(e))
}

#[derive(Debug)]
pub enum RunResult<I> {
    FoundBest(I),
    PopLimitExceeded,
}

pub struct Algorithm<AL> where AL: AlgorithmLayout {
    population_manager: Arc<AL::PM>,
    slaves: Vec<Slave<AL>>,
}

impl<AL> Algorithm<AL> where AL: AlgorithmLayout {
    pub fn new(population_manager: AL::PM, slaves_count: usize) -> Result<Algorithm<AL>, Error<AL::EL>> {
        Ok(Algorithm {
            population_manager: Arc::new(population_manager),
            slaves: try!((0 .. slaves_count).map(|i| Slave::spawn(i).map_err(|e| Error::SpawnSlave(e))).collect()),
        })
    }

    pub fn run(&mut self) -> Result<RunResult<AL::I>, Error<AL::EL>> {
        let _population = self.population_initialize();

        Ok(RunResult::PopLimitExceeded)
    }

    pub fn population_initialize(&mut self) -> Result<AL::P, Error<AL::EL>> {
        let init_command =
            Command::PopulationInitialize(self.population_manager.clone(), Arc::new(AtomicUsize::new(0)));
        try!(self.spread_sync(init_command));
        let maybe_population =
            Population::merge_many(self.slaves.iter_mut().flat_map(|s| s.last_report.take()).map(|r| r.population_results()));
        try!(maybe_population.map_err(|e| Error::Population(e))).ok_or(Error::UnexpectedEmptyPopulation)
    }

    fn spread_sync(&mut self, cmd: Command<AL>) -> Result<(), Error<AL::EL>> {
        for slave in self.slaves.iter() {
            slave.tx.send(cmd.clone()).unwrap();
        }
        let mut errors = Vec::new();
        for slave in self.slaves.iter_mut() {
            match slave.rx.recv().unwrap() {
                Ok(r) =>
                    slave.last_report = Some(r),
                Err(e) =>
                    errors.push(e),
            }
        }
        if errors.is_empty() {
            Ok(())
        } else {
            Err(Error::Several(errors))
        }
    }
}

#[cfg(test)]
mod tests {
}
<|endoftext|>


<commit_before>//! This crate provides type-erased versions of Serde's `Serialize`, `Serializer`
//! and `Deserializer` traits that can be used as [trait objects].
//!
//! [trait objects]: https://doc.rust-lang.org/book/trait-objects.html
//!
//! The usual Serde `Serialize`, `Serializer` and `Deserializer` traits cannot
//! be used as trait objects like `&dyn Serialize` or boxed trait objects like
//! `Box<dyn Serialize>` because of Rust's ["object safety" rules]. In
//! particular, all three traits contain generic methods which cannot be made
//! into a trait object.
//!
//! ["object safety" rules]: http://huonw.github.io/blog/2015/01/object-safety/
//!
//! This library should be considered a low-level building block for interacting
//! with Serde APIs in an object-safe way. Most use cases will require higher
//! level functionality such as provided by [`typetag`] which uses this crate
//! internally.
//!
//! [`typetag`]: https://github.com/dtolnay/typetag
//!
//! **The traits in this crate work seamlessly with any existing Serde
//! `Serialize` and `Deserialize` type and any existing Serde `Serializer` and
//! `Deserializer` format.**
//!
//! ## Serialization
//!
//! ```rust
//! use erased_serde::{Serialize, Serializer};
//! use std::collections::BTreeMap as Map;
//! use std::io;
//!
//! fn main() {
//!     // Construct some serializers.
//!     let json = &mut serde_json::Serializer::new(io::stdout());
//!     let cbor = &mut serde_cbor::Serializer::new(serde_cbor::ser::IoWrite::new(io::stdout()));
//!
//!     // The values in this map are boxed trait objects. Ordinarily this would not
//!     // be possible with serde::Serializer because of object safety, but type
//!     // erasure makes it possible with erased_serde::Serializer.
//!     let mut formats: Map<&str, Box<dyn Serializer>> = Map::new();
//!     formats.insert("json", Box::new(Serializer::erase(json)));
//!     formats.insert("cbor", Box::new(Serializer::erase(cbor)));
//!
//!     // These are boxed trait objects as well. Same thing here - type erasure
//!     // makes this possible.
//!     let mut values: Map<&str, Box<dyn Serialize>> = Map::new();
//!     values.insert("vec", Box::new(vec!["a", "b"]));
//!     values.insert("int", Box::new(65536));
//!
//!     // Pick a Serializer out of the formats map.
//!     let format = formats.get_mut("json").unwrap();
//!
//!     // Pick a Serialize out of the values map.
//!     let value = values.get("vec").unwrap();
//!
//!     // This line prints `["a","b"]` to stdout.
//!     value.erased_serialize(format).unwrap();
//! }
//! ```
//!
//! ## Deserialization
//!
//! ```rust
//! use erased_serde::Deserializer;
//! use std::collections::BTreeMap as Map;
//!
//! fn main() {
//!     static JSON: &'static [u8] = br#"{"A": 65, "B": 66}"#;
//!     static CBOR: &'static [u8] = &[162, 97, 65, 24, 65, 97, 66, 24, 66];
//!
//!     // Construct some deserializers.
//!     let json = &mut serde_json::Deserializer::from_slice(JSON);
//!     let cbor = &mut serde_cbor::Deserializer::from_slice(CBOR);
//!
//!     // The values in this map are boxed trait objects, which is not possible
//!     // with the normal serde::Deserializer because of object safety.
//!     let mut formats: Map<&str, Box<dyn Deserializer>> = Map::new();
//!     formats.insert("json", Box::new(Deserializer::erase(json)));
//!     formats.insert("cbor", Box::new(Deserializer::erase(cbor)));
//!
//!     // Pick a Deserializer out of the formats map.
//!     let format = formats.get_mut("json").unwrap();
//!
//!     let data: Map<String, usize> = erased_serde::deserialize(format).unwrap();
//!
//!     println!("{}", data["A"] + data["B"]);
//! }
//! ```

#![doc(html_root_url = "https://docs.rs/erased-serde/0.3.11")]
#![cfg_attr(not(feature = "std"), no_std)]

mod alloc {
    #[cfg(not(feature = "std"))]
    extern crate alloc;

    #[cfg(feature = "std")]
    use std as alloc;

    pub use self::alloc::borrow::ToOwned;
    pub use self::alloc::boxed::Box;
    pub use self::alloc::string::{String, ToString};
    pub use self::alloc::{vec, vec::Vec};
}

#[macro_use]
mod macros;

mod any;
mod de;
mod error;
mod features_check;
mod ser;

pub use crate::de::{deserialize, Deserializer};
pub use crate::error::{Error, Result};
pub use crate::ser::{serialize, Serialize, Serializer};

// Not public API.
#[doc(hidden)]
pub mod private;
<commit_msg>Add crosslink icons to top of rustdoc<commit_after>//! [![github]](https://github.com/dtolnay/erased-serde) [![crates-io]](https://crates.io/crates/erased-serde) [![docs-rs]](https://docs.rs/erased-serde)
//!
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K
//!
//! <br>
//!
//! This crate provides type-erased versions of Serde's `Serialize`, `Serializer`
//! and `Deserializer` traits that can be used as [trait objects].
//!
//! [trait objects]: https://doc.rust-lang.org/book/trait-objects.html
//!
//! The usual Serde `Serialize`, `Serializer` and `Deserializer` traits cannot
//! be used as trait objects like `&dyn Serialize` or boxed trait objects like
//! `Box<dyn Serialize>` because of Rust's ["object safety" rules]. In
//! particular, all three traits contain generic methods which cannot be made
//! into a trait object.
//!
//! ["object safety" rules]: http://huonw.github.io/blog/2015/01/object-safety/
//!
//! This library should be considered a low-level building block for interacting
//! with Serde APIs in an object-safe way. Most use cases will require higher
//! level functionality such as provided by [`typetag`] which uses this crate
//! internally.
//!
//! [`typetag`]: https://github.com/dtolnay/typetag
//!
//! **The traits in this crate work seamlessly with any existing Serde
//! `Serialize` and `Deserialize` type and any existing Serde `Serializer` and
//! `Deserializer` format.**
//!
//! ## Serialization
//!
//! ```rust
//! use erased_serde::{Serialize, Serializer};
//! use std::collections::BTreeMap as Map;
//! use std::io;
//!
//! fn main() {
//!     // Construct some serializers.
//!     let json = &mut serde_json::Serializer::new(io::stdout());
//!     let cbor = &mut serde_cbor::Serializer::new(serde_cbor::ser::IoWrite::new(io::stdout()));
//!
//!     // The values in this map are boxed trait objects. Ordinarily this would not
//!     // be possible with serde::Serializer because of object safety, but type
//!     // erasure makes it possible with erased_serde::Serializer.
//!     let mut formats: Map<&str, Box<dyn Serializer>> = Map::new();
//!     formats.insert("json", Box::new(Serializer::erase(json)));
//!     formats.insert("cbor", Box::new(Serializer::erase(cbor)));
//!
//!     // These are boxed trait objects as well. Same thing here - type erasure
//!     // makes this possible.
//!     let mut values: Map<&str, Box<dyn Serialize>> = Map::new();
//!     values.insert("vec", Box::new(vec!["a", "b"]));
//!     values.insert("int", Box::new(65536));
//!
//!     // Pick a Serializer out of the formats map.
//!     let format = formats.get_mut("json").unwrap();
//!
//!     // Pick a Serialize out of the values map.
//!     let value = values.get("vec").unwrap();
//!
//!     // This line prints `["a","b"]` to stdout.
//!     value.erased_serialize(format).unwrap();
//! }
//! ```
//!
//! ## Deserialization
//!
//! ```rust
//! use erased_serde::Deserializer;
//! use std::collections::BTreeMap as Map;
//!
//! fn main() {
//!     static JSON: &'static [u8] = br#"{"A": 65, "B": 66}"#;
//!     static CBOR: &'static [u8] = &[162, 97, 65, 24, 65, 97, 66, 24, 66];
//!
//!     // Construct some deserializers.
//!     let json = &mut serde_json::Deserializer::from_slice(JSON);
//!     let cbor = &mut serde_cbor::Deserializer::from_slice(CBOR);
//!
//!     // The values in this map are boxed trait objects, which is not possible
//!     // with the normal serde::Deserializer because of object safety.
//!     let mut formats: Map<&str, Box<dyn Deserializer>> = Map::new();
//!     formats.insert("json", Box::new(Deserializer::erase(json)));
//!     formats.insert("cbor", Box::new(Deserializer::erase(cbor)));
//!
//!     // Pick a Deserializer out of the formats map.
//!     let format = formats.get_mut("json").unwrap();
//!
//!     let data: Map<String, usize> = erased_serde::deserialize(format).unwrap();
//!
//!     println!("{}", data["A"] + data["B"]);
//! }
//! ```

#![doc(html_root_url = "https://docs.rs/erased-serde/0.3.11")]
#![cfg_attr(not(feature = "std"), no_std)]

mod alloc {
    #[cfg(not(feature = "std"))]
    extern crate alloc;

    #[cfg(feature = "std")]
    use std as alloc;

    pub use self::alloc::borrow::ToOwned;
    pub use self::alloc::boxed::Box;
    pub use self::alloc::string::{String, ToString};
    pub use self::alloc::{vec, vec::Vec};
}

#[macro_use]
mod macros;

mod any;
mod de;
mod error;
mod features_check;
mod ser;

pub use crate::de::{deserialize, Deserializer};
pub use crate::error::{Error, Result};
pub use crate::ser::{serialize, Serialize, Serializer};

// Not public API.
#[doc(hidden)]
pub mod private;
<|endoftext|>


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

//! # Message Format
//!
//! A [`Message`] is a piece of user-visible text that typically has
//! variable elements.
//!
//! Often, when writing your application, you need to customize the
//! output based on various variable values:
//!
//! > Your search had no results.
//!
//! > Your search had one result.
//!
//! > Your search had 3 results.
//!
//! You don't want to have specific code for each message output to
//! build up the text, and ideally, you'll be supporting localization
//! so that your application can be used by people who speak other
//! languages, which often have different rules concerning pluralization,
//! gender and list formatting.
//!
//! Separating messages from the code has other benefits as well apart
//! from making localization easier. You may need different branding of
//! your product for different builds, or you may want to be able to have
//! someone edit and proofread the text without having to have them modify
//! the code itself.
//!
//! This module currently provides support for messages using the
//! [ICU Message Format]. In the future, we hope to support other
//! message formats as well, especially L20n.
//!
//! ## Installation
//!
//! This crate works with Cargo and is on
//! [crates.io](https://crates.io/crates/message-format).
//! Add it to your `Cargo.toml` like so:
//!
//! ```toml
//! [dependencies]
//! message-format = "0.0.1"
//! ```
//!
//! This library depends upon some macros being used, so at the top of your crate,
//! you will want to make sure that macros from this crate are used:
//!
//! ```
//! #[macro_use]
//! extern crate message_format;
//! # fn main() {}
//! ```
//!
//! ## Contexts
//!
//! The context stores information that is shared between all of the formats
//! that are formatted using that context. (You might want to have multiple
//! contexts, or you might not.)
//!
//! For now, this stores the locale that is being used, but in the future,
//! it will be used for additional features.
//!
//! ## ICU Formatted Messages
//!
//! The simplest way to create an ICU formatted [`Message`] from code is
//! to [`parse`] it from a text format:
//!
//! ```
//! use message_format::icu;
//!
//! let m = icu::parse("Connecting to {host}...").unwrap();
//! ```
//!
//! For details on the [ICU Message Format] syntax, see the [`icu` module].
//!
//! ## L20n Formatted Messages
//!
//! Support for the [L20n] localization format is under development.
//!
//! ## Formatting a Message
//!
//! Messages need arguments or parameters. Since messages typically have named
//! arguments, we can't just pass arguments directly like we might do with
//! `format!` or other lower level formatting operations. Instead, we have
//! our own macros.
//!
//! Arguments can be specified as `name => value` or, if you have a variable
//! with the same name as the argument already, then as just `name`.
//!
//! ```
//! #[macro_use]
//! extern crate message_format;
//!
//! use message_format::{Context, icu};
//!
//! fn main() {
//!     let ctx = Context::default();
//!     let m1 = icu::parse("Connecting to {host}...").unwrap();
//!     assert_eq!(format_message!(ctx, &m1, host => "localhost"),
//!                "Connecting to localhost...");
//!
//!     let m2 = icu::parse("{name} went to {place}.").unwrap();
//!     let name = "Jacob";
//!     assert_eq!(format_message!(ctx, &m2, name, place => "the store"),
//!                "Jacob went to the store.");
//! }
//! ```
//!
//! ## Future Directions
//!
//! In the future, we want to extend this library to support a number of
//! additional features:
//!
//! * Serializing and deserializing messages in a binary format to avoid
//!   needing to parse them on every application startup.
//! * Integration with `rust-locale` or other libraries for doing locale
//!   specific formatting.
//! * Extending the types of data that can be used with [`Value`].
//! * Supporting [L20n] and perhaps other message format syntaxes. (This
//!   will probably require API changes.)
//! * Offline utilities for compiling and validating message format
//!   strings, converting to and from various formats like XLIFF, etc.
//!
//! ## Contributions
//!
//! Contributions are welcome.
//!
//! [ICU Message Format]: icu/index.html
//! [`icu` module]: icu/index.html
//! [L20n]: http://l20n.org/
//! [`parse`]: icu/fn.parse.html
//! [`Message`]: struct.Message.html
//! [`Value`]: enum.Value.html

#![warn(missing_docs)]
#![deny(trivial_numeric_casts,
        unsafe_code, unstable_features,
        unused_import_braces, unused_qualifications)]

extern crate language_tags;
#[macro_use]
extern crate nom;

pub mod icu;
pub mod l20n;
mod args;
mod context;
mod macros;
mod message;
mod message_part;
mod plural_category;
mod plural_classifiers;
mod value;

pub use self::args::{arg, Args};
pub use self::context::Context;
pub use self::message::Message;
pub use self::message_part::MessagePart;
pub use self::plural_category::PluralCategory;
pub use self::plural_classifiers::*;
pub use self::value::{AsValue, Value};
<commit_msg>Improve docs.<commit_after>// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! # Message Format
//!
//! A [`Message`] is a piece of user-visible text that typically has
//! variable elements.
//!
//! Often, when writing your application, you need to customize the
//! output based on various variable values:
//!
//! ```text
//! Your search had no results.
//! Your search had one result.
//! Your search had 3 results.
//! ```
//!
//! You don't want to have specific code for each message output to
//! build up the text, and ideally, you'll be supporting localization
//! so that your application can be used by people who speak other
//! languages, which often have different rules concerning pluralization,
//! gender and list formatting.
//!
//! Using the [ICU Message Format] syntax supported by this library, the
//! above text would be generated by this message (in English):
//!
//! ```text
//! {count, plural,
//!   =0 {Your search had no results.}
//!   =1 {Your search had one result.}
//!   other {Your search had # results.}}
//! ```
//!
//! Assuming you had that parsed into a message `search_results`, the code
//! to format that might look like:
//!
//! ```
//! # #[macro_use]
//! # extern crate message_format;
//! # fn main () {
//! # let ctx = message_format::Context::default();
//! # let search_results = &message_format::icu::parse("...").unwrap();
//! # let results: Vec<&str> = vec![];
//! let s = format_message!(ctx, search_results, count => results.len());
//! # }
//! ```
//!
//! Other languages with different rules for plurals, gender and other
//! things can have correct output just by updating the message text without
//! having to modify the code.
//!
//! Separating messages from the code has other benefits as well apart
//! from making localization easier. You may need different branding of
//! your product for different builds, or you may want to be able to have
//! someone edit and proofread the text without having to have them modify
//! the code itself.
//!
//! This module currently provides support for messages using the
//! [ICU Message Format]. In the future, we will support the [L20n]
//! message format as well.
//!
//! ## Installation
//!
//! This crate works with Cargo and is on
//! [crates.io](https://crates.io/crates/message-format).
//! Add it to your `Cargo.toml` like so:
//!
//! ```toml
//! [dependencies]
//! message-format = "0.0.1"
//! ```
//!
//! This library depends upon some macros being used, so at the top of your crate,
//! you will want to make sure that macros from this crate are used:
//!
//! ```
//! #[macro_use]
//! extern crate message_format;
//! # fn main() {}
//! ```
//!
//! ## Contexts
//!
//! The context stores information that is shared between all of the formats
//! that are formatted using that context. (You might want to have multiple
//! contexts, or you might not.)
//!
//! For now, this stores the locale that is being used, but in the future,
//! it will be used for additional features.
//!
//! ## ICU Formatted Messages
//!
//! The simplest way to create an ICU formatted [`Message`] from code is
//! to [`parse`] it from a text format:
//!
//! ```
//! use message_format::icu;
//!
//! let m = icu::parse("Connecting to {host}...").unwrap();
//! ```
//!
//! For details on the [ICU Message Format] syntax, see the [`icu` module].
//!
//! ## L20n Formatted Messages
//!
//! Support for the [L20n] localization format is under development.
//!
//! ## Formatting a Message
//!
//! Messages need arguments or parameters. Since messages typically have named
//! arguments, we can't just pass arguments directly like we might do with
//! `format!` or other lower level formatting operations. Instead, we have
//! our own macros.
//!
//! Arguments can be specified as `name => value` or, if you have a variable
//! with the same name as the argument already, then as just `name`.
//!
//! ```
//! #[macro_use]
//! extern crate message_format;
//!
//! fn main() {
//!     let ctx = message_format::Context::default();
//!     let m1 = message_format::icu::parse("Connecting to {host}...").unwrap();
//!     assert_eq!(format_message!(ctx, &m1, host => "localhost"),
//!                "Connecting to localhost...");
//!
//!     let m2 = message_format::icu::parse("{name} went to {place}.").unwrap();
//!     let name = "Jacob";
//!     assert_eq!(format_message!(ctx, &m2, name, place => "the store"),
//!                "Jacob went to the store.");
//! }
//! ```
//!
//! ## Future Directions
//!
//! In the future, we want to extend this library to support a number of
//! additional features:
//!
//! * Serializing and deserializing messages in a binary format to avoid
//!   needing to parse them on every application startup.
//! * Integration with `rust-locale` or other libraries for doing locale
//!   specific formatting.
//! * Extending the types of data that can be used with [`Value`].
//! * Supporting [L20n] and perhaps other message format syntaxes. (This
//!   will probably require API changes.)
//! * Offline utilities for compiling and validating message format
//!   strings, converting to and from various formats like XLIFF, etc.
//!
//! ## Contributions
//!
//! Contributions are welcome.
//!
//! [ICU Message Format]: icu/index.html
//! [`icu` module]: icu/index.html
//! [L20n]: http://l20n.org/
//! [`parse`]: icu/fn.parse.html
//! [`Message`]: struct.Message.html
//! [`Value`]: enum.Value.html

#![warn(missing_docs)]
#![deny(trivial_numeric_casts,
        unsafe_code, unstable_features,
        unused_import_braces, unused_qualifications)]

extern crate language_tags;
#[macro_use]
extern crate nom;

pub mod icu;
pub mod l20n;
mod args;
mod context;
mod macros;
mod message;
mod message_part;
mod plural_category;
mod plural_classifiers;
mod value;

pub use self::args::{arg, Args};
pub use self::context::Context;
pub use self::message::Message;
pub use self::message_part::MessagePart;
pub use self::plural_category::PluralCategory;
pub use self::plural_classifiers::*;
pub use self::value::{AsValue, Value};
<|endoftext|>


<commit_before>#![cfg_attr(test, deny(warnings))]
#![warn(trivial_casts)]
#![forbid(unused, unused_extern_crates, unused_import_braces, unused_qualifications)]

pub fn nav(subdomain: &str, page: &str, is_admin: bool) -> String {
    format!(
        r#"

        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
            Toggle navigation

        </button>
        Willkommen in Wöllstein

Home

Unsere Angebote

Veranstaltungen

Presse

Galerie

Kontakt

Börse

        {right}

        "#,
        wiw=if subdomain == "boerse" { "//willkommeninwoellstein.de" } else { "" },
        boerse=if subdomain == "boerse" { "" } else { "//boerse.willkommeninwoellstein.de" },
        right=if subdomain == "boerse" && is_admin { r#"

neue Notiz

"# } else { "" },
        active_home=subdomain != "boerse" && page == "/",
        active_angebote=subdomain != "boerse" && page.starts_with("/angebote"),
        active_veranstaltungen=subdomain != "boerse" && page.starts_with("/veranstaltungen"),
        active_presse=subdomain != "boerse" && page.starts_with("/presse"),
        active_galerie=subdomain != "boerse" && page.starts_with("/galerie"),
        active_kontakt=subdomain != "boerse" && page.starts_with("/kontakt"),
        active_boerse=subdomain == "boerse",
    )
}<commit_msg>Fix navbar style<commit_after>#![cfg_attr(test, deny(warnings))]
#![warn(trivial_casts)]
#![forbid(unused, unused_extern_crates, unused_import_braces, unused_qualifications)]

pub fn nav(subdomain: &str, page: &str, is_admin: bool) -> String {
    format!(
        r#"

        <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">
            Toggle navigation

        </button>
        Willkommen in Wöllstein

Home

Unsere Angebote

Veranstaltungen

Presse

Galerie

Kontakt

Börse

        {right}

        "#,
        wiw=if subdomain == "boerse" { "//willkommeninwoellstein.de" } else { "" },
        boerse=if subdomain == "boerse" { "" } else { "//boerse.willkommeninwoellstein.de" },
        right=if subdomain == "boerse" && is_admin { r#"

neue Notiz

"# } else { "" },
        active_home=if subdomain != "boerse" && page == "/" { " class=\"active\"" } else { "" },
        active_angebote=if subdomain != "boerse" && page.starts_with("/angebote") { " class=\"active\"" } else { "" },
        active_veranstaltungen=if subdomain != "boerse" && page.starts_with("/veranstaltungen") { " class=\"active\"" } else { "" },
        active_presse=if subdomain != "boerse" && page.starts_with("/presse") { " class=\"active\"" } else { "" },
        active_galerie=if subdomain != "boerse" && page.starts_with("/galerie") { " class=\"active\"" } else { "" },
        active_kontakt=if subdomain != "boerse" && page.starts_with("/kontakt") { " class=\"active\"" } else { "" },
        active_boerse=if subdomain == "boerse" { " class=\"active\"" } else { "" },
    )
}<|endoftext|>


<commit_before>use fake_adapter::FakeBluetoothAdapter;
use std::error::Error;
use std::sync::Arc;

#[derive(Debug)]
pub struct FakeBluetoothDiscoverySession {
    adapter: Arc<FakeBluetoothAdapter>,
}

impl FakeBluetoothDiscoverySession {
    pub fn create_session(adapter: Arc<FakeBluetoothAdapter>) -> Result<FakeBluetoothDiscoverySession, Box<Error>> {
        Ok(FakeBluetoothDiscoverySession::new(adapter))
    }

    fn new(adapter: Arc<FakeBluetoothAdapter>) -> FakeBluetoothDiscoverySession {
        FakeBluetoothDiscoverySession {
            adapter: adapter,
        }
    }

    pub fn get_adapter(&self) -> Arc<FakeBluetoothAdapter> {
        self.adapter.clone()
    }

    pub fn start_discovery(&self) -> Result<(), Box<Error>> {
        Ok(())
    }

    pub fn stop_discovery(&self) -> Result<(), Box<Error>> {
        Ok(())
    }
}
<commit_msg>WIP: discovery_session session_error<commit_after>use fake_adapter::FakeBluetoothAdapter;
use std::error::Error;
use std::sync::Arc;

#[derive(Debug)]
pub struct FakeBluetoothDiscoverySession {
    adapter: Arc<FakeBluetoothAdapter>,
}

impl FakeBluetoothDiscoverySession {
    pub fn create_session(adapter: Arc<FakeBluetoothAdapter>) -> Result<FakeBluetoothDiscoverySession, Box<Error>> {
        Ok(FakeBluetoothDiscoverySession::new(adapter))
    }

    fn new(adapter: Arc<FakeBluetoothAdapter>) -> FakeBluetoothDiscoverySession {
        FakeBluetoothDiscoverySession {
            adapter: adapter,
        }
    }

    pub fn get_adapter(&self) -> Arc<FakeBluetoothAdapter> {
        self.adapter.clone()
    }

    pub fn start_discovery(&self) -> Result<(), Box<Error>> {
        match self.adapter.is_discoverable() {
            Ok(false) => Err(Box::from("Failed to start discovery session")),
            Ok(true) => Ok(()),
            Err(err) => Err(err),
        }
    }

    pub fn stop_discovery(&self) -> Result<(), Box<Error>> {
        Ok(())
    }
}
<|endoftext|>


<commit_before>use io;
use libc;
use sys::fd::FileDesc;

pub struct Stdin(());
pub struct Stdout(());
pub struct Stderr(());

impl Stdin {
    pub fn new() -> io::Result<Stdin> { Ok(Stdin(())) }

    pub fn read(&self, data: &mut [u8]) -> io::Result<usize> {
        let fd = FileDesc::new(libc::STDIN_FILENO);
        let ret = fd.read(data);
        fd.into_raw();
        ret
    }
}

impl Stdout {
    pub fn new() -> io::Result<Stdout> { Ok(Stdout(())) }

    pub fn write(&self, data: &[u8]) -> io::Result<usize> {
        let fd = FileDesc::new(libc::STDOUT_FILENO);
        let ret = fd.write(data);
        fd.into_raw();
        ret
    }

    pub fn flush(&self) -> io::Result<()> {
        Ok(())
    }
}

impl Stderr {
    pub fn new() -> io::Result<Stderr> { Ok(Stderr(())) }

    pub fn write(&self, data: &[u8]) -> io::Result<usize> {
        let fd = FileDesc::new(libc::STDERR_FILENO);
        let ret = fd.write(data);
        fd.into_raw();
        ret
    }

    pub fn flush(&self) -> io::Result<()> {
        Ok(())
    }
}

// FIXME: right now this raw stderr handle is used in a few places because
//        std::io::stderr_raw isn't exposed, but once that's exposed this impl
//        should go away
impl io::Write for Stderr {
    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
        Stderr::write(self, data)
    }

    fn flush(&mut self) -> io::Result<()> {
        Stderr::flush(self)
    }
}

pub fn is_ebadf(err: &io::Error) -> bool {
    err.raw_os_error() == Some(libc::EBADF as i32)
}

pub const STDIN_BUF_SIZE: usize = ::sys_common::io::DEFAULT_BUF_SIZE;

pub fn panic_output() -> Option<impl io::Write> {
    Stderr::new().ok()
}
<commit_msg>Rollup merge of #58295 - RalfJung:stdio, r=alexcrichton<commit_after>use io;
use libc;
use sys::fd::FileDesc;

pub struct Stdin(());
pub struct Stdout(());
pub struct Stderr(());

impl Stdin {
    pub fn new() -> io::Result<Stdin> { Ok(Stdin(())) }

    pub fn read(&self, data: &mut [u8]) -> io::Result<usize> {
        let fd = FileDesc::new(libc::STDIN_FILENO);
        let ret = fd.read(data);
        fd.into_raw(); // do not close this FD
        ret
    }
}

impl Stdout {
    pub fn new() -> io::Result<Stdout> { Ok(Stdout(())) }

    pub fn write(&self, data: &[u8]) -> io::Result<usize> {
        let fd = FileDesc::new(libc::STDOUT_FILENO);
        let ret = fd.write(data);
        fd.into_raw(); // do not close this FD
        ret
    }

    pub fn flush(&self) -> io::Result<()> {
        Ok(())
    }
}

impl Stderr {
    pub fn new() -> io::Result<Stderr> { Ok(Stderr(())) }

    pub fn write(&self, data: &[u8]) -> io::Result<usize> {
        let fd = FileDesc::new(libc::STDERR_FILENO);
        let ret = fd.write(data);
        fd.into_raw(); // do not close this FD
        ret
    }

    pub fn flush(&self) -> io::Result<()> {
        Ok(())
    }
}

// FIXME: right now this raw stderr handle is used in a few places because
//        std::io::stderr_raw isn't exposed, but once that's exposed this impl
//        should go away
impl io::Write for Stderr {
    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
        Stderr::write(self, data)
    }

    fn flush(&mut self) -> io::Result<()> {
        Stderr::flush(self)
    }
}

pub fn is_ebadf(err: &io::Error) -> bool {
    err.raw_os_error() == Some(libc::EBADF as i32)
}

pub const STDIN_BUF_SIZE: usize = ::sys_common::io::DEFAULT_BUF_SIZE;

pub fn panic_output() -> Option<impl io::Write> {
    Stderr::new().ok()
}
<|endoftext|>


<commit_before>use crate::bindings;
use lucet_runtime::{self, MmapRegion, Module as LucetModule, Region, UntypedRetVal, Val};
use lucetc::{Compiler, CpuFeatures, Error as LucetcError};
use std::io;
use std::process::Command;
use std::sync::Arc;
use thiserror::Error;

#[derive(Debug, Error)]
pub enum ScriptError {
    #[error("Validation error")]
    ValidationError(#[source] LucetcError),
    #[error("Program error")]
    ProgramError(#[source] LucetcError),
    #[error("Compilation error")]
    CompileError(#[source] LucetcError),
    #[error("Codegen error")]
    CodegenError(#[source] LucetcError),
    #[error("Load error")]
    LoadError(#[source] lucet_runtime::Error),
    #[error("Instantiation error")]
    InstantiateError(#[source] lucet_runtime::Error),
    #[error("Runtime error")]
    RuntimeError(#[source] lucet_runtime::Error),
    #[error("Malformed script: {0}")]
    MalformedScript(String),
    #[error("IO error")]
    IoError(#[from] io::Error),
    #[error("run_ld error: {0}")]
    LdError(String),
}

impl ScriptError {
    pub fn unsupported(&self) -> bool {
        match self {
            ScriptError::ProgramError(ref lucetc_err)
            | ScriptError::ValidationError(ref lucetc_err)
            | ScriptError::CompileError(ref lucetc_err) => match lucetc_err {
                &LucetcError::Unsupported(_) => true,
                _ => false,
            },
            _ => false,
        }
    }
}

pub struct ScriptEnv {
    instances: Vec<(Option<String>, lucet_runtime::InstanceHandle)>,
}

fn program_error(e: LucetcError) -> ScriptError {
    match e {
        LucetcError::WasmValidation(_) => ScriptError::ValidationError(e),
        _ => ScriptError::ProgramError(e),
    }
}

impl ScriptEnv {
    pub fn new() -> Self {
        Self {
            instances: Vec::new(),
        }
    }
    pub fn instantiate(&mut self, module: &[u8], name: &Option<String>) -> Result<(), ScriptError> {
        let bindings = bindings::spec_test_bindings();
        let builder = Compiler::builder()
            .with_cpu_features(CpuFeatures::baseline())
            .with_count_instructions(true);
        let compiler = builder.create(module, &bindings).map_err(program_error)?;

        let dir = tempfile::Builder::new().prefix("codegen").tempdir()?;
        let objfile_path = dir.path().join("a.o");
        let sofile_path = dir.path().join("a.so");

        compiler
            .object_file()
            .map_err(ScriptError::CompileError)?
            .write(&objfile_path)
            .map_err(ScriptError::CodegenError)?;

        let mut cmd_ld = Command::new("ld");
        cmd_ld.arg(objfile_path.clone());
        cmd_ld.arg("-shared");
        cmd_ld.arg("-o");
        cmd_ld.arg(sofile_path.clone());
        let run_ld = cmd_ld.output()?;
        if !run_ld.status.success() {
            let message = format!(
                "ld {:?}: {}",
                objfile_path,
                String::from_utf8_lossy(&run_ld.stderr)
            );

            return Err(ScriptError::LdError(message));
        }

        let lucet_module: Arc<dyn LucetModule> =
            lucet_runtime::DlModule::load(sofile_path).map_err(ScriptError::LoadError)?;

        let lucet_region = MmapRegion::create(
            1,
            &lucet_runtime::Limits::default().with_heap_memory_size(4 * 1024 * 1024 * 1024),
        )
        .expect("valid region");

        let lucet_instance = lucet_region
            .new_instance(lucet_module.clone())
            .map_err(ScriptError::InstantiateError)?;

        self.instances.push((name.clone(), lucet_instance));
        Ok(())
    }

    fn instance_named_mut(
        &mut self,
        name: &Option<String>,
    ) -> Result<&mut (Option<String>, lucet_runtime::InstanceHandle), ScriptError> {
        Ok(match name {
            // None means the last defined module should be used
            None => self
                .instances
                .last_mut()
                .ok_or_else(|| ScriptError::MalformedScript("no defined instances".to_owned()))?,
            Some(ref n) => self
                .instances
                .iter_mut()
                .find(|(iname, _)| *iname == *name)
                .ok_or_else(|| ScriptError::MalformedScript(format!("no instance named {}", n)))?,
        })
    }

    pub fn instance_named(
        &self,
        name: &Option<String>,
    ) -> Result<&lucet_runtime::InstanceHandle, ScriptError> {
        Ok(match name {
            // None means the last defined module should be used
            None => self
                .instances
                .last()
                .map(|(_fst, snd)| snd)
                .ok_or_else(|| ScriptError::MalformedScript("no defined instances".to_owned()))?,
            Some(ref n) => self
                .instances
                .iter()
                .find(|(iname, _)| *iname == *name)
                .map(|(_fst, snd)| snd)
                .ok_or_else(|| ScriptError::MalformedScript(format!("no instance named {}", n)))?,
        })
    }

    pub fn run(
        &mut self,
        name: &Option<String>,
        field: &str,
        args: Vec<Val>,
    ) -> Result<UntypedRetVal, ScriptError> {
        let (_, ref mut inst) = self.instance_named_mut(name)?;
        inst.run(field, &args)
            .and_then(|rr| rr.returned())
            .map_err(ScriptError::RuntimeError)
    }

    pub fn register(&mut self, name: &Option<String>, as_name: &str) -> Result<(), ScriptError> {
        let (ref mut oldname, _) = self.instance_named_mut(name)?;
        *oldname = Some(as_name.to_owned());
        Ok(())
    }

    pub fn delete_last(&mut self) {
        let last_index = self.instances.len() - 1;
        self.instances.remove(last_index);
    }
}
<commit_msg>[lucet-spectest] respect LD environment variable<commit_after>use crate::bindings;
use lucet_runtime::{self, MmapRegion, Module as LucetModule, Region, UntypedRetVal, Val};
use lucetc::{Compiler, CpuFeatures, Error as LucetcError};
use std::io;
use std::process::Command;
use std::sync::Arc;
use thiserror::Error;

#[derive(Debug, Error)]
pub enum ScriptError {
    #[error("Validation error")]
    ValidationError(#[source] LucetcError),
    #[error("Program error")]
    ProgramError(#[source] LucetcError),
    #[error("Compilation error")]
    CompileError(#[source] LucetcError),
    #[error("Codegen error")]
    CodegenError(#[source] LucetcError),
    #[error("Load error")]
    LoadError(#[source] lucet_runtime::Error),
    #[error("Instantiation error")]
    InstantiateError(#[source] lucet_runtime::Error),
    #[error("Runtime error")]
    RuntimeError(#[source] lucet_runtime::Error),
    #[error("Malformed script: {0}")]
    MalformedScript(String),
    #[error("IO error")]
    IoError(#[from] io::Error),
    #[error("run_ld error: {0}")]
    LdError(String),
}

impl ScriptError {
    pub fn unsupported(&self) -> bool {
        match self {
            ScriptError::ProgramError(ref lucetc_err)
            | ScriptError::ValidationError(ref lucetc_err)
            | ScriptError::CompileError(ref lucetc_err) => match lucetc_err {
                &LucetcError::Unsupported(_) => true,
                _ => false,
            },
            _ => false,
        }
    }
}

pub struct ScriptEnv {
    instances: Vec<(Option<String>, lucet_runtime::InstanceHandle)>,
}

fn program_error(e: LucetcError) -> ScriptError {
    match e {
        LucetcError::WasmValidation(_) => ScriptError::ValidationError(e),
        _ => ScriptError::ProgramError(e),
    }
}

impl ScriptEnv {
    pub fn new() -> Self {
        Self {
            instances: Vec::new(),
        }
    }
    pub fn instantiate(&mut self, module: &[u8], name: &Option<String>) -> Result<(), ScriptError> {
        let bindings = bindings::spec_test_bindings();
        let builder = Compiler::builder()
            .with_cpu_features(CpuFeatures::baseline())
            .with_count_instructions(true);
        let compiler = builder.create(module, &bindings).map_err(program_error)?;

        let dir = tempfile::Builder::new().prefix("codegen").tempdir()?;
        let objfile_path = dir.path().join("a.o");
        let sofile_path = dir.path().join("a.so");

        compiler
            .object_file()
            .map_err(ScriptError::CompileError)?
            .write(&objfile_path)
            .map_err(ScriptError::CodegenError)?;

        let mut cmd_ld = Command::new(std::env::var("LD").unwrap_or("ld".to_string()));
        cmd_ld.arg(objfile_path.clone());
        cmd_ld.arg("-shared");
        cmd_ld.arg("-o");
        cmd_ld.arg(sofile_path.clone());
        let run_ld = cmd_ld.output()?;
        if !run_ld.status.success() {
            let message = format!(
                "ld {:?}: {}",
                objfile_path,
                String::from_utf8_lossy(&run_ld.stderr)
            );

            return Err(ScriptError::LdError(message));
        }

        let lucet_module: Arc<dyn LucetModule> =
            lucet_runtime::DlModule::load(sofile_path).map_err(ScriptError::LoadError)?;

        let lucet_region = MmapRegion::create(
            1,
            &lucet_runtime::Limits::default().with_heap_memory_size(4 * 1024 * 1024 * 1024),
        )
        .expect("valid region");

        let lucet_instance = lucet_region
            .new_instance(lucet_module.clone())
            .map_err(ScriptError::InstantiateError)?;

        self.instances.push((name.clone(), lucet_instance));
        Ok(())
    }

    fn instance_named_mut(
        &mut self,
        name: &Option<String>,
    ) -> Result<&mut (Option<String>, lucet_runtime::InstanceHandle), ScriptError> {
        Ok(match name {
            // None means the last defined module should be used
            None => self
                .instances
                .last_mut()
                .ok_or_else(|| ScriptError::MalformedScript("no defined instances".to_owned()))?,
            Some(ref n) => self
                .instances
                .iter_mut()
                .find(|(iname, _)| *iname == *name)
                .ok_or_else(|| ScriptError::MalformedScript(format!("no instance named {}", n)))?,
        })
    }

    pub fn instance_named(
        &self,
        name: &Option<String>,
    ) -> Result<&lucet_runtime::InstanceHandle, ScriptError> {
        Ok(match name {
            // None means the last defined module should be used
            None => self
                .instances
                .last()
                .map(|(_fst, snd)| snd)
                .ok_or_else(|| ScriptError::MalformedScript("no defined instances".to_owned()))?,
            Some(ref n) => self
                .instances
                .iter()
                .find(|(iname, _)| *iname == *name)
                .map(|(_fst, snd)| snd)
                .ok_or_else(|| ScriptError::MalformedScript(format!("no instance named {}", n)))?,
        })
    }

    pub fn run(
        &mut self,
        name: &Option<String>,
        field: &str,
        args: Vec<Val>,
    ) -> Result<UntypedRetVal, ScriptError> {
        let (_, ref mut inst) = self.instance_named_mut(name)?;
        inst.run(field, &args)
            .and_then(|rr| rr.returned())
            .map_err(ScriptError::RuntimeError)
    }

    pub fn register(&mut self, name: &Option<String>, as_name: &str) -> Result<(), ScriptError> {
        let (ref mut oldname, _) = self.instance_named_mut(name)?;
        *oldname = Some(as_name.to_owned());
        Ok(())
    }

    pub fn delete_last(&mut self) {
        let last_index = self.instances.len() - 1;
        self.instances.remove(last_index);
    }
}
<|endoftext|>


<commit_before>use std::cmp::Ordering;

use libc::{size_t, c_int, c_uint};

// Bounded package merge algorithm, based on the paper
// "A Fast and Space-Economical Algorithm for Length-Limited Coding
// Jyrki Katajainen, Alistair Moffat, Andrew Turpin".

/// Nodes forming chains.
#[repr(C)]
pub struct Node {
  weight: size_t,     // Total weight (symbol count) of this chain.
  tail: *const Node,  // Previous node(s) of this chain, or 0 if none.
  count: c_int,       // Leaf symbol index, or number of leaves before this chain.
}

#[repr(C)]
pub struct Leaf {
  weight: size_t,     // Total weight (symbol count) of this chain.
  count: c_int,       // Leaf symbol index, or number of leaves before this chain.
}

/// Memory pool for nodes.
#[repr(C)]
pub struct NodePool {
  next: *const Node,   // Pointer to a possibly free node in the pool.
}

/// Initializes a chain node with the given values and marks it as in use.
#[no_mangle]
#[allow(non_snake_case)]
pub extern fn InitNode(weight: size_t, count: c_int, tail: *const Node, node_ptr: *mut Node) {
    let node = unsafe {
        assert!(!node_ptr.is_null());
        &mut *node_ptr
    };

    node.weight = weight;
    node.count = count;
    node.tail = tail;
}

/// Converts result of boundary package-merge to the bitlengths. The result in the
/// last chain of the last list contains the amount of active leaves in each list.
/// chain: Chain to extract the bit length from (last chain from last list).
#[no_mangle]
#[allow(non_snake_case)]
pub extern fn ExtractBitLengths(chain: *const Node, leaves: *const Leaf, bitlengths: *mut c_uint) {
    let mut counts = [0; 16];
    let mut end = 16;
    let mut ptr = 15;
    let mut value = 1;

    let mut node_ptr = chain;
    while !node_ptr.is_null() {
        let node = unsafe {
           &*node_ptr
        };

        end -= 1;
        counts[end] = node.count;

        node_ptr = node.tail;
    }

    let mut val = counts[15];
    while ptr >= end {
        while val > counts[ptr - 1] {
            unsafe {
                let leaf = &*leaves.offset((val - 1) as isize);
                *bitlengths.offset(leaf.count as isize) = value;
            }
            val -= 1;
        }
        ptr -= 1;
        value += 1;
    }
}

struct N {
    weight: size_t,
    leaf_count: c_int,
}

struct L {
    pub weight: size_t,
    pub index: size_t,
}
impl PartialEq for L {
    fn eq(&self, other: &Self) -> bool {
        self.weight == other.weight
    }
}
impl Eq for L { }
impl Ord for L {
    fn cmp(&self, other: &Self) -> Ordering {
        self.weight.cmp(&other.weight)
    }
}
impl PartialOrd for L {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

struct List {
    lookahead1: N,
    lookahead2: N,
    last_active: N,
    next_leaf_index: size_t,
}

pub fn length_limited_code_lengths(frequencies: &[size_t], maxbits: c_int) -> Vec<size_t> {
    let mut leaves = vec![];

    // Count used symbols and place them in the leaves.
    for (i, &freq) in frequencies.iter().enumerate() {
        if freq != 0 {
            leaves.push(L { weight: freq, index: i });
        }
    }

    // Sort the leaves from least frequent to most frequent.
    // Add index into the same variable for stable sorting.
    for leaf in leaves.iter_mut() {
        leaf.weight = (leaf.weight << 9) | leaf.index;
    }
    leaves.sort();
    for leaf in leaves.iter_mut() {
        leaf.weight >>= 9;
    }

    let mut lists = Vec::with_capacity(maxbits as usize);
    for _ in 0..maxbits {
        lists.push(List {
            lookahead1: N { weight: leaves[0].weight, leaf_count: 1 },
            lookahead2: N { weight: leaves[1].weight, leaf_count: 2 },
            last_active: N { weight: leaves[1].weight, leaf_count: 2 },
            next_leaf_index: 2,
        });
    }

    let n = frequencies.len();

    let mut result = vec![0; n];
    result
}

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

    #[test]
    fn test_from_paper_3() {
        let input = [1, 1, 5, 7, 10, 14];
        let output = length_limited_code_lengths(&input, 3);
        let answer = vec![3, 3, 3, 3, 2, 2];
        assert_eq!(output, answer);
    }

    #[test]
    fn test_from_paper_4() {
        let input = [1, 1, 5, 7, 10, 14];
        let output = length_limited_code_lengths(&input, 4);
        let answer = vec![4, 4, 3, 2, 2, 2];
        assert_eq!(output, answer);
    }

    // #[test]
    // fn one_test() {
    //     let input = [252, 0, 1, 6, 9, 10, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    //     let output = length_limited_code_lengths(&input, 7);
    //     let answer = vec![1, 0, 6, 4, 3, 3, 3, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    //     assert_eq!(output, answer);
    // }
}

// maxbits: 7
// frequencies: [252, 0, 1, 6, 9, 10, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]
// bitlengths: [1, 0, 6, 4, 3, 3, 3, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]
// maxbits: 7
// frequencies: [10, 0, 1, 6, 9, 4, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, ]
// bitlengths: [3, 0, 6, 4, 3, 4, 4, 5, 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, ]
// maxbits: 7
// frequencies: [4, 0, 1, 6, 9, 10, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, ]
// bitlengths: [4, 0, 6, 4, 3, 3, 4, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, ]
// maxbits: 7
// frequencies: [4, 0, 1, 6, 9, 4, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 1, 26, 0, ]
// bitlengths: [4, 0, 6, 4, 3, 4, 4, 4, 5, 0, 0, 0, 0, 0, 0, 0, 6, 1, 0, ]
// maxbits: 7
// frequencies: [19, 0, 1, 6, 9, 10, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, ]
// bitlengths: [2, 0, 6, 3, 3, 2, 3, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, ]
// maxbits: 7
// frequencies: [8, 0, 1, 6, 9, 4, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, ]
// bitlengths: [3, 0, 5, 3, 2, 3, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, ]
// maxbits: 7
// frequencies: [4, 0, 1, 6, 9, 10, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, ]
// bitlengths: [4, 0, 6, 3, 2, 2, 3, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 5, 4, ]
// maxbits: 7
// frequencies: [4, 0, 1, 6, 9, 4, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, ]
// bitlengths: [3, 0, 6, 3, 2, 3, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 6, 4, 4, ]
// maxbits: 15
// frequencies: [0, 0, 0, 0, 0, 0, 18, 0, 6, 0, 12, 2, 14, 9, 27, 15, 23, 15, 17, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]
// bitlengths: [0, 0, 0, 0, 0, 0, 3, 0, 5, 0, 4, 6, 4, 4, 3, 4, 3, 3, 3, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]
<commit_msg>Get the boundary package merge working<commit_after>use std::cmp::Ordering;

use libc::{size_t, c_int, c_uint};

// Bounded package merge algorithm, based on the paper
// "A Fast and Space-Economical Algorithm for Length-Limited Coding
// Jyrki Katajainen, Alistair Moffat, Andrew Turpin".

/// Nodes forming chains.
#[repr(C)]
pub struct Node {
  weight: size_t,     // Total weight (symbol count) of this chain.
  tail: *const Node,  // Previous node(s) of this chain, or 0 if none.
  count: c_int,       // Leaf symbol index, or number of leaves before this chain.
}

#[repr(C)]
pub struct Leaf {
  weight: size_t,     // Total weight (symbol count) of this chain.
  count: c_int,       // Leaf symbol index, or number of leaves before this chain.
}

/// Memory pool for nodes.
#[repr(C)]
pub struct NodePool {
  next: *const Node,   // Pointer to a possibly free node in the pool.
}

/// Initializes a chain node with the given values and marks it as in use.
#[no_mangle]
#[allow(non_snake_case)]
pub extern fn InitNode(weight: size_t, count: c_int, tail: *const Node, node_ptr: *mut Node) {
    let node = unsafe {
        assert!(!node_ptr.is_null());
        &mut *node_ptr
    };

    node.weight = weight;
    node.count = count;
    node.tail = tail;
}

/// Converts result of boundary package-merge to the bitlengths. The result in the
/// last chain of the last list contains the amount of active leaves in each list.
/// chain: Chain to extract the bit length from (last chain from last list).
#[no_mangle]
#[allow(non_snake_case)]
pub extern fn ExtractBitLengths(chain: *const Node, leaves: *const Leaf, bitlengths: *mut c_uint) {
    let mut counts = [0; 16];
    let mut end = 16;
    let mut ptr = 15;
    let mut value = 1;

    let mut node_ptr = chain;
    while !node_ptr.is_null() {
        let node = unsafe {
           &*node_ptr
        };

        end -= 1;
        counts[end] = node.count;

        node_ptr = node.tail;
    }

    let mut val = counts[15];
    while ptr >= end {
        while val > counts[ptr - 1] {
            unsafe {
                let leaf = &*leaves.offset((val - 1) as isize);
                *bitlengths.offset(leaf.count as isize) = value;
            }
            val -= 1;
        }
        ptr -= 1;
        value += 1;
    }
}

// #[derive(Clone, Copy, Debug)]
#[derive(Clone, Debug)]
struct N {
    weight: size_t,
    leaf_counts: Vec<c_int>,
}

#[derive(Debug)]
struct L {
    pub weight: size_t,
    pub index: size_t,
}
impl PartialEq for L {
    fn eq(&self, other: &Self) -> bool {
        self.weight == other.weight
    }
}
impl Eq for L { }
impl Ord for L {
    fn cmp(&self, other: &Self) -> Ordering {
        self.weight.cmp(&other.weight)
    }
}
impl PartialOrd for L {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

#[derive(Debug)]
struct List {
    lookahead1: N,
    lookahead2: N,
    next_leaf_index: size_t,
}

pub fn length_limited_code_lengths(frequencies: &[size_t], maxbits: c_int) -> Vec<size_t> {
    let mut leaves = vec![];

    // Count used symbols and place them in the leaves.
    for (i, &freq) in frequencies.iter().enumerate() {
        if freq != 0 {
            leaves.push(L { weight: freq, index: i });
        }
    }

    // Sort the leaves from least frequent to most frequent.
    // Add index into the same variable for stable sorting.
    for leaf in leaves.iter_mut() {
        leaf.weight = (leaf.weight << 9) | leaf.index;
    }
    leaves.sort();
    for leaf in leaves.iter_mut() {
        leaf.weight >>= 9;
    }

    let mut lists = Vec::with_capacity(maxbits as usize);
    for _ in 0..maxbits {
        lists.push(List {
            lookahead1: N { weight: leaves[0].weight, leaf_counts: vec![1] },
            lookahead2: N { weight: leaves[1].weight, leaf_counts: vec![2] },
            next_leaf_index: 2,
        });
    }

    // In the last list, 2 * numsymbols - 2 active chains need to be created. Two
    // are already created in the initialization. Each boundary_pm run creates one.
    let num_boundary_pm_runs = 2 * leaves.len() - 4;
    for _ in 0..num_boundary_pm_runs {
        lists = boundary_pm(lists, &leaves);
    }

    let n = frequencies.len();
    let mut result = vec![0; n];

    let mut a = lists.pop().unwrap().lookahead2.leaf_counts.into_iter().rev().peekable();

    let mut bitlength_value = 1;
    while let Some(leaf_count) = a.next() {
        println!("leaf_count = {:?}", leaf_count);
        let next_count = *a.peek().unwrap_or(&0);
        println!("next_count = {:?}", next_count);
        for i in next_count..leaf_count {
            println!("i = {:?}", i);
            println!("leaves[i as usize] = {:?}", leaves[i as usize]);
            result[leaves[i as usize].index as usize] = bitlength_value;
            println!("result = {:?}", result);
        }
        bitlength_value += 1;
    }

    result
}

fn boundary_pm(mut lists: Vec<List>, leaves: &Vec<L>) -> Vec<List> {
    let mut current_list = lists.pop().unwrap();
    if lists.is_empty() && current_list.next_leaf_index == leaves.len() {
        // We've added all the leaves to the lowest list, so we're done here
        lists.push(current_list);
        return lists;
    }

    current_list.lookahead1 = current_list.lookahead2;

    if lists.is_empty() {
        // We're in the lowest list, just add another leaf to the lookaheads
        // There will always be more leaves to be added on level 0 so this is safe.
        let ref next_leaf = leaves[current_list.next_leaf_index];
        current_list.lookahead2 = N {
            weight: next_leaf.weight,
            leaf_counts: vec![current_list.lookahead1.leaf_counts.last().unwrap() + 1],
        };
        current_list.next_leaf_index += 1;
        lists.push(current_list);
    } else {
        // We're at a list other than the lowest list.
        let previous_list = lists.pop().unwrap();
        let weight_sum = previous_list.lookahead1.weight + previous_list.lookahead2.weight;

        if current_list.next_leaf_index < leaves.len() && weight_sum > leaves[current_list.next_leaf_index].weight {
            // The next leaf goes next; counting itself makes the leaf_count increase by one.
            let mut last_leaf_counts = current_list.lookahead1.leaf_counts.clone();
            let mut last_count = last_leaf_counts.pop().unwrap();
            last_count += 1;
            last_leaf_counts.push(last_count);
            current_list.lookahead2 = N {
                weight: leaves[current_list.next_leaf_index].weight,
                leaf_counts: last_leaf_counts,
            };
            current_list.next_leaf_index += 1;
            lists.push(previous_list);
            lists.push(current_list);
        } else {
            // Make a tree from the lookaheads from the previous list; that goes next.
            // This is not a leaf node, so the leaf count stays the same.
            let mut last_leaf_counts = previous_list.lookahead2.leaf_counts.clone();
            last_leaf_counts.push(*current_list.lookahead1.leaf_counts.last().unwrap());
            current_list.lookahead2 = N {
                weight: weight_sum,
                leaf_counts: last_leaf_counts,
            };
            // The previous list needs two new lookahead nodes.
            lists.push(previous_list);
            lists = boundary_pm(lists, leaves);
            lists = boundary_pm(lists, leaves);
            lists.push(current_list);
        }
    }

    lists
}

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

    #[test]
    fn test_from_paper_3() {
        let input = [1, 1, 5, 7, 10, 14];
        let output = length_limited_code_lengths(&input, 3);
        let answer = vec![3, 3, 3, 3, 2, 2];
        assert_eq!(output, answer);
    }

    #[test]
    fn test_from_paper_4() {
        let input = [1, 1, 5, 7, 10, 14];
        let output = length_limited_code_lengths(&input, 4);
        let answer = vec![4, 4, 3, 2, 2, 2];
        assert_eq!(output, answer);
    }

    // #[test]
    // fn one_test() {
    //     let input = [252, 0, 1, 6, 9, 10, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    //     let output = length_limited_code_lengths(&input, 7);
    //     let answer = vec![1, 0, 6, 4, 3, 3, 3, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    //     assert_eq!(output, answer);
    // }
}

// maxbits: 7
// frequencies: [252, 0, 1, 6, 9, 10, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]
// bitlengths: [1, 0, 6, 4, 3, 3, 3, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]
// maxbits: 7
// frequencies: [10, 0, 1, 6, 9, 4, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, ]
// bitlengths: [3, 0, 6, 4, 3, 4, 4, 5, 6, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, ]
// maxbits: 7
// frequencies: [4, 0, 1, 6, 9, 10, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, ]
// bitlengths: [4, 0, 6, 4, 3, 3, 4, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, ]
// maxbits: 7
// frequencies: [4, 0, 1, 6, 9, 4, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 1, 26, 0, ]
// bitlengths: [4, 0, 6, 4, 3, 4, 4, 4, 5, 0, 0, 0, 0, 0, 0, 0, 6, 1, 0, ]
// maxbits: 7
// frequencies: [19, 0, 1, 6, 9, 10, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, ]
// bitlengths: [2, 0, 6, 3, 3, 2, 3, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, ]
// maxbits: 7
// frequencies: [8, 0, 1, 6, 9, 4, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, ]
// bitlengths: [3, 0, 5, 3, 2, 3, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, ]
// maxbits: 7
// frequencies: [4, 0, 1, 6, 9, 10, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, ]
// bitlengths: [4, 0, 6, 3, 2, 2, 3, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 5, 4, ]
// maxbits: 7
// frequencies: [4, 0, 1, 6, 9, 4, 6, 3, 2, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, ]
// bitlengths: [3, 0, 6, 3, 2, 3, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 6, 4, 4, ]
// maxbits: 15
// frequencies: [0, 0, 0, 0, 0, 0, 18, 0, 6, 0, 12, 2, 14, 9, 27, 15, 23, 15, 17, 8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]
// bitlengths: [0, 0, 0, 0, 0, 0, 3, 0, 5, 0, 4, 6, 4, 4, 3, 4, 3, 3, 3, 4, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]
<|endoftext|>


<commit_before>use Endpoint;
use PageableEndpoint;
use Pager;
use client::Client;
use response;

#[derive(Serialize, Debug, Clone)]
pub struct GetFullEntry {
	pub id: usize,
}

impl Endpoint for GetFullEntry {
	type ResponseType = response::info::Fullentry;
	#[doc(hidden)]
	const URL: &'static str = "info/fullentry";
}

#[derive(Serialize, Debug, Clone)]
pub struct GetEntry {
	pub id: usize,
}

impl Endpoint for GetEntry {
	type ResponseType = response::info::GetEntry;
	#[doc(hidden)]
	const URL: &'static str = "info/entry";
}

#[derive(Serialize, Debug, Clone)]
pub struct GetNames {
	pub id: usize,
}

#[derive(Serialize, Debug, Clone)]
pub struct GetGate {
	pub id: usize,
}

#[derive(Serialize, Debug, Clone)]
pub struct GetLang {
	pub id: usize,
}

#[derive(Serialize, Debug, Clone)]
pub struct GetSeason {
	pub id: usize,
}

#[derive(Serialize, Debug, Clone)]
pub struct GetGroups {
	pub id: usize,
}

#[derive(Serialize, Debug, Clone)]
pub struct GetPublisher {
	pub id: usize,
}

#[derive(Serialize, Debug, Clone)]
pub struct GetListinfo {
	pub id: usize,
	pub p: Option<i64>,
	pub limit: Option<i64>,
}

#[derive(Serialize, Debug, Clone)]
pub struct GetComments {
	pub id: usize,
	pub p: Option<usize>,
	pub limit: Option<usize>,
	pub sort: Option<String>,
}

impl Endpoint for GetComments {
	type ResponseType = Vec<response::info::Comment>;
	#[doc(hidden)]
	const URL: &'static str = "info/comments";
}

impl PageableEndpoint for GetComments {
	fn pager(self, client: Client) -> Pager<GetComments>
	{
		debug!("new pager with data: {:?}", self);
		Pager::new(client, self, Some(0), Some(3))
	}

	fn page_mut(&mut self) -> &mut Option<usize>
	{
		&mut self.p
	}

	fn limit_mut(&mut self) -> &mut Option<usize>
	{
		&mut self.limit
	}
}

#[derive(Serialize, Debug, Clone)]
pub struct GetRelations {
	pub info_id: usize,
	pub is_h: Option<bool>,
}

#[derive(Serialize, Debug, Clone)]
pub struct EntryTags {
	pub id: usize,
}

#[derive(Serialize, Debug, Clone)]
pub struct GetTranslatorgroup {
	pub id: usize,
}

#[derive(Serialize, Debug, Clone)]
pub struct GetIndustry {
	pub id: usize,
}

#[derive(Serialize, Debug, Clone)]
pub struct SetUserInfo {
	pub id: usize,
	/// since 'type' is a rust keyword, this parameter is renamed
	#[serde(rename = "type")]
	pub type_: String,
}
<commit_msg>add shortcut constructor<commit_after>use Endpoint;
use PageableEndpoint;
use Pager;
use client::Client;
use response;

#[derive(Serialize, Debug, Clone)]
pub struct GetFullEntry {
	pub id: usize,
}

impl Endpoint for GetFullEntry {
	type ResponseType = response::info::Fullentry;
	#[doc(hidden)]
	const URL: &'static str = "info/fullentry";
}

impl GetFullEntry {
	pub fn with_default(id: usize) -> Self {
		Self {
			id: id as usize
		}
	}
}

#[derive(Serialize, Debug, Clone)]
pub struct GetEntry {
	pub id: usize,
}

impl Endpoint for GetEntry {
	type ResponseType = response::info::GetEntry;
	#[doc(hidden)]
	const URL: &'static str = "info/entry";
}

impl GetEntry {
	pub fn with_default(id: usize) -> Self {
		Self {
			id: id as usize
		}
	}
}

#[derive(Serialize, Debug, Clone)]
pub struct GetNames {
	pub id: usize,
}

#[derive(Serialize, Debug, Clone)]
pub struct GetGate {
	pub id: usize,
}

#[derive(Serialize, Debug, Clone)]
pub struct GetLang {
	pub id: usize,
}

#[derive(Serialize, Debug, Clone)]
pub struct GetSeason {
	pub id: usize,
}

#[derive(Serialize, Debug, Clone)]
pub struct GetGroups {
	pub id: usize,
}

#[derive(Serialize, Debug, Clone)]
pub struct GetPublisher {
	pub id: usize,
}

#[derive(Serialize, Debug, Clone)]
pub struct GetListinfo {
	pub id: usize,
	pub p: Option<i64>,
	pub limit: Option<i64>,
}

#[derive(Serialize, Debug, Clone)]
pub struct GetComments {
	pub id: usize,
	pub p: Option<usize>,
	pub limit: Option<usize>,
	pub sort: Option<String>,
}

impl Endpoint for GetComments {
	type ResponseType = Vec<response::info::Comment>;
	#[doc(hidden)]
	const URL: &'static str = "info/comments";
}

impl PageableEndpoint for GetComments {
	fn pager(self, client: Client) -> Pager<GetComments>
	{
		debug!("new pager with data: {:?}", self);
		Pager::new(client, self, Some(0), Some(3))
	}

	fn page_mut(&mut self) -> &mut Option<usize>
	{
		&mut self.p
	}

	fn limit_mut(&mut self) -> &mut Option<usize>
	{
		&mut self.limit
	}
}

#[derive(Serialize, Debug, Clone)]
pub struct GetRelations {
	pub info_id: usize,
	pub is_h: Option<bool>,
}

#[derive(Serialize, Debug, Clone)]
pub struct EntryTags {
	pub id: usize,
}

#[derive(Serialize, Debug, Clone)]
pub struct GetTranslatorgroup {
	pub id: usize,
}

#[derive(Serialize, Debug, Clone)]
pub struct GetIndustry {
	pub id: usize,
}

#[derive(Serialize, Debug, Clone)]
pub struct SetUserInfo {
	pub id: usize,
	/// since 'type' is a rust keyword, this parameter is renamed
	#[serde(rename = "type")]
	pub type_: String,
}
<|endoftext|>


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

#![crate_name = "snowmew"]

extern crate "snowmew-core"         as _core;
extern crate "snowmew-graphics"     as _graphics;
extern crate "snowmew-loader"       as _loader;
extern crate "snowmew-physics"      as _physics;
extern crate "snowmew-position"     as _position;
extern crate "snowmew-render-mux"   as _render;
extern crate "snowmew-render-data"  as _render_data;

pub use _core::common::ObjectKey as ObjectKey;

pub mod render {
    pub use _render::RenderFactory as DefaultRender;
    pub use _render_data::{
        RenderData,
        Renderable
    };
    pub use _core::{
        RenderFactory,
        Render,
    };
}

pub mod graphics {
    pub use _graphics::{
        default,
        Drawable,
        Geometry,
        geometry,
        Graphics,
        GraphicsData,
        light,
        Light,
        material,
        Material,
        texture,
        Texture,
        texture_atlas,
        VertexBuffer,
        VertexBufferIter,
    };
}

pub mod position {
    pub use _position::{
        MatrixManager,
        Deltas,
        ComputedPositionGL,
        ComputedPosition,
        CalcPositionsCl,
        PositionData,
        Positions
    };
}

pub mod core {
    pub use _core::{
        DisplayConfig,
        Render,
        IOManager,
    };

    pub use _core::io::{
        InputHandle,
        Window,
    };

    pub use _core::game::Game;
    pub use _core::input;
}

pub mod common {
    pub use _core::common::{
        Common,
        CommonData,
        ObjectKey,
        Duplicate
    };
}

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

#![crate_name = "snowmew"]
#![feature(globs)]

extern crate "snowmew-core"         as _core;
extern crate "snowmew-graphics"     as _graphics;
extern crate "snowmew-loader"       as _loader;
extern crate "snowmew-physics"      as _physics;
extern crate "snowmew-position"     as _position;
extern crate "snowmew-render-mux"   as _render;
extern crate "snowmew-render-data"  as _render_data;

pub use _core::common::ObjectKey as ObjectKey;

pub mod render {
    pub use _render::RenderFactory as DefaultRender;
    pub use _render_data::{
        RenderData,
        Renderable
    };
    pub use _core::{
        RenderFactory,
        Render,
    };
}

pub mod graphics {
    pub use _graphics::{
        default,
        Drawable,
        Geometry,
        geometry,
        Graphics,
        GraphicsData,
        light,
        Light,
        material,
        Material,
        texture,
        Texture,
        texture_atlas,
        VertexBuffer,
        VertexBufferIter,
    };
}

pub mod position {
    pub use _position::{
        MatrixManager,
        Deltas,
        ComputedPositionGL,
        ComputedPosition,
        CalcPositionsCl,
        PositionData,
        Positions
    };
}

pub mod core {
    pub use _core::{
        DisplayConfig,
        Render,
        IOManager,
    };

    pub use _core::io::{
        InputHandle,
        Window,
    };

    pub use _core::game::Game;
}

pub mod common {
    pub use _core::common::{
        Common,
        CommonData,
        ObjectKey,
        Duplicate
    };
}

pub mod config  {
    pub use _core::SnowmewConfig as SnowmewConfig;
}

pub mod input {
    pub use _core::input::*;
    pub use _core::input_integrator::{
        InputIntegrator,
        InputIntegratorGameData,
        InputIntegratorState,
    };
    pub use _core::input_integrator::input_integrator as integrator;
}<|endoftext|>


<commit_before>use std::env;

fn main() {
    let mut newline = true;
    for arg in env::args().skip(1) {
        if arg == "-n" {
            newline = false;
            continue;
        }
        print!("{} ", arg);
    }
    if newline {
        print!("\n");
    }
}
<commit_msg>Fix compile error<commit_after>use std::env;

fn main() {
    let mut newline = true;
    for arg in env::args().skip(1) {
        if *arg == "-n" {
            newline = false;
        } else {
            print!("{} ", arg);
        }
    }
    if newline {
        print!("\n");
    }
}
<|endoftext|>