<commit_before>//! Provides an interface to output sound to the user's speakers.
//!
//! It consists of two main types: `SoundData` is just raw sound data,
//! and a `Source` is a `SoundData` connected to a particular sound
//! channel.

use std::fmt;
use std::io;
use std::io::Read;
use std::path;

use std::sync::Arc;

use mint;
use rodio;

use context::Context;
use filesystem;
use GameError;
use GameResult;

/// A struct that contains all information for tracking sound info.
///
/// You generally don't have to create this yourself, it will be part
/// of your `Context` object.
pub struct AudioContext {
    device: rodio::Device,
}

impl AudioContext {
    /// Create new AudioContext.
    pub fn new() -> GameResult<AudioContext> {
        let device = rodio::default_output_device().ok_or_else(|| {
            GameError::AudioError(String::from(
                "Could not initialize sound system (for some reason)",
            ))
        })?;
        Ok(AudioContext { device: device })
    }
}

impl fmt::Debug for AudioContext {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "<AudioContext: {:p}>", self)
    }
}

/// Static sound data stored in memory.
/// It is Arc'ed, so cheap to clone.
#[derive(Clone, Debug)]
pub struct SoundData(Arc<[u8]>);

impl SoundData {
    /// Create a new SoundData from the file at the given path.
    pub fn new<P: AsRef<path::Path>>(context: &mut Context, path: P) -> GameResult<Self> {
        let path = path.as_ref();
        let file = &mut filesystem::open(context, path)?;
        SoundData::from_read(file)
    }

    /// Copies the data in the given slice into a new SoundData object.
    pub fn from_bytes(data: &[u8]) -> Self {
        SoundData(Arc::from(data))
    }

    /// Creates a SoundData from any Read object; this involves
    /// copying it into a buffer.
    pub fn from_read<R>(reader: &mut R) -> GameResult<Self>
    where
        R: Read,
    {
        let mut buffer = Vec::new();
        let _ = reader.read_to_end(&mut buffer)?;

        Ok(SoundData::from(buffer))
    }
}

impl From<Arc<[u8]>> for SoundData {
    #[inline]
    fn from(arc: Arc<[u8]>) -> Self {
        SoundData(arc)
    }
}

impl From<Vec<u8>> for SoundData {
    fn from(v: Vec<u8>) -> Self {
        SoundData(Arc::from(v))
    }
}

impl From<Box<[u8]>> for SoundData {
    fn from(b: Box<[u8]>) -> Self {
        SoundData(Arc::from(b))
    }
}

impl AsRef<[u8]> for SoundData {
    #[inline]
    fn as_ref(&self) -> &[u8] {
        self.0.as_ref()
    }
}

/// A source of audio data connected to a particular `Channel`.
/// Will stop playing when dropped.
// TODO: Check and see if this matches Love2d's semantics!
// Eventually it might read from a streaming decoder of some kind,
// but for now it is just an in-memory SoundData structure.
// The source of a rodio decoder must be Send, which something
// that contains a reference to a ZipFile is not, so we are going
// to just slurp all the data into memory for now.
// There's really a lot of work that needs to be done here, since
// rodio has gotten better (if still somewhat arcane) and our filesystem
// code has done the data-slurping-from-zip's for us
// but for now it works.
pub struct Source {
    data: io::Cursor<SoundData>,
    sink: rodio::Sink,
    repeat: bool,
}

impl Source {
    /// Create a new Source from the given file.
    pub fn new<P: AsRef<path::Path>>(context: &mut Context, path: P) -> GameResult<Self> {
        let path = path.as_ref();
        let data = SoundData::new(context, path)?;
        Source::from_data(context, data)
    }

    /// Creates a new Source using the given SoundData object.
    pub fn from_data(context: &mut Context, data: SoundData) -> GameResult<Self> {
        let sink = rodio::Sink::new(&context.audio_context.device);
        let cursor = io::Cursor::new(data);
        Ok(Source {
            sink,
            data: cursor,
            repeat: false,
        })
    }

    /// Plays the Source.
    pub fn play(&self) -> GameResult {
        // Creating a new Decoder each time seems a little messy,
        // since it may do checking and data-type detection that is
        // redundant, but it's not super expensive.
        // See https://github.com/ggez/ggez/issues/98 for discussion
        use rodio::Source;
        let cursor = self.data.clone();
        let decoder = rodio::Decoder::new(cursor)?;
        if self.repeat {
            let repeating = decoder.repeat_infinite();
            self.sink.append(repeating);
        } else {
            self.sink.append(decoder);
        }
        Ok(())
    }

    /// Sets the source to repeat playback infinitely on next `play()`
    pub fn set_repeat(&mut self, repeat: bool) {
        self.repeat = repeat;
    }

    /// Gets whether or not the source is set to repeat.
    pub fn repeat(&self) -> bool {
        self.repeat
    }

    /// Pauses playback
    pub fn pause(&self) {
        self.sink.pause()
    }

    /// Resumes playback
    pub fn resume(&self) {
        self.sink.play()
    }

    /// Stops playback
    pub fn stop(&self) {
        self.sink.stop()
    }

    /// Returns whether or not the source is stopped
    /// -- that is, has no more data to play.
    pub fn stopped(&self) -> bool {
        self.sink.empty()
    }

    /// Gets the current volume
    pub fn volume(&self) -> f32 {
        self.sink.volume()
    }

    /// Sets the current volume
    pub fn set_volume(&mut self, value: f32) {
        self.sink.set_volume(value)
    }

    /// Get whether or not the source is paused
    pub fn paused(&self) -> bool {
        self.sink.is_paused()
    }

    /// Get whether or not the source is playing (ie, not paused
    /// and not stopped)
    pub fn playing(&self) -> bool {
        !self.paused() && !self.stopped()
    }
}

impl fmt::Debug for Source {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "<Audio source: {:p}>", self)
    }
}

/// A source of audio data located in space relative to a listener's ears.
/// Will stop playing when dropped.
pub struct SpatialSource {
    data: io::Cursor<SoundData>,
    sink: rodio::SpatialSink,
    repeat: bool,

    left_ear: mint::Point3<f32>,
    right_ear: mint::Point3<f32>,
    emitter_position: mint::Point3<f32>,
}

impl SpatialSource {
    /// Create a new Source from the given file.
    pub fn new<P: AsRef<path::Path>>(context: &mut Context, path: P) -> GameResult<Self> {
        let path = path.as_ref();
        let data = SoundData::new(context, path)?;
        SpatialSource::from_data(context, data)
    }

    /// Creates a new Source using the given SoundData object.
    pub fn from_data(context: &mut Context, data: SoundData) -> GameResult<Self> {
        let sink = rodio::SpatialSink::new(
            &context.audio_context.device,
            [0.0, 0.0, 0.0],
            [-1.0, 0.0, 0.0],
            [1.0, 0.0, 0.0],
        );

        let cursor = io::Cursor::new(data);

        Ok(SpatialSource {
            sink,
            data: cursor,
            repeat: false,
            left_ear: [-1.0, 0.0, 0.0].into(),
            right_ear: [1.0, 0.0, 0.0].into(),
            emitter_position: [0.0, 0.0, 0.0].into(),
        })
    }

    /// Plays the Source.
    pub fn play(&self) -> GameResult {
        use rodio::Source;
        let cursor = self.data.clone();
        let decoder = rodio::Decoder::new(cursor)?;
        if self.repeat {
            let repeating = decoder.repeat_infinite();
            self.sink.append(repeating);
        } else {
            self.sink.append(decoder);
        }
        Ok(())
    }

    /// Sets the source to repeat playback infinitely on next `play()`
    pub fn set_repeat(&mut self, repeat: bool) {
        self.repeat = repeat;
    }

    /// Gets whether or not the source is set to repeat.
    pub fn repeat(&self) -> bool {
        self.repeat
    }

    /// Pauses playback
    pub fn pause(&self) {
        self.sink.pause()
    }

    /// Resumes playback
    pub fn resume(&self) {
        self.sink.play()
    }

    /// Stops playback
    pub fn stop(&mut self) {
        // `rodio::SpatialSink` does not have a `.stop()` method at
        // the moment. To stop the current sound we drop the old
        // sink and create a new one in its place.
        let device = rodio::default_output_device().unwrap();
        self.sink = rodio::SpatialSink::new(
            &device,
            self.emitter_position.into(),
            self.left_ear.into(),
            self.right_ear.into(),
        );
    }

    /// Returns whether or not the source is stopped
    /// -- that is, has no more data to play.
    pub fn stopped(&self) -> bool {
        self.sink.empty()
    }

    /// Gets the current volume
    pub fn volume(&self) -> f32 {
        self.sink.volume()
    }

    /// Sets the current volume
    pub fn set_volume(&mut self, value: f32) {
        self.sink.set_volume(value)
    }

    /// Get whether or not the source is paused
    pub fn paused(&self) -> bool {
        self.sink.is_paused()
    }

    /// Get whether or not the source is playing (ie, not paused
    /// and not stopped)
    pub fn playing(&self) -> bool {
        !self.paused() && !self.stopped()
    }

    /// Set location of the sound
    pub fn set_position<P>(&mut self, pos: P)
    where
        P: Into<mint::Point3<f32>>,
    {
        self.emitter_position = pos.into();
        self.sink.set_emitter_position(self.emitter_position.into());
    }

    /// Set locations of the listener's ears
    pub fn set_ears<P>(&mut self, left: P, right: P)
    where
        P: Into<mint::Point3<f32>>,
    {
        self.left_ear = left.into();
        self.right_ear = right.into();
        self.sink.set_left_ear_position(self.left_ear.into());
        self.sink.set_right_ear_position(self.right_ear.into());
    }
}

impl fmt::Debug for SpatialSource {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "<Spatial audio source: {:p}>", self)
    }
}
<commit_msg>Add replace/detach/enqueue sound play methods<commit_after>//! Provides an interface to output sound to the user's speakers.
//!
//! It consists of two main types: `SoundData` is just raw sound data,
//! and a `Source` is a `SoundData` connected to a particular sound
//! channel.

use std::fmt;
use std::io;
use std::io::Read;
use std::mem;
use std::path;

use std::sync::Arc;

use mint;
use rodio;

use context::Context;
use filesystem;
use GameError;
use GameResult;

/// A struct that contains all information for tracking sound info.
///
/// You generally don't have to create this yourself, it will be part
/// of your `Context` object.
pub struct AudioContext {
    device: rodio::Device,
}

impl AudioContext {
    /// Create new AudioContext.
    pub fn new() -> GameResult<AudioContext> {
        let device = rodio::default_output_device().ok_or_else(|| {
            GameError::AudioError(String::from(
                "Could not initialize sound system (for some reason)",
            ))
        })?;
        Ok(AudioContext { device: device })
    }
}

impl fmt::Debug for AudioContext {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "<AudioContext: {:p}>", self)
    }
}

/// Static sound data stored in memory.
/// It is Arc'ed, so cheap to clone.
#[derive(Clone, Debug)]
pub struct SoundData(Arc<[u8]>);

impl SoundData {
    /// Create a new SoundData from the file at the given path.
    pub fn new<P: AsRef<path::Path>>(context: &mut Context, path: P) -> GameResult<Self> {
        let path = path.as_ref();
        let file = &mut filesystem::open(context, path)?;
        SoundData::from_read(file)
    }

    /// Copies the data in the given slice into a new SoundData object.
    pub fn from_bytes(data: &[u8]) -> Self {
        SoundData(Arc::from(data))
    }

