<commit_before>use std::hash::{Hash, Hasher,SipHasher};
use std::any::Any;
use std::rc::Rc;

#[derive (Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct SiphashID {
data: [u64; 2],
}
pub struct SiphashID_Generator {
data: [SipHasher; 2],
}
impl Hasher for SiphashID_Generator {
fn finish (& self)->u64 {panic!()}//Hack: this is actually for generating SiphashID, not 64-bit
fn write (&mut self, bytes: & [u8]) {self.data [0].write (bytes);self.data [1].write (bytes);}
//TODO: should we implement the others for efficiency?
}
impl SiphashID_Generator {
fn generate (& self)->SiphashID {SiphashID {data: [self.data [0].finish (), self.data [1].finish ()]}}
}

//TODO: Shouldn't "ordered type with minimum and maximum values" be a trait common to other situations as well? Find out if there's a standard name for that.
pub trait BaseTime: Clone + Ord {
  fn min_time ()->Self;
  fn max_time ()->Self;
}
impl BaseTime for i64 {
  fn min_time ()->i64 {i64::min_value ()}
  fn max_time ()->i64 {i64::max_value ()}
}

pub trait Field {
  type Data: Any;// = Self;

  /**
  Returns a constant identifier for the type, which must be 64 bits of random data.

  Thanks to the [birthday problem](https://en.wikipedia.org/wiki/Birthday_problem), this would have a >1% chance of a collision with a mere 700 million Field implementors. I don't think we need to worry about this. 128 bit IDs are necessary for entities, because computers can generate billions of them easily, but this isn't the same situation.

  It might seem desirable to default to a hash of the TypeId of Self, for the convenience of some implementations. However, Rust does not guarantee that the TypeId remains the same across different compilations or different compiler versions. And it certainly doesn't remain the same when you add or remove types from your code, which would be desirable for compatibility between different versions of your program. Also, the Rust interface for getting the TypeId is currently unstable. Using an explicit constant is simply better.

  TODO: change this into an associated constant once associated constants become stable.
  */
  fn unique_identifier ()->u64;

  /**
  Implementors MAY return true if first and second are indistinguishable.

  This is labeled "unsafe" because imperfect implementations can easily cause nondeterminism in the TimeSteward. Using the default is fine, and implementing it is only an optimization. Don't implement this unless you know what you're doing.

  This is similar to requiring Data to be PartialEq, but with an important difference. PartialEq only requires the comparison to be an equivalence relation, but does NOT require that (first == second) guarantee that there is no observable difference between the values. Therefore, trusting arbitrary implementations of PartialEq would be unsafe (in the sense that it would allow the TimeSteward to behave non-deterministically).

  TODO: perhaps we can create default implementations of this for POD types.
  TODO: can we create automated tests for implementations of this function?
  */
  fn guaranteed_equal__unsafe (first: & Self::Data, second: & Self::Data)->bool {false}
}

#[derive (Clone, PartialEq, Eq, Hash)]
struct FieldID {
  entity: SiphashID,
  field: u64,
}

#[derive (Clone, PartialEq, Eq, PartialOrd, Ord)]
struct GenericExtendedTime <Base: BaseTime> {
  base: Base,
  iteration: u64,
  id: SiphashID,
}

pub trait Basics {
  type Time: BaseTime;
  type Constants;
}
type ExtendedTime <B: Basics> = GenericExtendedTime <B::Time>;

//Note: in the future, we expect we might use a custom hash table type that knows it can rely on SiphashID to already be random, so we don't need to hash it again. This also applies to FieldID, although there may be some complications in that case.
impl Hash for SiphashID {
  fn hash <H: Hasher> (& self, state: &mut H) {self.data [0].hash (state);}
}
impl <Base: BaseTime> Hash for GenericExtendedTime <Base>{
  fn hash <H: Hasher> (& self, state: &mut H) {self.id.hash (state);}
}

pub trait Accessor <B: Basics> {
  fn get <F: Field> (&mut self, id: SiphashID)-> Option <& F::Data>;
  fn constants (& self)->& B::Constants;
}

pub trait MomentaryAccessor <B: Basics>: Accessor <B> {
  fn now (& self)->B::Time;
}

pub trait Mutator <B: Basics>: MomentaryAccessor <B> {
  fn get_mut <F: Field> (&mut self, id: SiphashID)->Option <&mut F::Data> where F::Data: Clone;
  fn set <F: Field> (&mut self, id: SiphashID, data: Option <F::Data>);
  fn random_bits (&mut self, num_bits:u32)->u64;
  fn random_id (&mut self)->SiphashID;
}
pub trait PredictorAccessor <B: Basics>: Accessor <B> {

}
pub trait Snapshot <B: Basics>: MomentaryAccessor <B> {
}

enum FiatEventOperationResult {
  Success,
  InvalidInput,
  InvalidTime,
}

pub trait TimeSteward <'a, B: Basics> {
  type S: Snapshot <B>;
  type M: Mutator <B>;
  type P: PredictorAccessor <B>;
  type Event;
  type Prediction;
  type Predictor;

  /**
  TimeSteward implementors are permitted, but not required, to discard old data in order to save memory. This may make the TimeSteward unusable at some points in its history.

  Newly created stewards should generally have valid_from() == B::Time::min_time().

  All implementors must obey certain restrictions on how other TimeSteward methods may change the result of valid_from(). Implementors may have their own methods that can alter this in customized ways, which should be documented with those individual methods.
  */
  fn valid_from (& self)->B::Time;

  /**
  Inserts a fiat event at some point in the history.

  If time < valid_from(), this does nothing and returns InvalidTime. If there is already a fiat event with the same time and distinguisher, this does nothing and returns InvalidInput. Otherwise, it inserts the event and returns Success.

  steward.insert_fiat_event(time, _) must not return InvalidTime if time >= steward.valid_from().
  steward.insert_fiat_event() may not change steward.valid_from().
  */
  fn insert_fiat_event (&mut self, time: B::Time, distinguisher: u64, event: Self::Event)->FiatEventOperationResult ;

  /**
  Erases a fiat event that has been inserted previously.

  If time < valid_from(), this does nothing and returns InvalidTime. If there is no fiat event with the specified time and distinguisher, this does nothing and returns InvalidInput. Otherwise, it erases the event and returns Success.

  steward.erase_fiat_event(time, _) must not return InvalidTime if time >= steward.valid_from().
  steward.erase_fiat_event() may not change steward.valid_from().
  */
  fn erase_fiat_event (&mut self, time: B::Time, distinguisher: u64)->FiatEventOperationResult ;

  /**
  Returns a "snapshot" into the TimeSteward.

  The snapshot is guaranteed to be valid and unchanging for the full lifetime of the TimeSteward. It is specific to both the time argument, and the current collection of fiat events. Callers may freely call mutable methods of the same TimeSteward after taking a snapshot, without changing the contents of the snapshot.

  Each TimeSteward implementor determines exactly how to provide these guarantees. Implementors should provide individual guarantees about the processor-time bounds of snapshot operations.

  steward.snapshot_before(time) must return Some if time >= steward.valid_from().
  steward.snapshot_before(time) may not increase steward.valid_from() beyond time.
  */
  //note: we implement "before" and not "after" because we might be banning events that happen during max_time
  fn snapshot_before (&mut self, time: B::Time)->Option <Self::S>;
}

pub trait FlatTimeSteward <'a, B: Basics>:TimeSteward <'a, B> {
  fn valid_strictly_between (& self)->(B::Time, B::Time);
}

type Event <B: Basics, M: Mutator <B>> =Rc <Fn (&mut M)>;
enum Prediction <B: Basics, M: Mutator <B>> {
  Nothing,
  Immediately (Event <B, M>),
  At (B::Time, Event <B, M>),
}
type Predictor <B: Basics, M: Mutator <B>, PA: PredictorAccessor <B>> =Rc <for <'b, 'c> Fn (& 'b mut PA)->Prediction <B, M>>;

mod SimpleFlatTimeSteward {
use super::{SiphashID, FieldID, Field, ExtendedTime, Basics, TimeSteward, FiatEventOperationResult};
use std::collections::{HashMap, BTreeMap};
use std::any::Any;
use std::borrow::{Borrow, Cow};
use std::rc::Rc;

struct ConstantPart <'a, B: Basics> {
  predictors: Vec<Predictor <'a, B>>,
  constants: B::Constants,
}
#[derive (Clone)]
struct BothParts <'a, B: Basics> {
  entity_states: HashMap< FieldID, Box <Any>>,
  last_change: B::Time,
  fiat_events: BTreeMap<ExtendedTime <B>, Event <'a, B>>,
  predictions: BTreeMap<ExtendedTime <B>, Prediction <'a, B>>,
  prediction_dependencies: HashMap<FieldID, Vec<ExtendedTime <B>>>,
  constant_part: Rc< ConstantPart <'a, B>>,
}

pub struct Steward <'a, B: Basics + 'a> {
  data: Cow <'a, BothParts <'a, B>>,
}
pub struct Snapshot <'a, B: Basics + 'a> {
  now: B::Time,
  data: &'a BothParts <'a, B>,
}
pub struct Mutator <'a, B: Basics + 'a> {
  now: B::Time,
  steward: & 'a mut BothParts <'a, B>,
}
pub struct PredictorAccessor <'a, B: Basics + 'a> {
  steward: & 'a mut BothParts <'a, B>,
}
type Event <'a, B: Basics + 'a> = super::Event <B, Mutator <'a, B>>;
type Prediction <'a, B: Basics + 'a> = super::Prediction <B, Mutator <'a, B>>;
type Predictor <'a, B: Basics + 'a> = super::Predictor <B, Mutator <'a, B>, PredictorAccessor <'a, B>>;

impl <'a, B: Basics> super::Accessor <B> for Snapshot <'a, B> {
  fn get <F: Field> (&mut self, id: SiphashID)-> Option <& F::Data> {
    self. data.get ::<F> (id)
  }
}
impl <'a, B: Basics> super::Accessor <B> for Mutator <'a, B> {
  fn get <F: Field> (&mut self, id: SiphashID)-> Option <& F::Data> {
    self. data.get::<F> (id)
  }
}
impl <'a, B: Basics> super::Accessor <B> for PredictorAccessor <'a, B> {
  fn get <F: Field> (&mut self, id: SiphashID)-> Option <& F::Data> {
    self. data.get::<F> (id)
  }
}

impl <'a, B: Basics> super::MomentaryAccessor <B> for Snapshot <'a, B> {
  fn now (& self)->B::Time {self.now}
}
impl <'a, B: Basics> super::MomentaryAccessor <B> for Mutator <'a, B> {
  fn now (& self)->B::Time {self.now}
}
impl <'a, B: Basics> super::PredictorAccessor <B> for PredictorAccessor <'a, B> {}
impl <'a, B: Basics> super::Snapshot <B> for Snapshot <'a, B> {}

impl <'a, B: Basics> super::Mutator <B> for Mutator <'a, B> {
  fn get_mut <F: Field> (&mut self, id: SiphashID)->Option <&mut F::Data> where F::Data: Clone {}
  fn set <F: Field> (&mut self, id: SiphashID, data: Option <F::Data>) {}
  fn random_bits (&mut self, num_bits:u32)->u64 {}
  fn random_id (&mut self)->SiphashID {}
}

impl <'a, B: Basics>BothParts <'a, B> {
  fn get <F: Field> (&mut self, id: SiphashID)-> Option <& F::Data> {
    self.entity_states.get (& FieldID {entity: id, field: F::unique_identifier ()}).map (| something | something.downcast ::<F::Data> ().unwrap ().borrow ())
  }
}

impl <'a, B: Basics>Steward <'a, B> {
  fn new (constants: B::Constants, predictors: Vec<Predictor <'a, B>>)->Self {}
}
impl <'a, B: Basics> super::TimeSteward <'a, B> for Steward <'a, B> {
  type S = Snapshot <'a, B>;
  type M =Mutator <'a, B>;
  type P =PredictorAccessor <'a, B>;

  type Event = Event <'a, B>;
  type Prediction = super::Prediction <B, Self::Event>;
  type Predictor = super::Predictor <B, Self::P, Self::Prediction>;

