<commit_before>//! A antialiasing oscillator.
//!
//! ## Waveforms
//!
//! The oscillator supports several classical waveforms. The square, triangle,
//! and saw waves support both aliased and antialiased variants.
//!
//! The aliased variants produce pure signals; for example, a square wave only
//! emits two values: `-1.0` and `+1.0`. This is useful when a control signal is
//! wanted, but produces aliasing in the frequency domain.
//!
//! The antialiased variants use PolyBLEP (polynomial bandlimited step) to
//! mitigate the aliasing in the pure signals. This results in a much cleaner
//! audible signal, and is more desirable for most musical purposes.
//!
//! ## Pitch Bend
//!
//! The oscillator supports pitch bending as an additional modifier of the base
//! frequency. This makes it easier to bend a single note when working with
//! MIDI, rather than manually tracking the base frequency and computing a new
//! frequency yourself.
//!
//! ## Low Frequency Oscillator
//!
//! The oscillator supports a low frequency oscillator (LFO) as optional input.
//! If provided, then the LFO is used to modulate the frequency of the
//! oscillator, producing a vibrato.
//!
//! ## Example
//!
//! The oscillator uses a builder pattern for initialization. The following will
//! set up an antialiased saw wave at 440 Hz, with a 0.1 step vibrato:
//!
//! ```
//! Oscillator::new(Saw(PolyBlep)).freq(440.0).lfo_intensity(0.1);
//! ```

use std::f32::consts::PI;
use num::traits::Float;
use rand::random;

use types::{SAMPLE_RATE, AudioDevice, Sample, Time};

/// The messages that the Oscillator responds to.
#[derive(Clone, Copy, Debug)]
pub enum OscillatorMessage {
    /// Set the frequency in Hz.
    SetFreq(f32),
    /// Set the waveform type.
    SetWaveform(Waveform),
    /// Set the LFO vibrato depth, in steps.
    SetLFOIntensity(f32),
    /// Set the pitch bend, in steps.
    SetBend(f32),
}
pub use self::OscillatorMessage::*;

/// Antialiasing method for certain waveforms.
#[derive(Clone, Copy, Debug)]
pub enum AntialiasType {
    /// Naive, aliasing waveforms.
    Aliased,
    /// Antialiasing using PolyBLEP.
    PolyBlep
}
pub use self::AntialiasType::*;

/// Oscillator waveforms.
#[derive(Clone, Copy, Debug)]
pub enum Waveform {
    /// A sine wave
    Sine,
    /// A saw wave
    Saw(AntialiasType),
    /// A square wave
    Square(AntialiasType),
    /// A triangle wave
    Tri(AntialiasType),
    /// Pure white noise
    WhiteNoise,
    /// A series of impulses
    PulseTrain
}
pub use self::Waveform::*;

/// An oscillator that generates a periodic waveform.
pub struct Oscillator {
    waveform: Waveform,
    lfo_intensity: f32,
    bend: f32,
    phase: f32,
    phase_delta: f32,
    last_sample: Sample,
}

impl Oscillator {
    /// Return an oscillator with the specified waveform.
    pub fn new(waveform: Waveform) -> Oscillator {
        Oscillator {
            waveform: waveform,
            lfo_intensity: 0.0,
            bend: 1.0,
            phase: 0.0,
            phase_delta: 0.0,
            last_sample: 0.0
        }
    }

    /// Set the frequency of the waveform, and return the same oscillator.
    pub fn freq(mut self, freq: f32) -> Oscillator {
        self.handle_message(SetFreq(freq));
        self
    }

    /// Set the intensity of the LFO vibrato, and return the same oscillator.
    ///
    /// The intensity is provided in half steps (1/2ths of an octave).
    pub fn lfo_intensity(mut self, lfo_intensity: f32) -> Oscillator {
        self.handle_message(SetLFOIntensity(lfo_intensity));
        self
    }

    /// Perform the action specified by the message.
    pub fn handle_message(&mut self, msg: OscillatorMessage) {
        match msg {
            SetFreq(freq) => {
                self.phase_delta = freq*2.0*PI/(SAMPLE_RATE as f32);
            },
            SetWaveform(waveform) => {
                self.waveform = waveform;
            },
            SetLFOIntensity(steps) => {
                self.lfo_intensity = steps/12.0;
            },
            SetBend(steps) => {
                self.bend = 2.0.powf(steps/12.0);
            },
        }
    }
}

impl AudioDevice for Oscillator {
    fn num_inputs(&self) -> usize {
        1
    }

    fn num_outputs(&self) -> usize {
        1
    }

    fn tick(&mut self, _: Time, inputs: &[Sample], outputs: &mut[Sample]) {
        // Tick the phase
        let phase_delta = if inputs.len() > 0 {
            self.phase_delta*2.0.powf(inputs[0]*self.lfo_intensity)*self.bend
        } else {
            self.phase_delta*self.bend
        };
        self.phase += phase_delta;
        if self.phase >= 2.0*PI {
            self.phase -= 2.0*PI;
        }

        // Compute the next sample
        let s: Sample = match self.waveform.clone() {
            Sine => self.phase.sin(),
            Saw(aa) => {
                let mut out = self.phase/PI -1.0;
                match aa {
                    PolyBlep => {
                        out -= poly_belp_offset(self.phase/(2.0*PI),
                                                phase_delta/(2.0*PI));
                    },
                    _ => ()
                }
                out
            },
            Square(aa) => {
                let mut out = if self.phase < PI { 1.0 } else { -1.0 };
                match aa {
                    PolyBlep => {
                        // two discontinuities, at rising and falling edges
                        out += poly_belp_offset(self.phase/(2.0*PI),
                                                phase_delta/(2.0*PI));
                        out -= poly_belp_offset(fmod(self.phase/(2.0*PI)+0.5, 1.0),
                                                phase_delta/(2.0*PI));
                    },
                    _ => ()
                }
                out
            },
            Tri(aa) => {
                // Compute a square wave signal
                let mut out = if self.phase < PI { 1.0 } else { -1.0 };
                match aa {
                    PolyBlep => {
                        // two discontinuities, at rising and falling edges
                        out += poly_belp_offset(self.phase/(2.0*PI),
                                                phase_delta/(2.0*PI));
                        out -= poly_belp_offset(fmod(self.phase/(2.0*PI)+0.5, 1.0),
                                                phase_delta/(2.0*PI));
                    },
                    _ => ()
                }

                // Perform leaky integration
                phase_delta*out + (1.0-phase_delta)*self.last_sample
            },
            WhiteNoise => 2.0*random::<f32>() - 1.0,
            PulseTrain => {
                // If we wrapped around...
                if self.phase < self.phase_delta {
                    1.0
                } else {
                    0.0
                }
            }
        };

        // Push the sample out
        self.last_sample = s;
        outputs[0] = s;
    }
}

/// Floating point modulus
fn fmod(n: f32, base: f32) -> f32 {
    assert!(base > 0.0);
    let mut out = n;
    while out < 0.0 {
        out += base;
    }
    while out >= base {
        out -= base;
    }
    out
}

/// Computes an offset for PolyBLEP antialiasing
///
/// `t` should be the current waveform phase, normalized
/// `dt` should be the change in phase for one sample time, normalized
fn poly_belp_offset(t: f32, dt: f32) -> f32 {
    if t < dt { // t ~= 0
        let t = t / dt;
        -t*t + 2.0*t - 1.0
    } else if t > 1.0-dt { // t ~= 1
        let t = (t-1.0) / dt;
        t*t + 2.0*t + 1.0
    } else {
        0.0
    }
}

// A couple of basic unit tests...
#[cfg(test)]
mod test {
    use utils::helpers::flt_eq;
    static EPSILON: f32 = 1e-6;

    /// Tests fmod with many values
    #[test]
    fn test_fmod() {
        use super::fmod;

        // negatives...
        assert!(flt_eq(fmod(-1.5, 1.0), 0.5, EPSILON));
        assert!(flt_eq(fmod(-1.0, 1.0), 0.0, EPSILON));
        assert!(flt_eq(fmod(-0.5, 1.0), 0.5, EPSILON));

        // in range...
        assert!(flt_eq(fmod(0.0, 1.0), 0.0, EPSILON));
        assert!(flt_eq(fmod(0.5, 1.0), 0.5, EPSILON));
        assert!(flt_eq(fmod(0.9, 1.0), 0.9, EPSILON));

        // above...
        assert!(flt_eq(fmod(1.0, 1.0), 0.0, EPSILON));
        assert!(flt_eq(fmod(1.5, 1.0), 0.5, EPSILON));
        assert!(flt_eq(fmod(2.0, 1.0), 0.0, EPSILON));
        assert!(flt_eq(fmod(2.5, 1.0), 0.5, EPSILON));

        // different base...
        assert!(flt_eq(fmod(-0.5, 0.9), 0.4, EPSILON));
        assert!(flt_eq(fmod(0.0, 0.9), 0.0, EPSILON));
        assert!(flt_eq(fmod(0.5, 0.9), 0.5, EPSILON));
        assert!(flt_eq(fmod(0.9, 0.9), 0.0, EPSILON));
        assert!(flt_eq(fmod(1.0, 0.9), 0.1, EPSILON));
    }

    /// Tests square wave
    #[test]
    fn test_naive_square() {
        use super::{AntialiasType, Waveform, Oscillator};
        use types::AudioDevice;
        let mut osc = Oscillator::new(Waveform::Square(AntialiasType::Aliased))
            .freq(4410.0);
        let input = vec![];
        let mut output = vec![0.0];

        osc.tick(0, &input, &mut output); assert!(output[0] == 1.0);
        osc.tick(1, &input, &mut output); assert!(output[0] == 1.0);
        osc.tick(2, &input, &mut output); assert!(output[0] == 1.0);
        osc.tick(3, &input, &mut output); assert!(output[0] == 1.0);
        osc.tick(4, &input, &mut output); assert!(output[0] == -1.0);
        osc.tick(5, &input, &mut output); assert!(output[0] == -1.0);
        osc.tick(6, &input, &mut output); assert!(output[0] == -1.0);
        osc.tick(7, &input, &mut output); assert!(output[0] == -1.0);
        osc.tick(8, &input, &mut output); assert!(output[0] == -1.0);
    }

    /// Tests saw wave
    #[test]
    fn test_naive_saw() {
        use super::{AntialiasType, Waveform, Oscillator};
        use types::AudioDevice;
        let mut osc = Oscillator::new(Waveform::Saw(AntialiasType::Aliased))
            .freq(4410.0);
        let input = vec![];
        let mut output = vec![0.0];

        osc.tick(0, &input, &mut output); assert!(flt_eq(output[0], -0.8, EPSILON));
        osc.tick(1, &input, &mut output); assert!(flt_eq(output[0], -0.6, EPSILON));
        osc.tick(2, &input, &mut output); assert!(flt_eq(output[0], -0.4, EPSILON));
        osc.tick(3, &input, &mut output); assert!(flt_eq(output[0], -0.2, EPSILON));
        osc.tick(4, &input, &mut output); assert!(flt_eq(output[0], 0.0, EPSILON));
        osc.tick(5, &input, &mut output); assert!(flt_eq(output[0], 0.2, EPSILON));
        osc.tick(6, &input, &mut output); assert!(flt_eq(output[0], 0.4, EPSILON));
        osc.tick(7, &input, &mut output); assert!(flt_eq(output[0], 0.6, EPSILON));
        osc.tick(8, &input, &mut output); assert!(flt_eq(output[0], 0.8, EPSILON));
    }
}
<commit_msg>Fix code example in oscillator<commit_after>//! A antialiasing oscillator.
//!
//! ## Waveforms
//!
//! The oscillator supports several classical waveforms. The square, triangle,
//! and saw waves support both aliased and antialiased variants.
//!
//! The aliased variants produce pure signals; for example, a square wave only
//! emits two values: `-1.0` and `+1.0`. This is useful when a control signal is
//! wanted, but produces aliasing in the frequency domain.
//!
//! The antialiased variants use PolyBLEP (polynomial bandlimited step) to
//! mitigate the aliasing in the pure signals. This results in a much cleaner
//! audible signal, and is more desirable for most musical purposes.
//!
//! ## Pitch Bend
//!
//! The oscillator supports pitch bending as an additional modifier of the base
//! frequency. This makes it easier to bend a single note when working with
//! MIDI, rather than manually tracking the base frequency and computing a new
//! frequency yourself.
//!
//! ## Low Frequency Oscillator
//!
//! The oscillator supports a low frequency oscillator (LFO) as optional input.
//! If provided, then the LFO is used to modulate the frequency of the
//! oscillator, producing a vibrato.
//!
//! ## Example
//!
//! The oscillator uses a builder pattern for initialization. The following will
//! set up an antialiased saw wave at 440 Hz, with a 0.1 step vibrato:
//!
//! ```
//! use oxcable::oscillator::*;
//! Oscillator::new(Saw(PolyBlep)).freq(440.0).lfo_intensity(0.1);
//! ```