    /// Creates a SoundData from any Read object; this involves
    /// copying it into a buffer.
    pub fn from_read<R>(reader: &mut R) -> GameResult<Self>
    where
        R: Read,
    {
        let mut buffer = Vec::new();
        let _ = reader.read_to_end(&mut buffer)?;

        Ok(SoundData::from(buffer))
    }
}

impl From<Arc<[u8]>> for SoundData {
    #[inline]
    fn from(arc: Arc<[u8]>) -> Self {
        SoundData(arc)
    }
}

impl From<Vec<u8>> for SoundData {
    fn from(v: Vec<u8>) -> Self {
        SoundData(Arc::from(v))
    }
}

impl From<Box<[u8]>> for SoundData {
    fn from(b: Box<[u8]>) -> Self {
        SoundData(Arc::from(b))
    }
}

impl AsRef<[u8]> for SoundData {
    #[inline]
    fn as_ref(&self) -> &[u8] {
        self.0.as_ref()
    }
}

/// A source of audio data connected to a particular `Channel`.
/// Will stop playing when dropped.
// TODO: Check and see if this matches Love2d's semantics!
// Eventually it might read from a streaming decoder of some kind,
// but for now it is just an in-memory SoundData structure.
// The source of a rodio decoder must be Send, which something
// that contains a reference to a ZipFile is not, so we are going
// to just slurp all the data into memory for now.
// There's really a lot of work that needs to be done here, since
// rodio has gotten better (if still somewhat arcane) and our filesystem
// code has done the data-slurping-from-zip's for us
// but for now it works.
pub struct Source {
    data: io::Cursor<SoundData>,
    sink: rodio::Sink,
    repeat: bool,
}

impl Source {
    /// Create a new Source from the given file.
    pub fn new<P: AsRef<path::Path>>(context: &mut Context, path: P) -> GameResult<Self> {
        let path = path.as_ref();
        let data = SoundData::new(context, path)?;
        Source::from_data(context, data)
    }

    /// Creates a new Source using the given SoundData object.
    pub fn from_data(context: &mut Context, data: SoundData) -> GameResult<Self> {
        let sink = rodio::Sink::new(&context.audio_context.device);
        let cursor = io::Cursor::new(data);
        Ok(Source {
            sink,
            data: cursor,
            repeat: false,
        })
    }

    /// Plays the Source; defaults to `play_restart`
    #[inline(always)]
    pub fn play(&mut self) -> GameResult {
        self.play_restart()
    }

    /// Plays the Source; restarts the sound if currently playing
    pub fn play_restart(&mut self) -> GameResult {
        self.stop();
        self.play_later()
    }

    /// Plays the Source; waits until done if the sound is currently playing
    pub fn play_later(&self) -> GameResult {
        // Creating a new Decoder each time seems a little messy,
        // since it may do checking and data-type detection that is
        // redundant, but it's not super expensive.
        // See https://github.com/ggez/ggez/issues/98 for discussion
        use rodio::Source;
        let cursor = self.data.clone();
        let decoder = rodio::Decoder::new(cursor)?;
        if self.repeat {
            let repeating = decoder.repeat_infinite();
            self.sink.append(repeating);
        } else {
            self.sink.append(decoder);
        }
        Ok(())
    }

    /// Play source "in the background"; cannot be stopped
    pub fn play_detached(&mut self) -> GameResult {
        self.stop();
        self.play_later()?;

        let device = rodio::default_output_device().unwrap();
        let new_sink = rodio::Sink::new(&device);
        let old_sink = mem::replace(&mut self.sink, new_sink);
        old_sink.detach();

        Ok(())
    }

    /// Sets the source to repeat playback infinitely on next `play()`
    pub fn set_repeat(&mut self, repeat: bool) {
        self.repeat = repeat;
    }

    /// Gets whether or not the source is set to repeat.
    pub fn repeat(&self) -> bool {
        self.repeat
    }

    /// Pauses playback
    pub fn pause(&self) {
        self.sink.pause()
    }

    /// Resumes playback
    pub fn resume(&self) {
        self.sink.play()
    }

    /// Stops playback
    pub fn stop(&mut self) {
        // Sinks cannot be reused after calling `.stop()`. See
        // https://github.com/tomaka/rodio/issues/171 for information.
        // To stop the current sound we have to drop the old sink and
        // create a new one in its place.
        // This is most ugly because in order to create a new sink
        // we need a `device`. However, we can only get the default
        // device without having access to a context. Currently that's
        // fine because the `AudioContext` uses the default device too,
        // but it may cause problems in the future if devices become
        // customizable.
        let device = rodio::default_output_device().unwrap();
        self.sink = rodio::Sink::new(&device);
    }

    /// Returns whether or not the source is stopped
    /// -- that is, has no more data to play.
    pub fn stopped(&self) -> bool {
        self.sink.empty()
    }

    /// Gets the current volume
    pub fn volume(&self) -> f32 {
        self.sink.volume()
    }

    /// Sets the current volume
    pub fn set_volume(&mut self, value: f32) {
        self.sink.set_volume(value)
    }

    /// Get whether or not the source is paused
    pub fn paused(&self) -> bool {
        self.sink.is_paused()
    }

    /// Get whether or not the source is playing (ie, not paused
    /// and not stopped)
    pub fn playing(&self) -> bool {
        !self.paused() && !self.stopped()
    }
}

impl fmt::Debug for Source {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "<Audio source: {:p}>", self)
    }
}

/// A source of audio data located in space relative to a listener's ears.
/// Will stop playing when dropped.
pub struct SpatialSource {
    data: io::Cursor<SoundData>,
    sink: rodio::SpatialSink,
    repeat: bool,

    left_ear: mint::Point3<f32>,
    right_ear: mint::Point3<f32>,
    emitter_position: mint::Point3<f32>,
}

impl SpatialSource {
    /// Create a new Source from the given file.
    pub fn new<P: AsRef<path::Path>>(context: &mut Context, path: P) -> GameResult<Self> {
        let path = path.as_ref();
        let data = SoundData::new(context, path)?;
        SpatialSource::from_data(context, data)
    }

    /// Creates a new Source using the given SoundData object.
    pub fn from_data(context: &mut Context, data: SoundData) -> GameResult<Self> {
        let sink = rodio::SpatialSink::new(
            &context.audio_context.device,
            [0.0, 0.0, 0.0],
            [-1.0, 0.0, 0.0],
            [1.0, 0.0, 0.0],
        );

        let cursor = io::Cursor::new(data);

        Ok(SpatialSource {
            sink,
            data: cursor,
            repeat: false,
            left_ear: [-1.0, 0.0, 0.0].into(),
            right_ear: [1.0, 0.0, 0.0].into(),
            emitter_position: [0.0, 0.0, 0.0].into(),
        })
    }

    /// Plays the Source; defaults to `play_restart`
    #[inline(always)]
    pub fn play(&mut self) -> GameResult {
        self.play_restart()
    }

    /// Plays the Source; restarts the sound if currently playing
    pub fn play_restart(&mut self) -> GameResult {
        self.stop();
        self.play_later()
    }

    /// Plays the Source; waits until done if the sound is currently playing
    pub fn play_later(&self) -> GameResult {
        use rodio::Source;
        let cursor = self.data.clone();
        let decoder = rodio::Decoder::new(cursor)?;
        if self.repeat {
            let repeating = decoder.repeat_infinite();
            self.sink.append(repeating);
        } else {
            self.sink.append(decoder);
        }
        Ok(())
    }

    /// Play source "in the background"; cannot be stopped
    pub fn play_detached(&mut self) -> GameResult {
        self.stop();
        self.play_later()?;

        let device = rodio::default_output_device().unwrap();
        let new_sink = rodio::SpatialSink::new(
            &device,
            self.emitter_position.into(),
            self.left_ear.into(),
            self.right_ear.into(),
        );
        let old_sink = mem::replace(&mut self.sink, new_sink);
        old_sink.detach();

        Ok(())
    }

    /// Sets the source to repeat playback infinitely on next `play()`
    pub fn set_repeat(&mut self, repeat: bool) {
        self.repeat = repeat;
    }

    /// Gets whether or not the source is set to repeat.
    pub fn repeat(&self) -> bool {
        self.repeat
    }

    /// Pauses playback
    pub fn pause(&self) {
        self.sink.pause()
    }

    /// Resumes playback
    pub fn resume(&self) {
        self.sink.play()
    }

    /// Stops playback
    pub fn stop(&mut self) {
        // `rodio::SpatialSink` does not have a `.stop()` method at
        // the moment. To stop the current sound we drop the old
        // sink and create a new one in its place.
        // This is most ugly because in order to create a new sink
        // we need a `device`. However, we can only get the default
        // device without having access to a context. Currently that's
        // fine because the `AudioContext` uses the default device too,
        // but it may cause problems in the future if devices become
        // customizable.
        let device = rodio::default_output_device().unwrap();
        self.sink = rodio::SpatialSink::new(
            &device,
            self.emitter_position.into(),
            self.left_ear.into(),
            self.right_ear.into(),
        );
    }

    /// Returns whether or not the source is stopped
    /// -- that is, has no more data to play.
    pub fn stopped(&self) -> bool {
        self.sink.empty()
    }

    /// Gets the current volume
    pub fn volume(&self) -> f32 {
        self.sink.volume()
    }

    /// Sets the current volume
    pub fn set_volume(&mut self, value: f32) {
        self.sink.set_volume(value)
    }

    /// Get whether or not the source is paused
    pub fn paused(&self) -> bool {
        self.sink.is_paused()
    }

    /// Get whether or not the source is playing (ie, not paused
    /// and not stopped)
    pub fn playing(&self) -> bool {
        !self.paused() && !self.stopped()
    }

    /// Set location of the sound
    pub fn set_position<P>(&mut self, pos: P)
    where
        P: Into<mint::Point3<f32>>,
    {
        self.emitter_position = pos.into();
        self.sink.set_emitter_position(self.emitter_position.into());
    }

    /// Set locations of the listener's ears
    pub fn set_ears<P>(&mut self, left: P, right: P)
    where
        P: Into<mint::Point3<f32>>,
    {
        self.left_ear = left.into();
        self.right_ear = right.into();
        self.sink.set_left_ear_position(self.left_ear.into());
        self.sink.set_right_ear_position(self.right_ear.into());
    }
}

impl fmt::Debug for SpatialSource {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "<Spatial audio source: {:p}>", self)
    }
}
<|endoftext|>


<commit_before>extern crate libc;
#[allow(dead_code)]
use statement::Statement;
use statement::CassStatement;
use error::CassError;
use error::Error;
use consistency::CassConsistency;

use libc::c_uint;

pub enum BatchType {
  LOGGED=0,
  UNLOGGED=1,
  COUNTER=2,
}

#[allow(dead_code)]
pub struct Batch {
  pub cass_batch:*mut CassBatch,
}

#[allow(dead_code)]
impl Batch {
  pub fn new(batch_type: BatchType) -> Batch {unsafe{
    Batch{cass_batch:cass_batch_new(batch_type as u32)}
  }}

  pub fn free(&self) {unsafe{
    cass_batch_free(self.cass_batch);
  }}

  pub fn add_statement(&mut self, statement: Statement) -> Error {unsafe{
    Error{cass_error:cass_batch_add_statement(self.cass_batch,statement.cass_statement)}
  }}

  pub fn set_consistency(&mut self, consistency: CassConsistency) -> Error {unsafe{
    Error{cass_error:cass_batch_set_consistency(self.cass_batch,consistency)}
  }}

}