  fn insert_fiat_event (&mut self, time: B::Time, distinguisher: u64, event: Self::Event)->FiatEventOperationResult {}
  fn erase_fiat_event (&mut self, time: B::Time, distinguisher: u64)->FiatEventOperationResult {}
  fn snapshot_before (&mut self, time: B::Time)->Option <Self::S> {}
}

}

 #[test]
fn it_works() {
}
<commit_msg>More implementing<commit_after>use std::hash::{Hash, Hasher,SipHasher};
use std::any::Any;
use std::rc::Rc;

#[derive (Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct SiphashID {
data: [u64; 2],
}
pub struct SiphashID_Generator {
data: [SipHasher; 2],
}
impl Hasher for SiphashID_Generator {
fn finish (& self)->u64 {panic!()}//Hack: this is actually for generating SiphashID, not 64-bit
fn write (&mut self, bytes: & [u8]) {self.data [0].write (bytes);self.data [1].write (bytes);}
//TODO: should we implement the others for efficiency?
}
impl SiphashID_Generator {
fn generate (& self)->SiphashID {SiphashID {data: [self.data [0].finish (), self.data [1].finish ()]}}
}

//TODO: Shouldn't "ordered type with minimum and maximum values" be a trait common to other situations as well? Find out if there's a standard name for that.
pub trait BaseTime: Clone + Ord {
  fn min_time ()->Self;
  fn max_time ()->Self;
}
impl BaseTime for i64 {
  fn min_time ()->i64 {i64::min_value ()}
  fn max_time ()->i64 {i64::max_value ()}
}

pub trait Field {
  type Data: Any;// = Self;

  /**
  Returns a constant identifier for the type, which must be 64 bits of random data.

  Thanks to the [birthday problem](https://en.wikipedia.org/wiki/Birthday_problem), this would have a >1% chance of a collision with a mere 700 million Field implementors. I don't think we need to worry about this. 128 bit IDs are necessary for entities, because computers can generate billions of them easily, but this isn't the same situation.

  It might seem desirable to default to a hash of the TypeId of Self, for the convenience of some implementations. However, Rust does not guarantee that the TypeId remains the same across different compilations or different compiler versions. And it certainly doesn't remain the same when you add or remove types from your code, which would be desirable for compatibility between different versions of your program. Also, the Rust interface for getting the TypeId is currently unstable. Using an explicit constant is simply better.

  TODO: change this into an associated constant once associated constants become stable.
  */
  fn unique_identifier ()->u64;

  /**
  Implementors MAY return true if first and second are indistinguishable.

  This is labeled "unsafe" because imperfect implementations can easily cause nondeterminism in the TimeSteward. Using the default is fine, and implementing it is only an optimization. Don't implement this unless you know what you're doing.

  This is similar to requiring Data to be PartialEq, but with an important difference. PartialEq only requires the comparison to be an equivalence relation, but does NOT require that (first == second) guarantee that there is no observable difference between the values. Therefore, trusting arbitrary implementations of PartialEq would be unsafe (in the sense that it would allow the TimeSteward to behave non-deterministically).

  TODO: perhaps we can create default implementations of this for POD types.
  TODO: can we create automated tests for implementations of this function?
  */
  fn guaranteed_equal__unsafe (first: & Self::Data, second: & Self::Data)->bool {false}
}

#[derive (Clone, PartialEq, Eq, Hash)]
struct FieldID {
  entity: SiphashID,
  field: u64,
}

#[derive (Clone, PartialEq, Eq, PartialOrd, Ord)]
struct GenericExtendedTime <Base: BaseTime> {
  base: Base,
  iteration: u64,
  id: SiphashID,
}

/**
This is intended to be implemented on an empty struct. Requiring Clone is a hack to work around [a compiler weakness](https://github.com/rust-lang/rust/issues/26925).
*/
pub trait Basics: Clone {
  type Time: BaseTime;
  type Constants;
}
type ExtendedTime <B: Basics> = GenericExtendedTime <B::Time>;

//Note: in the future, we expect we might use a custom hash table type that knows it can rely on SiphashID to already be random, so we don't need to hash it again. This also applies to FieldID, although there may be some complications in that case.
impl Hash for SiphashID {
  fn hash <H: Hasher> (& self, state: &mut H) {self.data [0].hash (state);}
}
impl <Base: BaseTime> Hash for GenericExtendedTime <Base>{
  fn hash <H: Hasher> (& self, state: &mut H) {self.id.hash (state);}
}

pub trait Accessor <B: Basics> {
  fn get <F: Field> (&mut self, id: SiphashID)-> Option <& F::Data>;
  fn constants (& self)->& B::Constants;
}

pub trait MomentaryAccessor <B: Basics>: Accessor <B> {
  fn now (& self)->B::Time;
}

pub trait Mutator <B: Basics>: MomentaryAccessor <B> {
  fn get_mut <F: Field> (&mut self, id: SiphashID)->Option <&mut F::Data> where F::Data: Clone;
  fn set <F: Field> (&mut self, id: SiphashID, data: Option <F::Data>);
  fn random_bits (&mut self, num_bits:u32)->u64;
  fn random_id (&mut self)->SiphashID;
}
pub trait PredictorAccessor <B: Basics>: Accessor <B> {

}
pub trait Snapshot <B: Basics>: MomentaryAccessor <B> {
}

pub enum FiatEventOperationResult {
  Success,
  InvalidInput,
  InvalidTime,
}

pub trait TimeSteward <'a, B: Basics> {
  type S: Snapshot <B>;
  type Event;

  /**
  TimeSteward implementors are permitted, but not required, to discard old data in order to save memory. This may make the TimeSteward unusable at some points in its history.

  Newly created stewards should generally have valid_from() == B::Time::min_time().

  All implementors must obey certain restrictions on how other TimeSteward methods may change the result of valid_from(). Implementors may have their own methods that can alter this in customized ways, which should be documented with those individual methods.
  */
  fn valid_from (& self)->B::Time;

  /**
  Inserts a fiat event at some point in the history.

  If time < valid_from(), this does nothing and returns InvalidTime. If there is already a fiat event with the same time and distinguisher, this does nothing and returns InvalidInput. Otherwise, it inserts the event and returns Success.

  steward.insert_fiat_event(time, _) must not return InvalidTime if time >= steward.valid_from().
  steward.insert_fiat_event() may not change steward.valid_from().
  */
  fn insert_fiat_event (&mut self, time: B::Time, distinguisher: u64, event: Self::Event)->FiatEventOperationResult ;

  /**
  Erases a fiat event that has been inserted previously.

  If time < valid_from(), this does nothing and returns InvalidTime. If there is no fiat event with the specified time and distinguisher, this does nothing and returns InvalidInput. Otherwise, it erases the event and returns Success.

  steward.erase_fiat_event(time, _) must not return InvalidTime if time >= steward.valid_from().
  steward.erase_fiat_event() may not change steward.valid_from().
  */
  fn erase_fiat_event (&mut self, time: B::Time, distinguisher: u64)->FiatEventOperationResult ;

  /**
  Returns a "snapshot" into the TimeSteward.

  The snapshot is guaranteed to be valid and unchanging for the full lifetime of the TimeSteward. It is specific to both the time argument, and the current collection of fiat events. Callers may freely call mutable methods of the same TimeSteward after taking a snapshot, without changing the contents of the snapshot.

  Each TimeSteward implementor determines exactly how to provide these guarantees. Implementors should provide individual guarantees about the processor-time bounds of snapshot operations.

  steward.snapshot_before(time) must return Some if time >= steward.valid_from().
  steward.snapshot_before(time) may not increase steward.valid_from() beyond time.
  */
  //note: we implement "before" and not "after" because we might be banning events that happen during max_time
  fn snapshot_before (&mut self, time: B::Time)->Option <Self::S>;
}

pub trait FlatTimeSteward <'a, B: Basics>:TimeSteward <'a, B> {
  fn valid_strictly_between (& self)->(B::Time, B::Time);
}