use std::f32::consts::PI;
use num::traits::Float;
use rand::random;

use types::{SAMPLE_RATE, AudioDevice, Sample, Time};

/// The messages that the Oscillator responds to.
#[derive(Clone, Copy, Debug)]
pub enum OscillatorMessage {
    /// Set the frequency in Hz.
    SetFreq(f32),
    /// Set the waveform type.
    SetWaveform(Waveform),
    /// Set the LFO vibrato depth, in steps.
    SetLFOIntensity(f32),
    /// Set the pitch bend, in steps.
    SetBend(f32),
}
pub use self::OscillatorMessage::*;

/// Antialiasing method for certain waveforms.
#[derive(Clone, Copy, Debug)]
pub enum AntialiasType {
    /// Naive, aliasing waveforms.
    Aliased,
    /// Antialiasing using PolyBLEP.
    PolyBlep
}
pub use self::AntialiasType::*;

/// Oscillator waveforms.
#[derive(Clone, Copy, Debug)]
pub enum Waveform {
    /// A sine wave
    Sine,
    /// A saw wave
    Saw(AntialiasType),
    /// A square wave
    Square(AntialiasType),
    /// A triangle wave
    Tri(AntialiasType),
    /// Pure white noise
    WhiteNoise,
    /// A series of impulses
    PulseTrain
}
pub use self::Waveform::*;

/// An oscillator that generates a periodic waveform.
pub struct Oscillator {
    waveform: Waveform,
    lfo_intensity: f32,
    bend: f32,
    phase: f32,
    phase_delta: f32,
    last_sample: Sample,
}

impl Oscillator {
    /// Return an oscillator with the specified waveform.
    pub fn new(waveform: Waveform) -> Oscillator {
        Oscillator {
            waveform: waveform,
            lfo_intensity: 0.0,
            bend: 1.0,
            phase: 0.0,
            phase_delta: 0.0,
            last_sample: 0.0
        }
    }

    /// Set the frequency of the waveform, and return the same oscillator.
    pub fn freq(mut self, freq: f32) -> Oscillator {
        self.handle_message(SetFreq(freq));
        self
    }

    /// Set the intensity of the LFO vibrato, and return the same oscillator.
    ///
    /// The intensity is provided in half steps (1/2ths of an octave).
    pub fn lfo_intensity(mut self, lfo_intensity: f32) -> Oscillator {
        self.handle_message(SetLFOIntensity(lfo_intensity));
        self
    }

    /// Perform the action specified by the message.
    pub fn handle_message(&mut self, msg: OscillatorMessage) {
        match msg {
            SetFreq(freq) => {
                self.phase_delta = freq*2.0*PI/(SAMPLE_RATE as f32);
            },
            SetWaveform(waveform) => {
                self.waveform = waveform;
            },
            SetLFOIntensity(steps) => {
                self.lfo_intensity = steps/12.0;
            },
            SetBend(steps) => {
                self.bend = 2.0.powf(steps/12.0);
            },
        }
    }
}

impl AudioDevice for Oscillator {
    fn num_inputs(&self) -> usize {
        1
    }

    fn num_outputs(&self) -> usize {
        1
    }

    fn tick(&mut self, _: Time, inputs: &[Sample], outputs: &mut[Sample]) {
        // Tick the phase
        let phase_delta = if inputs.len() > 0 {
            self.phase_delta*2.0.powf(inputs[0]*self.lfo_intensity)*self.bend
        } else {
            self.phase_delta*self.bend
        };
        self.phase += phase_delta;
        if self.phase >= 2.0*PI {
            self.phase -= 2.0*PI;
        }

        // Compute the next sample
        let s: Sample = match self.waveform.clone() {
            Sine => self.phase.sin(),
            Saw(aa) => {
                let mut out = self.phase/PI -1.0;
                match aa {
                    PolyBlep => {
                        out -= poly_belp_offset(self.phase/(2.0*PI),
                                                phase_delta/(2.0*PI));
                    },
                    _ => ()
                }
                out
            },
            Square(aa) => {
                let mut out = if self.phase < PI { 1.0 } else { -1.0 };
                match aa {
                    PolyBlep => {
                        // two discontinuities, at rising and falling edges
                        out += poly_belp_offset(self.phase/(2.0*PI),
                                                phase_delta/(2.0*PI));
                        out -= poly_belp_offset(fmod(self.phase/(2.0*PI)+0.5, 1.0),
                                                phase_delta/(2.0*PI));
                    },
                    _ => ()
                }
                out
            },
            Tri(aa) => {
                // Compute a square wave signal
                let mut out = if self.phase < PI { 1.0 } else { -1.0 };
                match aa {
                    PolyBlep => {
                        // two discontinuities, at rising and falling edges
                        out += poly_belp_offset(self.phase/(2.0*PI),
                                                phase_delta/(2.0*PI));
                        out -= poly_belp_offset(fmod(self.phase/(2.0*PI)+0.5, 1.0),
                                                phase_delta/(2.0*PI));
                    },
                    _ => ()
                }

                // Perform leaky integration
                phase_delta*out + (1.0-phase_delta)*self.last_sample
            },
            WhiteNoise => 2.0*random::<f32>() - 1.0,
            PulseTrain => {
                // If we wrapped around...
                if self.phase < self.phase_delta {
                    1.0
                } else {
                    0.0
                }
            }
        };

        // Push the sample out
        self.last_sample = s;
        outputs[0] = s;
    }
}

/// Floating point modulus
fn fmod(n: f32, base: f32) -> f32 {
    assert!(base > 0.0);
    let mut out = n;
    while out < 0.0 {
        out += base;
    }
    while out >= base {
        out -= base;
    }
    out
}

/// Computes an offset for PolyBLEP antialiasing
///
/// `t` should be the current waveform phase, normalized
/// `dt` should be the change in phase for one sample time, normalized
fn poly_belp_offset(t: f32, dt: f32) -> f32 {
    if t < dt { // t ~= 0
        let t = t / dt;
        -t*t + 2.0*t - 1.0
    } else if t > 1.0-dt { // t ~= 1
        let t = (t-1.0) / dt;
        t*t + 2.0*t + 1.0
    } else {
        0.0
    }
}

// A couple of basic unit tests...
#[cfg(test)]
mod test {
    use utils::helpers::flt_eq;
    static EPSILON: f32 = 1e-6;

    /// Tests fmod with many values
    #[test]
    fn test_fmod() {
        use super::fmod;

        // negatives...
        assert!(flt_eq(fmod(-1.5, 1.0), 0.5, EPSILON));
        assert!(flt_eq(fmod(-1.0, 1.0), 0.0, EPSILON));
        assert!(flt_eq(fmod(-0.5, 1.0), 0.5, EPSILON));

        // in range...
        assert!(flt_eq(fmod(0.0, 1.0), 0.0, EPSILON));
        assert!(flt_eq(fmod(0.5, 1.0), 0.5, EPSILON));
        assert!(flt_eq(fmod(0.9, 1.0), 0.9, EPSILON));

        // above...
        assert!(flt_eq(fmod(1.0, 1.0), 0.0, EPSILON));
        assert!(flt_eq(fmod(1.5, 1.0), 0.5, EPSILON));
        assert!(flt_eq(fmod(2.0, 1.0), 0.0, EPSILON));
        assert!(flt_eq(fmod(2.5, 1.0), 0.5, EPSILON));

        // different base...
        assert!(flt_eq(fmod(-0.5, 0.9), 0.4, EPSILON));
        assert!(flt_eq(fmod(0.0, 0.9), 0.0, EPSILON));
        assert!(flt_eq(fmod(0.5, 0.9), 0.5, EPSILON));
        assert!(flt_eq(fmod(0.9, 0.9), 0.0, EPSILON));
        assert!(flt_eq(fmod(1.0, 0.9), 0.1, EPSILON));
    }

    /// Tests square wave
    #[test]
    fn test_naive_square() {
        use super::{AntialiasType, Waveform, Oscillator};
        use types::AudioDevice;
        let mut osc = Oscillator::new(Waveform::Square(AntialiasType::Aliased))
            .freq(4410.0);
        let input = vec![];
        let mut output = vec![0.0];

        osc.tick(0, &input, &mut output); assert!(output[0] == 1.0);
        osc.tick(1, &input, &mut output); assert!(output[0] == 1.0);
        osc.tick(2, &input, &mut output); assert!(output[0] == 1.0);
        osc.tick(3, &input, &mut output); assert!(output[0] == 1.0);
        osc.tick(4, &input, &mut output); assert!(output[0] == -1.0);
        osc.tick(5, &input, &mut output); assert!(output[0] == -1.0);
        osc.tick(6, &input, &mut output); assert!(output[0] == -1.0);
        osc.tick(7, &input, &mut output); assert!(output[0] == -1.0);
        osc.tick(8, &input, &mut output); assert!(output[0] == -1.0);
    }

    /// Tests saw wave
    #[test]
    fn test_naive_saw() {
        use super::{AntialiasType, Waveform, Oscillator};
        use types::AudioDevice;
        let mut osc = Oscillator::new(Waveform::Saw(AntialiasType::Aliased))
            .freq(4410.0);
        let input = vec![];
        let mut output = vec![0.0];

        osc.tick(0, &input, &mut output); assert!(flt_eq(output[0], -0.8, EPSILON));
        osc.tick(1, &input, &mut output); assert!(flt_eq(output[0], -0.6, EPSILON));
        osc.tick(2, &input, &mut output); assert!(flt_eq(output[0], -0.4, EPSILON));
        osc.tick(3, &input, &mut output); assert!(flt_eq(output[0], -0.2, EPSILON));
        osc.tick(4, &input, &mut output); assert!(flt_eq(output[0], 0.0, EPSILON));
        osc.tick(5, &input, &mut output); assert!(flt_eq(output[0], 0.2, EPSILON));
        osc.tick(6, &input, &mut output); assert!(flt_eq(output[0], 0.4, EPSILON));
        osc.tick(7, &input, &mut output); assert!(flt_eq(output[0], 0.6, EPSILON));
        osc.tick(8, &input, &mut output); assert!(flt_eq(output[0], 0.8, EPSILON));
    }
}
<|endoftext|>


<commit_before>//! The futures-rs procedural macro implementations.

#![recursion_limit = "128"]
#![warn(rust_2018_idioms, unreachable_pub)]
// It cannot be included in the published code because this lints have false positives in the minimum required version.
#![cfg_attr(test, warn(single_use_lifetimes))]
#![warn(clippy::all)]

#![doc(test(attr(deny(warnings), allow(dead_code, unused_assignments, unused_variables))))]

#![doc(html_root_url = "https://docs.rs/futures-join-macro/0.3.0")]

extern crate proc_macro;

use proc_macro::TokenStream;
use proc_macro_hack::proc_macro_hack;

mod join;
mod select;

/// The `join!` macro.
#[proc_macro_hack]
pub fn join(input: TokenStream) -> TokenStream {
    crate::join::join(input)
}

/// The `try_join!` macro.
#[proc_macro_hack]
pub fn try_join(input: TokenStream) -> TokenStream {
    crate::join::try_join(input)
}