impl Drop for Batch {
  fn drop(&mut self) {
    self.free();
  }
}

  pub enum CassBatch { }
  type CassBatchType = c_uint;

  #[link(name = "cassandra")]
  extern "C" {
    fn cass_batch_new(_type: CassBatchType) -> *mut CassBatch;
    fn cass_batch_free(batch: *mut CassBatch);
    fn cass_batch_set_consistency(batch: *mut CassBatch, consistency: CassConsistency) -> CassError;
    fn cass_batch_add_statement(batch: *mut CassBatch, statement: *mut CassStatement) -> CassError;
  }

  #[cfg(test)]
  mod tests {
    pub use batch::BatchType;
    #[test]
    fn new() {
      super::Batch::new(BatchType::LOGGED);
      super::Batch::new(BatchType::UNLOGGED);
      super::Batch::new(BatchType::COUNTER);
    }
}

<commit_msg>fixed formatting<commit_after>extern crate libc;
#[allow(dead_code)]
use statement::Statement;
use statement::CassStatement;
use error::CassError;
use error::Error;
use consistency::CassConsistency;

use libc::c_uint;

pub enum BatchType {
  LOGGED=0,
  UNLOGGED=1,
  COUNTER=2,
}

#[allow(dead_code)]
pub struct Batch {
  pub cass_batch:*mut CassBatch,
}

#[allow(dead_code)]
impl Batch {
  pub fn new(batch_type: BatchType) -> Batch {unsafe{
    Batch{cass_batch:cass_batch_new(batch_type as u32)}
  }}

  pub fn free(&self) {unsafe{
    cass_batch_free(self.cass_batch);
  }}

  pub fn add_statement(&mut self, statement: Statement) -> Error {unsafe{
    Error{cass_error:cass_batch_add_statement(self.cass_batch,statement.cass_statement)}
  }}

  pub fn set_consistency(&mut self, consistency: CassConsistency) -> Error {unsafe{
    Error{cass_error:cass_batch_set_consistency(self.cass_batch,consistency)}
  }}

}

impl Drop for Batch {
  fn drop(&mut self) {
    self.free();
  }
}

pub enum CassBatch { }
type CassBatchType = c_uint;

#[link(name = "cassandra")]
extern "C" {
  fn cass_batch_new(_type: CassBatchType) -> *mut CassBatch;
  fn cass_batch_free(batch: *mut CassBatch);
  fn cass_batch_set_consistency(batch: *mut CassBatch, consistency: CassConsistency) -> CassError;
  fn cass_batch_add_statement(batch: *mut CassBatch, statement: *mut CassStatement) -> CassError;
}

#[cfg(test)]
mod tests {
  pub use batch::BatchType;

  #[test]
  fn new() {
    super::Batch::new(BatchType::LOGGED);
    super::Batch::new(BatchType::UNLOGGED);
    super::Batch::new(BatchType::COUNTER);
  }
}

<|endoftext|>


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

use serde_json::value::Value as Json;

use crate::error::RenderError;

#[derive(Clone, Debug)]
pub enum BlockParamHolder {
    // a reference to certain context value
    Path(Vec<String>),
    // an actual value holder
    Value(Json),
}

impl BlockParamHolder {
    pub fn value(v: Json) -> BlockParamHolder {
        BlockParamHolder::Value(v)
    }

    pub fn path(r: Vec<String>) -> BlockParamHolder {
        BlockParamHolder::Path(r)
    }
}

/// A map holds block parameters. The parameter can be either a value or a reference
#[derive(Clone, Debug, Default)]
pub struct BlockParams<'reg> {
    data: BTreeMap<&'reg str, BlockParamHolder>,
}

impl<'reg> BlockParams<'reg> {
    /// Create a empty block parameter map.
    pub fn new() -> BlockParams<'reg> {
        BlockParams::default()
    }

    /// Add a path reference as the parameter. The `path` is a vector of path
    /// segments the relative to current block's base path.
    pub fn add_path(&mut self, k: &'reg str, path: Vec<String>) -> Result<(), RenderError> {
        self.data.insert(k, BlockParamHolder::path(path));
        Ok(())
    }

    /// Add a value as parameter.
    pub fn add_value(&mut self, k: &'reg str, v: Json) -> Result<(), RenderError> {
        self.data.insert(k, BlockParamHolder::value(v));
        Ok(())
    }

    /// Get a block parameter by its name.
    pub fn get(&self, k: &str) -> Option<&BlockParamHolder> {
        self.data.get(k)
    }
}

/// A data structure holds contextual data for current block scope.
#[derive(Debug, Clone, Default)]
pub struct BlockContext<'reg: 'rc, 'rc> {
    /// the base_path of current block scope
    base_path: Vec<String>,
    /// the base_value of current block scope, not in use for now
    base_value: Option<&'rc Json>,
    /// current block context variables
    block_params: BlockParams<'reg>,
    /// local variables in current context
    local_variables: BTreeMap<String, Json>,
}

impl<'reg: 'rc, 'rc> BlockContext<'reg, 'rc> {
    /// create a new `BlockContext` with default data
    pub fn new() -> BlockContext<'reg, 'rc> {
        BlockContext::default()
    }

    /// set a local variable into current scope
    pub fn set_local_var(&mut self, name: String, value: Json) {
        self.local_variables.insert(name, value);
    }

    /// get a local variable from current scope
    pub fn get_local_var(&self, name: &str) -> Option<&Json> {
        self.local_variables.get(&format!("@{}", name))
    }

    /// borrow a reference to current scope's base path
    /// all paths inside this block will be relative to this path
    pub fn base_path(&self) -> &Vec<String> {
        &self.base_path
    }

    /// borrow a mutable reference to the base path
    pub fn base_path_mut(&mut self) -> &mut Vec<String> {
        &mut self.base_path
    }

    // TODO: disable for lifetime issue
    // pub fn base_value(&self) -> Option<&'rc Json> {
    //     self.base_value
    // }

    // pub fn base_value_mut(&mut self) -> &mut Option<&'rc Json> {
    //     &mut self.base_value
    // }

    // pub fn set_base_value(&mut self, value: &'rc Json) {
    //     self.base_value = Some(value);
    // }

    /// Get a block paramteter from this block.
    /// Block paramters needed to be supported by the block helper.
    /// The typical syntax for block parameter is:
    ///
    /// ```no_run
    /// {{#myblock param1 as |block_param1|}}
    ///    ...
    /// {{/myblock}}
    /// ```
    ///
    pub fn get_block_param(&self, block_param_name: &str) -> Option<&BlockParamHolder> {
        self.block_params.get(block_param_name)
    }

    /// Set a block paramter into this block.
    pub fn set_block_params(&mut self, block_params: BlockParams<'reg>) {
        self.block_params = block_params;
    }
}
<commit_msg>(fix) do not test handlebars block<commit_after>use std::collections::BTreeMap;

use serde_json::value::Value as Json;

use crate::error::RenderError;

#[derive(Clone, Debug)]
pub enum BlockParamHolder {
    // a reference to certain context value
    Path(Vec<String>),
    // an actual value holder
    Value(Json),
}

impl BlockParamHolder {
    pub fn value(v: Json) -> BlockParamHolder {
        BlockParamHolder::Value(v)
    }

    pub fn path(r: Vec<String>) -> BlockParamHolder {
        BlockParamHolder::Path(r)
    }
}

/// A map holds block parameters. The parameter can be either a value or a reference
#[derive(Clone, Debug, Default)]
pub struct BlockParams<'reg> {
    data: BTreeMap<&'reg str, BlockParamHolder>,
}

impl<'reg> BlockParams<'reg> {
    /// Create a empty block parameter map.
    pub fn new() -> BlockParams<'reg> {
        BlockParams::default()
    }

    /// Add a path reference as the parameter. The `path` is a vector of path
    /// segments the relative to current block's base path.
    pub fn add_path(&mut self, k: &'reg str, path: Vec<String>) -> Result<(), RenderError> {
        self.data.insert(k, BlockParamHolder::path(path));
        Ok(())
    }

    /// Add a value as parameter.
    pub fn add_value(&mut self, k: &'reg str, v: Json) -> Result<(), RenderError> {
        self.data.insert(k, BlockParamHolder::value(v));
        Ok(())
    }

    /// Get a block parameter by its name.
    pub fn get(&self, k: &str) -> Option<&BlockParamHolder> {
        self.data.get(k)
    }
}

/// A data structure holds contextual data for current block scope.
#[derive(Debug, Clone, Default)]
pub struct BlockContext<'reg: 'rc, 'rc> {
    /// the base_path of current block scope
    base_path: Vec<String>,
    /// the base_value of current block scope, not in use for now
    base_value: Option<&'rc Json>,
    /// current block context variables
    block_params: BlockParams<'reg>,
    /// local variables in current context
    local_variables: BTreeMap<String, Json>,
}

impl<'reg: 'rc, 'rc> BlockContext<'reg, 'rc> {
    /// create a new `BlockContext` with default data
    pub fn new() -> BlockContext<'reg, 'rc> {
        BlockContext::default()
    }

    /// set a local variable into current scope
    pub fn set_local_var(&mut self, name: String, value: Json) {
        self.local_variables.insert(name, value);
    }

    /// get a local variable from current scope
    pub fn get_local_var(&self, name: &str) -> Option<&Json> {
        self.local_variables.get(&format!("@{}", name))
    }

    /// borrow a reference to current scope's base path
    /// all paths inside this block will be relative to this path
    pub fn base_path(&self) -> &Vec<String> {
        &self.base_path
    }

    /// borrow a mutable reference to the base path
    pub fn base_path_mut(&mut self) -> &mut Vec<String> {
        &mut self.base_path
    }

    // TODO: disable for lifetime issue
    // pub fn base_value(&self) -> Option<&'rc Json> {
    //     self.base_value
    // }

    // pub fn base_value_mut(&mut self) -> &mut Option<&'rc Json> {
    //     &mut self.base_value
    // }

    // pub fn set_base_value(&mut self, value: &'rc Json) {
    //     self.base_value = Some(value);
    // }

    /// Get a block paramteter from this block.
    /// Block paramters needed to be supported by the block helper.
    /// The typical syntax for block parameter is:
    ///
    /// ```skip
    /// {{#myblock param1 as |block_param1|}}
    ///    ...
    /// {{/myblock}}
    /// ```
    ///
    pub fn get_block_param(&self, block_param_name: &str) -> Option<&BlockParamHolder> {
        self.block_params.get(block_param_name)
    }

    /// Set a block paramter into this block.
    pub fn set_block_params(&mut self, block_params: BlockParams<'reg>) {
        self.block_params = block_params;
    }
}
<|endoftext|>


<commit_before>//! Helper methods for colors

use crate::types::{Color, ColorComponent};