type Event <M> =Rc <Fn (&mut M)>;
#[derive (Clone)]
enum Prediction <B: Basics, E> {
  Nothing,
  Immediately (E),
  At (B::Time, E),
}
type Predictor <B: Basics, M: Mutator <B>, PA: PredictorAccessor <B>> =Rc <for <'b, 'c> Fn (& 'b mut PA)->Prediction <B, Event <M>>>;

mod SimpleFlatTimeSteward {
use super::{SiphashID, FieldID, Field, ExtendedTime, Basics, TimeSteward, FiatEventOperationResult};
use std::collections::{HashMap, BTreeMap};
use std::any::Any;
use std::borrow::{Borrow, Cow};
use std::rc::Rc;

struct ConstantPart <'a, B: Basics + 'a> {
  predictors: Vec<Predictor <'a, B>>,
  constants: B::Constants,
}
#[derive (Clone)]
struct BothParts <'a, B: Basics + 'a> {
  entity_states: HashMap< FieldID, Rc<Any>>,
  last_change: B::Time,
  fiat_events: BTreeMap<ExtendedTime <B>, Event <'a, B>>,
  predictions: BTreeMap<ExtendedTime <B>, Prediction <'a, B>>,
  prediction_dependencies: HashMap<FieldID, Vec<ExtendedTime <B>>>,
  constant_part: Rc< ConstantPart <'a, B>>,
}

pub struct Steward <'a, B: Basics + 'a> {
  data: Cow <'a, BothParts <'a, B>>,
}
pub struct Snapshot <'a, B: Basics + 'a> {
  now: B::Time,
  data: &'a BothParts <'a, B>,
}
pub struct Mutator <'a, B: Basics + 'a> {
  now: B::Time,
  data: & 'a mut BothParts <'a, B>,
}
pub struct PredictorAccessor <'a, B: Basics + 'a> {
  data: & 'a mut BothParts <'a, B>,
}
pub type Event <'a, B: Basics + 'a> = super::Event <Mutator <'a, B>>;
type Prediction <'a, B: Basics + 'a> = super::Prediction <B, Event <'a, B>>;
type Predictor <'a, B: Basics + 'a> = super::Predictor <B, Mutator <'a, B>, PredictorAccessor <'a, B>>;

impl <'a, B: Basics> super::Accessor <B> for Snapshot <'a, B> {
  fn get <F: Field> (&mut self, id: SiphashID)-> Option <& F::Data> {
    self. data.get ::<F> (id)
  }
  fn constants (& self)->& B::Constants {& self.data.constant_part.constants}
}
impl <'a, B: Basics> super::Accessor <B> for Mutator <'a, B> {
  fn get <F: Field> (&mut self, id: SiphashID)-> Option <& F::Data> {
    self. data.get::<F> (id)
  }
  fn constants (& self)->& B::Constants {& self.data.constant_part.constants}
}
impl <'a, B: Basics> super::Accessor <B> for PredictorAccessor <'a, B> {
  fn get <F: Field> (&mut self, id: SiphashID)-> Option <& F::Data> {
    self. data.get::<F> (id)
  }
  fn constants (& self)->& B::Constants {& self.data.constant_part.constants}
}

impl <'a, B: Basics> super::MomentaryAccessor <B> for Snapshot <'a, B> {
  fn now (& self)->B::Time {self.now}
}
impl <'a, B: Basics> super::MomentaryAccessor <B> for Mutator <'a, B> {
  fn now (& self)->B::Time {self.now}
}
impl <'a, B: Basics> super::PredictorAccessor <B> for PredictorAccessor <'a, B> {}
impl <'a, B: Basics> super::Snapshot <B> for Snapshot <'a, B> {}

impl <'a, B: Basics> super::Mutator <B> for Mutator <'a, B> {
  fn get_mut <F: Field> (&mut self, id: SiphashID)->Option <&mut F::Data> where F::Data: Clone {}
  fn set <F: Field> (&mut self, id: SiphashID, data: Option <F::Data>) {}
  fn random_bits (&mut self, num_bits:u32)->u64 {}
  fn random_id (&mut self)->SiphashID {}
}

impl <'a, B: Basics>BothParts <'a, B> {
  fn get <F: Field> (&mut self, id: SiphashID)-> Option <& F::Data> {
    self.entity_states.get (& FieldID {entity: id, field: F::unique_identifier ()}).map (| something | something.downcast_ref ::<F::Data> ().unwrap ().borrow ())
  }
}

impl <'a, B: Basics>Steward <'a, B> {
  fn new (constants: B::Constants, predictors: Vec<Predictor <'a, B>>)->Self {}
}
impl <'a, B: Basics> super::TimeSteward <'a, B> for Steward <'a, B> {
  type S = Snapshot <'a, B>;
  type Event = Event <'a, B>;

  fn valid_from (& self)->B::Time {}
  fn insert_fiat_event (&mut self, time: B::Time, distinguisher: u64, event: Self::Event)->FiatEventOperationResult {}
  fn erase_fiat_event (&mut self, time: B::Time, distinguisher: u64)->FiatEventOperationResult {}
  fn snapshot_before (&mut self, time: B::Time)->Option <Self::S> {}
}

}

 #[test]
fn it_works() {
}
<|endoftext|>


<commit_before>extern crate num;

pub mod create;
pub use create::*;

pub mod set;
pub use set::*;

pub mod mul;
pub use mul::*;

pub mod sdiv;
pub use sdiv::*;

pub mod misc;
pub use misc::*;

pub mod transform;
pub use transform::*;
<commit_msg>updates<commit_after>#![feature(no_std)]
#![no_std]

extern crate num;

pub mod create;
pub use create::*;

pub mod set;
pub use set::*;

pub mod mul;
pub use mul::*;

pub mod sdiv;
pub use sdiv::*;

pub mod misc;
pub use misc::*;

pub mod transform;
pub use transform::*;
<|endoftext|>


<commit_before>//! This crate provides only one struct, `PrimeIter` implementing `Iterator`
//! which yields prime numbers as an `u64`.
//!

/// `PrimeIter` is used for generating an endless stream of prime numbers in an
/// efficient way.
///
/// The implementation of `Iterator` makes it easy to iterate over prime
/// numbers.
///
/// Generating the first ten prime numbers:
///
/// ```
/// # use primeiter::PrimeIter;
///
/// let primes = PrimeIter::new();
/// let v: Vec<_> = primes.take(10).collect();
///
/// assert_eq!(v,vec![2,3,5,7,11,13,17,19,23,29]);
/// ```
///
/// Printing an endless stream of prime numbers:
///
/// ```no_run
/// # use primeiter::PrimeIter;
/// for prime in PrimeIter::new()
/// {
///		println!("{}",prime);
/// }
/// ```
///
pub struct PrimeIter
{
	primes: Vec<u64>,
}

impl PrimeIter
{
	/// Returns a new instance of `PrimeIter`.
	///
	/// # Examples
	///
	/// ```
	/// # use primeiter::PrimeIter;
	/// let iter = PrimeIter::new();
	/// ```
	///
	pub fn new() -> PrimeIter
	{
		PrimeIter
		{
			primes: Vec::new(),
		}
	}
}

impl Iterator for PrimeIter
{
	type Item = u64;

	fn next(&mut self) -> Option<Self::Item>
	{
		if self.primes.last() == None
		{
			self.primes.push(2);
			return Some(2);
		}
		'outer: for num in ((self.primes.last().unwrap()+1)..).filter(|i|*i%2!=0)
		{
			if self.primes.iter().take_while(|i|*i**i<=num).any(|i|num%i==0)
			{
				continue 'outer;
			}
			self.primes.push(num);
			return Some(num);
		}
		None
	}
}

<commit_msg>rewrite to be more rustic<commit_after>//! This crate provides only one struct, `PrimeIter` implementing `Iterator`
//! which yields prime numbers as an `u64`.
//!

/// `PrimeIter` is used for generating an endless stream of prime numbers in an
/// efficient way.
///
/// The implementation of `Iterator` makes it easy to iterate over prime
/// numbers.
///
/// Generating the first ten prime numbers:
///
/// ```
/// # use primeiter::PrimeIter;
///
/// let primes = PrimeIter::new();
/// let v: Vec<_> = primes.take(10).collect();
///
/// assert_eq!(v,vec![2,3,5,7,11,13,17,19,23,29]);
/// ```
///
/// Printing an endless stream of prime numbers:
///
/// ```no_run
/// # use primeiter::PrimeIter;
/// for prime in PrimeIter::new()
/// {
///		println!("{}",prime);
/// }
/// ```
///
pub struct PrimeIter
{
	primes: Vec<u64>,
}

impl PrimeIter
{
	/// Returns a new instance of `PrimeIter`.
	///
	/// # Examples
	///
	/// ```
	/// # use primeiter::PrimeIter;
	/// let iter = PrimeIter::new();
	/// ```
	///
	pub fn new() -> PrimeIter
	{
		PrimeIter
		{
			primes: Vec::new(),
		}
	}
}

impl Iterator for PrimeIter
{
	type Item = u64;

	fn next(&mut self) -> Option<Self::Item>
	{
		if let Some(&last) = self.primes.last()
		{
			for next in ((last+1)..).filter(|i|i&1 != 0)
			{
				if self.primes.iter().take_while(|&&i|i*i <= next).all(|&p|next%p != 0)
				{
					self.primes.push(next);
					return Some(next);
				}
			}
		}
		else
		{
			self.primes.push(2);
			return Some(2);
		}

		None
	}
}

<|endoftext|>


<commit_before>extern crate base64;
extern crate hyper;
extern crate libc;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
extern crate log4rs;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;

use base64::{encode, decode};
use hyper::Client;
use hyper::client::response::Response;
use hyper::header::{Headers, ContentType};
use hyper::mime::{Mime, TopLevel, SubLevel};
use hyper::status::StatusCode;
use libc::{uint8_t, size_t};
use log::LogLevelFilter;
use log4rs::append::file::FileAppender;
use log4rs::config::{Appender, Config, Logger, Root};
use log4rs::encode::pattern::PatternEncoder;
use serde::Serialize;
use std::collections::HashMap;
use std::env::var;
use std::io::Read;
use std::slice;
use std::sync::{Once, ONCE_INIT, Mutex};

const BASE_URL: &'static str = "http://localhost:8080/k2/ctapi/";

static OK: i8 = 0;
static ERR_INVALID: i8 = -1;
static ERR_HOST: i8 = -127;

static INIT: Once = ONCE_INIT;

lazy_static! {
    static ref MAP: Mutex<HashMap<u16, u16>> = Mutex::new(HashMap::new());
}

#[derive(Serialize)]
struct Empty();

#[derive(Serialize)]
struct RequestData {
    dad: u8,
    sad: u8,
    lenc: usize,
    command: String,
    lenr: usize,
}

#[allow(non_snake_case)]
#[derive(Deserialize)]
struct ResponseData {
    dad: u8,
    sad: u8,
    lenr: usize,
    response: String,
    responseCode: i8,
}

macro_rules! post_request {
    ($path:expr) => (post_request($path, &Empty{}));
    ($path:expr, $data:expr) => (post_request($path, $data));
}

#[no_mangle]
#[allow(non_snake_case, unused_must_use)]
pub extern "C" fn CT_init(ctn: u16, pn: u16) -> i8 {
    init_logging();

    debug!("CT_init: Called (ctn {}, pn {})", ctn, pn);

    // Do we know this CTN?
    if MAP.lock().unwrap().contains_key(&ctn) {
        debug!("CT_init: Card terminal has already been opened. Returning {}",
               ERR_INVALID);
        return ERR_INVALID;
    }

    // Build the request URL
    let endpoint = "ct_init".to_string();
    let path = endpoint + "/" + &ctn.to_string() + "/" + &pn.to_string();

    // Perform the request
    let mut response = post_request!(&path);

    match response.status {
        StatusCode::Ok => {
            // Cast server response
            let mut body = String::new();
            response.read_to_string(&mut body).unwrap();

            let status = body.parse::<i8>().unwrap();
            if status == OK {
                // Store CTN
                MAP.lock().unwrap().insert(ctn, pn);
                debug!("CT_init: Card terminal opened.");
            }

            debug!("CT_init: Returning {}", status);
            status
        }
        _ => {
            error!("CT_init: Response not OK! Returning {}", ERR_HOST);
            ERR_HOST
        }
    }
}

#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CT_data(ctn: u16,
                          dad: *mut uint8_t,
                          sad: *mut uint8_t,
                          lenc: size_t,
                          command: *const uint8_t,
                          lenr: *mut size_t,
                          response: *mut uint8_t)
                          -> i8 {
    init_logging();

    unsafe {
        let dad: &mut u8 = &mut *dad;

        let sad: &mut u8 = &mut *sad;

        let lenr: &mut size_t = &mut *lenr;

        let command = slice::from_raw_parts(command, lenc as usize);

        let response = slice::from_raw_parts_mut(response, *lenr);

        debug!("CT_data: Called (ctn {}, dad {}, sad {}, lenc {}, \
               command {:?}, lenr {}), response.len() {})",
               ctn,
               dad,
               sad,
               lenc,
               command,
               lenr,
               response.len());

        if !MAP.lock().unwrap().contains_key(&ctn) {
            debug!("CT_data: Card terminal has not been opened. Returning {}",
                   ERR_INVALID);
            return ERR_INVALID;
        }

        let requestData = RequestData {
            dad: *dad,
            sad: *sad,
            lenc: lenc,
            command: encode(command),
            lenr: *lenr,
        };

        let pn = MAP.lock().unwrap();
        let pn = pn.get(&ctn).unwrap();
        let endpoint = "ct_data".to_string();
        let path = endpoint + "/" + &ctn.to_string() + "/" + &pn.to_string();

        let mut http_response = post_request(&path, &requestData);

        match http_response.status {
            StatusCode::Ok => {
                // decode server response
                let mut body = String::new();
                http_response.read_to_string(&mut body).unwrap();
                debug!("CT_data: Response body: {}", body);

                let responseData: ResponseData = serde_json::from_str(&body).unwrap();

                if responseData.responseCode == OK {
                    *dad = responseData.dad;
                    *sad = responseData.sad;
                    *lenr = responseData.lenr;

                    let decoded = decode(&responseData.response).unwrap();
                    debug!("CT_data: Decoded response field {:?}", decoded);

                    for (place, element) in response.iter_mut().zip(decoded.iter()) {
                        *place = *element;
                    }
                }
                debug!("CT_data: Returning {}", responseData.responseCode);
                return responseData.responseCode;
            }
            _ => {
                error!("CT_data: Response not OK! Returning {}", ERR_HOST);
                ERR_HOST
            }
        }
    }
}

#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CT_close(ctn: u16) -> i8 {
    init_logging();

    debug!("CT_close: Called (ctn {})", ctn);

    // Do we know this CTN?
    if !MAP.lock().unwrap().contains_key(&ctn) {
        debug!("CT_close: Card terminal has not been opened. Returning {}",
               ERR_INVALID);
        return ERR_INVALID;
    }

    // Build the request URL
    let pn = MAP.lock().unwrap().get(&ctn).unwrap().clone();
    let endpoint = "ct_close".to_string();
    let path = endpoint + "/" + &ctn.to_string() + "/" + &pn.to_string();

    // Perform the request
    let mut response = post_request!(&path);

    match response.status {
        StatusCode::Ok => {
            // Cast server response
            let mut body = String::new();
            response.read_to_string(&mut body).unwrap();

            let status = body.parse::<i8>().unwrap();
            if status == OK {
                // Remove CTN
                MAP.lock().unwrap().remove(&ctn);
                debug!("CT_close: Card terminal has been closed.");
            }

            debug!("CT_close: Returning {}", status);
            status
        }
        _ => {
            error!("CT_close: Response not OK! Returning {}", ERR_HOST);
            ERR_HOST
        }
    }
}

fn init_logging() {
    match var("K2_LOG_PATH") {
        Ok(path) => {
            INIT.call_once(|| {
                let file = FileAppender::builder()
                    .encoder(Box::new(PatternEncoder::new("{d} {l} {M}: {m}{n}")))
                    .build(path + &"/ctehxk2.log".to_string())
                    .unwrap();

                let config = Config::builder()
                    .appender(Appender::builder().build("file", Box::new(file)))
                    .logger(Logger::builder()
                                .appender("file")
                                .additive(false)
                                .build("ctehxk2", LogLevelFilter::Debug))
                    .build(Root::builder()
                               .appender("file")
                               .build(LogLevelFilter::Error))
                    .unwrap();

                log4rs::init_config(config).unwrap();
            })
        }
        _ => (),
    }
}