/// The `select!` macro.
#[proc_macro_hack]
pub fn select(input: TokenStream) -> TokenStream {
    crate::select::select(input)
}

/// The `select_biased!` macro.
#[proc_macro_hack]
pub fn select_biased(input: TokenStream) -> TokenStream {
    crate::select::select_biased(input)
}
<commit_msg>Allow unused crate warning for newer compilers<commit_after>//! The futures-rs procedural macro implementations.

#![recursion_limit = "128"]
#![warn(rust_2018_idioms, unreachable_pub)]
// It cannot be included in the published code because this lints have false positives in the minimum required version.
#![cfg_attr(test, warn(single_use_lifetimes))]
#![warn(clippy::all)]

#![doc(test(attr(deny(warnings), allow(dead_code, unused_assignments, unused_variables))))]

#![doc(html_root_url = "https://docs.rs/futures-join-macro/0.3.0")]

// Since https://github.com/rust-lang/cargo/pull/7700 `proc_macro` is part of the prelude for
// proc-macro crates, but to support older compilers we still need this explicit `extern crate`.
#[allow(unused_extern_crates)]
extern crate proc_macro;

use proc_macro::TokenStream;
use proc_macro_hack::proc_macro_hack;

mod join;
mod select;

/// The `join!` macro.
#[proc_macro_hack]
pub fn join(input: TokenStream) -> TokenStream {
    crate::join::join(input)
}

/// The `try_join!` macro.
#[proc_macro_hack]
pub fn try_join(input: TokenStream) -> TokenStream {
    crate::join::try_join(input)
}

/// The `select!` macro.
#[proc_macro_hack]
pub fn select(input: TokenStream) -> TokenStream {
    crate::select::select(input)
}

/// The `select_biased!` macro.
#[proc_macro_hack]
pub fn select_biased(input: TokenStream) -> TokenStream {
    crate::select::select_biased(input)
}
<|endoftext|>


<commit_before>import libc::{c_void, c_int, c_char};

export surface;
export surface_flag;
export swsurface, hwsurface, asyncblit;
export video_mode_flag;
export anyformat, hwpalette, doublebuf, fullscreen, opengl,
       openglblit, resizable, noframe;
export set_video_mode, free_surface;
export load_bmp;
export display_format;
export blit_surface;
export flip;
export create_rgb_surface;

type rw_ops = c_void;

// FIXME: Should be an enum
type surface = c_void;

type rect = {
    x: i16,
    y: i16,
    w: u16,
    h: u16
};

enum surface_flag {
    swsurface = 0x00000000,
    hwsurface = 0x00000001,
    asyncblit = 0x00000004,
}

enum video_mode_flag {
    anyformat  = 0x10000000,
    hwpalette  = 0x20000000,
    doublebuf  = 0x40000000,
    fullscreen = 0x80000000,
    opengl     = 0x00000002,
    openglblit = 0x0000000A,
    resizable  = 0x00000010,
    noframe    = 0x00000020,
}

fn set_video_mode(
    width: int,
    height: int,
    bitsperpixel: int,
    surface_flags: [surface_flag],
    video_mode_flags: [video_mode_flag]
) -> *surface {
    let flags = vec::foldl(0u32, surface_flags) {|flags, flag|
        flags | flag as u32
    };
    let flags = vec::foldl(flags, video_mode_flags) {|flags, flag|
        flags | flag as u32
    };
    SDL::SDL_SetVideoMode(width as c_int, height as c_int,
                          bitsperpixel as c_int, flags)
}

fn free_surface(surface: *surface) {
    SDL::SDL_FreeSurface(surface)
}

fn load_bmp(file: str) -> *surface unsafe {
    str::as_buf(file) {|buf|
        let  buf = unsafe::reinterpret_cast(buf);
        str::as_buf("rb") {|rbbuf|
            let rbbuf = unsafe::reinterpret_cast(rbbuf);
            SDL::SDL_LoadBMP_RW(SDL::SDL_RWFromFile(buf, rbbuf), 1 as c_int)
        }
    }
}

fn display_format(surface: *surface) -> *surface {
    SDL::SDL_DisplayFormat(surface)
}

fn blit_surface(src: *surface, srcrect: *rect,
                dst: *surface, dstrect: *rect) -> bool {
    let res = SDL::SDL_UpperBlit(src, srcrect, dst, dstrect);
    ret res == 0 as c_int;
}

fn flip(screen: *surface) -> bool {
    SDL::SDL_Flip(screen) == 0 as c_int
}

fn create_rgb_surface(
    surface_flags: [surface_flag],
    width: int, height: int, bits_per_pixel: int,
    rmask: u32, gmask: u32, bmask: u32, amask: u32) -> *surface {

    let flags = vec::foldl(0u32, surface_flags) {|flags, flag|
        flags | flag as u32
    };
    SDL::SDL_CreateRGBSurface(
        flags, width as c_int, height as c_int, bits_per_pixel as c_int,
        rmask, gmask, bmask, amask)
}

native mod SDL {
    fn SDL_SetVideoMode(width: c_int, height: c_int,
                        bitsperpixel: c_int, flags: u32) -> *surface;
    fn SDL_FreeSurface(surface: *surface);
    fn SDL_LoadBMP_RW(src: *rw_ops, freesrc: c_int) -> *surface;
    fn SDL_RWFromFile(file: *c_char, mode: *c_char) -> *rw_ops;
    fn SDL_DisplayFormat(surface: *surface) -> *surface;
    fn SDL_UpperBlit(src: *surface, srcrect: *rect,
                     dst: *surface, dstrect: *rect) -> c_int;
    fn SDL_Flip(screen: *surface) -> c_int;
    fn SDL_CreateRGBSurface(flags: u32, width: c_int, height: c_int,
                            bitsPerPixel: c_int,
                            Rmask: u32, Gmask: u32, Bmask: u32, Amask: u32) -> *surface;
}
<commit_msg>Define some of the members of surface<commit_after>import libc::{c_void, c_int, c_char};

export surface;
export surface_flag;
export swsurface, hwsurface, asyncblit;
export video_mode_flag;
export anyformat, hwpalette, doublebuf, fullscreen, opengl,
       openglblit, resizable, noframe;
export set_video_mode, free_surface;
export load_bmp;
export display_format;
export blit_surface;
export flip;
export create_rgb_surface;

type rw_ops = c_void;

type surface = {
    flags: u32,
    format: *c_void,
    w: c_int,
    h: c_int,
    pitch: u16,
    pixels: *c_void,
    offset: c_int
    // FIXME: Remaining are unlisted
};

type rect = {
    x: i16,
    y: i16,
    w: u16,
    h: u16
};

enum surface_flag {
    swsurface = 0x00000000,
    hwsurface = 0x00000001,
    asyncblit = 0x00000004,
}

enum video_mode_flag {
    anyformat  = 0x10000000,
    hwpalette  = 0x20000000,
    doublebuf  = 0x40000000,
    fullscreen = 0x80000000,
    opengl     = 0x00000002,
    openglblit = 0x0000000A,
    resizable  = 0x00000010,
    noframe    = 0x00000020,
}

fn set_video_mode(
    width: int,
    height: int,
    bitsperpixel: int,
    surface_flags: [surface_flag],
    video_mode_flags: [video_mode_flag]
) -> *surface {
    let flags = vec::foldl(0u32, surface_flags) {|flags, flag|
        flags | flag as u32
    };
    let flags = vec::foldl(flags, video_mode_flags) {|flags, flag|
        flags | flag as u32
    };
    SDL::SDL_SetVideoMode(width as c_int, height as c_int,
                          bitsperpixel as c_int, flags)
}

fn free_surface(surface: *surface) {
    SDL::SDL_FreeSurface(surface)
}

fn load_bmp(file: str) -> *surface unsafe {
    str::as_buf(file) {|buf|
        let  buf = unsafe::reinterpret_cast(buf);
        str::as_buf("rb") {|rbbuf|
            let rbbuf = unsafe::reinterpret_cast(rbbuf);
            SDL::SDL_LoadBMP_RW(SDL::SDL_RWFromFile(buf, rbbuf), 1 as c_int)
        }
    }
}

fn display_format(surface: *surface) -> *surface {
    SDL::SDL_DisplayFormat(surface)
}

fn blit_surface(src: *surface, srcrect: *rect,
                dst: *surface, dstrect: *rect) -> bool {
    let res = SDL::SDL_UpperBlit(src, srcrect, dst, dstrect);
    ret res == 0 as c_int;
}

fn flip(screen: *surface) -> bool {
    SDL::SDL_Flip(screen) == 0 as c_int
}

fn create_rgb_surface(
    surface_flags: [surface_flag],
    width: int, height: int, bits_per_pixel: int,
    rmask: u32, gmask: u32, bmask: u32, amask: u32) -> *surface {

    let flags = vec::foldl(0u32, surface_flags) {|flags, flag|
        flags | flag as u32
    };
    SDL::SDL_CreateRGBSurface(
        flags, width as c_int, height as c_int, bits_per_pixel as c_int,
        rmask, gmask, bmask, amask)
}

native mod SDL {
    fn SDL_SetVideoMode(width: c_int, height: c_int,
                        bitsperpixel: c_int, flags: u32) -> *surface;
    fn SDL_FreeSurface(surface: *surface);
    fn SDL_LoadBMP_RW(src: *rw_ops, freesrc: c_int) -> *surface;
    fn SDL_RWFromFile(file: *c_char, mode: *c_char) -> *rw_ops;
    fn SDL_DisplayFormat(surface: *surface) -> *surface;
    fn SDL_UpperBlit(src: *surface, srcrect: *rect,
                     dst: *surface, dstrect: *rect) -> c_int;
    fn SDL_Flip(screen: *surface) -> c_int;
    fn SDL_CreateRGBSurface(flags: u32, width: c_int, height: c_int,
                            bitsPerPixel: c_int,
                            Rmask: u32, Gmask: u32, Bmask: u32, Amask: u32) -> *surface;
}
<|endoftext|>


<commit_before>extern crate pty;
extern crate libc;

use std::io::prelude::*;
use std::string::String;
use std::process::Command;
use pty::fork::{Fork, Master};

fn read_line(master:&mut Master) -> String {
    let mut buf = [0];
    let mut res = String::new();
    while buf[0] as char != '\n' {
        master.read(&mut buf).expect("cannot read 1 byte");
        res.push(buf[0] as char)
    }
    res
}

#[test]
fn it_can_read_write() {
    let fork = Fork::from_ptmx().unwrap();

    if let Some(mut master) = fork.is_parent().ok() {
        let _ = master.write("echo readme!\n".to_string().as_bytes());

        read_line(&mut master); // this is the "echo readme!" we just sent
        read_line(&mut master); // this is the shell and "echo readme!" again
        assert_eq!(read_line(&mut master).trim(), "readme!");
        let _ = master.write("exit\n".to_string().as_bytes());
    } else {
        let _ = Command::new("bash").status();
    }
}
<commit_msg>fix for stable rust<commit_after>extern crate pty;
extern crate libc;

use std::io::prelude::*;
use std::string::String;
use std::process::Command;
use self::pty::fork::{Fork, Master};

fn read_line(master:&mut Master) -> String {
    let mut buf = [0];
    let mut res = String::new();
    while buf[0] as char != '\n' {
        master.read(&mut buf).expect("cannot read 1 byte");
        res.push(buf[0] as char)
    }
    res
}

#[test]
fn it_can_read_write() {
    let fork = Fork::from_ptmx().unwrap();

    if let Some(mut master) = fork.is_parent().ok() {
        let _ = master.write("echo readme!\n".to_string().as_bytes());

        read_line(&mut master); // this is the "echo readme!" we just sent
        read_line(&mut master); // this is the shell and "echo readme!" again
        assert_eq!(read_line(&mut master).trim(), "readme!");
        let _ = master.write("exit\n".to_string().as_bytes());
    } else {
        let _ = Command::new("bash").status();
    }
}
<|endoftext|>


<commit_before>import libc::{c_void, c_int, c_char};

export surface;
export surface_flag;
export swsurface, hwsurface, asyncblit;
export video_mode_flag;
export anyformat, hwpalette, doublebuf, fullscreen, opengl,
       openglblit, resizable, noframe;