/// Black color.
pub const BLACK: Color = [0.0, 0.0, 0.0, 1.0];
/// Blue color.
pub const BLUE: Color = [0.0, 0.0, 255.0, 1.0];
/// Cyan color.
pub const CYAN: Color = [0.0, 255.0, 255.0, 1.0];
/// Gray color.
pub const GRAY: Color = [128.0, 128.0, 128.0, 1.0];
/// Green color.
pub const GREEN: Color = [0.0, 128.0, 0.0, 1.0];
/// Lime color.
pub const LIME: Color = [0.0, 255.0, 0.0, 1.0];
/// Magenta color.
pub const MAGENTA: Color = [255.0, 0.0, 255.0, 1.0];
/// Maroon color.
pub const MAROON: Color = [128.0, 0.0, 0.0, 1.0];
/// Navy color.
pub const NAVY: Color = [0.0, 0.0, 128.0, 1.0];
/// Olive color.
pub const OLIVE: Color = [128.0, 128.0, 0.0, 1.0];
/// Purple color.
pub const PURPLE: Color = [128.0, 0.0, 128.0, 1.0];
/// Red color.
pub const RED: Color = [255.0, 0.0, 0.0, 1.0];
/// Silver color.
pub const SILVER: Color = [192.0, 192.0, 192.0, 1.0];
/// Teal color.
pub const TEAL: Color = [0.0, 128.0, 128.0, 1.0];
/// White color.
pub const WHITE: Color = [255.0, 255.0, 255.0, 1.0];
/// Yellow color.
pub const YELLOW: Color = [255.0, 255.0, 0.0, 1.0];
/// Transparent color.
pub const TRANSPARENT: Color = [0.0; 4];

/// Returns a grey color
pub fn grey(f: ColorComponent) -> Color {
    [f, f, f, 1.0]
}

/// Returns a semi-transparent white color
pub fn alpha(f: ColorComponent) -> Color {
    [1.0, 1.0, 1.0, f]
}

/// Converts from hexadecimal color format
pub fn hex(hex: &str) -> Color {
    use read_color::rgb_maybe_a;

    let (rgb, a) = rgb_maybe_a(&mut hex.chars()).unwrap();
    let color = match a {
        None => [rgb[0], rgb[1], rgb[2], 255],
        Some(a) => [rgb[0], rgb[1], rgb[2], a],
    };
    let inv_255 = 1.0f32 / 255.0f32;
    [
        color[0] as f32 * inv_255,
        color[1] as f32 * inv_255,
        color[2] as f32 * inv_255,
        color[3] as f32 * inv_255,
    ]
}

#[inline(always)]
fn component_srgb_to_linear(f: ColorComponent) -> ColorComponent {
    if f <= 0.04045 {
        f / 12.92
    } else {
        ((f + 0.055) / 1.055).powf(2.4)
    }
}

/// Converts gamma (brightness) from sRGB to linear color space.
///
/// sRGB is the default color space for image editors, pictures, internet etc.
/// Linear gamma yields better results when doing math with colors.
pub fn gamma_srgb_to_linear(c: Color) -> Color {
    [
        component_srgb_to_linear(c[0]),
        component_srgb_to_linear(c[1]),
        component_srgb_to_linear(c[2]),
        c[3],
    ]
}

#[inline(always)]
fn component_linear_to_srgb(f: ColorComponent) -> ColorComponent {
    if f <= 0.0031308 {
        f * 12.92
    } else {
        1.055 * f.powf(1.0 / 2.4) - 0.055
    }
}

/// Converts gamma (brightness) of a color from linear color space to sRGB.
///
/// sRGB is the default color space for image editors, pictures, internet etc.
/// Linear gamma yields better results when doing math with colors.
pub fn gamma_linear_to_srgb(c: Color) -> Color {
    [
        component_linear_to_srgb(c[0]),
        component_linear_to_srgb(c[1]),
        component_linear_to_srgb(c[2]),
        c[3],
    ]
}
<commit_msg>Fix: Color components go up to 1.0 (not 255.0)<commit_after>//! Helper methods for colors

use crate::types::{Color, ColorComponent};

/// Black color.
pub const BLACK: Color = [0.0, 0.0, 0.0, 1.0];
/// Blue color.
pub const BLUE: Color = [0.0, 0.0, 1.0, 1.0];
/// Cyan color.
pub const CYAN: Color = [0.0, 1.0, 1.0, 1.0];
/// Gray color.
pub const GRAY: Color = [0.5, 0.5, 0.5, 1.0];
/// Green color.
pub const GREEN: Color = [0.0, 0.5, 0.0, 1.0];
/// Lime color.
pub const LIME: Color = [0.0, 1.0, 0.0, 1.0];
/// Magenta color.
pub const MAGENTA: Color = [1.0, 0.0, 1.0, 1.0];
/// Maroon color.
pub const MAROON: Color = [0.5, 0.0, 0.0, 1.0];
/// Navy color.
pub const NAVY: Color = [0.0, 0.0, 0.5, 1.0];
/// Olive color.
pub const OLIVE: Color = [0.5, 0.5, 0.0, 1.0];
/// Purple color.
pub const PURPLE: Color = [0.5, 0.0, 0.5, 1.0];
/// Red color.
pub const RED: Color = [1.0, 0.0, 0.0, 1.0];
/// Silver color.
pub const SILVER: Color = [0.75, 0.75, 0.75, 1.0];
/// Teal color.
pub const TEAL: Color = [0.0, 0.5, 0.5, 1.0];
/// White color.
pub const WHITE: Color = [1.0, 1.0, 1.0, 1.0];
/// Yellow color.
pub const YELLOW: Color = [1.0, 1.0, 0.0, 1.0];
/// Transparent color.
pub const TRANSPARENT: Color = [0.0; 4];

/// Returns a grey color
/// # Arguments
/// * `f` - The brightness of the color. 0.0 is black, 1.0 is white
pub fn grey(f: ColorComponent) -> Color {
    [f, f, f, 1.0]
}

/// Returns a semi-transparent white color
pub fn alpha(f: ColorComponent) -> Color {
    [1.0, 1.0, 1.0, f]
}

/// Converts from hexadecimal color format
pub fn hex(hex: &str) -> Color {
    use read_color::rgb_maybe_a;

    let (rgb, a) = rgb_maybe_a(&mut hex.chars()).unwrap();
    let color = match a {
        None => [rgb[0], rgb[1], rgb[2], 255],
        Some(a) => [rgb[0], rgb[1], rgb[2], a],
    };
    let inv_255 = 1.0f32 / 255.0f32;
    [
        color[0] as f32 * inv_255,
        color[1] as f32 * inv_255,
        color[2] as f32 * inv_255,
        color[3] as f32 * inv_255,
    ]
}

#[inline(always)]
fn component_srgb_to_linear(f: ColorComponent) -> ColorComponent {
    if f <= 0.04045 {
        f / 12.92
    } else {
        ((f + 0.055) / 1.055).powf(2.4)
    }
}

/// Converts gamma (brightness) from sRGB to linear color space.
///
/// sRGB is the default color space for image editors, pictures, internet etc.
/// Linear gamma yields better results when doing math with colors.
pub fn gamma_srgb_to_linear(c: Color) -> Color {
    [
        component_srgb_to_linear(c[0]),
        component_srgb_to_linear(c[1]),
        component_srgb_to_linear(c[2]),
        c[3],
    ]
}

#[inline(always)]
fn component_linear_to_srgb(f: ColorComponent) -> ColorComponent {
    if f <= 0.0031308 {
        f * 12.92
    } else {
        1.055 * f.powf(1.0 / 2.4) - 0.055
    }
}

/// Converts gamma (brightness) of a color from linear color space to sRGB.
///
/// sRGB is the default color space for image editors, pictures, internet etc.
/// Linear gamma yields better results when doing math with colors.
pub fn gamma_linear_to_srgb(c: Color) -> Color {
    [
        component_linear_to_srgb(c[0]),
        component_linear_to_srgb(c[1]),
        component_linear_to_srgb(c[2]),
        c[3],
    ]
}
<|endoftext|>


<commit_before>const DATA: &'static str = include_str!("../data/input_24.txt");

pub fn main() -> Vec<String> {
    part1();
    vec![]
}

fn part1() {
    let v = DATA.lines().map(|l| l.parse::<u64>().unwrap()).collect::<Vec<u64>>();
    let weight = v.iter().sum::<u64>() / 3;
    let ps = PowerSet::with_prune_condition(&v, |ss| ss.iter().sum::<u64>() > weight);
    let count = ps.filter(|ss| ss.iter().sum::<u64>() == weight)
                  .filter(|ss| ss.len() == 6)
                  .map(|ss| ss.iter().product::<u64>())
                  .collect::<Vec<_>>();
    println!("{:?}", count.iter().min());
}