fn post_request<T>(path: &str, payload: &T) -> Response
    where T: Serialize
{
    let base_url = var("K2_BASE_URL").unwrap_or(BASE_URL.to_string());
    let url = base_url + path;

    let client = Client::new();

    let mut headers = Headers::new();
    headers.set(ContentType(Mime(TopLevel::Application, SubLevel::Json, vec![])));

    let body = serde_json::to_string(&payload).unwrap();

    debug!("HTTP POST URL: {}", url);
    debug!("HTTP POST body: {:?}", body);

    let response = client
        .post(&url)
        .headers(headers)
        .body(&body[..])
        .send()
        .unwrap();

    debug!("{:?}", response); // TODO enrich output
    response
}
<commit_msg>remove global unsafe - adjust debug output<commit_after>extern crate base64;
extern crate hyper;
extern crate libc;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate log;
extern crate log4rs;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;

use base64::{encode, decode};
use hyper::Client;
use hyper::client::response::Response;
use hyper::header::{Headers, ContentType};
use hyper::mime::{Mime, TopLevel, SubLevel};
use hyper::status::StatusCode;
use libc::{uint8_t, size_t};
use log::LogLevelFilter;
use log4rs::append::file::FileAppender;
use log4rs::config::{Appender, Config, Logger, Root};
use log4rs::encode::pattern::PatternEncoder;
use serde::Serialize;
use std::collections::HashMap;
use std::env::var;
use std::io::Read;
use std::slice;
use std::sync::{Once, ONCE_INIT, Mutex};

const BASE_URL: &'static str = "http://localhost:8080/k2/ctapi/";

static OK: i8 = 0;
static ERR_INVALID: i8 = -1;
static ERR_HOST: i8 = -127;

static INIT: Once = ONCE_INIT;

lazy_static! {
    static ref MAP: Mutex<HashMap<u16, u16>> = Mutex::new(HashMap::new());
}

#[derive(Serialize)]
struct Empty();

#[derive(Serialize)]
struct RequestData {
    dad: u8,
    sad: u8,
    lenc: usize,
    command: String,
    lenr: usize,
}

#[allow(non_snake_case)]
#[derive(Deserialize)]
struct ResponseData {
    dad: u8,
    sad: u8,
    lenr: usize,
    response: String,
    responseCode: i8,
}

macro_rules! post_request {
    ($path:expr) => (post_request($path, &Empty{}));
    ($path:expr, $data:expr) => (post_request($path, $data));
}

#[no_mangle]
#[allow(non_snake_case, unused_must_use)]
pub extern "C" fn CT_init(ctn: u16, pn: u16) -> i8 {
    init_logging();

    debug!("CT_init: Called (ctn {}, pn {})", ctn, pn);

    // Do we know this CTN?
    if MAP.lock().unwrap().contains_key(&ctn) {
        debug!("CT_init: Card terminal has already been opened. Returning {}",
               ERR_INVALID);
        return ERR_INVALID;
    }

    // Build the request URL
    let endpoint = "ct_init".to_string();
    let path = endpoint + "/" + &ctn.to_string() + "/" + &pn.to_string();

    // Perform the request
    let mut response = post_request!(&path);

    match response.status {
        StatusCode::Ok => {
            // Cast server response
            let mut body = String::new();
            response.read_to_string(&mut body).unwrap();

            let status = body.parse::<i8>().unwrap();
            if status == OK {
                // Store CTN
                MAP.lock().unwrap().insert(ctn, pn);
                debug!("CT_init: Card terminal opened.");
            }

            debug!("CT_init: Returning {}", status);
            status
        }
        _ => {
            error!("CT_init: Response not OK! Returning {}", ERR_HOST);
            ERR_HOST
        }
    }
}

#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CT_data(ctn: u16,
                          dad: *mut uint8_t,
                          sad: *mut uint8_t,
                          lenc: size_t,
                          command: *const uint8_t,
                          lenr: *mut size_t,
                          response: *mut uint8_t)
                          -> i8 {
    init_logging();

    debug!("CT_data: Called");
    debug!(" ctn: {}", ctn);

    let _dad: &mut u8 = unsafe { &mut *dad };
    debug!(" dad: {}", _dad);

    let _sad: &mut u8 = unsafe { &mut *sad };
    debug!(" sad: {}", _sad);
    debug!(" lenc: {}", lenc);

    let _command = unsafe { slice::from_raw_parts(command, lenc as usize) };
    debug!(" command: {:?}", _command);

    let _lenr: &mut size_t = unsafe { &mut *lenr };
    debug!(" lenr: {}", _lenr);

    let _response = unsafe { slice::from_raw_parts_mut(response, *_lenr) };
    debug!(" response.len(): {}", _response.len());

    if !MAP.lock().unwrap().contains_key(&ctn) {
        debug!("CT_data: Card terminal has not been opened. Returning {}",
               ERR_INVALID);
        return ERR_INVALID;
    }

    let requestData = RequestData {
        dad: *_dad,
        sad: *_sad,
        lenc: lenc,
        command: encode(_command),
        lenr: *_lenr,
    };

    let pn = MAP.lock().unwrap();
    let pn = pn.get(&ctn).unwrap();
    let endpoint = "ct_data".to_string();
    let path = endpoint + "/" + &ctn.to_string() + "/" + &pn.to_string();

    let mut http_response = post_request(&path, &requestData);

    match http_response.status {
        StatusCode::Ok => {
            // decode server response
            let mut body = String::new();
            http_response.read_to_string(&mut body).unwrap();
            debug!("CT_data: Response body: {}", body);

            let responseData: ResponseData = serde_json::from_str(&body).unwrap();

            if responseData.responseCode == OK {
                *_dad = responseData.dad;
                *_sad = responseData.sad;
                *_lenr = responseData.lenr;

                let decoded = decode(&responseData.response).unwrap();
                debug!("CT_data: Decoded response field {:?}", decoded);

                for (place, element) in _response.iter_mut().zip(decoded.iter()) {
                    *place = *element;
                }
            }
            debug!("CT_data: Returning {}", responseData.responseCode);
            return responseData.responseCode;
        }
        _ => {
            error!("CT_data: Response not OK! Returning {}", ERR_HOST);
            ERR_HOST
        }
    }
}

#[no_mangle]
#[allow(non_snake_case)]
pub extern "C" fn CT_close(ctn: u16) -> i8 {
    init_logging();

    debug!("CT_close: Called (ctn {})", ctn);

    // Do we know this CTN?
    if !MAP.lock().unwrap().contains_key(&ctn) {
        debug!("CT_close: Card terminal has not been opened. Returning {}",
               ERR_INVALID);
        return ERR_INVALID;
    }

    // Build the request URL
    let pn = MAP.lock().unwrap().get(&ctn).unwrap().clone();
    let endpoint = "ct_close".to_string();
    let path = endpoint + "/" + &ctn.to_string() + "/" + &pn.to_string();

    // Perform the request
    let mut response = post_request!(&path);

    match response.status {
        StatusCode::Ok => {
            // Cast server response
            let mut body = String::new();
            response.read_to_string(&mut body).unwrap();

            let status = body.parse::<i8>().unwrap();
            if status == OK {
                // Remove CTN
                MAP.lock().unwrap().remove(&ctn);
                debug!("CT_close: Card terminal has been closed.");
            }

            debug!("CT_close: Returning {}", status);
            status
        }
        _ => {
            error!("CT_close: Response not OK! Returning {}", ERR_HOST);
            ERR_HOST
        }
    }
}

fn init_logging() {
    match var("K2_LOG_PATH") {
        Ok(path) => {
            INIT.call_once(|| {
                let file = FileAppender::builder()
                    .encoder(Box::new(PatternEncoder::new("{d} {l} {M}: {m}{n}")))
                    .build(path + &"/ctehxk2.log".to_string())
                    .unwrap();

                let config = Config::builder()
                    .appender(Appender::builder().build("file", Box::new(file)))
                    .logger(Logger::builder()
                                .appender("file")
                                .additive(false)
                                .build("ctehxk2", LogLevelFilter::Debug))
                    .build(Root::builder()
                               .appender("file")
                               .build(LogLevelFilter::Error))
                    .unwrap();

                log4rs::init_config(config).unwrap();
            })
        }
        _ => (),
    }
}

fn post_request<T>(path: &str, payload: &T) -> Response
    where T: Serialize
{
    let base_url = var("K2_BASE_URL").unwrap_or(BASE_URL.to_string());
    let url = base_url + path;

    let client = Client::new();

    let mut headers = Headers::new();
    headers.set(ContentType(Mime(TopLevel::Application, SubLevel::Json, vec![])));

    let body = serde_json::to_string(&payload).unwrap();

    debug!("HTTP POST URL: {}", url);
    debug!("HTTP POST body: {:?}", body);

    let response = client
        .post(&url)
        .headers(headers)
        .body(&body[..])
        .send()
        .unwrap();

    debug!("{:?}", response); // TODO enrich output
    response
}
<|endoftext|>


<commit_before>use glium::{VertexBuffer, IndexBuffer};
use glium::backend::glutin_backend::GlutinFacade;
use glium::index::{PrimitiveType, BufferCreationError};

#[derive(Copy, Clone)]
pub struct BaseVertex {
    pub position: [f32; 3],
}

implement_vertex!(BaseVertex, position);

pub struct Mesh {
    pub vb: VertexBuffer<BaseVertex>,
    pub ib: IndexBuffer<u32>,
}

impl Mesh {
    pub fn new(facade: &GlutinFacade, vb_data: &[BaseVertex], ib_data: &[u32]) -> Result<Mesh, String>
    {
        let vb = match VertexBuffer::new(facade, vb_data) {
            Ok(vb) => vb,
            Err(e) => return Err(format!("Error create vertex buffer: {}", e))
        };

        let ib = match IndexBuffer::new(facade, PrimitiveType::TrianglesList, ib_data) {
            Ok(ib) => ib,
            Err(e) => return Err(format!("Error create index buffer: {}", match e {
                BufferCreationError::IndexTypeNotSupported => format!("IndexTypeNotSupported"),
                BufferCreationError::PrimitiveTypeNotSupported => format!("PrimitiveTypeNotSupported"),
                BufferCreationError::BufferCreationError(creation_err) => format!("BufferCreationError={}", creation_err),
            }))
        };

        Ok(Mesh {
            vb: vb,
            ib: ib,
        })
    }
}
<commit_msg>mesh теперь работает с разными типами вершин<commit_after>use glium::{Vertex, VertexBuffer, IndexBuffer};
use glium::backend::glutin_backend::GlutinFacade;
use glium::index::{PrimitiveType};

#[derive(Copy, Clone)]
pub struct VertexBase {
    pub pos: [f32; 3],
}

implement_vertex!(VertexBase, pos);

#[derive(Copy, Clone)]
pub struct VertexTex {
    pub pos: [f32; 3],
    pub tex: [f32; 2],
}

implement_vertex!(VertexTex, pos, tex);

pub struct Mesh<TVertex> where TVertex: Copy {
    pub vb: VertexBuffer<TVertex>,
    pub ib: IndexBuffer<u32>,
}

impl<TVertex> Mesh<TVertex> where TVertex: Vertex {
    pub fn new(facade: &GlutinFacade, vb_data: &[TVertex], ib_data: &[u32]) -> Result<Mesh<TVertex>, String>
    {
        let vb = match VertexBuffer::new(facade, vb_data) {
            Ok(vb) => vb,
            Err(e) => return Err(format!("Error create vertex buffer: {}", e))
        };

        let ib = match IndexBuffer::new(facade, PrimitiveType::TrianglesList, ib_data) {
            Ok(ib) => ib,
            Err(e) => return Err(format!("Error create index buffer: {:?}", e))
        };

        Ok(Mesh {
            vb: vb,
            ib: ib,
        })
    }
}
<|endoftext|>