export set_video_mode, free_surface;
export load_bmp;
export display_format;
export blit_surface;
export flip;

type rw_ops = c_void;

// FIXME: Should be an enum
type surface = c_void;

type rect = {
    x: i16,
    y: i16,
    w: u16,
    h: u16
};

enum surface_flag {
    swsurface = 0x00000000,
    hwsurface = 0x00000001,
    asyncblit = 0x00000004,
}

enum video_mode_flag {
    anyformat  = 0x10000000,
    hwpalette  = 0x20000000,
    doublebuf  = 0x40000000,
    fullscreen = 0x80000000,
    opengl     = 0x00000002,
    openglblit = 0x0000000A,
    resizable  = 0x00000010,
    noframe    = 0x00000020,
}

fn set_video_mode(
    width: int,
    height: int,
    bitsperpixel: int,
    surface_flags: [surface_flag],
    video_mode_flags: [video_mode_flag]
) -> *surface {
    let flags = vec::foldl(0u32, surface_flags) {|flags, flag|
        flags | flag as u32
    };
    let flags = vec::foldl(flags, video_mode_flags) {|flags, flag|
        flags | flag as u32
    };
    SDL::SDL_SetVideoMode(width as c_int, height as c_int,
                          bitsperpixel as c_int, flags)
}

fn free_surface(surface: *surface) {
    SDL::SDL_FreeSurface(surface)
}

fn load_bmp(file: str) -> *surface unsafe {
    str::as_buf(file) {|buf|
        let  buf = unsafe::reinterpret_cast(buf);
        str::as_buf("rb") {|rbbuf|
            let rbbuf = unsafe::reinterpret_cast(rbbuf);
            SDL::SDL_LoadBMP_RW(SDL::SDL_RWFromFile(buf, rbbuf), 1 as c_int)
        }
    }
}

fn display_format(surface: *surface) -> *surface {
    SDL::SDL_DisplayFormat(surface)
}

fn blit_surface(src: *surface, srcrect: *rect,
                dst: *surface, dstrect: *rect) -> bool {
    let res = SDL::SDL_UpperBlit(src, srcrect, dst, dstrect);
    ret res == 0 as c_int;
}

fn flip(screen: *surface) -> bool {
    SDL::SDL_Flip(screen) == 0 as c_int
}

native mod SDL {
    fn SDL_SetVideoMode(width: c_int, height: c_int,
                        bitsperpixel: c_int, flags: u32) -> *surface;
    fn SDL_FreeSurface(surface: *surface);
    fn SDL_LoadBMP_RW(src: *rw_ops, freesrc: c_int) -> *surface;
    fn SDL_RWFromFile(file: *c_char, mode: *c_char) -> *rw_ops;
    fn SDL_DisplayFormat(surface: *surface) -> *surface;
    fn SDL_UpperBlit(src: *surface, srcrect: *rect,
                     dst: *surface, dstrect: *rect) -> c_int;
    fn SDL_Flip(screen: *surface) -> c_int;
}
<commit_msg>Add create_rgb_surface<commit_after>import libc::{c_void, c_int, c_char};

export surface;
export surface_flag;
export swsurface, hwsurface, asyncblit;
export video_mode_flag;
export anyformat, hwpalette, doublebuf, fullscreen, opengl,
       openglblit, resizable, noframe;
export set_video_mode, free_surface;
export load_bmp;
export display_format;
export blit_surface;
export flip;
export create_rgb_surface;

type rw_ops = c_void;

// FIXME: Should be an enum
type surface = c_void;

type rect = {
    x: i16,
    y: i16,
    w: u16,
    h: u16
};

enum surface_flag {
    swsurface = 0x00000000,
    hwsurface = 0x00000001,
    asyncblit = 0x00000004,
}

enum video_mode_flag {
    anyformat  = 0x10000000,
    hwpalette  = 0x20000000,
    doublebuf  = 0x40000000,
    fullscreen = 0x80000000,
    opengl     = 0x00000002,
    openglblit = 0x0000000A,
    resizable  = 0x00000010,
    noframe    = 0x00000020,
}

fn set_video_mode(
    width: int,
    height: int,
    bitsperpixel: int,
    surface_flags: [surface_flag],
    video_mode_flags: [video_mode_flag]
) -> *surface {
    let flags = vec::foldl(0u32, surface_flags) {|flags, flag|
        flags | flag as u32
    };
    let flags = vec::foldl(flags, video_mode_flags) {|flags, flag|
        flags | flag as u32
    };
    SDL::SDL_SetVideoMode(width as c_int, height as c_int,
                          bitsperpixel as c_int, flags)
}

fn free_surface(surface: *surface) {
    SDL::SDL_FreeSurface(surface)
}

fn load_bmp(file: str) -> *surface unsafe {
    str::as_buf(file) {|buf|
        let  buf = unsafe::reinterpret_cast(buf);
        str::as_buf("rb") {|rbbuf|
            let rbbuf = unsafe::reinterpret_cast(rbbuf);
            SDL::SDL_LoadBMP_RW(SDL::SDL_RWFromFile(buf, rbbuf), 1 as c_int)
        }
    }
}

fn display_format(surface: *surface) -> *surface {
    SDL::SDL_DisplayFormat(surface)
}

fn blit_surface(src: *surface, srcrect: *rect,
                dst: *surface, dstrect: *rect) -> bool {
    let res = SDL::SDL_UpperBlit(src, srcrect, dst, dstrect);
    ret res == 0 as c_int;
}

fn flip(screen: *surface) -> bool {
    SDL::SDL_Flip(screen) == 0 as c_int
}

fn create_rgb_surface(
    surface_flags: [surface_flag],
    width: int, height: int, bits_per_pixel: int,
    rmask: u32, gmask: u32, bmask: u32, amask: u32) -> *surface {

    let flags = vec::foldl(0u32, surface_flags) {|flags, flag|
        flags | flag as u32
    };
    SDL::SDL_CreateRGBSurface(
        flags, width as c_int, height as c_int, bits_per_pixel as c_int,
        rmask, gmask, bmask, amask)
}

native mod SDL {
    fn SDL_SetVideoMode(width: c_int, height: c_int,
                        bitsperpixel: c_int, flags: u32) -> *surface;
    fn SDL_FreeSurface(surface: *surface);
    fn SDL_LoadBMP_RW(src: *rw_ops, freesrc: c_int) -> *surface;
    fn SDL_RWFromFile(file: *c_char, mode: *c_char) -> *rw_ops;
    fn SDL_DisplayFormat(surface: *surface) -> *surface;
    fn SDL_UpperBlit(src: *surface, srcrect: *rect,
                     dst: *surface, dstrect: *rect) -> c_int;
    fn SDL_Flip(screen: *surface) -> c_int;
    fn SDL_CreateRGBSurface(flags: u32, width: c_int, height: c_int,
                            bitsPerPixel: c_int,
                            Rmask: u32, Gmask: u32, Bmask: u32, Amask: u32) -> *surface;
}
<|endoftext|>


<commit_before>//! these are also doc comments
//! but for crates, modules or functions
//! triple quotes looks nicer than these sad

fn main() {

    // these are comments

    /// these are doc comments
    /// boring kind of things to do here
    /// ok has support for markdown inside
}
<commit_msg>if was nice but can't use /// in random place hmm.<commit_after>//! these are also doc comments
//! but for crates, modules or functions
//! triple quotes looks nicer than these sad