struct PowerSet<'a, T, F>
    where T: 'a + Copy,
          F: Fn(&[T]) -> bool
{
    stack: Vec<(Vec<T>, &'a [T])>,
    stop: F,
}

impl<'a, T, F> PowerSet<'a, T, F>
    where T: 'a + Copy,
          F: Fn(&[T]) -> bool
{
    // not sure why this doesn't compile
    // expected type parameter, found fn item
    //
    //  fn new(data: &'a [T]) -> PowerSet<'a, T, F> {
    //      PowerSet::with_prune_condition(data, |_| false)
    //  }

    fn with_prune_condition(data: &'a [T], stop: F) -> PowerSet<'a, T, F> {
        let mut stack = Vec::new();
        if let Some((selected, remaining)) = data.split_last() {
            stack.push((vec![*selected], remaining));
            stack.push((vec![], remaining));
        } else {
            stack.push((vec![], data))
        }
        PowerSet {
            stack: stack,
            stop: stop,
        }
    }
}

impl<'a, T, F> Iterator for PowerSet<'a, T, F>
    where T: 'a + Copy,
          F: Fn(&[T]) -> bool
{
    type Item = Vec<T>;

    fn next(&mut self) -> Option<Vec<T>> {
        if let Some((selected, remaining)) = self.stack.pop() {
            if let Some((sel, rem)) = remaining.split_last() {
                if !(self.stop)(&selected) {
                    let mut r = selected.clone();
                    r.push(*sel);
                    self.stack.push((r, rem));
                    self.stack.push((selected, rem));
                }
                self.next()
            } else {
                Some(selected)
            }
        } else {
            None
        }
    }
}
<commit_msg>day 24 part 2<commit_after>const DATA: &'static str = include_str!("../data/input_24.txt");

pub fn main() -> Vec<String> {
    let v = DATA.lines().map(|l| l.parse::<u64>().unwrap()).collect::<Vec<u64>>();
    let weight = v.iter().sum::<u64>() / 3;
    let s1 = min_qe(&v, weight).to_string();

    let weight = v.iter().sum::<u64>() / 4;
    let s2 = min_qe(&v, weight).to_string();
    vec![s1, s2]
}

fn min_qe(data: &[u64], weight: u64) -> u64 {
    let ps = PowerSet::with_prune_condition(&data, |ss| ss.iter().sum::<u64>() > weight);
    let subsets = ps.filter(|ss| ss.iter().sum::<u64>() == weight).collect::<Vec<_>>();
    let size = subsets.iter().map(|ss| ss.len()).min().unwrap();
    subsets.iter()
           .filter(|ss| ss.len() == size)
           .map(|ss| ss.iter().product::<u64>())
           .min()
           .unwrap()
}

struct PowerSet<'a, T, F>
    where T: 'a + Copy,
          F: Fn(&[T]) -> bool
{
    stack: Vec<(Vec<T>, &'a [T])>,
    stop: F,
}

impl<'a, T, F> PowerSet<'a, T, F>
    where T: 'a + Copy,
          F: Fn(&[T]) -> bool
{
    // not sure why this doesn't compile
    // expected type parameter, found fn item
    //
    //  fn new(data: &'a [T]) -> PowerSet<'a, T, F> {
    //      PowerSet::with_prune_condition(data, |_| false)
    //  }

    fn with_prune_condition(data: &'a [T], stop: F) -> PowerSet<'a, T, F> {
        let mut stack = Vec::new();
        if let Some((selected, remaining)) = data.split_last() {
            stack.push((vec![*selected], remaining));
            stack.push((vec![], remaining));
        } else {
            stack.push((vec![], data))
        }
        PowerSet {
            stack: stack,
            stop: stop,
        }
    }
}

impl<'a, T, F> Iterator for PowerSet<'a, T, F>
    where T: 'a + Copy,
          F: Fn(&[T]) -> bool
{
    type Item = Vec<T>;

    fn next(&mut self) -> Option<Vec<T>> {
        if let Some((selected, remaining)) = self.stack.pop() {
            if let Some((sel, rem)) = remaining.split_last() {
                if !(self.stop)(&selected) {
                    let mut r = selected.clone();
                    r.push(*sel);
                    self.stack.push((r, rem));
                    self.stack.push((selected, rem));
                }
                self.next()
            } else {
                Some(selected)
            }
        } else {
            None
        }
    }
}
<|endoftext|>


<commit_before>use job::Job;
use std::default::Default;
use std::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
use std::sync::Mutex;

const INITIAL_SIZE: usize = 1024;

pub struct ThreadDeque {
    jobs: Vec<AtomicPtr<Job>>,
    bottom: AtomicUsize,
    top: AtomicUsize,
    lock: Mutex<()>,
}

impl ThreadDeque {
    pub fn new() -> ThreadDeque {
        ThreadDeque {
            jobs: (0..INITIAL_SIZE).map(|_| AtomicPtr::default()).collect(),
            bottom: AtomicUsize::default(),
            top: AtomicUsize::default(),
            lock: Mutex::new(())
        }
    }

    #[inline]
    pub unsafe fn push(&self, job: *mut Job) {
        let top = self.top.load(Ordering::SeqCst);   // Probably could be "Relaxed"
        self.jobs[top].store(job, Ordering::SeqCst); // Unclear if AtomicPtr is needed here?
        self.top.store(top + 1, Ordering::SeqCst);
    }

    #[inline]
    pub unsafe fn pop(&self) -> bool {
        let top = self.top.load(Ordering::SeqCst);
        let previous = top - 1;
        self.top.store(previous, Ordering::SeqCst);

        let bottom = self.bottom.load(Ordering::SeqCst);
        if bottom > previous {
            self.top.store(top, Ordering::SeqCst);
            let _lock = self.lock.lock().unwrap();
            let bottom = self.bottom.load(Ordering::SeqCst);
            if bottom > previous {
                return false;
            }
            self.top.store(previous, Ordering::SeqCst);
        }

        true
    }

    #[inline]
    pub unsafe fn steal(&self) -> Option<*mut Job> {
        let _lock = self.lock.lock().unwrap();

        let bottom = self.bottom.load(Ordering::SeqCst);
        let next = bottom + 1;
        self.bottom.store(next, Ordering::SeqCst);

        let top = self.top.load(Ordering::SeqCst);
        if next > top {
            self.bottom.store(bottom, Ordering::SeqCst);
            None
        } else {
            Some(self.jobs[bottom].load(Ordering::SeqCst))
        }
    }
}

<commit_msg>Switch to relaxed ordering in some cases where I believe it is safe. This produces a noticeable speedup.<commit_after>use job::Job;
use std::default::Default;
use std::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
use std::sync::Mutex;

const INITIAL_SIZE: usize = 1024;

pub struct ThreadDeque {
    jobs: Vec<AtomicPtr<Job>>,
    bottom: AtomicUsize,
    top: AtomicUsize,
    lock: Mutex<()>,
}

impl ThreadDeque {
    pub fn new() -> ThreadDeque {
        ThreadDeque {
            jobs: (0..INITIAL_SIZE).map(|_| AtomicPtr::default()).collect(),
            bottom: AtomicUsize::default(),
            top: AtomicUsize::default(),
            lock: Mutex::new(())
        }
    }

    #[inline]
    pub unsafe fn push(&self, job: *mut Job) {
        let top = self.top.load(Ordering::Relaxed); // (1)
        self.jobs[top].store(job, Ordering::Relaxed); // (4)
        self.top.store(top + 1, Ordering::SeqCst);
    }

    #[inline]
    pub unsafe fn pop(&self) -> bool {
        let top = self.top.load(Ordering::Relaxed); // (1)
        let previous = top - 1;
        self.top.store(previous, Ordering::SeqCst);

        let bottom = self.bottom.load(Ordering::SeqCst);
        if bottom > previous {
            self.top.store(top, Ordering::SeqCst);
            let _lock = self.lock.lock().unwrap();
            let bottom = self.bottom.load(Ordering::Relaxed); // (2)
            if bottom > previous {
                return false;
            }
            self.top.store(previous, Ordering::Relaxed); // (1, 2)
        }

        true
    }

    #[inline]
    pub unsafe fn steal(&self) -> Option<*mut Job> {
        let _lock = self.lock.lock().unwrap();

        let bottom = self.bottom.load(Ordering::Relaxed); // (2)
        let next = bottom + 1;
        self.bottom.store(next, Ordering::SeqCst); // (3)

        let top = self.top.load(Ordering::SeqCst);
        if next > top {
            self.bottom.store(bottom, Ordering::SeqCst); // (3)
            None
        } else {
            Some(self.jobs[bottom].load(Ordering::Relaxed)) // (4)
        }
    }
}

// Justification and notes regarding memory ordering:
// (1) The top variable is only modified by the owner thread, so *reads* need not
//     synchronize with other threads.
// (2) The bottom variable is only *mutated* under lock, so once we've acquired
//     the lock we can read with a relaxed ordering.
// (3) Nonetheless, bottom is read by owner thread without lock, so stores
//     require some fences.
// (4) The jobs array itself is effectively guarded by reads and
//     stores to `top`, so relaxed ordering is sufficient.
<|endoftext|>


<commit_before>use crate::context::ContextError;
use std::any::TypeId;
use std::error::Error as StdError;
use std::fmt::{self, Debug, Display};
use std::mem;
use std::ops::{Deref, DerefMut};
use std::ptr;

#[cfg(backtrace)]
use std::backtrace::{Backtrace, BacktraceStatus};

/// The `Error` type, a wrapper around a dynamic error type.
///
/// `Error` works a lot like `Box<dyn std::error::Error>`, but with these
/// differences:
///
/// - `Error` requires that the error is `Send`, `Sync`, and `'static`.
/// - `Error` guarantees that a backtrace is available, even if the underlying
///   error type does not provide one.
/// - `Error` is represented as a narrow pointer — exactly one word in
///   size instead of two.
pub struct Error {
    inner: Box<ErrorImpl<()>>,
}

impl Error {
    /// Create a new error object from any error type.
    ///
    /// The error type must be threadsafe and `'static`, so that the `Error`
    /// will be as well.
    ///
    /// If the error type does not provide a backtrace, a backtrace will be
    /// created here to ensure that a backtrace exists.
    pub fn new<E>(error: E) -> Self
    where
        E: StdError + Send + Sync + 'static,
    {
        // Captured here instead of in Error::construct to have one fewer layer
        // of wrapping visible in the backtrace.
        #[cfg(backtrace)]
        let backtrace = match error.backtrace() {
            Some(_) => None,
            None => Some(Backtrace::capture()),
        };

        #[cfg(not(backtrace))]
        let backtrace = None;

        Error::construct(error, TypeId::of::<E>(), backtrace)
    }

    pub(crate) fn new_adhoc<M>(message: M, backtrace: Option<Backtrace>) -> Self
    where
        M: Display + Debug + Send + Sync + 'static,
    {
        Error::construct(MessageError(message), TypeId::of::<M>(), backtrace)
    }

    fn construct<E>(error: E, type_id: TypeId, backtrace: Option<Backtrace>) -> Self
    where
        E: StdError + Send + Sync + 'static,
    {
        unsafe {
            let obj = mem::transmute::<&dyn StdError, TraitObject>(&error);
            let inner = Box::new(ErrorImpl {
                vtable: obj.vtable,
                type_id,
                backtrace,
                error,
            });
            Error {
                inner: mem::transmute::<Box<ErrorImpl<E>>, Box<ErrorImpl<()>>>(inner),
            }
        }
    }

    /// Wrap the error value with additional context.
    ///
    /// For attaching context to a `Result` as it is propagated, the
    /// [`Context`][crate::Context] extension trait may be more convenient than
    /// this function.
    pub fn context<C>(self, context: C) -> Self
    where
        C: Display + Send + Sync + 'static,
    {
        Error::from(ContextError {
            error: self,
            context,
        })
    }

    /// Get the backtrace for this Error.
    ///
    /// Backtraces are only available on the nightly channel. Tracking issue:
    /// [rust-lang/rust#53487][tracking].
    ///
    /// In order for the backtrace to be meaningful, the environment variable
    /// `RUST_LIB_BACKTRACE=1` must be defined. Backtraces are somewhat
    /// expensive to capture in Rust, so we don't necessarily want to be
    /// capturing them all over the place all the time.
    ///
    /// [tracking]: https://github.com/rust-lang/rust/issues/53487
    #[cfg(backtrace)]
    pub fn backtrace(&self) -> &Backtrace {
        // NB: this unwrap can only fail if the underlying error's backtrace
        // method is nondeterministic, which would only happen in maliciously
        // constructed code
        self.inner
            .backtrace
            .as_ref()
            .or_else(|| self.inner.error().backtrace())
            .expect("backtrace capture failed")
    }

    /// An iterator of the chain of source errors contained by this Error.
    ///
    /// This iterator will visit every error in the cause chain of this error
    /// object, beginning with the error that this error object was created
    /// from.
    pub fn chain(&self) -> Chain {
        Chain {
            next: Some(self.inner.error()),
        }
    }

    /// Returns `true` if `E` is the type wrapped by this error object.
    pub fn is<E>(&self) -> bool
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        TypeId::of::<E>() == self.inner.type_id
    }

    /// Attempt to downcast the error object to a concrete type.
    pub fn downcast<E>(self) -> Result<E, Self>
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        if let Some(error) = self.downcast_ref::<E>() {
            unsafe {
                let error = ptr::read(error);
                drop(ptr::read(&self.inner));
                mem::forget(self);
                Ok(error)
            }
        } else {
            Err(self)
        }
    }

    /// Downcast this error object by reference.
    pub fn downcast_ref<E>(&self) -> Option<&E>
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        if self.is::<E>() {
            unsafe { Some(&*(self.inner.error() as *const dyn StdError as *const E)) }
        } else {
            None
        }
    }

    /// Downcast this error object by mutable reference.
    pub fn downcast_mut<E>(&mut self) -> Option<&mut E>
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        if self.is::<E>() {
            unsafe { Some(&mut *(self.inner.error_mut() as *mut dyn StdError as *mut E)) }
        } else {
            None
        }
    }
}

#[cfg(not(backtrace))]
pub(crate) enum Backtrace {}

impl<E> From<E> for Error
where
    E: StdError + Send + Sync + 'static,
{
    fn from(error: E) -> Self {
        Error::new(error)
    }
}

impl Deref for Error {
    type Target = dyn StdError + Send + Sync + 'static;

    fn deref(&self) -> &Self::Target {
        self.inner.error()
    }
}

impl DerefMut for Error {
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.inner.error_mut()
    }
}

impl Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        writeln!(f, "{}", self.inner.error())?;

        let mut chain = self.chain().skip(1).enumerate();
        if let Some((n, error)) = chain.next() {
            writeln!(f, "\ncaused by:")?;
            writeln!(f, "\t{}: {}", n, error)?;
            for (n, error) in chain {
                writeln!(f, "\t{}: {}", n, error)?;
            }
        }

        #[cfg(backtrace)]
        {
            let backtrace = self.backtrace();
            match backtrace.status() {
                BacktraceStatus::Captured => {
                    writeln!(f, "\n{}", backtrace)?;
                }
                BacktraceStatus::Disabled => {
                    writeln!(
                        f,
                        "\nbacktrace disabled; run with RUST_LIB_BACKTRACE=1 environment variable to display a backtrace"
                    )?;
                }
                _ => {}
            }
        }

        Ok(())
    }
}

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