<commit_before>#![feature(alloc)]
#![feature(core)]
#![cfg_attr(test, feature(std_misc))]

use std::boxed::FnBox;
use std::cell::{Ref, RefMut, RefCell};
use std::marker::PhantomData;
use std::mem;
use std::sync::{Arc, Weak};
use std::sync::mpsc::sync_channel;

use self::debug::ThreadDebugger;

pub trait IsolationRunner: Sync + 'static {
    fn run_on_owning_thread(&self, f: Box<FnBox() + Send>);
}

pub enum OwningThread {}
pub enum NonOwningThread {}

pub struct ThreadIsolated<T, R: IsolationRunner, ThreadKind> {
    inner: Arc<Inner<T, R>>,
    debug: ThreadDebugger,
    _marker: PhantomData<ThreadKind>,
}

struct Inner<T, R: IsolationRunner> {
    item: RefCell<T>,
    runner: R,
}

impl<T, R: IsolationRunner> ThreadIsolated<T, R, OwningThread> {
    pub unsafe fn new(item: T, runner: R) -> ThreadIsolated<T, R, OwningThread> {
        ThreadIsolated{
            inner: Arc::new(Inner{
                item: RefCell::new(item),
                runner: runner,
            }),
            debug: ThreadDebugger::new(),
            _marker: PhantomData,
        }
    }

    pub fn borrow(&self) -> Ref<T> {
        self.debug.assert_on_originating_thread();
        self.inner.item.borrow()
    }

    pub fn borrow_mut(&self) -> RefMut<T> {
        self.debug.assert_on_originating_thread();
        self.inner.item.borrow_mut()
    }

    pub fn clone_for_non_owning_thread(&self) -> ThreadIsolated<T, R, NonOwningThread> {
        ThreadIsolated{
            inner: self.inner.clone(),
            debug: self.debug,
            _marker: PhantomData,
        }
    }

    pub fn downgrade_for_non_owning_thread(&self) -> ThreadIsolatedWeak<T, R> {
        ThreadIsolatedWeak{
            inner: self.inner.downgrade(),
            debug: self.debug,
        }
    }
}

impl<T, R: IsolationRunner> ThreadIsolated<T, R, NonOwningThread> {
    pub unsafe fn as_owning_thread(self) -> ThreadIsolated<T, R, OwningThread> {
        self.debug.assert_on_originating_thread();
        ThreadIsolated{
            inner: self.inner,
            debug: self.debug,
            _marker: PhantomData,
        }
    }

    pub fn with<U, F>(&self, f: F) -> U where
        F: FnOnce(&RefCell<T>) -> U + Send,
        U: Send,
    {
        self.debug.assert_not_on_originating_thread();

        let (tx, rx) = sync_channel(1);

        let closure: Box<FnBox() + Send> = Box::new(move|| {
            self.debug.assert_on_originating_thread();
            let u = f(&self.inner.item);
            tx.send(u).unwrap();
        });

        // `closure` contains references, but IsolationRunner expects an FnBox
        // that is 'static. We're using a channel to block until after `f` has been
        // called, so any references it contains will be alive as long as they need
        // to be. The borrow checker can't know that (the channels are purely a
        // runtime thing), so we'll use mem::transmute to force `closure` to *look*
        // like a 'static FnBox.
        //
        // This is safe because the runner can only call closure once, and we won't
        // return until after that call finishes.
        let closure: Box<FnBox() + Send + 'static> = unsafe { mem::transmute(closure) };
        self.inner.runner.run_on_owning_thread(closure);

        // Memory safety of the above closure relies on this recv() blocking until
        // the closure has run. It's not safe for us to just panic if recv() fails;
        // we need to tear down the whole process.
        match rx.recv() {
            Ok(u) => u,
            Err(err) => {
                println!("recv() failed: {}", err);
                unsafe { std::intrinsics::abort(); }
            }
        }
    }
}

impl<T, R: IsolationRunner> Clone for ThreadIsolated<T, R, NonOwningThread> {
    fn clone(&self) -> ThreadIsolated<T, R, NonOwningThread> {
        ThreadIsolated{
            inner: self.inner.clone(),
            debug: self.debug,
            _marker: PhantomData,
        }
    }
}

unsafe impl<T, R: IsolationRunner> Send for ThreadIsolated<T, R, NonOwningThread> {}
unsafe impl<T, R: IsolationRunner> Sync for ThreadIsolated<T, R, NonOwningThread> {}

pub struct ThreadIsolatedWeak<T, R: IsolationRunner> {
    inner: Weak<Inner<T, R>>,
    debug: ThreadDebugger,
}

impl<T, R: IsolationRunner> ThreadIsolatedWeak<T, R> {
    pub fn upgrade(&self) -> Option<ThreadIsolated<T, R, NonOwningThread>> {
        self.inner.upgrade().map(|inner| {
            ThreadIsolated{
                inner: inner,
                debug: self.debug,
                _marker: PhantomData,
            }
        })
    }
}

unsafe impl<T, R: IsolationRunner> Send for ThreadIsolatedWeak<T, R> {}
unsafe impl<T, R: IsolationRunner> Sync for ThreadIsolatedWeak<T, R> {}

#[cfg(debug_assertions)]
mod debug {
    use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};

    static THREAD_ID_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT;

    fn next_thread_id() -> usize {
        THREAD_ID_COUNTER.fetch_add(1, Ordering::SeqCst)
    }

    thread_local!(static THREAD_ID: usize = next_thread_id());

    fn our_thread_id() -> usize {
        THREAD_ID.with(|t| *t)
    }

    #[derive(Copy,Clone)]
    pub struct ThreadDebugger {
        thread_id: usize,
    }

    impl ThreadDebugger {
        pub fn new() -> ThreadDebugger {
            ThreadDebugger{
                thread_id: our_thread_id(),
            }
        }

        pub fn assert_on_originating_thread(&self) {
            assert!(self.thread_id == our_thread_id(), "item accessed off of owning thread");
        }

        pub fn assert_not_on_originating_thread(&self) {
            assert!(self.thread_id != our_thread_id(),
                    "item unexpectedly accessed on owning thread");
        }
    }
}

#[cfg(not(debug_assertions))]
mod debug {
    #[derive(Copy,Clone)]
    pub struct ThreadDebugger;

    impl ThreadDebugger {
        pub fn new() -> ThreadDebugger { ThreadDebugger }
        pub fn assert_on_originating_thread(&self) {}
        pub fn assert_not_on_originating_thread(&self) {}
    }
}

#[cfg(test)]
mod test {
    use std::thread;
    use std::sync::{Arc, Barrier, Mutex};
    use std::sync::mpsc::{channel, Sender};
    use std::boxed::FnBox;

    use super::{IsolationRunner, ThreadIsolated};

    #[test]
    fn test_normal_use() {
        // Create an isolation runner that uses channels to send boxed functions
        // back to the main thread for it to run.
        struct Runner {
            tx: Mutex<Sender<Box<FnBox() + Send>>>,
        }

        impl IsolationRunner for Runner {
            fn run_on_owning_thread(&self, boxed: Box<FnBox() + Send>) {
                let guard = self.tx.lock().unwrap();
                guard.send(boxed).unwrap();
            }
        }

        let (tx, rx) = channel();
        let (tx_f, rx_f) = channel();
        let (tx_clone, rx_clone) = channel();
        let runner = Runner{ tx: Mutex::new(tx_f) };

        // start up the owning thread
        let handle = thread::spawn(move|| {
            // create our ThreadIsolated...
            let t = unsafe { ThreadIsolated::new(0i32, runner) };

            // ...and give a non-owning clone back to the test_normal_use thread.
            tx_clone.send(t.clone_for_non_owning_thread()).unwrap();

            loop {
                select! (
                    // If we receive a message on rx, confirm that t has been incremented
                    // the expected number of times, then exit.
                    _ = rx.recv() => {
                        assert_eq!(*t.borrow(), 20);
                        return
                    },

                    // If we receive a function on rx_f, run it.
                    f = rx_f.recv() => {
                        f.unwrap()();
                    }
                )
            }
        });

        // start up 10 worker threads, each of which will try to increment the counter
        // owned by the thread above twice.
        let barrier = Arc::new(Barrier::new(11));
        let non_owning_t = rx_clone.recv().unwrap();
        for _ in 0 .. 10 {
            let b = barrier.clone();
            let t = non_owning_t.clone();
            thread::spawn(move|| {
                let t2 = t.clone();
                t.with(|refcell| {
                    *refcell.borrow_mut() += 1;

                    // Inside `with`, we're on the owning thread, so we can (unsafely)
                    // convert a NonOwningThread handle to an OwningThread handle.
                    let owning_t = unsafe { t2.as_owning_thread() };
                    *owning_t.borrow_mut() += 1;
                });
                b.wait();
            });
        }

        // wait until all worker threads are finished
        barrier.wait();

        // send the owning thread the message to check that its counter is as expected
        tx.send(()).unwrap();

        assert!(handle.join().is_ok());
    }

    #[cfg(debug_assertions)]
    mod debug_tests {
        use std::thread;
        use std::boxed::FnBox;
        use ::{IsolationRunner, ThreadIsolated};

        struct UnsafeNoopRunner;

        impl IsolationRunner for UnsafeNoopRunner {
            fn run_on_owning_thread(&self, f: Box<FnBox() + Send>) {
                f()
            }
        }

        #[test]
        fn test_accessing_nonowning_value_from_owning_thread_panics() {
            let handle = thread::spawn(move|| {
                let t = unsafe { ThreadIsolated::new(0i32, UnsafeNoopRunner) };
                let t2 = t.clone_for_non_owning_thread();

                t2.with(|t| {
                    *t.borrow_mut() = 1;
                });
            });

            assert!(handle.join().is_err());
        }

        #[test]
        fn test_accessing_owning_value_from_nonowning_thread_panics() {
            let t = unsafe { ThreadIsolated::new(0i32, UnsafeNoopRunner) };
            let t2 = t.clone_for_non_owning_thread();

            let handle = thread::spawn(move|| {
                t2.with(|t| {
                    *t.borrow_mut() = 1;
                });
            });

            assert!(handle.join().is_err());
        }

        #[test]
        fn test_as_owning_thread_panics_if_called_off_owning_thread() {
            let t = unsafe { ThreadIsolated::new(0i32, UnsafeNoopRunner) };
            let t2 = t.clone_for_non_owning_thread();

            let handle = thread::spawn(move|| {
                let _ = unsafe { t2.as_owning_thread() };
            });

            assert!(handle.join().is_err());
        }
    }
}
<commit_msg>Use Box<IsolationRunner> instead of making it a generic bound<commit_after>#![feature(alloc)]
#![feature(core)]
#![cfg_attr(test, feature(std_misc))]

use std::boxed::FnBox;
use std::cell::{Ref, RefMut, RefCell};
use std::marker::PhantomData;
use std::mem;
use std::sync::{Arc, Weak};
use std::sync::mpsc::sync_channel;

use self::debug::ThreadDebugger;

pub trait IsolationRunner: Sync + 'static {
    fn run_on_owning_thread(&self, f: Box<FnBox() + Send>);
}

pub enum OwningThread {}
pub enum NonOwningThread {}

pub struct ThreadIsolated<T, ThreadKind> {
    inner: Arc<Inner<T>>,
    debug: ThreadDebugger,
    _marker: PhantomData<ThreadKind>,
}

struct Inner<T> {
    item: RefCell<T>,
    runner: Box<IsolationRunner>,
}

impl<T> ThreadIsolated<T, OwningThread> {
    pub unsafe fn new<R: IsolationRunner>(item: T, runner: R) -> ThreadIsolated<T, OwningThread> {
        ThreadIsolated{
            inner: Arc::new(Inner{
                item: RefCell::new(item),
                runner: Box::new(runner),
            }),
            debug: ThreadDebugger::new(),
            _marker: PhantomData,
        }
    }

    pub fn borrow(&self) -> Ref<T> {
        self.debug.assert_on_originating_thread();
        self.inner.item.borrow()
    }

    pub fn borrow_mut(&self) -> RefMut<T> {
        self.debug.assert_on_originating_thread();
        self.inner.item.borrow_mut()
    }