/// these are doc comments
/// boring kind of things to do here
/// ok has support for markdown inside
fn main() {

    // these are comments

    let x = 5;

    // no bloody paren nice
    if x == 5 {
        println!("yes x is 5");
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate pod_typeinfo;

use std::mem;

use pod_typeinfo::Type::*;
use pod_typeinfo::{Type, TypeInfo};

#[test]
fn test_scalar_types() {
    fn check_type<T: TypeInfo>(ty: Type) {
        assert_eq!(<T as TypeInfo>::type_info(), ty);
        assert_eq!(ty.size(), mem::size_of::<T>());
    }
    check_type::<i8>(Int8);
    check_type::<i16>(Int16);
    check_type::<i32>(Int32);
    check_type::<i64>(Int64);
    check_type::<u8>(UInt8);
    check_type::<u16>(UInt16);
    check_type::<u32>(UInt32);
    check_type::<u64>(UInt64);
    check_type::<isize>(ISize);
    check_type::<usize>(USize);
    check_type::<f32>(Float32);
    check_type::<f64>(Float64);
    check_type::<bool>(Bool);
    check_type::<char>(Char);

}
<commit_msg>Test is_scalar/is_array/is_compound for scalar types<commit_after>#[macro_use]
extern crate pod_typeinfo;

use std::mem;

use pod_typeinfo::Type::*;
use pod_typeinfo::{Type, TypeInfo};

#[test]
fn test_scalar_types() {
    fn check_scalar_type<T: TypeInfo>(ty: Type) {
        assert_eq!(<T as TypeInfo>::type_info(), ty);
        assert_eq!(ty.size(), mem::size_of::<T>());
        assert!(ty.is_scalar() && !ty.is_array() && !ty.is_compound());
    }
    check_scalar_type::<i8>(Int8);
    check_scalar_type::<i16>(Int16);
    check_scalar_type::<i32>(Int32);
    check_scalar_type::<i64>(Int64);
    check_scalar_type::<u8>(UInt8);
    check_scalar_type::<u16>(UInt16);
    check_scalar_type::<u32>(UInt32);
    check_scalar_type::<u64>(UInt64);
    check_scalar_type::<isize>(ISize);
    check_scalar_type::<usize>(USize);
    check_scalar_type::<f32>(Float32);
    check_scalar_type::<f64>(Float64);
    check_scalar_type::<bool>(Bool);
    check_scalar_type::<char>(Char);

}
<|endoftext|>


<commit_before>#![feature(phase)]

#[phase(plugin, link)] extern crate rustspec;
#[phase(plugin)] extern crate rustspec_assertions;

#[deriving(Show)]
#[deriving(Clone)]
#[deriving(PartialEq)]
struct Point {
    x: int,
    y: int
}

impl Add<Point, Point> for Point {
    fn add(&self, other: &Point) -> Point {
        Point { x: self.x + other.x, y: self.y + other.y }
    }
}

scenario!("Point", {
    before({
        let one = 1i;
    });

    describe("#add", {
        before({
            let point_a = ::Point { x: one, y: one };
            let point_b = ::Point { x: 2i, y: 2i };
        });

        it("adds two points", {
            let point_c = point_a + point_b;
            expect(point_c.x).to(eq!(3i));
            expect(point_c.y).to(eq!(3i));
        });

        it.fails("adds two points and fails", {
            let point_c = point_a + point_b;
            expect(point_c.x).to(eq!(4i));
            expect(point_c.y).to(eq!(4i));
        });

        it.ignores("ignores this", {
            let point_c = point_a + point_b;
            expect(point_c.x).to(eq!(4i));
            expect(point_c.y).to(eq!(4i));
        });

        context("testing PartialEq", {
            before({
                let point_3 = point_a + point_b;
            });

            it("passes with equals", {
                let point_c = point_a + point_b;
                expect(point_c).to(eq!(point_3));
            });
        });
    });
})
<commit_msg>comment bugged test case<commit_after>#![feature(phase)]

#[phase(plugin, link)] extern crate rustspec;
#[phase(plugin)] extern crate rustspec_assertions;

#[deriving(Show)]
#[deriving(Clone)]
#[deriving(PartialEq)]
struct Point {
    x: int,
    y: int
}

impl Add<Point, Point> for Point {
    fn add(&self, other: &Point) -> Point {
        Point { x: self.x + other.x, y: self.y + other.y }
    }
}

scenario!("Point", {
    before({
        let one = 1i;
    });

    describe("#add", {
        before({
            let point_a = ::Point { x: one, y: one };
            let point_b = ::Point { x: 2i, y: 2i };
        });

        it("adds two points", {
            let point_c = point_a + point_b;
            expect(point_c.x).to(eq!(3i));
            expect(point_c.y).to(eq!(3i));
        });

        it.fails("adds two points and fails", {
            let point_c = point_a + point_b;
            expect(point_c.x).to(eq!(4i));
            expect(point_c.y).to(eq!(4i));
        });

        it.ignores("ignores this", {
            let point_c = point_a + point_b;
            expect(point_c.x).to(eq!(4i));
            expect(point_c.y).to(eq!(4i));
        });

        // Commented until bugfixed
        // context("testing PartialEq", {
        //     before({
        //         let point_3 = point_a + point_b;
        //     });

        //     it("passes with equals", {
        //         let point_c = point_a + point_b;
        //         expect(point_c).to(eq!(point_3));
        //     });
        // });
    });
})
<|endoftext|>


<commit_before>//! Contains traits responsible for the actual construction of SQL statements
//!
//! The types in this module are part of Diesel's public API, but are generally
//! only useful for implementing Diesel plugins. Applications should generally
//! not need to care about the types inside of this module.

#[macro_use]
mod query_id;
#[macro_use]
mod clause_macro;

mod ast_pass;
pub mod bind_collector;
mod debug_query;
mod delete_statement;
#[doc(hidden)]
pub mod functions;
#[doc(hidden)]
pub mod nodes;
mod distinct_clause;
mod group_by_clause;
mod limit_clause;
mod offset_clause;
mod order_clause;
mod returning_clause;
mod select_clause;
mod select_statement;
pub mod where_clause;
pub mod insert_statement;
pub mod update_statement;

pub use self::ast_pass::AstPass;
pub use self::bind_collector::BindCollector;
pub use self::debug_query::DebugQuery;
pub use self::query_id::QueryId;
#[doc(hidden)]
pub use self::select_statement::{BoxedSelectStatement, SelectStatement};
#[doc(inline)]
pub use self::update_statement::{AsChangeset, Changeset, IncompleteUpdateStatement,
                                 IntoUpdateTarget, UpdateStatement, UpdateTarget};
#[doc(inline)]
pub use self::insert_statement::{IncompleteDefaultInsertStatement, IncompleteInsertStatement};

use std::error::Error;

use backend::Backend;
use result::QueryResult;

#[doc(hidden)]
pub type Binds = Vec<Option<Vec<u8>>>;
pub type BuildQueryResult = Result<(), Box<Error + Send + Sync>>;

/// Apps should not need to concern themselves with this trait.
///
/// This is the trait used to actually construct a SQL query. You will take one
/// of these as an argument if you're implementing
/// [`QueryFragment`](trait.QueryFragment.html) manually.
pub trait QueryBuilder<DB: Backend> {
    fn push_sql(&mut self, sql: &str);
    fn push_identifier(&mut self, identifier: &str) -> QueryResult<()>;
    fn push_bind_param(&mut self);
    fn finish(self) -> String;
}

/// A complete SQL query with a return type. This can be a select statement, or
/// a command such as `update` or `insert` with a `RETURNING` clause. Unlike
/// [`Expression`](../expression/trait.Expression.html), types implementing this
/// trait are guaranteed to be executable on their own.
pub trait Query {
    type SqlType;
}

impl<'a, T: Query> Query for &'a T {
    type SqlType = T::SqlType;
}

/// An untyped fragment of SQL. This may be a complete SQL command (such as
/// an update statement without a `RETURNING` clause), or a subsection (such as
/// our internal types used to represent a `WHERE` clause). All methods on
/// [`Connection`](../connection/trait.Connection.html) that execute a query require this
/// trait to be implemented.
pub trait QueryFragment<DB: Backend> {
    fn walk_ast(&self, pass: AstPass<DB>) -> QueryResult<()>;

    fn to_sql(&self, out: &mut DB::QueryBuilder) -> QueryResult<()> {
        self.walk_ast(AstPass::to_sql(out))
    }

    fn collect_binds(
        &self,
        out: &mut DB::BindCollector,
        metadata_lookup: &DB::MetadataLookup,
    ) -> QueryResult<()> {
        self.walk_ast(AstPass::collect_binds(out, metadata_lookup))
    }

    fn is_safe_to_cache_prepared(&self) -> QueryResult<bool> {
        let mut result = true;
        self.walk_ast(AstPass::is_safe_to_cache_prepared(&mut result))?;
        Ok(result)
    }
}

impl<T: ?Sized, DB> QueryFragment<DB> for Box<T>
where
    DB: Backend,
    T: QueryFragment<DB>,
{
    fn walk_ast(&self, pass: AstPass<DB>) -> QueryResult<()> {
        QueryFragment::walk_ast(&**self, pass)
    }
}

impl<'a, T: ?Sized, DB> QueryFragment<DB> for &'a T
where
    DB: Backend,
    T: QueryFragment<DB>,
{
    fn walk_ast(&self, pass: AstPass<DB>) -> QueryResult<()> {
        QueryFragment::walk_ast(&**self, pass)
    }
}

impl<DB: Backend> QueryFragment<DB> for () {
    fn walk_ast(&self, _: AstPass<DB>) -> QueryResult<()> {
        Ok(())
    }
}

/// Types that can be converted into a complete, typed SQL query. This is used
/// internally to automatically add the right select clause when none is
/// specified, or to automatically add `RETURNING *` in certain contexts
pub trait AsQuery {
    type SqlType;
    type Query: Query<SqlType = Self::SqlType>;

    fn as_query(self) -> Self::Query;
}

impl<T: Query> AsQuery for T {
    type SqlType = <Self as Query>::SqlType;
    type Query = Self;

    fn as_query(self) -> Self::Query {
        self
    }
}

/// Takes a query `QueryFragment` expression as an argument and returns a type
/// that implements `fmt::Display` and `fmt::Debug` to show the query.
///
/// The `Display` implementation will show the exact query being sent to the
/// server, with a comment showing the values of the bind parameters. The
/// `Debug` implementation will include the same information in a more
/// structured form, and respects pretty printing.
///
/// # Example
///
/// ### Returning SQL from a count statement:
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// #
/// # #[macro_use] extern crate diesel;
/// # use diesel::*;
/// # use schema::*;
/// #
/// # fn main() {
/// #   use schema::users::dsl::*;
/// let sql = debug_query::<DB, _>(&users.count()).to_string();
/// # if cfg!(feature = "postgres") {
/// #     assert_eq!(sql, r#"SELECT COUNT(*) FROM "users" -- binds: []"#);
/// # } else {
/// assert_eq!(sql, "SELECT COUNT(*) FROM `users` -- binds: []");
/// # }
///
/// let query = users.find(1);
/// let debug = debug_query::<DB, _>(&query);
/// # if cfg!(feature = "postgres") {
/// #     assert_eq!(debug.to_string(), "SELECT \"users\".\"id\", \"users\".\"name\" \
/// #         FROM \"users\" WHERE \"users\".\"id\" = $1 -- binds: [1]");
/// # } else {
/// assert_eq!(debug.to_string(), "SELECT `users`.`id`, `users`.`name` FROM `users` \
///     WHERE `users`.`id` = ? -- binds: [1]");
/// # }
///
/// let debug = format!("{:?}", debug);
/// # if !cfg!(feature = "postgres") { // Escaping that string is a pain
/// let expected = "Query { \
///     sql: \"SELECT `users`.`id`, `users`.`name` FROM `users` WHERE \
///         `users`.`id` = ?\", \
///     binds: [1] \
/// }";
/// assert_eq!(debug, expected);
/// # }
/// # }
/// ```
pub fn debug_query<DB, T>(query: &T) -> DebugQuery<T, DB> {
    DebugQuery::new(query)
}

#[doc(hidden)]
#[cfg(all(feature = "with-deprecated", feature = "postgres"))]
pub fn deprecated_debug_sql<T>(query: &T) -> String
where
    T: QueryFragment<::pg::Pg>,
{
    debug_query(query).to_string()
}

#[doc(hidden)]
#[cfg(all(feature = "with-deprecated", feature = "mysql", not(feature = "postgres")))]
pub fn deprecated_debug_sql<T>(query: &T) -> String
where
    T: QueryFragment<::mysql::Mysql>,
{
    debug_query(query).to_string()
}

#[doc(hidden)]
#[cfg(all(feature = "with-deprecated", feature = "sqlite",
            not(any(feature = "postgres", feature = "mysql"))))]
pub fn deprecated_debug_sql<T>(query: &T) -> String
where
    T: QueryFragment<::sqlite::Sqlite>,
{
    debug_query(query).to_string()
}

#[doc(hidden)]
#[cfg(all(feature = "with-deprecated",
            not(any(feature = "postgres", feature = "mysql", feature = "sqlite"))))]
pub fn deprecated_debug_sql<T>(_query: &T) -> String {
    String::from(
        "At least one backend must be enabled to generated debug SQL",
    )
}
<commit_msg>Document all items on `QueryFragment` [ci skip]<commit_after>//! Contains traits responsible for the actual construction of SQL statements
//!
//! The types in this module are part of Diesel's public API, but are generally
//! only useful for implementing Diesel plugins. Applications should generally
//! not need to care about the types inside of this module.

#[macro_use]
mod query_id;
#[macro_use]
mod clause_macro;

mod ast_pass;
pub mod bind_collector;
mod debug_query;
mod delete_statement;
#[doc(hidden)]
pub mod functions;
#[doc(hidden)]
pub mod nodes;
mod distinct_clause;
mod group_by_clause;
mod limit_clause;
mod offset_clause;
mod order_clause;
mod returning_clause;
mod select_clause;
mod select_statement;
pub mod where_clause;
pub mod insert_statement;
pub mod update_statement;

pub use self::ast_pass::AstPass;
pub use self::bind_collector::BindCollector;
pub use self::debug_query::DebugQuery;
pub use self::query_id::QueryId;
#[doc(hidden)]
pub use self::select_statement::{BoxedSelectStatement, SelectStatement};
#[doc(inline)]
pub use self::update_statement::{AsChangeset, Changeset, IncompleteUpdateStatement,
                                 IntoUpdateTarget, UpdateStatement, UpdateTarget};
#[doc(inline)]
pub use self::insert_statement::{IncompleteDefaultInsertStatement, IncompleteInsertStatement};

use std::error::Error;

use backend::Backend;
use result::QueryResult;

#[doc(hidden)]
pub type Binds = Vec<Option<Vec<u8>>>;
pub type BuildQueryResult = Result<(), Box<Error + Send + Sync>>;

/// Apps should not need to concern themselves with this trait.
///
/// This is the trait used to actually construct a SQL query. You will take one
/// of these as an argument if you're implementing
/// [`QueryFragment`](trait.QueryFragment.html) manually.
pub trait QueryBuilder<DB: Backend> {
    fn push_sql(&mut self, sql: &str);
    fn push_identifier(&mut self, identifier: &str) -> QueryResult<()>;
    fn push_bind_param(&mut self);
    fn finish(self) -> String;
}

/// A complete SQL query with a return type. This can be a select statement, or
/// a command such as `update` or `insert` with a `RETURNING` clause. Unlike
/// [`Expression`](../expression/trait.Expression.html), types implementing this
/// trait are guaranteed to be executable on their own.
pub trait Query {
    type SqlType;
}

impl<'a, T: Query> Query for &'a T {
    type SqlType = T::SqlType;
}

/// An untyped fragment of SQL. This may be a complete SQL command (such as
/// an update statement without a `RETURNING` clause), or a subsection (such as
/// our internal types used to represent a `WHERE` clause). All methods on
/// [`Connection`](../connection/trait.Connection.html) that execute a query require this
/// trait to be implemented.
pub trait QueryFragment<DB: Backend> {
    /// Walk over this `QueryFragment` for all passes.
    ///
    /// This method is where the actual behavior of an AST node is implemented.
    /// This method will contain the behavior required for all possible AST
    /// passes. See the documentation of [`AstPass`] for more details.
    ///
    /// [`AstPass`]: struct.AstPass.html
    fn walk_ast(&self, pass: AstPass<DB>) -> QueryResult<()>;