unsafe impl Send for Error {}
unsafe impl Sync for Error {}

impl Drop for Error {
    fn drop(&mut self) {
        unsafe { ptr::drop_in_place(self.inner.error_mut()) }
    }
}

// repr C to ensure that `E` remains in the final position
#[repr(C)]
struct ErrorImpl<E> {
    vtable: *const (),
    type_id: TypeId,
    backtrace: Option<Backtrace>,
    error: E,
}

// repr C to ensure that transmuting from trait objects is safe
#[repr(C)]
struct TraitObject {
    data: *const (),
    vtable: *const (),
}

#[repr(transparent)]
struct MessageError<M>(M);

impl<M> Debug for MessageError<M>
where
    M: Display + Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Debug::fmt(&self.0, f)
    }
}

impl<M> Display for MessageError<M>
where
    M: Display + Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Display::fmt(&self.0, f)
    }
}

impl<M> StdError for MessageError<M> where M: Display + Debug + 'static {}

impl ErrorImpl<()> {
    fn error(&self) -> &(dyn StdError + Send + Sync + 'static) {
        let object = TraitObject {
            data: &self.error,
            vtable: self.vtable,
        };

        unsafe { mem::transmute::<TraitObject, &(dyn StdError + Send + Sync + 'static)>(object) }
    }

    fn error_mut(&mut self) -> &mut (dyn StdError + Send + Sync + 'static) {
        let object = TraitObject {
            data: &mut self.error,
            vtable: self.vtable,
        };

        unsafe {
            mem::transmute::<TraitObject, &mut (dyn StdError + Send + Sync + 'static)>(object)
        }
    }
}

/// Iterator of a chain of source errors.
pub struct Chain<'a> {
    next: Option<&'a (dyn StdError + 'static)>,
}

impl<'a> Iterator for Chain<'a> {
    type Item = &'a (dyn StdError + 'static);

    fn next(&mut self) -> Option<Self::Item> {
        let next = self.next.take()?;
        self.next = next.source();
        Some(next)
    }
}

#[cfg(test)]
mod repr_correctness {
    use super::*;
    use std::marker::Unpin;
    use std::mem;
    use std::sync::atomic::AtomicBool;
    use std::sync::atomic::Ordering::SeqCst;
    use std::sync::Arc;

    #[test]
    fn size_of_error() {
        assert_eq!(mem::size_of::<Error>(), mem::size_of::<usize>());
    }

    #[test]
    fn error_autotraits() {
        fn assert<E: Unpin + Send + Sync + 'static>() {}
        assert::<Error>();
    }

    #[test]
    fn drop_works() {
        #[derive(Debug)]
        struct DetectDrop {
            has_dropped: Arc<AtomicBool>,
        }

        impl StdError for DetectDrop {}

        impl Display for DetectDrop {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                write!(f, "does something")
            }
        }

        impl Drop for DetectDrop {
            fn drop(&mut self) {
                let already_dropped = self.has_dropped.swap(true, SeqCst);
                assert!(!already_dropped);
            }
        }

        let has_dropped = Arc::new(AtomicBool::new(false));

        drop(Error::from(DetectDrop {
            has_dropped: has_dropped.clone(),
        }));

        assert!(has_dropped.load(SeqCst));
    }
}
<commit_msg>Add example to Error::downcast_ref<commit_after>use crate::context::ContextError;
use std::any::TypeId;
use std::error::Error as StdError;
use std::fmt::{self, Debug, Display};
use std::mem;
use std::ops::{Deref, DerefMut};
use std::ptr;

#[cfg(backtrace)]
use std::backtrace::{Backtrace, BacktraceStatus};

/// The `Error` type, a wrapper around a dynamic error type.
///
/// `Error` works a lot like `Box<dyn std::error::Error>`, but with these
/// differences:
///
/// - `Error` requires that the error is `Send`, `Sync`, and `'static`.
/// - `Error` guarantees that a backtrace is available, even if the underlying
///   error type does not provide one.
/// - `Error` is represented as a narrow pointer — exactly one word in
///   size instead of two.
pub struct Error {
    inner: Box<ErrorImpl<()>>,
}

impl Error {
    /// Create a new error object from any error type.
    ///
    /// The error type must be threadsafe and `'static`, so that the `Error`
    /// will be as well.
    ///
    /// If the error type does not provide a backtrace, a backtrace will be
    /// created here to ensure that a backtrace exists.
    pub fn new<E>(error: E) -> Self
    where
        E: StdError + Send + Sync + 'static,
    {
        // Captured here instead of in Error::construct to have one fewer layer
        // of wrapping visible in the backtrace.
        #[cfg(backtrace)]
        let backtrace = match error.backtrace() {
            Some(_) => None,
            None => Some(Backtrace::capture()),
        };

        #[cfg(not(backtrace))]
        let backtrace = None;

        Error::construct(error, TypeId::of::<E>(), backtrace)
    }

    pub(crate) fn new_adhoc<M>(message: M, backtrace: Option<Backtrace>) -> Self
    where
        M: Display + Debug + Send + Sync + 'static,
    {
        Error::construct(MessageError(message), TypeId::of::<M>(), backtrace)
    }

    fn construct<E>(error: E, type_id: TypeId, backtrace: Option<Backtrace>) -> Self
    where
        E: StdError + Send + Sync + 'static,
    {
        unsafe {
            let obj = mem::transmute::<&dyn StdError, TraitObject>(&error);
            let inner = Box::new(ErrorImpl {
                vtable: obj.vtable,
                type_id,
                backtrace,
                error,
            });
            Error {
                inner: mem::transmute::<Box<ErrorImpl<E>>, Box<ErrorImpl<()>>>(inner),
            }
        }
    }

    /// Wrap the error value with additional context.
    ///
    /// For attaching context to a `Result` as it is propagated, the
    /// [`Context`][crate::Context] extension trait may be more convenient than
    /// this function.
    pub fn context<C>(self, context: C) -> Self
    where
        C: Display + Send + Sync + 'static,
    {
        Error::from(ContextError {
            error: self,
            context,
        })
    }

    /// Get the backtrace for this Error.
    ///
    /// Backtraces are only available on the nightly channel. Tracking issue:
    /// [rust-lang/rust#53487][tracking].
    ///
    /// In order for the backtrace to be meaningful, the environment variable
    /// `RUST_LIB_BACKTRACE=1` must be defined. Backtraces are somewhat
    /// expensive to capture in Rust, so we don't necessarily want to be
    /// capturing them all over the place all the time.
    ///
    /// [tracking]: https://github.com/rust-lang/rust/issues/53487
    #[cfg(backtrace)]
    pub fn backtrace(&self) -> &Backtrace {
        // NB: this unwrap can only fail if the underlying error's backtrace
        // method is nondeterministic, which would only happen in maliciously
        // constructed code
        self.inner
            .backtrace
            .as_ref()
            .or_else(|| self.inner.error().backtrace())
            .expect("backtrace capture failed")
    }

    /// An iterator of the chain of source errors contained by this Error.
    ///
    /// This iterator will visit every error in the cause chain of this error
    /// object, beginning with the error that this error object was created
    /// from.
    pub fn chain(&self) -> Chain {
        Chain {
            next: Some(self.inner.error()),
        }
    }

    /// Returns `true` if `E` is the type wrapped by this error object.
    pub fn is<E>(&self) -> bool
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        TypeId::of::<E>() == self.inner.type_id
    }

    /// Attempt to downcast the error object to a concrete type.
    pub fn downcast<E>(self) -> Result<E, Self>
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        if let Some(error) = self.downcast_ref::<E>() {
            unsafe {
                let error = ptr::read(error);
                drop(ptr::read(&self.inner));
                mem::forget(self);
                Ok(error)
            }
        } else {
            Err(self)
        }
    }

    /// Downcast this error object by reference.
    ///
    /// # Example
    ///
    /// ```
    /// # use anyhow::anyhow;
    /// # use std::fmt::{self, Display};
    /// # use std::task::Poll;
    /// #
    /// # #[derive(Debug)]
    /// # enum DataStoreError {
    /// #     Censored(()),
    /// # }
    /// #
    /// # impl Display for DataStoreError {
    /// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
    /// #         unimplemented!()
    /// #     }
    /// # }
    /// #
    /// # impl std::error::Error for DataStoreError {}
    /// #
    /// # const REDACTED_CONTENT: () = ();
    /// #
    /// # let error = anyhow!("...");
    /// # let root_cause = &error;
    /// #
    /// # let ret =
    /// // If the error was caused by redaction, then return a tombstone instead
    /// // of the content.
    /// match root_cause.downcast_ref::<DataStoreError>() {
    ///     Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)),
    ///     None => Err(error),
    /// }
    /// # ;
    /// ```
    pub fn downcast_ref<E>(&self) -> Option<&E>
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        if self.is::<E>() {
            unsafe { Some(&*(self.inner.error() as *const dyn StdError as *const E)) }
        } else {
            None
        }
    }

    /// Downcast this error object by mutable reference.
    pub fn downcast_mut<E>(&mut self) -> Option<&mut E>
    where
        E: Display + Debug + Send + Sync + 'static,
    {
        if self.is::<E>() {
            unsafe { Some(&mut *(self.inner.error_mut() as *mut dyn StdError as *mut E)) }
        } else {
            None
        }
    }
}

#[cfg(not(backtrace))]
pub(crate) enum Backtrace {}

impl<E> From<E> for Error
where
    E: StdError + Send + Sync + 'static,
{
    fn from(error: E) -> Self {
        Error::new(error)
    }
}

impl Deref for Error {
    type Target = dyn StdError + Send + Sync + 'static;

    fn deref(&self) -> &Self::Target {
        self.inner.error()
    }
}

impl DerefMut for Error {
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.inner.error_mut()
    }
}

impl Debug for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        writeln!(f, "{}", self.inner.error())?;

        let mut chain = self.chain().skip(1).enumerate();
        if let Some((n, error)) = chain.next() {
            writeln!(f, "\ncaused by:")?;
            writeln!(f, "\t{}: {}", n, error)?;
            for (n, error) in chain {
                writeln!(f, "\t{}: {}", n, error)?;
            }
        }

        #[cfg(backtrace)]
        {
            let backtrace = self.backtrace();
            match backtrace.status() {
                BacktraceStatus::Captured => {
                    writeln!(f, "\n{}", backtrace)?;
                }
                BacktraceStatus::Disabled => {
                    writeln!(
                        f,
                        "\nbacktrace disabled; run with RUST_LIB_BACKTRACE=1 environment variable to display a backtrace"
                    )?;
                }
                _ => {}
            }
        }

        Ok(())
    }
}

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

unsafe impl Send for Error {}
unsafe impl Sync for Error {}

impl Drop for Error {
    fn drop(&mut self) {
        unsafe { ptr::drop_in_place(self.inner.error_mut()) }
    }
}

// repr C to ensure that `E` remains in the final position
#[repr(C)]
struct ErrorImpl<E> {
    vtable: *const (),
    type_id: TypeId,
    backtrace: Option<Backtrace>,
    error: E,
}

// repr C to ensure that transmuting from trait objects is safe
#[repr(C)]
struct TraitObject {
    data: *const (),
    vtable: *const (),
}