    pub fn clone_for_non_owning_thread(&self) -> ThreadIsolated<T, NonOwningThread> {
        ThreadIsolated{
            inner: self.inner.clone(),
            debug: self.debug,
            _marker: PhantomData,
        }
    }

    pub fn downgrade_for_non_owning_thread(&self) -> ThreadIsolatedWeak<T> {
        ThreadIsolatedWeak{
            inner: self.inner.downgrade(),
            debug: self.debug,
        }
    }
}

impl<T> ThreadIsolated<T, NonOwningThread> {
    pub unsafe fn as_owning_thread(self) -> ThreadIsolated<T, OwningThread> {
        self.debug.assert_on_originating_thread();
        ThreadIsolated{
            inner: self.inner,
            debug: self.debug,
            _marker: PhantomData,
        }
    }

    pub fn with<U, F>(&self, f: F) -> U where
        F: FnOnce(&RefCell<T>) -> U + Send,
        U: Send,
    {
        self.debug.assert_not_on_originating_thread();

        let (tx, rx) = sync_channel(1);

        let closure: Box<FnBox() + Send> = Box::new(move|| {
            self.debug.assert_on_originating_thread();
            let u = f(&self.inner.item);
            tx.send(u).unwrap();
        });

        // `closure` contains references, but IsolationRunner expects an FnBox
        // that is 'static. We're using a channel to block until after `f` has been
        // called, so any references it contains will be alive as long as they need
        // to be. The borrow checker can't know that (the channels are purely a
        // runtime thing), so we'll use mem::transmute to force `closure` to *look*
        // like a 'static FnBox.
        //
        // This is safe because the runner can only call closure once, and we won't
        // return until after that call finishes.
        let closure: Box<FnBox() + Send + 'static> = unsafe { mem::transmute(closure) };
        self.inner.runner.run_on_owning_thread(closure);

        // Memory safety of the above closure relies on this recv() blocking until
        // the closure has run. It's not safe for us to just panic if recv() fails;
        // we need to tear down the whole process.
        match rx.recv() {
            Ok(u) => u,
            Err(err) => {
                println!("recv() failed: {}", err);
                unsafe { std::intrinsics::abort(); }
            }
        }
    }
}

impl<T> Clone for ThreadIsolated<T, NonOwningThread> {
    fn clone(&self) -> ThreadIsolated<T, NonOwningThread> {
        ThreadIsolated{
            inner: self.inner.clone(),
            debug: self.debug,
            _marker: PhantomData,
        }
    }
}

unsafe impl<T> Send for ThreadIsolated<T, NonOwningThread> {}
unsafe impl<T> Sync for ThreadIsolated<T, NonOwningThread> {}

pub struct ThreadIsolatedWeak<T> {
    inner: Weak<Inner<T>>,
    debug: ThreadDebugger,
}

impl<T> ThreadIsolatedWeak<T> {
    pub fn upgrade(&self) -> Option<ThreadIsolated<T, NonOwningThread>> {
        self.inner.upgrade().map(|inner| {
            ThreadIsolated{
                inner: inner,
                debug: self.debug,
                _marker: PhantomData,
            }
        })
    }
}

unsafe impl<T> Send for ThreadIsolatedWeak<T> {}
unsafe impl<T> Sync for ThreadIsolatedWeak<T> {}

#[cfg(debug_assertions)]
mod debug {
    use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};

    static THREAD_ID_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT;

    fn next_thread_id() -> usize {
        THREAD_ID_COUNTER.fetch_add(1, Ordering::SeqCst)
    }

    thread_local!(static THREAD_ID: usize = next_thread_id());

    fn our_thread_id() -> usize {
        THREAD_ID.with(|t| *t)
    }

    #[derive(Copy,Clone)]
    pub struct ThreadDebugger {
        thread_id: usize,
    }

    impl ThreadDebugger {
        pub fn new() -> ThreadDebugger {
            ThreadDebugger{
                thread_id: our_thread_id(),
            }
        }

        pub fn assert_on_originating_thread(&self) {
            assert!(self.thread_id == our_thread_id(), "item accessed off of owning thread");
        }

        pub fn assert_not_on_originating_thread(&self) {
            assert!(self.thread_id != our_thread_id(),
                    "item unexpectedly accessed on owning thread");
        }
    }
}

#[cfg(not(debug_assertions))]
mod debug {
    #[derive(Copy,Clone)]
    pub struct ThreadDebugger;

    impl ThreadDebugger {
        pub fn new() -> ThreadDebugger { ThreadDebugger }
        pub fn assert_on_originating_thread(&self) {}
        pub fn assert_not_on_originating_thread(&self) {}
    }
}

#[cfg(test)]
mod test {
    use std::thread;
    use std::sync::{Arc, Barrier, Mutex};
    use std::sync::mpsc::{channel, Sender};
    use std::boxed::FnBox;

    use super::{IsolationRunner, ThreadIsolated};

    #[test]
    fn test_normal_use() {
        // Create an isolation runner that uses channels to send boxed functions
        // back to the main thread for it to run.
        struct Runner {
            tx: Mutex<Sender<Box<FnBox() + Send>>>,
        }

        impl IsolationRunner for Runner {
            fn run_on_owning_thread(&self, boxed: Box<FnBox() + Send>) {
                let guard = self.tx.lock().unwrap();
                guard.send(boxed).unwrap();
            }
        }

        let (tx, rx) = channel();
        let (tx_f, rx_f) = channel();
        let (tx_clone, rx_clone) = channel();
        let runner = Runner{ tx: Mutex::new(tx_f) };

        // start up the owning thread
        let handle = thread::spawn(move|| {
            // create our ThreadIsolated...
            let t = unsafe { ThreadIsolated::new(0i32, runner) };

            // ...and give a non-owning clone back to the test_normal_use thread.
            tx_clone.send(t.clone_for_non_owning_thread()).unwrap();

            loop {
                select! (
                    // If we receive a message on rx, confirm that t has been incremented
                    // the expected number of times, then exit.
                    _ = rx.recv() => {
                        assert_eq!(*t.borrow(), 20);
                        return
                    },

                    // If we receive a function on rx_f, run it.
                    f = rx_f.recv() => {
                        f.unwrap()();
                    }
                )
            }
        });

        // start up 10 worker threads, each of which will try to increment the counter
        // owned by the thread above twice.
        let barrier = Arc::new(Barrier::new(11));
        let non_owning_t = rx_clone.recv().unwrap();
        for _ in 0 .. 10 {
            let b = barrier.clone();
            let t = non_owning_t.clone();
            thread::spawn(move|| {
                let t2 = t.clone();
                t.with(|refcell| {
                    *refcell.borrow_mut() += 1;

                    // Inside `with`, we're on the owning thread, so we can (unsafely)
                    // convert a NonOwningThread handle to an OwningThread handle.
                    let owning_t = unsafe { t2.as_owning_thread() };
                    *owning_t.borrow_mut() += 1;
                });
                b.wait();
            });
        }

        // wait until all worker threads are finished
        barrier.wait();

        // send the owning thread the message to check that its counter is as expected
        tx.send(()).unwrap();

        assert!(handle.join().is_ok());
    }

    #[cfg(debug_assertions)]
    mod debug_tests {
        use std::thread;
        use std::boxed::FnBox;
        use ::{IsolationRunner, ThreadIsolated};

        struct UnsafeNoopRunner;

        impl IsolationRunner for UnsafeNoopRunner {
            fn run_on_owning_thread(&self, f: Box<FnBox() + Send>) {
                f()
            }
        }

        #[test]
        fn test_accessing_nonowning_value_from_owning_thread_panics() {
            let handle = thread::spawn(move|| {
                let t = unsafe { ThreadIsolated::new(0i32, UnsafeNoopRunner) };
                let t2 = t.clone_for_non_owning_thread();

                t2.with(|t| {
                    *t.borrow_mut() = 1;
                });
            });

            assert!(handle.join().is_err());
        }

        #[test]
        fn test_accessing_owning_value_from_nonowning_thread_panics() {
            let t = unsafe { ThreadIsolated::new(0i32, UnsafeNoopRunner) };
            let t2 = t.clone_for_non_owning_thread();

            let handle = thread::spawn(move|| {
                t2.with(|t| {
                    *t.borrow_mut() = 1;
                });
            });

            assert!(handle.join().is_err());
        }

        #[test]
        fn test_as_owning_thread_panics_if_called_off_owning_thread() {
            let t = unsafe { ThreadIsolated::new(0i32, UnsafeNoopRunner) };
            let t2 = t.clone_for_non_owning_thread();

            let handle = thread::spawn(move|| {
                let _ = unsafe { t2.as_owning_thread() };
            });

            assert!(handle.join().is_err());
        }
    }
}
<|endoftext|>


<commit_before>//! A simple event driven highly available message queue backed with PostgreSQL,
//! focused on stability and performance.
//!
//! ## Producer
//!
//! ```rust,no_run
//! extern crate pqbus;
//!
//! use pqbus::{Queue ,StringMessage};
//!
//! fn main() {
//!     let bus = pqbus::new("postgres://postgres@localhost/pqbus", "myapp").unwrap();
//!     let queue = bus.queue("new_users").unwrap();
//!     queue.push(StringMessage::new("sgibbs"));
//! }
//! ```
//!
//! ## Consumer
//!
//! ```rust,no_run
//! extern crate pqbus;
//!
//! use pqbus::{Queue, StringMessage};
//!
//! fn main() {
//!     let bus = pqbus::new("postgres://postgres@localhost/pqbus", "myapp").unwrap();
//!     let queue: Queue<StringMessage> = bus.queue("new_users").unwrap();
//!     for message in queue.messages_blocking() {
//!         println!("New User: {}", message.unwrap());
//!     }
//! }
//! ```
//!
#![crate_type = "lib"]
#![deny(missing_docs)]

extern crate postgres;
extern crate retry;

use postgres::{Connection, SslMode};
use postgres::notification::Notifications;
use postgres::stmt::Statement;
use retry::retry;
use std::fmt;
use std::result;
use std::time::Duration;
use std::marker::PhantomData;

use error::Error;
use iter::{MessageIter, NextMessageBlocking, NextMessagePending};

pub mod error;
pub mod iter;

/// Convenience alias
pub type Result<T> = result::Result<T, Error>;

/// Highest level namespace. Constructs `Queue`s.
pub struct PqBus {
    name: String,
    conn: Connection,
}

/// A named message queue
pub struct Queue<'a, T>
    where T: From<Vec<u8>> + Into<Vec<u8>>
{
    notifications: Notifications<'a>,
    pop_stmt: Statement<'a>,
    push_stmt: Statement<'a>,
    notify_stmt: Statement<'a>,
    size_stmt: Statement<'a>,
    phantom: PhantomData<T>,
}

/// Constructs a new PqBus
///
/// # Example
///
/// ```rust,no_run
/// let bus = pqbus::new("postgres://postgres@localhost/pqbus", "myapp").unwrap();
/// ```
pub fn new<S, T>(db_uri: S, name: T) -> Result<PqBus>
    where S: Into<String>,
          T: Into<String>
{
    let uri = db_uri.into();

    let conn = match retry(10,
                           100,
                           || Connection::connect(uri.as_ref(), SslMode::None),
                           |r| {
                               if let &Err(ref e) = r {
                                   println!("Failed to connect to postgresql server: {}", e);
                               }
                               r.is_ok()
                           }) {
        Err(e) => {
            println!("Giving up on postgresql server connection: {}", e);
            return Err(Error::Connection(uri, e));
        }
        Ok(c) => c.unwrap(),
    };

    Ok(PqBus {
        conn: conn,
        name: name.into(),
    })
}

impl PqBus {
    fn table_name<S>(&self, queue_name: S) -> String
        where S: Into<String>
    {
        format!("pqbus_{}_{}_queue", self.name, queue_name.into())
    }