    /// Converts this `QueryFragment` to its SQL representation
    fn to_sql(&self, out: &mut DB::QueryBuilder) -> QueryResult<()> {
        self.walk_ast(AstPass::to_sql(out))
    }

    /// Serializes all bind parameters in this query.
    ///
    /// A bind parameter is a value which is sent separately from the query
    /// itself. It is represented in SQL with a placeholder such as `?` or `$1`.
    fn collect_binds(
        &self,
        out: &mut DB::BindCollector,
        metadata_lookup: &DB::MetadataLookup,
    ) -> QueryResult<()> {
        self.walk_ast(AstPass::collect_binds(out, metadata_lookup))
    }

    /// Is this query safe to store in the prepared statement cache?
    ///
    /// In order to keep our prepared statement cache at a reasonable size, we
    /// avoid caching any queries which represent a potentially unbounded number
    /// of SQL queries. Generally this will only return `true` for queries for
    /// which `to_sql` will always construct exactly identical SQL.
    ///
    /// Some examples of where this method will return `false` are:
    ///
    /// - `SqlLiteral` (We don't know if the SQL was constructed dynamically, so
    ///   we must assume that it was)
    /// - `In` and `NotIn` (Each value requires a separate bind param
    ///   placeholder)
    fn is_safe_to_cache_prepared(&self) -> QueryResult<bool> {
        let mut result = true;
        self.walk_ast(AstPass::is_safe_to_cache_prepared(&mut result))?;
        Ok(result)
    }
}

impl<T: ?Sized, DB> QueryFragment<DB> for Box<T>
where
    DB: Backend,
    T: QueryFragment<DB>,
{
    fn walk_ast(&self, pass: AstPass<DB>) -> QueryResult<()> {
        QueryFragment::walk_ast(&**self, pass)
    }
}

impl<'a, T: ?Sized, DB> QueryFragment<DB> for &'a T
where
    DB: Backend,
    T: QueryFragment<DB>,
{
    fn walk_ast(&self, pass: AstPass<DB>) -> QueryResult<()> {
        QueryFragment::walk_ast(&**self, pass)
    }
}

impl<DB: Backend> QueryFragment<DB> for () {
    fn walk_ast(&self, _: AstPass<DB>) -> QueryResult<()> {
        Ok(())
    }
}

/// Types that can be converted into a complete, typed SQL query. This is used
/// internally to automatically add the right select clause when none is
/// specified, or to automatically add `RETURNING *` in certain contexts
pub trait AsQuery {
    type SqlType;
    type Query: Query<SqlType = Self::SqlType>;

    fn as_query(self) -> Self::Query;
}

impl<T: Query> AsQuery for T {
    type SqlType = <Self as Query>::SqlType;
    type Query = Self;

    fn as_query(self) -> Self::Query {
        self
    }
}

/// Takes a query `QueryFragment` expression as an argument and returns a type
/// that implements `fmt::Display` and `fmt::Debug` to show the query.
///
/// The `Display` implementation will show the exact query being sent to the
/// server, with a comment showing the values of the bind parameters. The
/// `Debug` implementation will include the same information in a more
/// structured form, and respects pretty printing.
///
/// # Example
///
/// ### Returning SQL from a count statement:
///
/// ```rust
/// # include!("../doctest_setup.rs");
/// #
/// # #[macro_use] extern crate diesel;
/// # use diesel::*;
/// # use schema::*;
/// #
/// # fn main() {
/// #   use schema::users::dsl::*;
/// let sql = debug_query::<DB, _>(&users.count()).to_string();
/// # if cfg!(feature = "postgres") {
/// #     assert_eq!(sql, r#"SELECT COUNT(*) FROM "users" -- binds: []"#);
/// # } else {
/// assert_eq!(sql, "SELECT COUNT(*) FROM `users` -- binds: []");
/// # }
///
/// let query = users.find(1);
/// let debug = debug_query::<DB, _>(&query);
/// # if cfg!(feature = "postgres") {
/// #     assert_eq!(debug.to_string(), "SELECT \"users\".\"id\", \"users\".\"name\" \
/// #         FROM \"users\" WHERE \"users\".\"id\" = $1 -- binds: [1]");
/// # } else {
/// assert_eq!(debug.to_string(), "SELECT `users`.`id`, `users`.`name` FROM `users` \
///     WHERE `users`.`id` = ? -- binds: [1]");
/// # }
///
/// let debug = format!("{:?}", debug);
/// # if !cfg!(feature = "postgres") { // Escaping that string is a pain
/// let expected = "Query { \
///     sql: \"SELECT `users`.`id`, `users`.`name` FROM `users` WHERE \
///         `users`.`id` = ?\", \
///     binds: [1] \
/// }";
/// assert_eq!(debug, expected);
/// # }
/// # }
/// ```
pub fn debug_query<DB, T>(query: &T) -> DebugQuery<T, DB> {
    DebugQuery::new(query)
}

#[doc(hidden)]
#[cfg(all(feature = "with-deprecated", feature = "postgres"))]
pub fn deprecated_debug_sql<T>(query: &T) -> String
where
    T: QueryFragment<::pg::Pg>,
{
    debug_query(query).to_string()
}

#[doc(hidden)]
#[cfg(all(feature = "with-deprecated", feature = "mysql", not(feature = "postgres")))]
pub fn deprecated_debug_sql<T>(query: &T) -> String
where
    T: QueryFragment<::mysql::Mysql>,
{
    debug_query(query).to_string()
}

#[doc(hidden)]
#[cfg(all(feature = "with-deprecated", feature = "sqlite",
            not(any(feature = "postgres", feature = "mysql"))))]
pub fn deprecated_debug_sql<T>(query: &T) -> String
where
    T: QueryFragment<::sqlite::Sqlite>,
{
    debug_query(query).to_string()
}

#[doc(hidden)]
#[cfg(all(feature = "with-deprecated",
            not(any(feature = "postgres", feature = "mysql", feature = "sqlite"))))]
pub fn deprecated_debug_sql<T>(_query: &T) -> String {
    String::from(
        "At least one backend must be enabled to generated debug SQL",
    )
}
<|endoftext|>


<commit_before>// aux-build:struct-field-privacy.rs

extern crate "struct-field-privacy" as xc;

use xc::B;

fn main () {
    let k = B {
        aa: 20, //~ ERROR structure `struct-field-privacy::B` has no field named `aa`
        //~^ HELP did you mean `a`?
        bb: 20, //~ ERROR structure `struct-field-privacy::B` has no field named `bb`
    };
}
<commit_msg>added local crate struct with priv field to test<commit_after>// aux-build:struct-field-privacy.rs

extern crate "struct-field-privacy" as xc;

use xc::B;

struct A {
    pub a: u32,
    b: u32,
}

fn main () {
    // external crate struct
    let k = B {
        aa: 20, //~ ERROR structure `struct-field-privacy::B` has no field named `aa`
        //~^ HELP did you mean `a`?
        bb: 20, //~ ERROR structure `struct-field-privacy::B` has no field named `bb`
    };
    // local crate struct
    let l = A {
        aa: 20, //~ ERROR structure `A` has no field named `aa`
        //~^ HELP did you mean `a`?
        bb: 20, //~ ERROR structure `A` has no field named `bb`
        //~^ HELP did you mean `b`?
    };
}
<|endoftext|>


<commit_before>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

struct A { a: int, b: Box<int> }
struct B { a: Box<int>, b: Box<int> }

fn borrow<T>(_: &T) { }

fn move_after_copy() {
    let x = A { a: 1, b: box 2 };
    drop(x.a);
    drop(x.b);
}

fn move_after_fu_copy() {
    let x = A { a: 1, b: box 2 };
    let _y = A { b: box 3, .. x };
    drop(x.b);
}

fn fu_move_after_copy() {
    let x = A { a: 1, b: box 2 };
    drop(x.a);
    let _y = A { a: 3, .. x };
}

fn fu_move_after_fu_copy() {
    let x = A { a: 1, b: box 2 };
    let _y = A { b: box 3, .. x };
    let _z = A { a: 4, .. x };
}

fn copy_after_move() {
    let x = A { a: 1, b: box 2 };
    drop(x.b);
    drop(x.a);
}

fn copy_after_fu_move() {
    let x = A { a: 1, b: box 2 };
    let y = A { a: 3, .. x };
    drop(x.a);
}

fn fu_copy_after_move() {
    let x = A { a: 1, b: box 2 };
    drop(x.b);
    let _y = A { b: box 3, .. x };
}

fn fu_copy_after_fu_move() {
    let x = A { a: 1, b: box 2 };
    let _y = A { a: 3, .. x };
    let _z = A { b: box 3, .. x };
}

fn borrow_after_move() {
    let x = A { a: 1, b: box 2 };
    drop(x.b);
    borrow(&x.a);
}

fn borrow_after_fu_move() {
    let x = A { a: 1, b: box 2 };
    let _y = A { a: 3, .. x };
    borrow(&x.a);
}

fn move_after_borrow() {
    let x = A { a: 1, b: box 2 };
    borrow(&x.a);
    drop(x.b);
}

fn fu_move_after_borrow() {
    let x = A { a: 1, b: box 2 };
    borrow(&x.a);
    let _y = A { a: 3, .. x };
}

fn mut_borrow_after_mut_borrow() {
    let mut x = A { a: 1, b: box 2 };
    let y = &mut x.a;
    let z = &mut x.b;
    drop(*y);
    drop(**z);
}

fn move_after_move() {
    let x = B { a: box 1, b: box 2 };
    drop(x.a);
    drop(x.b);
}

fn move_after_fu_move() {
    let x = B { a: box 1, b: box 2 };
    let y = B { a: box 3, .. x };
    drop(x.a);
}

fn fu_move_after_move() {
    let x = B { a: box 1, b: box 2 };
    drop(x.a);
    let z = B { a: box 3, .. x };
    drop(z.b);
}

fn fu_move_after_fu_move() {
    let x = B { a: box 1, b: box 2 };
    let _y = B { b: box 3, .. x };
    let _z = B { a: box 4, .. x };
}

fn copy_after_assign_after_move() {
    let mut x = A { a: 1, b: box 2 };
    drop(x.b);
    x = A { a: 3, b: box 4 };
    drop(*x.b);
}

fn copy_after_field_assign_after_move() {
    let mut x = A { a: 1, b: box 2 };
    drop(x.b);
    x.b = box 3;
    drop(*x.b);
}

fn borrow_after_assign_after_move() {
    let mut x = A { a: 1, b: box 2 };
    drop(x.b);
    x = A { a: 3, b: box 4 };
    borrow(&x.b);
}

fn borrow_after_field_assign_after_move() {
    let mut x = A { a: 1, b: box 2 };
    drop(x.b);
    x.b = box 3;
    borrow(&x.b);
}

fn move_after_assign_after_move() {
    let mut x = A { a: 1, b: box 2 };
    let _y = x.b;
    x = A { a: 3, b: box 4 };
    drop(x.b);
}

fn move_after_field_assign_after_move() {
    let mut x = A { a: 1, b: box 2 };
    drop(x.b);
    x.b = box 3;
    drop(x.b);
}

fn copy_after_assign_after_uninit() {
    let mut x: A;
    x = A { a: 1, b: box 2 };
    drop(x.a);
}

fn borrow_after_assign_after_uninit() {
    let mut x: A;
    x = A { a: 1, b: box 2 };
    borrow(&x.a);
}

fn move_after_assign_after_uninit() {
    let mut x: A;
    x = A { a: 1, b: box 2 };
    drop(x.b);
}

fn main() {
    move_after_copy();
    move_after_fu_copy();
    fu_move_after_copy();
    fu_move_after_fu_copy();
    copy_after_move();
    copy_after_fu_move();
    fu_copy_after_move();
    fu_copy_after_fu_move();

    borrow_after_move();
    borrow_after_fu_move();
    move_after_borrow();
    fu_move_after_borrow();
    mut_borrow_after_mut_borrow();

    move_after_move();
    move_after_fu_move();
    fu_move_after_move();
    fu_move_after_fu_move();

    copy_after_assign_after_move();
    copy_after_field_assign_after_move();
    borrow_after_assign_after_move();
    borrow_after_field_assign_after_move();
    move_after_assign_after_move();
    move_after_field_assign_after_move();

    copy_after_assign_after_uninit();
    borrow_after_assign_after_uninit();
    move_after_assign_after_uninit();
}