#[repr(transparent)]
struct MessageError<M>(M);

impl<M> Debug for MessageError<M>
where
    M: Display + Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Debug::fmt(&self.0, f)
    }
}

impl<M> Display for MessageError<M>
where
    M: Display + Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Display::fmt(&self.0, f)
    }
}

impl<M> StdError for MessageError<M> where M: Display + Debug + 'static {}

impl ErrorImpl<()> {
    fn error(&self) -> &(dyn StdError + Send + Sync + 'static) {
        let object = TraitObject {
            data: &self.error,
            vtable: self.vtable,
        };

        unsafe { mem::transmute::<TraitObject, &(dyn StdError + Send + Sync + 'static)>(object) }
    }

    fn error_mut(&mut self) -> &mut (dyn StdError + Send + Sync + 'static) {
        let object = TraitObject {
            data: &mut self.error,
            vtable: self.vtable,
        };

        unsafe {
            mem::transmute::<TraitObject, &mut (dyn StdError + Send + Sync + 'static)>(object)
        }
    }
}

/// Iterator of a chain of source errors.
pub struct Chain<'a> {
    next: Option<&'a (dyn StdError + 'static)>,
}

impl<'a> Iterator for Chain<'a> {
    type Item = &'a (dyn StdError + 'static);

    fn next(&mut self) -> Option<Self::Item> {
        let next = self.next.take()?;
        self.next = next.source();
        Some(next)
    }
}

#[cfg(test)]
mod repr_correctness {
    use super::*;
    use std::marker::Unpin;
    use std::mem;
    use std::sync::atomic::AtomicBool;
    use std::sync::atomic::Ordering::SeqCst;
    use std::sync::Arc;

    #[test]
    fn size_of_error() {
        assert_eq!(mem::size_of::<Error>(), mem::size_of::<usize>());
    }

    #[test]
    fn error_autotraits() {
        fn assert<E: Unpin + Send + Sync + 'static>() {}
        assert::<Error>();
    }

    #[test]
    fn drop_works() {
        #[derive(Debug)]
        struct DetectDrop {
            has_dropped: Arc<AtomicBool>,
        }

        impl StdError for DetectDrop {}

        impl Display for DetectDrop {
            fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                write!(f, "does something")
            }
        }

        impl Drop for DetectDrop {
            fn drop(&mut self) {
                let already_dropped = self.has_dropped.swap(true, SeqCst);
                assert!(!already_dropped);
            }
        }

        let has_dropped = Arc::new(AtomicBool::new(false));

        drop(Error::from(DetectDrop {
            has_dropped: has_dropped.clone(),
        }));

        assert!(has_dropped.load(SeqCst));
    }
}
<|endoftext|>


<commit_before>macro_rules! impl_error_conversion {
    ($err_name:ident, $($from_ty:ty => $to_ty:ident,)+) => {
        $(
        impl From<$from_ty> for $err_name {
            fn from(f: $from_ty) -> $err_name {
                $err_name::$to_ty(f)
            }
        }
        )+
    };
}