    /// Constructs a queue on the bus from the given `name`.
    pub fn queue<'a, T>(&'a self, name: &str) -> Result<Queue<'a, T>>
        where T: From<Vec<u8>> + Into<Vec<u8>>
    {
        let table_name = self.table_name(name);
        try!(self.conn
            .execute(&format!(r#"
                CREATE TABLE IF NOT EXISTS {} (
                    id SERIAL PRIMARY KEY,
                    message bytea NOT NULL,
                    lock VARCHAR DEFAULT NULL
                )"#,
                              table_name),
                     &[])
            .map_err(|e| Error::Create(e)));
        Queue::new(&self.conn, &self.table_name(name))
    }
}

/// A push pop message queue.
impl<'a, T> Queue<'a, T>
    where T: From<Vec<u8>> + Into<Vec<u8>>
{
    fn new(conn: &'a Connection, table_name: &String) -> Result<Self> {
        try!(conn.execute(&format!("LISTEN {}", table_name), &[]).map_err(|e| Error::Listen(e)));
        Ok(Queue {
            notifications: conn.notifications(),
            push_stmt:
                try!(conn.prepare_cached(&format!("INSERT INTO {} (message) VALUES ($1)", table_name))),
            notify_stmt: try!(conn.prepare_cached(&format!("NOTIFY {}", table_name))),
            size_stmt: try!(conn.prepare_cached(&format!("SELECT count(*) FROM  {}", table_name))),
            pop_stmt: try!(conn.prepare_cached(&format!(r#"
                        UPDATE {n} q
                        SET lock = 'me'
                        FROM  (
                           SELECT id,message
                           FROM   {n}
                           WHERE  lock is NULL
                           LIMIT  1
                           FOR UPDATE SKIP LOCKED
                           ) sub
                        WHERE q.id = sub.id
                        RETURNING q.id, q.message;
                        "#,
                                                        n = table_name))),
            phantom: PhantomData,
        })
    }

    /// Returns the number of messages in the queue.
    pub fn size(&self) -> Result<i64> {
        let result = try!(self.size_stmt.query(&[]).map_err(|e| Error::Size(e)));
        let row = result.get(0);
        Ok(row.get("count"))
    }

    /// Determines if there are any pending messages.
    pub fn is_empty(&self) -> Result<bool> {
        Ok(try!(self.size()) == 0)
    }

    /// Pushes a message into the queue.
    pub fn push(&self, message: T) -> Result<bool>
        where T: Into<Vec<u8>>
    {
        let b: Vec<u8> = message.into();
        try!(self.push_stmt.execute(&[&b]).map_err(|e| Error::Push(e)));
        try!(self.notify_stmt.execute(&[]).map_err(|e| Error::Notify(e)));
        Ok(true)
    }

    /// Pops a message from the queue. Blocks if there are none pending.
    pub fn pop_blocking(&self) -> Result<T>
        where T: From<Vec<u8>>
    {
        loop {
            let p = try!(self.pop());
            if p.is_some() {
                return Ok(p.unwrap());
            }
            self.notifications.blocking_iter().next();
        }
    }

    /// Pops a message from the queue. Blocks for duration of `timeout` if there are none pending.
    pub fn pop_wait(&self, timeout: Duration) -> Result<Option<T>>
        where T: From<Vec<u8>>
    {
        {
            let p = try!(self.pop());
            if p.is_some() {
                return Ok(p);
            }
        }
        self.notifications.timeout_iter(timeout).next();
        {
            let p = try!(self.pop());
            if p.is_some() {
                return Ok(p);
            }
        }
        Ok(None)
    }

    /// Run a closure on messages in the queue. Blocks if there are none pending.
    pub fn pop_callback<F>(&self, work_fn: F) -> Result<bool>
        where F: Fn(T)
    {
        loop {
            self.consume_pending_notifications();
            try!(self.consume_pending_items(&work_fn));
            self.wait_for_next_notification();
        }
    }

    /// Pops a message from the queue if there is one pending.
    pub fn pop(&self) -> Result<Option<T>>
        where T: From<Vec<u8>>
    {
        let locked = try!(self.pop_stmt.query(&[]).map_err(|e| Error::Pop(e)));
        if locked.is_empty() {
            return Ok(None);
        }

        let locked_row = locked.get(0);
        let _id: i32 = match locked_row.get_opt("id") {
            None => {
                println!("No lock obtained");
                return Ok(None);
            }
            Some(Err(e)) => {
                println!("Failed to convert lock value: {}", e);
                return Ok(None);
            }
            Some(Ok(r)) => r,
        };

        let message: Vec<u8> = match locked_row.get_opt("message") {
            None => {
                println!("No message obtained");
                return Ok(None);
            }
            Some(Err(e)) => {
                println!("Failed to convert message value: {}", e);
                return Ok(None);
            }
            Some(Ok(r)) => r,
        };

        return Ok(Some(message.into()));
    }

    fn consume_pending_notifications(&self) {
        while !self.notifications.is_empty() {
            self.notifications.iter().next();
        }
    }

    fn consume_pending_items<F>(&self, work_fn: F) -> Result<u32>
        where F: Fn(T),
              T: From<Vec<u8>>
    {
        let mut i = 0;
        loop {
            match try!(self.pop()) {
                None => return Ok(i),
                Some(message) => {
                    work_fn(message);
                    i += 1;
                }
            }
        }
    }

    fn wait_for_next_notification(&self) {
        self.notifications.blocking_iter().next();
    }

    /// Returns an iterator over pending messages. Ends when the queue is empty.
    pub fn messages(&'a self) -> MessageIter<'a, NextMessagePending, T> {
        MessageIter::new(self, NextMessagePending {})
    }

    /// Returns an iterator over messages that blocks until a message is received if none are pending.
    /// This function never returns.
    pub fn messages_blocking(&'a self) -> MessageIter<'a, NextMessageBlocking, T> {
        MessageIter::new(self, NextMessageBlocking {})
    }
}

/// Message containing a utf8 String
pub struct StringMessage {
    body: String,
}

impl StringMessage {
    /// Construct a new StringMessage from `s`.
    pub fn new<S>(s: S) -> Self
        where S: Into<String>
    {
        StringMessage { body: s.into() }
    }

    /// Returns a reference to the inner `String`.
    pub fn body(&self) -> &String {
        &self.body
    }
}

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

impl Into<Vec<u8>> for StringMessage {
    fn into(self) -> Vec<u8> {
        self.body.into()
    }
}

impl From<Vec<u8>> for StringMessage {
    fn from(v: Vec<u8>) -> StringMessage {
        StringMessage { body: String::from_utf8(v).unwrap() }
    }
}
<commit_msg>Add doc on Custom Messages<commit_after>//! A simple event driven highly available message queue backed with PostgreSQL,
//! focused on stability and performance.
//!
//! ## Producer
//!
//! ```rust,no_run
//! extern crate pqbus;
//!
//! use pqbus::{Queue, StringMessage};
//!
//! fn main() {
//!     let bus = pqbus::new("postgres://postgres@localhost/pqbus", "myapp").unwrap();
//!     let queue = bus.queue("new_users").unwrap();
//!     queue.push(StringMessage::new("sgibbs"));
//! }
//! ```
//!
//! ## Consumer
//!
//! ```rust,no_run
//! extern crate pqbus;
//!
//! use pqbus::{Queue, StringMessage};
//!
//! fn main() {
//!     let bus = pqbus::new("postgres://postgres@localhost/pqbus", "myapp").unwrap();
//!     let queue: Queue<StringMessage> = bus.queue("new_users").unwrap();
//!     for message in queue.messages_blocking() {
//!         println!("New User: {}", message.unwrap());
//!     }
//! }
//! ```
//!
//! ## Custom Messages
//!
//! Any struct that satisfies the trait bonds `From<Vec<u8>>` and `Into<Vec<u8>>` the can be sent
//! over a queue.
//!
//! ```rust,no_run
//! extern crate pqbus;
//!
//! struct User;
//!
//! impl Into<Vec<u8>> for User {
//!     fn into(self) -> Vec<u8> {
//!         vec![0, 1, 0, 1]
//!     }
//! }
//!
//! impl From<Vec<u8>> for User {
//!     fn from(v: Vec<u8>) -> User {
//!         User
//!     }
//! }
//!
//! fn main() {
//!     let bus = pqbus::new("postgres://postgres@localhost/pqbus", "myapp").unwrap();
//!     let queue = bus.queue("new_users").unwrap();
//!
//!     let user = User;
//!     queue.push(user);
//! }
//! ```
//!
#![crate_type = "lib"]
#![deny(missing_docs)]

extern crate postgres;
extern crate retry;

use postgres::{Connection, SslMode};
use postgres::notification::Notifications;
use postgres::stmt::Statement;
use retry::retry;
use std::fmt;
use std::result;
use std::time::Duration;
use std::marker::PhantomData;

use error::Error;
use iter::{MessageIter, NextMessageBlocking, NextMessagePending};

pub mod error;
pub mod iter;

/// Convenience alias
pub type Result<T> = result::Result<T, Error>;

/// Highest level namespace. Constructs `Queue`s.
pub struct PqBus {
    name: String,
    conn: Connection,
}

/// A named message queue
pub struct Queue<'a, T>
    where T: From<Vec<u8>> + Into<Vec<u8>>
{
    notifications: Notifications<'a>,
    pop_stmt: Statement<'a>,
    push_stmt: Statement<'a>,
    notify_stmt: Statement<'a>,
    size_stmt: Statement<'a>,
    phantom: PhantomData<T>,
}

/// Constructs a new PqBus
///
/// # Example
///
/// ```rust,no_run
/// let bus = pqbus::new("postgres://postgres@localhost/pqbus", "myapp").unwrap();
/// ```
pub fn new<S, T>(db_uri: S, name: T) -> Result<PqBus>
    where S: Into<String>,
          T: Into<String>
{
    let uri = db_uri.into();

    let conn = match retry(10,
                           100,
                           || Connection::connect(uri.as_ref(), SslMode::None),
                           |r| {
                               if let &Err(ref e) = r {
                                   println!("Failed to connect to postgresql server: {}", e);
                               }
                               r.is_ok()
                           }) {
        Err(e) => {
            println!("Giving up on postgresql server connection: {}", e);
            return Err(Error::Connection(uri, e));
        }
        Ok(c) => c.unwrap(),
    };

    Ok(PqBus {
        conn: conn,
        name: name.into(),
    })
}

impl PqBus {
    fn table_name<S>(&self, queue_name: S) -> String
        where S: Into<String>
    {
        format!("pqbus_{}_{}_queue", self.name, queue_name.into())
    }

    /// Constructs a queue on the bus from the given `name`.
    pub fn queue<'a, T>(&'a self, name: &str) -> Result<Queue<'a, T>>
        where T: From<Vec<u8>> + Into<Vec<u8>>
    {
        let table_name = self.table_name(name);
        try!(self.conn
            .execute(&format!(r#"
                CREATE TABLE IF NOT EXISTS {} (
                    id SERIAL PRIMARY KEY,
                    message bytea NOT NULL,
                    lock VARCHAR DEFAULT NULL
                )"#,
                              table_name),
                     &[])
            .map_err(|e| Error::Create(e)));
        Queue::new(&self.conn, &self.table_name(name))
    }
}

/// A push pop message queue.
impl<'a, T> Queue<'a, T>
    where T: From<Vec<u8>> + Into<Vec<u8>>
{
    fn new(conn: &'a Connection, table_name: &String) -> Result<Self> {
        try!(conn.execute(&format!("LISTEN {}", table_name), &[]).map_err(|e| Error::Listen(e)));
        Ok(Queue {
            notifications: conn.notifications(),
            push_stmt:
                try!(conn.prepare_cached(&format!("INSERT INTO {} (message) VALUES ($1)", table_name))),
            notify_stmt: try!(conn.prepare_cached(&format!("NOTIFY {}", table_name))),
            size_stmt: try!(conn.prepare_cached(&format!("SELECT count(*) FROM  {}", table_name))),
            pop_stmt: try!(conn.prepare_cached(&format!(r#"
                        UPDATE {n} q
                        SET lock = 'me'
                        FROM  (
                           SELECT id,message
                           FROM   {n}
                           WHERE  lock is NULL
                           LIMIT  1
                           FOR UPDATE SKIP LOCKED
                           ) sub
                        WHERE q.id = sub.id
                        RETURNING q.id, q.message;
                        "#,
                                                        n = table_name))),
            phantom: PhantomData,
        })
    }

    /// Returns the number of messages in the queue.
    pub fn size(&self) -> Result<i64> {
        let result = try!(self.size_stmt.query(&[]).map_err(|e| Error::Size(e)));
        let row = result.get(0);
        Ok(row.get("count"))
    }

    /// Determines if there are any pending messages.
    pub fn is_empty(&self) -> Result<bool> {
        Ok(try!(self.size()) == 0)
    }

    /// Pushes a message into the queue.
    pub fn push(&self, message: T) -> Result<bool>
        where T: Into<Vec<u8>>
    {
        let b: Vec<u8> = message.into();
        try!(self.push_stmt.execute(&[&b]).map_err(|e| Error::Push(e)));
        try!(self.notify_stmt.execute(&[]).map_err(|e| Error::Notify(e)));
        Ok(true)
    }

    /// Pops a message from the queue. Blocks if there are none pending.
    pub fn pop_blocking(&self) -> Result<T>
        where T: From<Vec<u8>>
    {
        loop {
            let p = try!(self.pop());
            if p.is_some() {
                return Ok(p.unwrap());
            }
            self.notifications.blocking_iter().next();
        }
    }

    /// Pops a message from the queue. Blocks for duration of `timeout` if there are none pending.
    pub fn pop_wait(&self, timeout: Duration) -> Result<Option<T>>
        where T: From<Vec<u8>>
    {
        {
            let p = try!(self.pop());
            if p.is_some() {
                return Ok(p);
            }
        }
        self.notifications.timeout_iter(timeout).next();
        {
            let p = try!(self.pop());
            if p.is_some() {
                return Ok(p);
            }
        }
        Ok(None)
    }

    /// Run a closure on messages in the queue. Blocks if there are none pending.
    pub fn pop_callback<F>(&self, work_fn: F) -> Result<bool>
        where F: Fn(T)
    {
        loop {
            self.consume_pending_notifications();
            try!(self.consume_pending_items(&work_fn));
            self.wait_for_next_notification();
        }
    }

    /// Pops a message from the queue if there is one pending.
    pub fn pop(&self) -> Result<Option<T>>
        where T: From<Vec<u8>>
    {
        let locked = try!(self.pop_stmt.query(&[]).map_err(|e| Error::Pop(e)));
        if locked.is_empty() {
            return Ok(None);
        }

        let locked_row = locked.get(0);
        let _id: i32 = match locked_row.get_opt("id") {
            None => {
                println!("No lock obtained");
                return Ok(None);
            }
            Some(Err(e)) => {
                println!("Failed to convert lock value: {}", e);
                return Ok(None);
            }
            Some(Ok(r)) => r,
        };

        let message: Vec<u8> = match locked_row.get_opt("message") {
            None => {
                println!("No message obtained");
                return Ok(None);
            }
            Some(Err(e)) => {
                println!("Failed to convert message value: {}", e);
                return Ok(None);
            }
            Some(Ok(r)) => r,
        };

        return Ok(Some(message.into()));
    }

    fn consume_pending_notifications(&self) {
        while !self.notifications.is_empty() {
            self.notifications.iter().next();
        }
    }

    fn consume_pending_items<F>(&self, work_fn: F) -> Result<u32>
        where F: Fn(T),
              T: From<Vec<u8>>
    {
        let mut i = 0;
        loop {
            match try!(self.pop()) {
                None => return Ok(i),
                Some(message) => {
                    work_fn(message);
                    i += 1;
                }
            }
        }
    }

    fn wait_for_next_notification(&self) {
        self.notifications.blocking_iter().next();
    }

    /// Returns an iterator over pending messages. Ends when the queue is empty.
    pub fn messages(&'a self) -> MessageIter<'a, NextMessagePending, T> {
        MessageIter::new(self, NextMessagePending {})
    }

    /// Returns an iterator over messages that blocks until a message is received if none are pending.
    /// This function never returns.
    pub fn messages_blocking(&'a self) -> MessageIter<'a, NextMessageBlocking, T> {
        MessageIter::new(self, NextMessageBlocking {})
    }
}

/// Message containing a utf8 String
pub struct StringMessage {
    body: String,
}

impl StringMessage {
    /// Construct a new StringMessage from `s`.
    pub fn new<S>(s: S) -> Self
        where S: Into<String>
    {
        StringMessage { body: s.into() }
    }

    /// Returns a reference to the inner `String`.
    pub fn body(&self) -> &String {
        &self.body
    }
}

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

impl Into<Vec<u8>> for StringMessage {
    fn into(self) -> Vec<u8> {
        self.body.into()
    }
}

impl From<Vec<u8>> for StringMessage {
    fn from(v: Vec<u8>) -> StringMessage {
        StringMessage { body: String::from_utf8(v).unwrap() }
    }
}
<|endoftext|>


<commit_before>extern crate log;

use std::io::{Write, stderr};
use std::sync::Mutex;

use log::{Log, LogLevelFilter, LogMetadata, LogRecord, SetLoggerError};

pub struct Writer(pub Box<Write + Send>);

struct Logger {
    writers: Mutex<Vec<Writer>>,
}

impl Log for Logger {
    fn enabled(&self, _: &LogMetadata) -> bool {
        true
    }

    fn log(&self, rec: &LogRecord) {
        let mut writers = match self.writers.lock() {
            Ok(writers) => writers,
            Err(err) => {
                let _ = writeln!(stderr(), "{:?}", err);
                return;
            },
        };
        let loc = rec.location();
        for i in 0..writers.len() {
            let _ = writeln!(
                writers[i].0,
                "{}:{}:{}:\t{}",
                loc.file(), loc.line(), rec.level(), rec.args());
        }
    }
}

pub fn init(writers: Vec<Writer>) -> Result<(), SetLoggerError> {
    log::set_logger(|max_level| {
        max_level.set(LogLevelFilter::max());
        Box::new(Logger {writers: Mutex::new(writers)})
    })
}
<commit_msg>Change logging format<commit_after>extern crate log;

use std::io::{Write, stderr};
use std::sync::Mutex;

use log::{Log, LogLevelFilter, LogMetadata, LogRecord, SetLoggerError};

pub struct Writer(pub Box<Write + Send>);

struct Logger {
    writers: Mutex<Vec<Writer>>,
}

impl Log for Logger {
    fn enabled(&self, _: &LogMetadata) -> bool {
        true
    }

    fn log(&self, rec: &LogRecord) {
        let mut writers = match self.writers.lock() {
            Ok(writers) => writers,
            Err(err) => {
                let _ = writeln!(stderr(), "{:?}", err);
                return;
            },
        };
        let loc = rec.location();
        for i in 0..writers.len() {
            let _ = writeln!(
                writers[i].0,
                "{}:{}:{}:{}",
                rec.level(), loc.file(), loc.line(), rec.args());
        }
    }
}

pub fn init(writers: Vec<Writer>) -> Result<(), SetLoggerError> {
    log::set_logger(|max_level| {
        max_level.set(LogLevelFilter::max());
        Box::new(Logger {writers: Mutex::new(writers)})
    })
}
<|endoftext|>


<commit_before>//! [Algorithm][1] to compute the [discrete Fourier transform][2] and its
//! inverse.
//!
//! [1]: https://en.wikipedia.org/wiki/Fast_Fourier_transform
//! [2]: https://en.wikipedia.org/wiki/Discrete_Fourier_transform

// The implementation is based on:
// http://www.librow.com/articles/article-10

extern crate complex;

pub use complex::c64;

/// Perform the Fourier transform.
///
/// The number of points should be a power of two.
///
/// ## Panics
///
/// The function panics if the number of points is not a power of two.
pub fn forward(data: &mut [c64]) {
    let n = data.len();
    if n < 1 || n & (n - 1) != 0 {
        panic!("expected the number of points to be a power of two");
    }
    rearrange(data, n);
    perform(data, n, false);
}

/// Perform the inverse Fourier transform.
///
/// The number of points should be a power of two.
///
/// ## Panics
///
/// The function panics if the number of points is not a power of two.
pub fn inverse(data: &mut [c64], scaling: bool) {
    let n = data.len();
    if n < 1 || n & (n - 1) != 0 {
        panic!("expected the number of points to be a power of two");
    }
    rearrange(data, n);
    perform(data, n, true);
    if scaling {
        scale(data, n);
    }
}

#[inline(always)]
fn rearrange(data: &mut [c64], n: usize) {
    let mut target = 0;
    for position in 0..n {
        if target > position {
            data.swap(position, target);
        }
        let mut mask = n >> 1;
        while target & mask != 0 {
            target &= !mask;
            mask >>= 1;
        }
        target |= mask;
    }
}

#[inline(always)]
fn perform(data: &mut [c64], n: usize, inverse: bool) {
    use std::f64::consts::PI;

    let pi = if inverse { PI } else { -PI };
    let mut step = 1;
    while step < n {
        let jump = step << 1;
        let delta = pi / step as f64;
        let sine = (0.5 * delta).sin();
        let multiplier = c64(-2.0 * sine * sine, delta.sin());
        let mut factor = c64(1.0, 0.0);
        for group in 0..step {
            let mut pair = group;
            while pair < n {
                let match_pair = pair + step;
                let product = factor * data[match_pair];
                data[match_pair] = data[pair] - product;
                data[pair] = data[pair] + product;
                pair += jump;
            }
            factor = multiplier * factor + factor;
        }
        step <<= 1;
    }
}

#[inline(always)]
fn scale(data: &mut [c64], n: usize) {
    let factor = 1.0 / n as f64;
    for position in 0..n {
        data[position] = data[position] * factor;
    }
}
<commit_msg>Adjust the description<commit_after>//! [Algorithm][1] to compute the [discrete Fourier transform][2] and its
//! inverse.
//!
//! [1]: https://en.wikipedia.org/wiki/Fast_Fourier_transform
//! [2]: https://en.wikipedia.org/wiki/Discrete_Fourier_transform

// The implementation is based on:
// http://www.librow.com/articles/article-10

extern crate complex;

pub use complex::c64;

/// Perform the forward transform.
///
/// The number of points should be a power of two.
///
/// ## Panics
///
/// The function panics if the number of points is not a power of two.
pub fn forward(data: &mut [c64]) {
    let n = data.len();
    if n < 1 || n & (n - 1) != 0 {
        panic!("expected the number of points to be a power of two");
    }
    rearrange(data, n);
    perform(data, n, false);
}

/// Perform the inverse transform.
///
/// The number of points should be a power of two.
///
/// ## Panics
///
/// The function panics if the number of points is not a power of two.
pub fn inverse(data: &mut [c64], scaling: bool) {
    let n = data.len();
    if n < 1 || n & (n - 1) != 0 {
        panic!("expected the number of points to be a power of two");
    }
    rearrange(data, n);
    perform(data, n, true);
    if scaling {
        scale(data, n);
    }
}

#[inline(always)]
fn rearrange(data: &mut [c64], n: usize) {
    let mut target = 0;
    for position in 0..n {
        if target > position {
            data.swap(position, target);
        }
        let mut mask = n >> 1;
        while target & mask != 0 {
            target &= !mask;
            mask >>= 1;
        }
        target |= mask;
    }
}

#[inline(always)]
fn perform(data: &mut [c64], n: usize, inverse: bool) {
    use std::f64::consts::PI;

    let pi = if inverse { PI } else { -PI };
    let mut step = 1;
    while step < n {
        let jump = step << 1;
        let delta = pi / step as f64;
        let sine = (0.5 * delta).sin();
        let multiplier = c64(-2.0 * sine * sine, delta.sin());
        let mut factor = c64(1.0, 0.0);
        for group in 0..step {
            let mut pair = group;
            while pair < n {
                let match_pair = pair + step;
                let product = factor * data[match_pair];
                data[match_pair] = data[pair] - product;
                data[pair] = data[pair] + product;
                pair += jump;
            }
            factor = multiplier * factor + factor;
        }
        step <<= 1;
    }
}

#[inline(always)]
fn scale(data: &mut [c64], n: usize) {
    let factor = 1.0 / n as f64;
    for position in 0..n {
        data[position] = data[position] * factor;
    }
}
<|endoftext|>