<commit_msg>Add more borrowck tests for functional update moves<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

struct A { a: int, b: Box<int> }
struct B { a: Box<int>, b: Box<int> }

fn borrow<T>(_: &T) { }

fn move_after_copy() {
    let x = A { a: 1, b: box 2 };
    drop(x.a);
    drop(x.b);
}

fn move_after_fu_copy() {
    let x = A { a: 1, b: box 2 };
    let _y = A { b: box 3, .. x };
    drop(x.b);
}

fn fu_move_after_copy() {
    let x = A { a: 1, b: box 2 };
    drop(x.a);
    let _y = A { a: 3, .. x };
}

fn fu_move_after_fu_copy() {
    let x = A { a: 1, b: box 2 };
    let _y = A { b: box 3, .. x };
    let _z = A { a: 4, .. x };
}

fn copy_after_move() {
    let x = A { a: 1, b: box 2 };
    drop(x.b);
    drop(x.a);
}

fn copy_after_fu_move() {
    let x = A { a: 1, b: box 2 };
    let y = A { a: 3, .. x };
    drop(x.a);
}

fn fu_copy_after_move() {
    let x = A { a: 1, b: box 2 };
    drop(x.b);
    let _y = A { b: box 3, .. x };
}

fn fu_copy_after_fu_move() {
    let x = A { a: 1, b: box 2 };
    let _y = A { a: 3, .. x };
    let _z = A { b: box 3, .. x };
}

fn borrow_after_move() {
    let x = A { a: 1, b: box 2 };
    drop(x.b);
    borrow(&x.a);
}

fn borrow_after_fu_move() {
    let x = A { a: 1, b: box 2 };
    let _y = A { a: 3, .. x };
    borrow(&x.a);
}

fn move_after_borrow() {
    let x = A { a: 1, b: box 2 };
    borrow(&x.a);
    drop(x.b);
}

fn fu_move_after_borrow() {
    let x = A { a: 1, b: box 2 };
    borrow(&x.a);
    let _y = A { a: 3, .. x };
}

fn mut_borrow_after_mut_borrow() {
    let mut x = A { a: 1, b: box 2 };
    let y = &mut x.a;
    let z = &mut x.b;
    drop(*y);
    drop(**z);
}

fn move_after_move() {
    let x = B { a: box 1, b: box 2 };
    drop(x.a);
    drop(x.b);
}

fn move_after_fu_move() {
    let x = B { a: box 1, b: box 2 };
    let y = B { a: box 3, .. x };
    drop(x.a);
}

fn fu_move_after_move() {
    let x = B { a: box 1, b: box 2 };
    drop(x.a);
    let z = B { a: box 3, .. x };
    drop(z.b);
}

fn fu_move_after_fu_move() {
    let x = B { a: box 1, b: box 2 };
    let _y = B { b: box 3, .. x };
    let _z = B { a: box 4, .. x };
}

fn copy_after_assign_after_move() {
    let mut x = A { a: 1, b: box 2 };
    drop(x.b);
    x = A { a: 3, b: box 4 };
    drop(*x.b);
}

fn copy_after_assign_after_fu_move() {
    let mut x = A { a: 1, b: box 2 };
    let _y = A { a: 3, .. x };
    x = A { a: 3, b: box 4 };
    drop(*x.b);
}

fn copy_after_field_assign_after_move() {
    let mut x = A { a: 1, b: box 2 };
    drop(x.b);
    x.b = box 3;
    drop(*x.b);
}

fn copy_after_field_assign_after_fu_move() {
    let mut x = A { a: 1, b: box 2 };
    let _y = A { a: 3, .. x };
    x.b = box 3;
    drop(*x.b);
}

fn borrow_after_assign_after_move() {
    let mut x = A { a: 1, b: box 2 };
    drop(x.b);
    x = A { a: 3, b: box 4 };
    borrow(&x.b);
}

fn borrow_after_assign_after_fu_move() {
    let mut x = A { a: 1, b: box 2 };
    let _y = A { a: 3, .. x };
    x = A { a: 3, b: box 4 };
    borrow(&x.b);
}

fn borrow_after_field_assign_after_move() {
    let mut x = A { a: 1, b: box 2 };
    drop(x.b);
    x.b = box 3;
    borrow(&x.b);
}

fn borrow_after_field_assign_after_fu_move() {
    let mut x = A { a: 1, b: box 2 };
    let _y = A { a: 3, .. x };
    x.b = box 3;
    borrow(&x.b);
}

fn move_after_assign_after_move() {
    let mut x = A { a: 1, b: box 2 };
    let _y = x.b;
    x = A { a: 3, b: box 4 };
    drop(x.b);
}

fn move_after_assign_after_fu_move() {
    let mut x = A { a: 1, b: box 2 };
    let _y = A { a: 3, .. x };
    x = A { a: 3, b: box 4 };
    drop(x.b);
}

fn move_after_field_assign_after_move() {
    let mut x = A { a: 1, b: box 2 };
    drop(x.b);
    x.b = box 3;
    drop(x.b);
}

fn move_after_field_assign_after_fu_move() {
    let mut x = A { a: 1, b: box 2 };
    let _y = A { a: 3, .. x };
    x.b = box 3;
    drop(x.b);
}

fn copy_after_assign_after_uninit() {
    let mut x: A;
    x = A { a: 1, b: box 2 };
    drop(x.a);
}

fn borrow_after_assign_after_uninit() {
    let mut x: A;
    x = A { a: 1, b: box 2 };
    borrow(&x.a);
}

fn move_after_assign_after_uninit() {
    let mut x: A;
    x = A { a: 1, b: box 2 };
    drop(x.b);
}

fn main() {
    move_after_copy();
    move_after_fu_copy();
    fu_move_after_copy();
    fu_move_after_fu_copy();
    copy_after_move();
    copy_after_fu_move();
    fu_copy_after_move();
    fu_copy_after_fu_move();

    borrow_after_move();
    borrow_after_fu_move();
    move_after_borrow();
    fu_move_after_borrow();
    mut_borrow_after_mut_borrow();

    move_after_move();
    move_after_fu_move();
    fu_move_after_move();
    fu_move_after_fu_move();

    copy_after_assign_after_move();
    copy_after_assign_after_fu_move();
    copy_after_field_assign_after_move();
    copy_after_field_assign_after_fu_move();

    borrow_after_assign_after_move();
    borrow_after_assign_after_fu_move();
    borrow_after_field_assign_after_move();
    borrow_after_field_assign_after_fu_move();

    move_after_assign_after_move();
    move_after_assign_after_fu_move();
    move_after_field_assign_after_move();
    move_after_field_assign_after_fu_move();

    copy_after_assign_after_uninit();
    borrow_after_assign_after_uninit();
    move_after_assign_after_uninit();
}

<|endoftext|>


<commit_before>use definitions::bytecode;
use definitions::typedef::*;
use error::*;
use ieee754::Ieee754;
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;

// We use CGA for the display resolution
const DISPLAY_WIDTH: usize = 320;
const DISPLAY_HEIGHT: usize = 200;

/// We can adjust the buffer register count here
pub const BUF_REG_COUNT: usize = 32;

/// A register for displaying color data on a virtual display
struct DisplayRegister {
    color_mode: ColorMode,
    data: [[SmallWord; DISPLAY_HEIGHT]; DISPLAY_WIDTH],
}

/// A register type for comparing two values
struct CompareRegister {
    cmp1: Word,
    cmp2: Word,
}

/// The mode for *interpreting* the color data in the framebuffer
enum ColorMode {
    _1Bit,
    _8Bit,
    _24Bit,
}

/// The whole state of the VM
pub struct VM {
    pc: Address,
    stack_ptr: Address,
    buf_regs: [Word; BUF_REG_COUNT],
    display_reg: DisplayRegister,
    cmp_reg: CompareRegister,
    stack: Vec<Word>,
}

impl VM {
    pub fn new() -> VM {
        VM {
            pc: 0,
            stack_ptr: 0,
            buf_regs: [0; BUF_REG_COUNT],
            display_reg: DisplayRegister {
                color_mode: ColorMode::_24Bit,
                data: [[0; DISPLAY_HEIGHT]; DISPLAY_WIDTH],
            },
            cmp_reg: CompareRegister { cmp1: 0, cmp2: 0 },
            stack: Vec::new(),
        }
    }

    pub fn exec<P: AsRef<Path>>(&mut self, path: P) -> VMResult<()> {
        let mut image_file = File::open(path).chain_err(|| "unable to open game image")?;
        let mut image_bytes: Vec<Byte> = Vec::new();
        image_file.read_to_end(&mut image_bytes).chain_err(|| "unable to read image")?;

        while self.pc < image_bytes.len() {
            let byte = self.current_byte(&image_bytes).chain_err(|| "unable to read current byte")?;

            match byte {
                bytecode::HALT => break,
                bytecode::ADD => self.add().chain_err(|| "unable to execute 'add' instruction")?,
                bytecode::SUB => self.sub().chain_err(|| "unable to execute 'sub' instruction")?,
                bytecode::MUL => self.mul().chain_err(|| "unable to execute 'mul' instruction")?,
                bytecode::DIV => self.div().chain_err(|| "unable to execute 'div' instruction")?,
                bytecode::PRINT => {
                    self.print().chain_err(|| "unable to execute 'print' instruction")?
                }
                bytecode::PUSH => {
                    let res = self.read_word(&image_bytes).chain_err(|| "unable to read word")?;

                    self.push_word(res).chain_err(|| "unable to push value to the stack")?;
                }
                bytecode::JMP => {
                    let addr = self.read_word(&image_bytes).chain_err(|| "unable to read word")?;

                    self.jmp(addr as Address).chain_err(|| "unable to jump")?;
                    continue;
                }
                bytecode::JZ => {
                    let addr = self.read_word(&image_bytes).chain_err(|| "unable to read word")?;

                    let top_of_stack = self.peek_number()
                        .chain_err(|| "unable to get current top of stack")?;

                    if top_of_stack == 0.0 {
                        self.jmp(addr as Address).chain_err(|| "unable to jump")?;
                        continue;
                    }
                }
                bytecode::JNZ => {
                    let addr = self.read_word(&image_bytes).chain_err(|| "unable to read word")?;

                    let top_of_stack = self.peek_number()
                        .chain_err(|| "unable to get current top of stack")?;

                    if top_of_stack != 0.0 {
                        self.jmp(addr as Address).chain_err(|| "unable to jump")?;
                        continue;
                    }
                }
                _ => bail!("unexpected opcode {:02x} at address {:?}", byte, self.pc),
            }

            self.advance_pc().chain_err(|| "unable to advance program counter")?;
        }

        Ok(())
    }

    fn push_word(&mut self, value: Word) -> VMResult<()> {
        if !self.stack.is_empty() {
            self.stack_ptr += 1;
        }

        self.stack.push(value);

        Ok(())
    }

    fn push_number(&mut self, value: Number) -> VMResult<()> {
        self.push_word(value.bits())
    }

    fn pop_word(&mut self) -> VMResult<Word> {
        if self.stack.is_empty() {
            bail!("unable to pop word off an empty Stack");
        }

        let res = self.stack.remove(self.stack_ptr);
        if !self.stack.is_empty() {
            self.stack_ptr -= 1;
        }

        Ok(res)
    }

    fn pop_number(&mut self) -> VMResult<Number> {
        let top = self.pop_word().chain_err(|| "unable to pop word off the stack")?;
        Ok(Number::from_bits(top))
    }

    fn add(&mut self) -> VMResult<()> {
        let b = self.pop_number().chain_err(|| "unable to pop word off the stack")?;
        let a = self.pop_number().chain_err(|| "unable to pop word off the stack")?;
        self.push_number(a + b).chain_err(|| "unable to push value to the stack")?;
        Ok(())
    }