#[derive(Fail, Debug)]
pub enum Error {
    #[fail(display = "io error")]
    Io(#[cause] ::std::io::Error),

    #[fail(display = "sync service error")]
    BackendError(#[cause] BackendError),

    #[fail(display = "error processing series")]
    SeriesError(#[cause] SeriesError),

    #[fail(display = "config error")]
    ConfigError(#[cause] ConfigError),

    #[fail(display = "path to [{}] not found. Try setting it with -p", _0)]
    SeriesNotFound(String),

    #[fail(display = "no information about the series to watch was provided")]
    NoSeriesInfoProvided,
}

impl_error_conversion!(Error,
    ::std::io::Error => Io,
    BackendError => BackendError,
    SeriesError => SeriesError,
    ConfigError => ConfigError,
);

#[derive(Fail, Debug)]
pub enum SeriesError {
    #[fail(display = "io error")]
    Io(#[cause] ::std::io::Error),

    #[fail(display = "input error")]
    InputError(#[cause] InputError),

    #[fail(display = "error serializing toml")]
    TomlSerialize(#[cause] ::toml::ser::Error),

    #[fail(display = "error deserializing toml")]
    TomlDeserialize(#[cause] ::toml::de::Error),

    #[fail(display = "failed to open video player")]
    FailedToOpenPlayer(#[cause] ::std::io::Error),

    #[fail(display = "episode number parse failed")]
    EpisodeNumParseFailed(#[cause] ::std::num::ParseIntError),

    #[fail(display = "sync service error")]
    Backend(#[cause] BackendError),

    #[fail(display = "no episodes found")]
    NoEpisodesFound,

    #[fail(display = "multiple series found")]
    MultipleSeriesFound,

    #[fail(display = "unable to get filename")]
    UnableToGetFilename,

    #[fail(display = "failed to get regex captures on episode")]
    EpisodeRegexCaptureFailed,

    #[fail(display = "specified path is not a directory: {}", _0)]
    NotADirectory(String),

    #[fail(display = "episode {} not found", _0)]
    EpisodeNotFound(u32),
}

impl_error_conversion!(SeriesError,
    ::std::io::Error => Io,
    InputError => InputError,
    ::toml::ser::Error => TomlSerialize,
    ::toml::de::Error => TomlDeserialize,
    BackendError => Backend,
);

#[derive(Fail, Debug)]
pub enum InputError {
    #[fail(display = "failed to read line")]
    ReadFailed(#[cause] ::std::io::Error),

    #[fail(display = "failed to parse input string to number")]
    IntParseFailed(#[cause] ::std::num::ParseIntError),
}

#[derive(Fail, Debug)]
pub enum ConfigError {
    #[fail(display = "io error")]
    Io(#[cause] ::std::io::Error),

    #[fail(display = "input is not valid UTF8")]
    FromUtf8Error(#[cause] ::std::string::FromUtf8Error),

    #[fail(display = "error serializing toml")]
    TomlSerialize(#[cause] ::toml::ser::Error),

    #[fail(display = "error deserializing toml")]
    TomlDeserialize(#[cause] ::toml::de::Error),

    #[fail(display = "access token decode failed")]
    FailedTokenDecode(#[cause] ::base64::DecodeError),

    #[fail(display = "access token not set for sync service")]
    TokenNotSet,
}

impl_error_conversion!(ConfigError,
    ::std::io::Error => Io,
    ::std::string::FromUtf8Error => FromUtf8Error,
    ::toml::ser::Error => TomlSerialize,
    ::toml::de::Error => TomlDeserialize,
);

#[derive(Fail, Debug)]
pub enum BackendError {
    #[fail(display = "io error")]
    Io(#[cause] ::std::io::Error),

    #[fail(display = "config error")]
    ConfigError(#[cause] ConfigError),

    #[fail(display = "HTTP error")]
    HttpError(#[cause] ::reqwest::Error),

    #[fail(display = "json error")]
    Json(#[cause] ::serde_json::Error),

    #[fail(display = "received invalid JSON response")]
    InvalidJsonResponse,

    #[fail(display = "list update failed: {}", _0)]
    ListUpdate(String),
}

impl_error_conversion!(BackendError,
    ::std::io::Error => Io,
    ConfigError => ConfigError,
    ::reqwest::Error => HttpError,
    ::serde_json::Error => Json,
);
<commit_msg>Rename IntParseFailed error type to ParseFailed to allow for generic parse errors<commit_after>macro_rules! impl_error_conversion {
    ($err_name:ident, $($from_ty:ty => $to_ty:ident,)+) => {
        $(
        impl From<$from_ty> for $err_name {
            fn from(f: $from_ty) -> $err_name {
                $err_name::$to_ty(f)
            }
        }
        )+
    };
}

#[derive(Fail, Debug)]
pub enum Error {
    #[fail(display = "io error")]
    Io(#[cause] ::std::io::Error),

    #[fail(display = "sync service error")]
    BackendError(#[cause] BackendError),

    #[fail(display = "error processing series")]
    SeriesError(#[cause] SeriesError),

    #[fail(display = "config error")]
    ConfigError(#[cause] ConfigError),

    #[fail(display = "path to [{}] not found. Try setting it with -p", _0)]
    SeriesNotFound(String),

    #[fail(display = "no information about the series to watch was provided")]
    NoSeriesInfoProvided,
}

impl_error_conversion!(Error,
    ::std::io::Error => Io,
    BackendError => BackendError,
    SeriesError => SeriesError,
    ConfigError => ConfigError,
);

#[derive(Fail, Debug)]
pub enum SeriesError {
    #[fail(display = "io error")]
    Io(#[cause] ::std::io::Error),

    #[fail(display = "input error")]
    InputError(#[cause] InputError),

    #[fail(display = "error serializing toml")]
    TomlSerialize(#[cause] ::toml::ser::Error),

    #[fail(display = "error deserializing toml")]
    TomlDeserialize(#[cause] ::toml::de::Error),

    #[fail(display = "failed to open video player")]
    FailedToOpenPlayer(#[cause] ::std::io::Error),

    #[fail(display = "episode number parse failed")]
    EpisodeNumParseFailed(#[cause] ::std::num::ParseIntError),

    #[fail(display = "sync service error")]
    Backend(#[cause] BackendError),

    #[fail(display = "no episodes found")]
    NoEpisodesFound,

    #[fail(display = "multiple series found")]
    MultipleSeriesFound,

    #[fail(display = "unable to get filename")]
    UnableToGetFilename,

    #[fail(display = "failed to get regex captures on episode")]
    EpisodeRegexCaptureFailed,

    #[fail(display = "specified path is not a directory: {}", _0)]
    NotADirectory(String),

    #[fail(display = "episode {} not found", _0)]
    EpisodeNotFound(u32),
}

impl_error_conversion!(SeriesError,
    ::std::io::Error => Io,
    InputError => InputError,
    ::toml::ser::Error => TomlSerialize,
    ::toml::de::Error => TomlDeserialize,
    BackendError => Backend,
);

#[derive(Fail, Debug)]
pub enum InputError {
    #[fail(display = "failed to read line")]
    ReadFailed(#[cause] ::std::io::Error),

    #[fail(display = "failed to parse type: {}", _0)]
    ParseFailed(String),
}

#[derive(Fail, Debug)]
pub enum ConfigError {
    #[fail(display = "io error")]
    Io(#[cause] ::std::io::Error),

    #[fail(display = "input is not valid UTF8")]
    FromUtf8Error(#[cause] ::std::string::FromUtf8Error),

    #[fail(display = "error serializing toml")]
    TomlSerialize(#[cause] ::toml::ser::Error),

    #[fail(display = "error deserializing toml")]
    TomlDeserialize(#[cause] ::toml::de::Error),

    #[fail(display = "access token decode failed")]
    FailedTokenDecode(#[cause] ::base64::DecodeError),

    #[fail(display = "access token not set for sync service")]
    TokenNotSet,
}

impl_error_conversion!(ConfigError,
    ::std::io::Error => Io,
    ::std::string::FromUtf8Error => FromUtf8Error,
    ::toml::ser::Error => TomlSerialize,
    ::toml::de::Error => TomlDeserialize,
);

#[derive(Fail, Debug)]
pub enum BackendError {
    #[fail(display = "io error")]
    Io(#[cause] ::std::io::Error),

    #[fail(display = "config error")]
    ConfigError(#[cause] ConfigError),

    #[fail(display = "HTTP error")]
    HttpError(#[cause] ::reqwest::Error),

    #[fail(display = "json error")]
    Json(#[cause] ::serde_json::Error),

    #[fail(display = "received invalid JSON response")]
    InvalidJsonResponse,

    #[fail(display = "list update failed: {}", _0)]
    ListUpdate(String),
}

impl_error_conversion!(BackendError,
    ::std::io::Error => Io,
    ConfigError => ConfigError,
    ::reqwest::Error => HttpError,
    ::serde_json::Error => Json,
);
<|endoftext|>


<commit_before>use std::error;
use std::fmt;
use std::io;
use std::string;

/// Type alias for the result of tag operations.
pub type Result<T> = ::std::result::Result<T, Error>;

/// Kinds of errors that may occur while performing metadata operations.
#[derive(Debug)]
pub enum ErrorKind {
    /// An error kind indicating that an IO error has occurred. Contains the original io::Error.
    Io(io::Error),
    /// An error kind indicating that a string decoding error has occurred. Contains the invalid
    /// bytes.
    StringDecoding(string::FromUtf8Error),
    /// An error kind indicating that some input was invalid.
    InvalidInput,
}

/// A structure able to represent any error that may occur while performing metadata operations.
pub struct Error {
    /// The kind of error.
    pub kind: ErrorKind,
    /// A human readable string describing the error.
    pub description: &'static str,
}

impl Error {
    /// Creates a new `Error` using the error kind and description.
    pub fn new(kind: ErrorKind, description: &'static str) -> Error {
        Error { kind, description }
    }
}

impl error::Error for Error {
    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
        match self.kind {
            ErrorKind::Io(ref err) => Some(err),
            ErrorKind::StringDecoding(ref err) => Some(err),
            _ => None,
        }
    }
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error {
            kind: ErrorKind::Io(err),
            description: "",
        }
    }
}

impl From<string::FromUtf8Error> for Error {
    fn from(err: string::FromUtf8Error) -> Error {
        Error {
            kind: ErrorKind::StringDecoding(err),
            description: "",
        }
    }
}

impl fmt::Debug for Error {
    fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {
        if self.description != "" {
            write!(out, "{:?}: {}", self.kind, self.description)
        } else {
            write!(out, "{:?}", self.kind)
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {
        if self.description != "" {
            write!(out, "{:?}: {}", self.kind, self.description)
        } else {
            write!(out, "{:?}", self.kind)
        }
    }
}
<commit_msg>Better Error display Make error display resemble the original implementation better.<commit_after>use std::error;
use std::fmt;
use std::io;
use std::string;

/// Type alias for the result of tag operations.
pub type Result<T> = ::std::result::Result<T, Error>;

/// Kinds of errors that may occur while performing metadata operations.
#[derive(Debug)]
pub enum ErrorKind {
    /// An error kind indicating that an IO error has occurred. Contains the original io::Error.
    Io(io::Error),
    /// An error kind indicating that a string decoding error has occurred. Contains the invalid
    /// bytes.
    StringDecoding(string::FromUtf8Error),
    /// An error kind indicating that some input was invalid.
    InvalidInput,
}

/// A structure able to represent any error that may occur while performing metadata operations.
pub struct Error {
    /// The kind of error.
    pub kind: ErrorKind,
    /// A human readable string describing the error.
    pub description: &'static str,
}

impl Error {
    /// Creates a new `Error` using the error kind and description.
    pub fn new(kind: ErrorKind, description: &'static str) -> Error {
        Error { kind, description }
    }
}

impl error::Error for Error {
    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
        match self.kind {
            ErrorKind::Io(ref err) => Some(err),
            ErrorKind::StringDecoding(ref err) => Some(err),
            _ => None,
        }
    }
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error {
            kind: ErrorKind::Io(err),
            description: "",
        }
    }
}

impl From<string::FromUtf8Error> for Error {
    fn from(err: string::FromUtf8Error) -> Error {
        Error {
            kind: ErrorKind::StringDecoding(err),
            description: "",
        }
    }
}

impl fmt::Debug for Error {
    fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {
        if self.description != "" {
            write!(out, "{:?}: {}", self.kind, self.description)
        } else if let Some(source) = error::Error::source(self) {
            write!(out, "{}", source)
        } else {
            write!(out, "{:?}", self.kind)
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {
        if self.description != "" {
            write!(out, "{:?}: {}", self.kind, self.description)
        } else if let Some(source) = error::Error::source(self) {
            write!(out, "{}", source)
        } else {
            write!(out, "{:?}", self.kind)
        }
    }
}
<|endoftext|>


<commit_before>// The Computer Language Benchmarks Game
// http://benchmarksgame.alioth.debian.org/
//
// contributed by the Rust Project Developers
// contributed by TeXitoi

#![feature(os, old_io)]

use std::cmp::min;
use std::old_io;
use std::num::Float;

const LINE_LENGTH: usize = 60;
const IM: u32 = 139968;

struct MyRandom {
    last: u32
}
impl MyRandom {
    fn new() -> MyRandom { MyRandom { last: 42 } }
    fn normalize(p: f32) -> u32 {(p * IM as f32).floor() as u32}
    fn gen(&mut self) -> u32 {
        self.last = (self.last * 3877 + 29573) % IM;
        self.last
    }
}

struct AAGen<'a> {
    rng: &'a mut MyRandom,
    data: Vec<(u32, u8)>
}
impl<'a> AAGen<'a> {
    fn new<'b>(rng: &'b mut MyRandom, aa: &[(char, f32)]) -> AAGen<'b> {
        let mut cum = 0.;
        let data = aa.iter()
            .map(|&(ch, p)| { cum += p; (MyRandom::normalize(cum), ch as u8) })
            .collect();
        AAGen { rng: rng, data: data }
    }
}
impl<'a> Iterator for AAGen<'a> {
    type Item = u8;

    fn next(&mut self) -> Option<u8> {
        let r = self.rng.gen();
        self.data.iter()
            .skip_while(|pc| pc.0 < r)
            .map(|&(_, c)| c)
            .next()
    }
}

fn make_fasta<W: Writer, I: Iterator<Item=u8>>(
    wr: &mut W, header: &str, mut it: I, mut n: usize)
    -> std::old_io::IoResult<()>
{
    try!(wr.write_all(header.as_bytes()));
    let mut line = [0u8; LINE_LENGTH + 1];
    while n > 0 {
        let nb = min(LINE_LENGTH, n);
        for i in (0..nb) {
            line[i] = it.next().unwrap();
        }
        n -= nb;
        line[nb] = '\n' as u8;
        try!(wr.write_all(&line[..(nb+1)]));
    }
    Ok(())
}

fn run<W: Writer>(writer: &mut W) -> std::old_io::IoResult<()> {
    let n = std::env::args_os().nth(1)
        .and_then(|s| s.into_string().ok())
        .and_then(|n| n.parse().ok())
        .unwrap_or(1000);

    let rng = &mut MyRandom::new();
    let alu =
        "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG\
        GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA\
        CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT\
        ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA\
        GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG\
        AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC\
        AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";
    let iub = &[('a', 0.27), ('c', 0.12), ('g', 0.12),
                ('t', 0.27), ('B', 0.02), ('D', 0.02),
                ('H', 0.02), ('K', 0.02), ('M', 0.02),
                ('N', 0.02), ('R', 0.02), ('S', 0.02),
                ('V', 0.02), ('W', 0.02), ('Y', 0.02)];
    let homosapiens = &[('a', 0.3029549426680),
                        ('c', 0.1979883004921),
                        ('g', 0.1975473066391),
                        ('t', 0.3015094502008)];

    try!(make_fasta(writer, ">ONE Homo sapiens alu\n",
                    alu.as_bytes().iter().cycle().map(|c| *c), n * 2));
    try!(make_fasta(writer, ">TWO IUB ambiguity codes\n",
                    AAGen::new(rng, iub), n * 3));
    try!(make_fasta(writer, ">THREE Homo sapiens frequency\n",
                    AAGen::new(rng, homosapiens), n * 5));

    writer.flush()
}

fn main() {
    run(&mut old_io::stdout()).unwrap()
}
<commit_msg>update fasta to new io<commit_after>// The Computer Language Benchmarks Game
// http://benchmarksgame.alioth.debian.org/
//
// contributed by the Rust Project Developers
// contributed by TeXitoi

#![feature(os, io)]

use std::cmp::min;
use std::io;
use std::num::Float;

const LINE_LENGTH: usize = 60;
const IM: u32 = 139968;

struct MyRandom {
    last: u32
}
impl MyRandom {
    fn new() -> MyRandom { MyRandom { last: 42 } }
    fn normalize(p: f32) -> u32 {(p * IM as f32).floor() as u32}
    fn gen(&mut self) -> u32 {
        self.last = (self.last * 3877 + 29573) % IM;
        self.last
    }
}

struct AAGen<'a> {
    rng: &'a mut MyRandom,
    data: Vec<(u32, u8)>
}
impl<'a> AAGen<'a> {
    fn new<'b>(rng: &'b mut MyRandom, aa: &[(char, f32)]) -> AAGen<'b> {
        let mut cum = 0.;
        let data = aa.iter()
            .map(|&(ch, p)| { cum += p; (MyRandom::normalize(cum), ch as u8) })
            .collect();
        AAGen { rng: rng, data: data }
    }
}
impl<'a> Iterator for AAGen<'a> {
    type Item = u8;

    fn next(&mut self) -> Option<u8> {
        let r = self.rng.gen();
        self.data.iter()
            .skip_while(|pc| pc.0 < r)
            .map(|&(_, c)| c)
            .next()
    }
}

fn make_fasta<W: io::Write, I: Iterator<Item=u8>>(
    wr: &mut W, header: &str, mut it: I, mut n: usize)
    -> io::Result<()>
{
    try!(wr.write_all(header.as_bytes()));
    let mut line = [0u8; LINE_LENGTH + 1];
    while n > 0 {
        let nb = min(LINE_LENGTH, n);
        for i in (0..nb) {
            line[i] = it.next().unwrap();
        }
        n -= nb;
        line[nb] = '\n' as u8;
        try!(wr.write_all(&line[..(nb+1)]));
    }
    Ok(())
}

fn run<W: io::Write>(writer: &mut W) -> io::Result<()> {
    let n = std::env::args_os().nth(1)
        .and_then(|s| s.into_string().ok())
        .and_then(|n| n.parse().ok())
        .unwrap_or(1000);

    let rng = &mut MyRandom::new();
    let alu =
        "GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG\
        GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA\
        CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT\
        ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA\
        GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG\
        AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC\
        AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";
    let iub = &[('a', 0.27), ('c', 0.12), ('g', 0.12),
                ('t', 0.27), ('B', 0.02), ('D', 0.02),
                ('H', 0.02), ('K', 0.02), ('M', 0.02),
                ('N', 0.02), ('R', 0.02), ('S', 0.02),
                ('V', 0.02), ('W', 0.02), ('Y', 0.02)];
    let homosapiens = &[('a', 0.3029549426680),
                        ('c', 0.1979883004921),
                        ('g', 0.1975473066391),
                        ('t', 0.3015094502008)];

    try!(make_fasta(writer, ">ONE Homo sapiens alu\n",
                    alu.as_bytes().iter().cycle().map(|c| *c), n * 2));
    try!(make_fasta(writer, ">TWO IUB ambiguity codes\n",
                    AAGen::new(rng, iub), n * 3));
    try!(make_fasta(writer, ">THREE Homo sapiens frequency\n",
                    AAGen::new(rng, homosapiens), n * 5));

    writer.flush()
}

fn main() {
    run(&mut io::stdout()).unwrap()
}
<|endoftext|>