    fn sub(&mut self) -> VMResult<()> {
        let b = self.pop_number().chain_err(|| "unable to pop word off the stack")?;
        let a = self.pop_number().chain_err(|| "unable to pop word off the stack")?;
        self.push_number(a - b).chain_err(|| "unable to push to stack")?;
        Ok(())
    }

    fn mul(&mut self) -> VMResult<()> {
        let b = self.pop_number().chain_err(|| "unable to pop word off the stack")?;
        let a = self.pop_number().chain_err(|| "unable to pop word off the stack")?;
        self.push_number(a * b).chain_err(|| "unable to push to stack")?;
        Ok(())
    }

    fn div(&mut self) -> VMResult<()> {
        let b = self.pop_number().chain_err(|| "unable to pop word off the stack")?;
        let a = self.pop_number().chain_err(|| "unable to pop word off the stack")?;
        self.push_number(a / b).chain_err(|| "unable to push to stack")?;
        Ok(())
    }

    fn jmp(&mut self, addr: Address) -> VMResult<()> {
        self.pc = addr;
        Ok(())
    }

    fn read_word(&mut self, bytes: &Vec<Byte>) -> VMResult<Word> {
        // Build a Word from single bytes
        let mut res: Word = 0;
        for _ in 0..8 {
            res <<= 8;
            self.advance_pc().chain_err(|| "unable to advance program counter")?;
            let current_byte = self.current_byte(&bytes)
                .chain_err(|| "unable to read current byte")?;
            res |= current_byte as Word;
        }

        Ok(res)
    }

    fn read_small_word(&mut self, bytes: &Vec<Byte>) -> VMResult<SmallWord> {
        // Build a Word from single bytes
        let mut res: SmallWord = 0;
        for _ in 0..4 {
            res <<= 8;
            self.advance_pc().chain_err(|| "unable to advance program counter")?;
            let current_byte = self.current_byte(&bytes)
                .chain_err(|| "unable to read current byte")?;
            res |= current_byte as SmallWord;
        }

        Ok(res)
    }

    fn read_tiny_word(&mut self, bytes: &Vec<Byte>) -> VMResult<TinyWord> {
        // Build a Word from single bytes
        let mut res: TinyWord = 0;
        for _ in 0..2 {
            res <<= 8;
            self.advance_pc().chain_err(|| "unable to advance program counter")?;
            let current_byte = self.current_byte(&bytes)
                .chain_err(|| "unable to read current byte")?;
            res |= current_byte as TinyWord;
        }

        Ok(res)
    }

    fn advance_pc(&mut self) -> VMResult<()> {
        self.pc += 1;
        Ok(())
    }

    fn current_byte(&mut self, bytes: &Vec<Byte>) -> VMResult<Byte> {
        if self.pc < bytes.len() {
            Ok(bytes[self.pc])
        } else {
            bail!("program counter out of bounds");
        }
    }

    fn peek_word(&mut self) -> VMResult<Word> {
        if self.stack_ptr < self.stack.len() {
            Ok(self.stack[self.stack_ptr])
        } else {
            bail!("stack pointer out of bounds");
        }
    }

    fn peek_number(&mut self) -> VMResult<Number> {
        let top = self.peek_word().chain_err(|| "unable to peek for word")?;
        Ok(Number::from_bits(top))
    }

    fn print(&mut self) -> VMResult<()> {
        let top = self.peek_number().chain_err(|| "unable to get current top of stack")?;
        println!("{:?}", top);
        Ok(())
    }
}
<commit_msg>Added more documentation<commit_after>use definitions::bytecode;
use definitions::typedef::*;
use error::*;
use ieee754::Ieee754;
use std::fs::File;
use std::io::prelude::*;
use std::path::Path;

// We use CGA for the display resolution
pub const DISPLAY_WIDTH: usize = 320;
pub const DISPLAY_HEIGHT: usize = 200;

/// We can adjust the buffer register count here
pub const BUF_REG_COUNT: usize = 32;

/// A register for displaying color data on a virtual display
struct DisplayRegister {
    color_mode: ColorMode,
    data: [[SmallWord; DISPLAY_HEIGHT]; DISPLAY_WIDTH],
}

/// A register type for comparing two values
struct CompareRegister {
    cmp1: Word,
    cmp2: Word,
}

/// The mode for *interpreting* the color data in the framebuffer
enum ColorMode {
    _1Bit,
    _8Bit,
    _24Bit,
}

/// The whole state of the VM
pub struct VM {
    /// The program counter
    pc: Address,
    /// The stack pointer
    stack_ptr: Address,
    /// The buffer registers
    buf_regs: [Word; BUF_REG_COUNT],
    display_reg: DisplayRegister,
    cmp_reg: CompareRegister,
    stack: Vec<Word>,
}

impl VM {
    pub fn new() -> VM {
        VM {
            pc: 0,
            stack_ptr: 0,
            buf_regs: [0; BUF_REG_COUNT],
            display_reg: DisplayRegister {
                color_mode: ColorMode::_24Bit,
                data: [[0; DISPLAY_HEIGHT]; DISPLAY_WIDTH],
            },
            cmp_reg: CompareRegister { cmp1: 0, cmp2: 0 },
            stack: Vec::new(),
        }
    }

    pub fn exec<P: AsRef<Path>>(&mut self, path: P) -> VMResult<()> {
        let mut image_file = File::open(path).chain_err(|| "unable to open game image")?;
        let mut image_bytes: Vec<Byte> = Vec::new();
        image_file.read_to_end(&mut image_bytes).chain_err(|| "unable to read image")?;

        while self.pc < image_bytes.len() {
            let byte = self.current_byte(&image_bytes).chain_err(|| "unable to read current byte")?;

            match byte {
                bytecode::HALT => break,
                bytecode::ADD => self.add().chain_err(|| "unable to execute 'add' instruction")?,
                bytecode::SUB => self.sub().chain_err(|| "unable to execute 'sub' instruction")?,
                bytecode::MUL => self.mul().chain_err(|| "unable to execute 'mul' instruction")?,
                bytecode::DIV => self.div().chain_err(|| "unable to execute 'div' instruction")?,
                bytecode::PRINT => {
                    self.print().chain_err(|| "unable to execute 'print' instruction")?
                }
                bytecode::PUSH => {
                    let res = self.read_word(&image_bytes).chain_err(|| "unable to read word")?;

                    self.push_word(res).chain_err(|| "unable to push value to the stack")?;
                }
                bytecode::JMP => {
                    let addr = self.read_word(&image_bytes).chain_err(|| "unable to read word")?;

                    self.jmp(addr as Address).chain_err(|| "unable to jump")?;
                    continue;
                }
                bytecode::JZ => {
                    let addr = self.read_word(&image_bytes).chain_err(|| "unable to read word")?;

                    let top_of_stack = self.peek_number()
                        .chain_err(|| "unable to get current top of stack")?;

                    if top_of_stack == 0.0 {
                        self.jmp(addr as Address).chain_err(|| "unable to jump")?;
                        continue;
                    }
                }
                bytecode::JNZ => {
                    let addr = self.read_word(&image_bytes).chain_err(|| "unable to read word")?;

                    let top_of_stack = self.peek_number()
                        .chain_err(|| "unable to get current top of stack")?;

                    if top_of_stack != 0.0 {
                        self.jmp(addr as Address).chain_err(|| "unable to jump")?;
                        continue;
                    }
                }
                _ => bail!("unexpected opcode {:02x} at address {:?}", byte, self.pc),
            }

            self.advance_pc().chain_err(|| "unable to advance program counter")?;
        }

        Ok(())
    }

    fn push_word(&mut self, value: Word) -> VMResult<()> {
        if !self.stack.is_empty() {
            self.stack_ptr += 1;
        }

        self.stack.push(value);

        Ok(())
    }

    fn push_number(&mut self, value: Number) -> VMResult<()> {
        self.push_word(value.bits())
    }

    fn pop_word(&mut self) -> VMResult<Word> {
        if self.stack.is_empty() {
            bail!("unable to pop word off an empty Stack");
        }

        let res = self.stack.remove(self.stack_ptr);
        if !self.stack.is_empty() {
            self.stack_ptr -= 1;
        }

        Ok(res)
    }

    fn pop_number(&mut self) -> VMResult<Number> {
        let top = self.pop_word().chain_err(|| "unable to pop word off the stack")?;
        Ok(Number::from_bits(top))
    }

    fn add(&mut self) -> VMResult<()> {
        let b = self.pop_number().chain_err(|| "unable to pop word off the stack")?;
        let a = self.pop_number().chain_err(|| "unable to pop word off the stack")?;
        self.push_number(a + b).chain_err(|| "unable to push value to the stack")?;
        Ok(())
    }

    fn sub(&mut self) -> VMResult<()> {
        let b = self.pop_number().chain_err(|| "unable to pop word off the stack")?;
        let a = self.pop_number().chain_err(|| "unable to pop word off the stack")?;
        self.push_number(a - b).chain_err(|| "unable to push to stack")?;
        Ok(())
    }

    fn mul(&mut self) -> VMResult<()> {
        let b = self.pop_number().chain_err(|| "unable to pop word off the stack")?;
        let a = self.pop_number().chain_err(|| "unable to pop word off the stack")?;
        self.push_number(a * b).chain_err(|| "unable to push to stack")?;
        Ok(())
    }

    fn div(&mut self) -> VMResult<()> {
        let b = self.pop_number().chain_err(|| "unable to pop word off the stack")?;
        let a = self.pop_number().chain_err(|| "unable to pop word off the stack")?;
        self.push_number(a / b).chain_err(|| "unable to push to stack")?;
        Ok(())
    }

    fn jmp(&mut self, addr: Address) -> VMResult<()> {
        self.pc = addr;
        Ok(())
    }

    fn read_word(&mut self, bytes: &Vec<Byte>) -> VMResult<Word> {
        // Build a Word from single bytes
        let mut res: Word = 0;
        for _ in 0..8 {
            res <<= 8;
            self.advance_pc().chain_err(|| "unable to advance program counter")?;
            let current_byte = self.current_byte(&bytes)
                .chain_err(|| "unable to read current byte")?;
            res |= current_byte as Word;
        }

        Ok(res)
    }

    fn read_small_word(&mut self, bytes: &Vec<Byte>) -> VMResult<SmallWord> {
        // Build a Word from single bytes
        let mut res: SmallWord = 0;
        for _ in 0..4 {
            res <<= 8;
            self.advance_pc().chain_err(|| "unable to advance program counter")?;
            let current_byte = self.current_byte(&bytes)
                .chain_err(|| "unable to read current byte")?;
            res |= current_byte as SmallWord;
        }

        Ok(res)
    }

    fn read_tiny_word(&mut self, bytes: &Vec<Byte>) -> VMResult<TinyWord> {
        // Build a Word from single bytes
        let mut res: TinyWord = 0;
        for _ in 0..2 {
            res <<= 8;
            self.advance_pc().chain_err(|| "unable to advance program counter")?;
            let current_byte = self.current_byte(&bytes)
                .chain_err(|| "unable to read current byte")?;
            res |= current_byte as TinyWord;
        }

        Ok(res)
    }

    fn advance_pc(&mut self) -> VMResult<()> {
        self.pc += 1;
        Ok(())
    }

    fn current_byte(&mut self, bytes: &Vec<Byte>) -> VMResult<Byte> {
        if self.pc < bytes.len() {
            Ok(bytes[self.pc])
        } else {
            bail!("program counter out of bounds");
        }
    }

    fn peek_word(&mut self) -> VMResult<Word> {
        if self.stack_ptr < self.stack.len() {
            Ok(self.stack[self.stack_ptr])
        } else {
            bail!("stack pointer out of bounds");
        }
    }

    fn peek_number(&mut self) -> VMResult<Number> {
        let top = self.peek_word().chain_err(|| "unable to peek for word")?;
        Ok(Number::from_bits(top))
    }

    fn print(&mut self) -> VMResult<()> {
        let top = self.peek_number().chain_err(|| "unable to get current top of stack")?;
        println!("{:?}", top);
        Ok(())
    }
}
<|endoftext|>