<commit_before>//! Audio IO from WAV files.

use byteorder::{self, ReadBytesExt, WriteBytesExt, LittleEndian};
use std::fs::File;
use std::io::{self, Read, Seek, SeekFrom, Write};

use error::{Error, Result};
use types::{SAMPLE_RATE, AudioDevice, Time, Sample};

/// Reads audio from a wav file.
///
/// The reader will continue until it runs out of samples. When it does, the
/// reader will return silence until it is reset to the beginning of the file.
pub struct WavReader<R: Read> {
    num_channels: usize,
    num_samples: Time,
    samples_read: Time,
    reader: R
}

impl WavReader<File> {
    /// Returns a `WavReader` reading the provided file.
    pub fn open(filename: &str) -> Result<Self> {
        let file = try!(File::open(filename));
        WavReader::new(file)
    }
}

impl<R: Read> WavReader<R> {
    /// Retuns a `WavReader` reading anything implementing `Read`.
    pub fn new(mut reader: R) -> Result<Self> {
        let header = try!(WavHeader::read_from_file(&mut reader));
        Ok(WavReader {
            num_channels: header.num_channels as usize,
            num_samples: (header.data_size / ((header.bit_depth/8) as u32) /
                (header.num_channels as u32)) as Time,
            samples_read: 0,
            reader: reader
        })
    }

    /// Returns the number of audio samples in the wav file.
    pub fn get_num_samples(&self) -> Time {
        self.num_samples
    }

    /// Returns true if we have read the entire wav file.
    pub fn is_done(&self) -> bool {
        self.samples_read >= self.num_samples
    }
}

impl<R: Read+Seek> WavReader<R> {
    /// Resets the reader to begin reading from the start of the file.
    pub fn restart(&mut self) -> io::Result<u64> {
        self.samples_read = 0;
        self.reader.seek(SeekFrom::Start(44))
    }
}

impl<R: Read> AudioDevice for WavReader<R> {
    fn num_inputs(&self) -> usize {
        0
    }

    fn num_outputs(&self) -> usize {
        self.num_channels
    }

    fn tick(&mut self, _: Time, _: &[Sample], outputs: &mut[Sample]) {
        for i in 0..self.num_channels {
            let s = if self.samples_read < self.num_samples {
                let n = self.reader.read_i16::<LittleEndian>()
                    .expect("Failed to read next sample from wav.");
                (n as Sample) / 32768.0
            } else {
                0.0
            };
            outputs[i] = s;
        }
        self.samples_read += 1;
    }
}

/// Writes audio to a wav file.
///
/// The writer initializes the data_size to be 0. This will not be overwritten
/// with the proper size until `update_data_size` is called.
///
/// While `WavReader` only requires its type be `Seek` to use the `restart`
/// method, the `WavWriter` reqiures `Seek` for all types, because the final
/// data size must be written to the header when the writer leaves scope.
pub struct WavWriter<W: Write+Seek> {
    num_channels: usize,
    samples_written: usize,
    writer: W,
}

impl WavWriter<File> {
    /// Returns a `WavWriter` writing to the provided file.
    pub fn create(filename: &str, num_channels: usize)
            -> Result<Self> {
        let file = try!(File::create(filename));
        WavWriter::new(file, num_channels)
    }
}

impl<W: Write+Seek> WavWriter<W> {
    /// Returns a `WavWriter` writing to anything implementing `Write`.
    pub fn new(mut writer: W, num_channels: usize) -> Result<Self> {
        let header = WavHeader::new(num_channels as u16, SAMPLE_RATE as u32,
                                    0u32);
        try!(header.write_to_file(&mut writer));
        Ok(WavWriter {
            num_channels: num_channels,
            samples_written: 0,
            writer: writer,
        })
    }
}

impl<W: Write+Seek> Drop for WavWriter<W> {
    fn drop(&mut self) {
        // Updates the wav header to have the correct amount of data written
        let data_size = self.samples_written * self.num_channels * 16/8;
        let file_size = 36+data_size;
        self.writer.seek(SeekFrom::Start(4))
            .expect("Failed to seek wav file size.");
        self.writer.write_u32::<LittleEndian>(file_size as u32)
            .expect("Failed to write wav file size.");
        self.writer.seek(SeekFrom::Start(40))
            .expect("Failed to seek wav data size.");
        self.writer.write_u32::<LittleEndian>(data_size as u32)
            .expect("Failed to write wav data size.");
    }
}

impl<W: Write+Seek> AudioDevice for WavWriter<W> {
    fn num_inputs(&self) -> usize {
        self.num_channels
    }

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

    fn tick(&mut self, _: Time, inputs: &[Sample], _: &mut[Sample]) {
        for s in inputs.iter() {
            let mut clipped = *s;
            if clipped > 0.999f32 { clipped = 0.999f32; }
            if clipped < -0.999f32 { clipped = -0.999f32; }
            self.writer.write_i16::<LittleEndian>((clipped*32768.0) as i16)
                .expect("Failed to write next sample to wav file.");
        }
        self.samples_written += 1;
    }
}

/// Constants for the strings used in a wav header
static RIFF: u32 = 0x46464952;
static WAVE: u32 = 0x45564157;
static FMT_: u32 = 0x20746d66;
static DATA: u32 = 0x61746164;

/// A struct container for the wav header
#[derive(Clone, Debug)]
struct WavHeader {
    riff_hdr: u32,
    file_size: u32,
    wave_lbl: u32,
    fmt_hdr: u32,
    section_size: u32,
    format: u16,
    num_channels: u16,
    sample_rate: u32,
    byte_rate: u32,
    block_align: u16,
    bit_depth: u16,
    data_hdr: u32,
    data_size: u32,
}

impl WavHeader {
    /// Returns a new wav header with all values initalized for our supported
    /// audio formats
    fn new(num_channels: u16, sample_rate: u32, data_size: u32) -> Self {
        WavHeader {
            riff_hdr: RIFF,
            file_size: data_size+36,
            wave_lbl: WAVE,
            fmt_hdr: FMT_,
            section_size: 16,
            format: 1,
            num_channels: num_channels,
            sample_rate: sample_rate,
            byte_rate: sample_rate*(num_channels as u32)*16/8,
            block_align: num_channels*16/8,
            bit_depth: 16,
            data_hdr: DATA,
            data_size: data_size,
        }
    }

    /// Attempts to read a wav header from the provided file
    fn read_from_file<R: Read>(f: &mut R) -> Result<Self> {
        let riff_hdr = try!(f.read_u32::<LittleEndian>());
        let file_size = try!(f.read_u32::<LittleEndian>());
        let wave_lbl = try!(f.read_u32::<LittleEndian>());
        let fmt_hdr = try!(f.read_u32::<LittleEndian>());
        let section_size = try!(f.read_u32::<LittleEndian>());
        let format = try!(f.read_u16::<LittleEndian>());
        let num_channels = try!(f.read_u16::<LittleEndian>());
        let sample_rate = try!(f.read_u32::<LittleEndian>());
        let byte_rate = try!(f.read_u32::<LittleEndian>());
        let block_align = try!(f.read_u16::<LittleEndian>());
        let bit_depth = try!(f.read_u16::<LittleEndian>());
        let data_hdr = try!(f.read_u32::<LittleEndian>());
        let data_size = try!(f.read_u32::<LittleEndian>());
        let header = WavHeader {
            riff_hdr: riff_hdr,
            file_size: file_size,
            wave_lbl: wave_lbl,
            fmt_hdr: fmt_hdr,
            section_size: section_size,
            format: format,
            num_channels: num_channels,
            sample_rate: sample_rate,
            byte_rate: byte_rate,
            block_align: block_align,
            bit_depth: bit_depth,
            data_hdr: data_hdr,
            data_size: data_size
        };
        header.check()
    }

    /// Returns the header if the wav header has valid fields and uses the
    /// supported formats, otherwise return a descriptive error
    fn check(self) -> Result<Self> {
        // Check the headers are correct
        if self.riff_hdr != RIFF { return Err(Error::InvalidFile); }
        if self.wave_lbl != WAVE { return Err(Error::InvalidFile); }
        if self.fmt_hdr  != FMT_ { return Err(Error::InvalidFile); }
        if self.data_hdr != DATA { return Err(Error::InvalidFile); }

        // Check sizes are correct
        if self.file_size != self.data_size + 36 {
            return Err(Error::InvalidFile);
        }
        if self.section_size != 16 {
            return Err(Error::InvalidFile);
        }
        if self.byte_rate != self.sample_rate*(self.num_channels as u32)*
            (self.bit_depth as u32)/8 {
            return Err(Error::InvalidFile);
        }
        if self.block_align != self.num_channels*self.bit_depth/8 {
            return Err(Error::InvalidFile);
        }

        // Check for formats we can read
        if self.format != 1 {
            return Err(Error::Unsupported("Only PCM is supported"));
        }
        if self.sample_rate != (SAMPLE_RATE as u32) {
            return Err(Error::Unsupported(
                    "Sample rate conversion not supported"));
        }
        if self.bit_depth != 16 {
            return Err(Error::Unsupported("Only 16-bit supported"));
        }

        // If this header is valid, then return it instead
        Ok(self)
    }

    /// Attempts to write this wav header to the provided file
    fn write_to_file<W: Write>(&self, w: &mut W) -> byteorder::Result<()> {
        w.write_u32::<LittleEndian>(self.riff_hdr)
            .and_then(|()| w.write_u32::<LittleEndian>(self.file_size))
            .and_then(|()| w.write_u32::<LittleEndian>(self.wave_lbl))
            .and_then(|()| w.write_u32::<LittleEndian>(self.fmt_hdr))
            .and_then(|()| w.write_u32::<LittleEndian>(self.section_size))
            .and_then(|()| w.write_u16::<LittleEndian>(self.format))
            .and_then(|()| w.write_u16::<LittleEndian>(self.num_channels))
            .and_then(|()| w.write_u32::<LittleEndian>(self.sample_rate))
            .and_then(|()| w.write_u32::<LittleEndian>(self.byte_rate))
            .and_then(|()| w.write_u16::<LittleEndian>(self.block_align))
            .and_then(|()| w.write_u16::<LittleEndian>(self.bit_depth))
            .and_then(|()| w.write_u32::<LittleEndian>(self.data_hdr))
            .and_then(|()| w.write_u32::<LittleEndian>(self.data_size))
    }
}
<commit_msg>Open wav files using AsRef<Path> args<commit_after>//! Audio IO from WAV files.

use byteorder::{self, ReadBytesExt, WriteBytesExt, LittleEndian};
use std::fs::File;
use std::io::{self, Read, Seek, SeekFrom, Write};
use std::path::Path;

use error::{Error, Result};
use types::{SAMPLE_RATE, AudioDevice, Time, Sample};

/// Reads audio from a wav file.
///
/// The reader will continue until it runs out of samples. When it does, the
/// reader will return silence until it is reset to the beginning of the file.
pub struct WavReader<R: Read> {
    num_channels: usize,
    num_samples: Time,
    samples_read: Time,
    reader: R
}

impl WavReader<File> {
    /// Returns a `WavReader` reading the provided file.
    pub fn open<P: AsRef<Path>>(filename: P) -> Result<Self> {
        let file = try!(File::open(filename));
        WavReader::new(file)
    }
}

impl<R: Read> WavReader<R> {
    /// Retuns a `WavReader` reading anything implementing `Read`.
    pub fn new(mut reader: R) -> Result<Self> {
        let header = try!(WavHeader::read_from_file(&mut reader));
        Ok(WavReader {
            num_channels: header.num_channels as usize,
            num_samples: (header.data_size / ((header.bit_depth/8) as u32) /
                (header.num_channels as u32)) as Time,
            samples_read: 0,
            reader: reader
        })
    }

    /// Returns the number of audio samples in the wav file.
    pub fn get_num_samples(&self) -> Time {
        self.num_samples
    }

    /// Returns true if we have read the entire wav file.
    pub fn is_done(&self) -> bool {
        self.samples_read >= self.num_samples
    }
}

impl<R: Read+Seek> WavReader<R> {
    /// Resets the reader to begin reading from the start of the file.
    pub fn restart(&mut self) -> io::Result<u64> {
        self.samples_read = 0;
        self.reader.seek(SeekFrom::Start(44))
    }
}

impl<R: Read> AudioDevice for WavReader<R> {
    fn num_inputs(&self) -> usize {
        0
    }

    fn num_outputs(&self) -> usize {
        self.num_channels
    }

    fn tick(&mut self, _: Time, _: &[Sample], outputs: &mut[Sample]) {
        for i in 0..self.num_channels {
            let s = if self.samples_read < self.num_samples {
                let n = self.reader.read_i16::<LittleEndian>()
                    .expect("Failed to read next sample from wav.");
                (n as Sample) / 32768.0
            } else {
                0.0
            };
            outputs[i] = s;
        }
        self.samples_read += 1;
    }
}

/// Writes audio to a wav file.
///
/// The writer initializes the data_size to be 0. This will not be overwritten
/// with the proper size until `update_data_size` is called.
///
/// While `WavReader` only requires its type be `Seek` to use the `restart`
/// method, the `WavWriter` reqiures `Seek` for all types, because the final
/// data size must be written to the header when the writer leaves scope.
pub struct WavWriter<W: Write+Seek> {
    num_channels: usize,
    samples_written: usize,
    writer: W,
}

impl WavWriter<File> {
    /// Returns a `WavWriter` writing to the provided file.
    pub fn create<P: AsRef<Path>>(filename: P, num_channels: usize)
            -> Result<Self> {
        let file = try!(File::create(filename));
        WavWriter::new(file, num_channels)
    }
}

impl<W: Write+Seek> WavWriter<W> {
    /// Returns a `WavWriter` writing to anything implementing `Write`.
    pub fn new(mut writer: W, num_channels: usize) -> Result<Self> {
        let header = WavHeader::new(num_channels as u16, SAMPLE_RATE as u32,
                                    0u32);
        try!(header.write_to_file(&mut writer));
        Ok(WavWriter {
            num_channels: num_channels,
            samples_written: 0,
            writer: writer,
        })
    }
}

impl<W: Write+Seek> Drop for WavWriter<W> {
    fn drop(&mut self) {
        // Updates the wav header to have the correct amount of data written
        let data_size = self.samples_written * self.num_channels * 16/8;
        let file_size = 36+data_size;
        self.writer.seek(SeekFrom::Start(4))
            .expect("Failed to seek wav file size.");
        self.writer.write_u32::<LittleEndian>(file_size as u32)
            .expect("Failed to write wav file size.");
        self.writer.seek(SeekFrom::Start(40))
            .expect("Failed to seek wav data size.");
        self.writer.write_u32::<LittleEndian>(data_size as u32)
            .expect("Failed to write wav data size.");
    }
}

impl<W: Write+Seek> AudioDevice for WavWriter<W> {
    fn num_inputs(&self) -> usize {
        self.num_channels
    }

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

    fn tick(&mut self, _: Time, inputs: &[Sample], _: &mut[Sample]) {
        for s in inputs.iter() {
            let mut clipped = *s;
            if clipped > 0.999f32 { clipped = 0.999f32; }
            if clipped < -0.999f32 { clipped = -0.999f32; }
            self.writer.write_i16::<LittleEndian>((clipped*32768.0) as i16)
                .expect("Failed to write next sample to wav file.");
        }
        self.samples_written += 1;
    }
}

/// Constants for the strings used in a wav header
static RIFF: u32 = 0x46464952;
static WAVE: u32 = 0x45564157;
static FMT_: u32 = 0x20746d66;
static DATA: u32 = 0x61746164;

/// A struct container for the wav header
#[derive(Clone, Debug)]
struct WavHeader {
    riff_hdr: u32,
    file_size: u32,
    wave_lbl: u32,
    fmt_hdr: u32,
    section_size: u32,
    format: u16,
    num_channels: u16,
    sample_rate: u32,
    byte_rate: u32,
    block_align: u16,
    bit_depth: u16,
    data_hdr: u32,
    data_size: u32,
}

impl WavHeader {
    /// Returns a new wav header with all values initalized for our supported
    /// audio formats
    fn new(num_channels: u16, sample_rate: u32, data_size: u32) -> Self {
        WavHeader {
            riff_hdr: RIFF,
            file_size: data_size+36,
            wave_lbl: WAVE,
            fmt_hdr: FMT_,
            section_size: 16,
            format: 1,
            num_channels: num_channels,
            sample_rate: sample_rate,
            byte_rate: sample_rate*(num_channels as u32)*16/8,
            block_align: num_channels*16/8,
            bit_depth: 16,
            data_hdr: DATA,
            data_size: data_size,
        }
    }

    /// Attempts to read a wav header from the provided file
    fn read_from_file<R: Read>(f: &mut R) -> Result<Self> {
        let riff_hdr = try!(f.read_u32::<LittleEndian>());
        let file_size = try!(f.read_u32::<LittleEndian>());
        let wave_lbl = try!(f.read_u32::<LittleEndian>());
        let fmt_hdr = try!(f.read_u32::<LittleEndian>());
        let section_size = try!(f.read_u32::<LittleEndian>());
        let format = try!(f.read_u16::<LittleEndian>());
        let num_channels = try!(f.read_u16::<LittleEndian>());
        let sample_rate = try!(f.read_u32::<LittleEndian>());
        let byte_rate = try!(f.read_u32::<LittleEndian>());
        let block_align = try!(f.read_u16::<LittleEndian>());
        let bit_depth = try!(f.read_u16::<LittleEndian>());
        let data_hdr = try!(f.read_u32::<LittleEndian>());
        let data_size = try!(f.read_u32::<LittleEndian>());
        let header = WavHeader {
            riff_hdr: riff_hdr,
            file_size: file_size,
            wave_lbl: wave_lbl,
            fmt_hdr: fmt_hdr,
            section_size: section_size,
            format: format,
            num_channels: num_channels,
            sample_rate: sample_rate,
            byte_rate: byte_rate,
            block_align: block_align,
            bit_depth: bit_depth,
            data_hdr: data_hdr,
            data_size: data_size
        };
        header.check()
    }

    /// Returns the header if the wav header has valid fields and uses the
    /// supported formats, otherwise return a descriptive error
    fn check(self) -> Result<Self> {
        // Check the headers are correct
        if self.riff_hdr != RIFF { return Err(Error::InvalidFile); }
        if self.wave_lbl != WAVE { return Err(Error::InvalidFile); }
        if self.fmt_hdr  != FMT_ { return Err(Error::InvalidFile); }
        if self.data_hdr != DATA { return Err(Error::InvalidFile); }

        // Check sizes are correct
        if self.file_size != self.data_size + 36 {
            return Err(Error::InvalidFile);
        }
        if self.section_size != 16 {
            return Err(Error::InvalidFile);
        }
        if self.byte_rate != self.sample_rate*(self.num_channels as u32)*
            (self.bit_depth as u32)/8 {
            return Err(Error::InvalidFile);
        }
        if self.block_align != self.num_channels*self.bit_depth/8 {
            return Err(Error::InvalidFile);
        }

        // Check for formats we can read
        if self.format != 1 {
            return Err(Error::Unsupported("Only PCM is supported"));
        }
        if self.sample_rate != (SAMPLE_RATE as u32) {
            return Err(Error::Unsupported(
                    "Sample rate conversion not supported"));
        }
        if self.bit_depth != 16 {
            return Err(Error::Unsupported("Only 16-bit supported"));
        }

        // If this header is valid, then return it instead
        Ok(self)
    }

    /// Attempts to write this wav header to the provided file
    fn write_to_file<W: Write>(&self, w: &mut W) -> byteorder::Result<()> {
        w.write_u32::<LittleEndian>(self.riff_hdr)
            .and_then(|()| w.write_u32::<LittleEndian>(self.file_size))
            .and_then(|()| w.write_u32::<LittleEndian>(self.wave_lbl))
            .and_then(|()| w.write_u32::<LittleEndian>(self.fmt_hdr))
            .and_then(|()| w.write_u32::<LittleEndian>(self.section_size))
            .and_then(|()| w.write_u16::<LittleEndian>(self.format))
            .and_then(|()| w.write_u16::<LittleEndian>(self.num_channels))
            .and_then(|()| w.write_u32::<LittleEndian>(self.sample_rate))
            .and_then(|()| w.write_u32::<LittleEndian>(self.byte_rate))
            .and_then(|()| w.write_u16::<LittleEndian>(self.block_align))
            .and_then(|()| w.write_u16::<LittleEndian>(self.bit_depth))
            .and_then(|()| w.write_u32::<LittleEndian>(self.data_hdr))
            .and_then(|()| w.write_u32::<LittleEndian>(self.data_size))
    }
}
<|endoftext|>


<commit_before>use chrono::{DateTime, UTC, Timelike};
use byteorder::{WriteBytesExt, BigEndian};

#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub struct TermRef(u32);

impl TermRef {
    pub fn new(ord: u32) -> TermRef {
        TermRef(ord)
    }

    pub fn ord(&self) -> u32 {
        self.0
    }
}

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
pub struct Term(Vec<u8>);

impl Term {
    pub fn from_bytes(bytes: &[u8]) -> Term {
        Term(bytes.to_vec())
    }

    pub fn from_string(string: &str) -> Term {
        let mut bytes = Vec::with_capacity(string.len());

        for byte in string.as_bytes() {
            bytes.push(*byte);
        }

        Term(bytes)
    }

    pub fn from_boolean(value: bool) -> Term {
        if value {
            Term(vec![b't'])
        } else {
            Term(vec![b'f'])
        }
    }

    pub fn from_integer(value: i64) -> Term {
        let mut bytes = Vec::with_capacity(8);
        bytes.write_i64::<BigEndian>(value).unwrap();
        Term(bytes)
    }

    pub fn from_datetime(value: &DateTime<UTC>) -> Term {
        let mut bytes = Vec::with_capacity(0);
        let timestamp = value.timestamp();
        let micros = value.nanosecond() / 1000;
        let timestamp_with_micros = timestamp * 1000000 + micros as i64;
        bytes.write_i64::<BigEndian>(timestamp_with_micros).unwrap();
        Term(bytes)
    }

    pub fn as_bytes(&self) -> &[u8] {
        &self.0
    }
}

#[cfg(test)]
mod tests {
    use chrono::{DateTime, UTC, Timelike};
    use super::Term;

    #[test]
    fn test_string_to_bytes() {
        let term = Term::from_string("foo");

        assert_eq!(term.as_bytes().to_vec(), vec![102, 111, 111])
    }

    #[test]
    fn test_hiragana_string_to_bytes() {
        let term = Term::from_string("こんにちは");

        assert_eq!(term.as_bytes().to_vec(), vec![227, 129, 147, 227, 130, 147, 227, 129, 171, 227, 129, 161, 227, 129, 175])
    }

    #[test]
    fn test_blank_string_to_bytes() {
        let term = Term::from_string("");

        assert_eq!(term.as_bytes().to_vec(), vec![])
    }

    #[test]
    fn test_boolean_true_to_bytes() {
        let term = Term::from_boolean(true);

        // 116 = 't' in ASCII
        assert_eq!(term.as_bytes().to_vec(), vec![116])
    }

    #[test]
    fn test_boolean_false_to_bytes() {
        let term = Term::from_boolean(false);

        // 102 = 'f' in ASCII
        assert_eq!(term.as_bytes().to_vec(), vec![102])
    }

    #[test]
    fn test_integer_to_bytes() {
        let term = Term::from_integer(123);

        assert_eq!(term.as_bytes().to_vec(), vec![0, 0, 0, 0, 0, 0, 0, 123])
    }

    #[test]
    fn test_negative_integer_to_bytes() {
        let term = Term::from_integer(-123);

        assert_eq!(term.as_bytes().to_vec(), vec![255, 255, 255, 255, 255, 255, 255, 133])
    }

    #[test]
    fn test_datetime_to_bytes() {
        let date = "2016-07-23T16:15:00+01:00".parse::<DateTime<UTC>>().unwrap();
        let term = Term::from_datetime(&date);

        assert_eq!(term.as_bytes().to_vec(), vec![0, 5, 56, 79, 3, 191, 101, 0])
    }

    #[test]
    fn test_datetime_with_microseconds_to_bytes() {
        let mut date = "2016-07-23T16:15:00+01:00".parse::<DateTime<UTC>>().unwrap();
        date = date.with_nanosecond(123123123).unwrap();
        let term = Term::from_datetime(&date);

        // This is exactly 123123 higher than the result of "test_datetime_to_bytes"
        assert_eq!(term.as_bytes().to_vec(), vec![0, 5, 56, 79, 3, 193, 69, 243])
    }

    #[test]
    fn test_datetime_with_different_timezone_to_bytes() {
        let date = "2016-07-23T16:15:00+02:00".parse::<DateTime<UTC>>().unwrap();
        let term = Term::from_datetime(&date);

        // This is exactly 3_600_000_000 lower than the result of "test_datetime_to_bytes"
        assert_eq!(term.as_bytes().to_vec(), vec![0, 5, 56, 78, 45, 43, 193, 0])
    }
}
<commit_msg>Fix test<commit_after>use chrono::{DateTime, UTC, Timelike};
use byteorder::{WriteBytesExt, BigEndian};

#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub struct TermRef(u32);

impl TermRef {
    pub fn new(ord: u32) -> TermRef {
        TermRef(ord)
    }

    pub fn ord(&self) -> u32 {
        self.0
    }
}

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
pub struct Term(Vec<u8>);

impl Term {
    pub fn from_bytes(bytes: &[u8]) -> Term {
        Term(bytes.to_vec())
    }

    pub fn from_string(string: &str) -> Term {
        let mut bytes = Vec::with_capacity(string.len());

        for byte in string.as_bytes() {
            bytes.push(*byte);
        }

        Term(bytes)
    }

    pub fn from_boolean(value: bool) -> Term {
        if value {
            Term(vec![b't'])
        } else {
            Term(vec![b'f'])
        }
    }

    pub fn from_integer(value: i64) -> Term {
        let mut bytes = Vec::with_capacity(8);
        bytes.write_i64::<BigEndian>(value).unwrap();
        Term(bytes)
    }

    pub fn from_datetime(value: &DateTime<UTC>) -> Term {
        let mut bytes = Vec::with_capacity(0);
        let timestamp = value.timestamp();
        let micros = value.nanosecond() / 1000;
        let timestamp_with_micros = timestamp * 1000000 + micros as i64;
        bytes.write_i64::<BigEndian>(timestamp_with_micros).unwrap();
        Term(bytes)
    }

    pub fn as_bytes(&self) -> &[u8] {
        &self.0
    }
}

#[cfg(test)]
mod tests {
    use chrono::{DateTime, UTC, Timelike};
    use super::Term;

    #[test]
    fn test_string_to_bytes() {
        let term = Term::from_string("foo");

        assert_eq!(term.as_bytes().to_vec(), vec![102, 111, 111])
    }

    #[test]
    fn test_hiragana_string_to_bytes() {
        let term = Term::from_string("こんにちは");

        assert_eq!(term.as_bytes().to_vec(), vec![227, 129, 147, 227, 130, 147, 227, 129, 171, 227, 129, 161, 227, 129, 175])
    }

    #[test]
    fn test_blank_string_to_bytes() {
        let term = Term::from_string("");

        assert_eq!(term.as_bytes().to_vec(), vec![] as Vec<u8>)
    }

    #[test]
    fn test_boolean_true_to_bytes() {
        let term = Term::from_boolean(true);

        // 116 = 't' in ASCII
        assert_eq!(term.as_bytes().to_vec(), vec![116])
    }

    #[test]
    fn test_boolean_false_to_bytes() {
        let term = Term::from_boolean(false);

        // 102 = 'f' in ASCII
        assert_eq!(term.as_bytes().to_vec(), vec![102])
    }

    #[test]
    fn test_integer_to_bytes() {
        let term = Term::from_integer(123);

        assert_eq!(term.as_bytes().to_vec(), vec![0, 0, 0, 0, 0, 0, 0, 123])
    }

    #[test]
    fn test_negative_integer_to_bytes() {
        let term = Term::from_integer(-123);

        assert_eq!(term.as_bytes().to_vec(), vec![255, 255, 255, 255, 255, 255, 255, 133])
    }

    #[test]
    fn test_datetime_to_bytes() {
        let date = "2016-07-23T16:15:00+01:00".parse::<DateTime<UTC>>().unwrap();
        let term = Term::from_datetime(&date);

        assert_eq!(term.as_bytes().to_vec(), vec![0, 5, 56, 79, 3, 191, 101, 0])
    }

    #[test]
    fn test_datetime_with_microseconds_to_bytes() {
        let mut date = "2016-07-23T16:15:00+01:00".parse::<DateTime<UTC>>().unwrap();
        date = date.with_nanosecond(123123123).unwrap();
        let term = Term::from_datetime(&date);

        // This is exactly 123123 higher than the result of "test_datetime_to_bytes"
        assert_eq!(term.as_bytes().to_vec(), vec![0, 5, 56, 79, 3, 193, 69, 243])
    }

    #[test]
    fn test_datetime_with_different_timezone_to_bytes() {
        let date = "2016-07-23T16:15:00+02:00".parse::<DateTime<UTC>>().unwrap();
        let term = Term::from_datetime(&date);

        // This is exactly 3_600_000_000 lower than the result of "test_datetime_to_bytes"
        assert_eq!(term.as_bytes().to_vec(), vec![0, 5, 56, 78, 45, 43, 193, 0])
    }
}
<|endoftext|>


<commit_before>#![cfg_attr(
    target_arch = "spirv",
    no_std,
    feature(register_attr),
    register_attr(spirv)
)]

use rust_gpu_toy_shared::Config;
#[cfg(not(target_arch = "spirv"))]
use spirv_std::macros::spirv;
use spirv_std::num_traits::Float;

use spirv_std::{
    glam::{vec2, vec4, UVec3, Vec2, Vec4},
    image, Sampler,
};

#[spirv(compute(threads(16, 16)))]
pub fn main(
    #[spirv(uniform, descriptor_set = 0, binding = 0)] config: &Config,
    #[spirv(descriptor_set = 0, binding = 1)] output_buffer: &image::StorageImage2d,
    #[spirv(global_invocation_id)] global_ix: UVec3,
) {
    let frag_coord = global_ix.truncate().as_f32()
        / vec2(config.width as f32, config.height as f32)
        - vec2(0.5, 0.5);

    // Shadertoy like code goes here
    let frag_color = vec4(
        frag_coord.x + 0.5,
        frag_coord.y + 0.5,
        config.time.sin(),
        1.0,
    );

    unsafe { output_buffer.write(global_ix.truncate(), frag_color) }
}

// A simple vert/frag shader to copy an image to the swapchain.

#[spirv(fragment)]
pub fn fs_main(
    #[spirv(descriptor_set = 0, binding = 0)] image: &image::Image2d,
    #[spirv(descriptor_set = 0, binding = 1)] sampler: &Sampler,
    in_tex_coord: Vec2,
    output: &mut Vec4,
) {
    *output = image.sample(*sampler, in_tex_coord);
}

#[spirv(vertex)]
pub fn vs_main(
    #[spirv(vertex_index)] in_vertex_index: u32,
    #[spirv(instance_index)] in_instance_index: u32,
    #[spirv(position, invariant)] out_pos: &mut Vec4,
    out_tex_coord: &mut Vec2,
) {
    let x = ((in_vertex_index & 1) ^ in_instance_index) as f32;
    let y = ((in_vertex_index >> 1) ^ in_instance_index) as f32;
    *out_pos = vec4(x * 2. - 1., 1. - y * 2., 0., 1.);
    *out_tex_coord = vec2(x, y);
}
<commit_msg>Use storage_buffer to match<commit_after>#![cfg_attr(
    target_arch = "spirv",
    no_std,
    feature(register_attr),
    register_attr(spirv)
)]

use rust_gpu_toy_shared::Config;
#[cfg(not(target_arch = "spirv"))]
use spirv_std::macros::spirv;
use spirv_std::num_traits::Float;

use spirv_std::{
    glam::{vec2, vec4, UVec3, Vec2, Vec4},
    image, Sampler,
};

#[spirv(compute(threads(16, 16)))]
pub fn main(
    #[spirv(storage_buffer, descriptor_set = 0, binding = 0)] config: &Config,
    #[spirv(descriptor_set = 0, binding = 1)] output_buffer: &image::StorageImage2d,
    #[spirv(global_invocation_id)] global_ix: UVec3,
) {
    let frag_coord = global_ix.truncate().as_f32()
        / vec2(config.width as f32, config.height as f32)
        - vec2(0.5, 0.5);

    // Shadertoy like code goes here
    let frag_color = vec4(
        frag_coord.x + 0.5,
        frag_coord.y + 0.5,
        config.time.sin(),
        1.0,
    );

    unsafe { output_buffer.write(global_ix.truncate(), frag_color) }
}

// A simple vert/frag shader to copy an image to the swapchain.

#[spirv(fragment)]
pub fn fs_main(
    #[spirv(descriptor_set = 0, binding = 0)] image: &image::Image2d,
    #[spirv(descriptor_set = 0, binding = 1)] sampler: &Sampler,
    in_tex_coord: Vec2,
    output: &mut Vec4,
) {
    *output = image.sample(*sampler, in_tex_coord);
}

#[spirv(vertex)]
pub fn vs_main(
    #[spirv(vertex_index)] in_vertex_index: u32,
    #[spirv(instance_index)] in_instance_index: u32,
    #[spirv(position, invariant)] out_pos: &mut Vec4,
    out_tex_coord: &mut Vec2,
) {
    let x = ((in_vertex_index & 1) ^ in_instance_index) as f32;
    let y = ((in_vertex_index >> 1) ^ in_instance_index) as f32;
    *out_pos = vec4(x * 2. - 1., 1. - y * 2., 0., 1.);
    *out_tex_coord = vec2(x, y);
}
<|endoftext|>


<commit_before><commit_msg>more r+c<commit_after><|endoftext|>


<commit_before>/// Implement `serde::Serialize` for a trait object that has
/// `erased_serde::Serialize` as a supertrait.
///
/// ```
/// use erased_serde::serialize_trait_object;
///
/// trait Event: erased_serde::Serialize {
///     /* ... */
/// }
///
/// erased_serde::serialize_trait_object!(Event);
/// ```
///
/// The macro supports traits that have type parameters and/or `where` clauses.
///
/// ```
/// # use erased_serde::serialize_trait_object;
/// #
/// trait Difficult<T>: erased_serde::Serialize where T: Copy {
///     /* ... */
/// }
///
/// serialize_trait_object!(<T> Difficult<T> where T: Copy);
/// ```
#[macro_export]
macro_rules! serialize_trait_object {
    ($($path:tt)+) => {
        $crate::__internal_serialize_trait_object!(begin $($path)+);
    };
}

#[doc(hidden)]
#[macro_export]
macro_rules! __internal_serialize_trait_object {
    // Invocation started with `<`, parse generics.
    (begin < $($rest:tt)*) => {
        $crate::__internal_serialize_trait_object!(generics () () $($rest)*);
    };

    // Invocation did not start with `<`.
    (begin $first:tt $($rest:tt)*) => {
        $crate::__internal_serialize_trait_object!(path () ($first) $($rest)*);
    };

    // End of generics.
    (generics ($($generics:tt)*) () > $($rest:tt)*) => {
        $crate::__internal_serialize_trait_object!(path ($($generics)*) () $($rest)*);
    };

    // Generics open bracket.
    (generics ($($generics:tt)*) ($($brackets:tt)*) < $($rest:tt)*) => {
        $crate::__internal_serialize_trait_object!(generics ($($generics)* <) ($($brackets)* <) $($rest)*);
    };

    // Generics close bracket.
    (generics ($($generics:tt)*) (< $($brackets:tt)*) > $($rest:tt)*) => {
        $crate::__internal_serialize_trait_object!(generics ($($generics)* >) ($($brackets)*) $($rest)*);
    };

    // Token inside of generics.
    (generics ($($generics:tt)*) ($($brackets:tt)*) $first:tt $($rest:tt)*) => {
        $crate::__internal_serialize_trait_object!(generics ($($generics)* $first) ($($brackets)*) $($rest)*);
    };

    // End with `where` clause.
    (path ($($generics:tt)*) ($($path:tt)*) where $($rest:tt)*) => {
        $crate::__internal_serialize_trait_object!(sendsync ($($generics)*) ($($path)*) ($($rest)*));
    };

    // End without `where` clause.
    (path ($($generics:tt)*) ($($path:tt)*)) => {
        $crate::__internal_serialize_trait_object!(sendsync ($($generics)*) ($($path)*) ());
    };

    // Token inside of path.
    (path ($($generics:tt)*) ($($path:tt)*) $first:tt $($rest:tt)*) => {
        $crate::__internal_serialize_trait_object!(path ($($generics)*) ($($path)* $first) $($rest)*);
    };

    // Expand into four impls.
    (sendsync ($($generics:tt)*) ($($path:tt)*) ($($bound:tt)*)) => {
        $crate::__internal_serialize_trait_object!(impl ($($generics)*) ($($path)*) ($($bound)*));
        $crate::__internal_serialize_trait_object!(impl ($($generics)*) ($($path)* + $crate::private::Send) ($($bound)*));
        $crate::__internal_serialize_trait_object!(impl ($($generics)*) ($($path)* + $crate::private::Sync) ($($bound)*));
        $crate::__internal_serialize_trait_object!(impl ($($generics)*) ($($path)* + $crate::private::Send + $crate::private::Sync) ($($bound)*));
    };

    // The impl.
    (impl ($($generics:tt)*) ($($path:tt)*) ($($bound:tt)*)) => {
        impl<'erased, $($generics)*> $crate::private::serde::Serialize for dyn $($path)* + 'erased where $($bound)* {
            fn serialize<S>(&self, serializer: S) -> $crate::private::Result<S::Ok, S::Error> where S: $crate::private::serde::Serializer {
                $crate::serialize(self, serializer)
            }
        }
    };
}

// TEST ////////////////////////////////////////////////////////////////////////

#[cfg(test)]
mod tests {
    use crate::Serialize;

    fn assert_serialize<T: ?Sized + serde::Serialize>() {}

    #[test]
    fn test_plain() {
        trait Trait: Serialize {}

        serialize_trait_object!(Trait);
        assert_serialize::<dyn Trait>();
        assert_serialize::<dyn Trait + Send>();
    }

    #[test]
    fn test_type_parameter() {
        trait Trait<T>: Serialize {}

        serialize_trait_object!(<T> Trait<T>);
        assert_serialize::<dyn Trait<u32>>();
        assert_serialize::<dyn Trait<u32> + Send>();
    }

    #[test]
    fn test_generic_bound() {
        trait Trait<T: PartialEq<T>, U>: Serialize {}

        serialize_trait_object!(<T: PartialEq<T>, U> Trait<T, U>);
        assert_serialize::<dyn Trait<u32, ()>>();
        assert_serialize::<dyn Trait<u32, ()> + Send>();
    }

    #[test]
    fn test_where_clause() {
        trait Trait<T>: Serialize
        where
            T: Clone,
        {
        }

        serialize_trait_object!(<T> Trait<T> where T: Clone);
        assert_serialize::<dyn Trait<u32>>();
        assert_serialize::<dyn Trait<u32> + Send>();
    }
}
<commit_msg>Reformat where-clauses in serialize_trait_object implementation<commit_after>/// Implement `serde::Serialize` for a trait object that has
/// `erased_serde::Serialize` as a supertrait.
///
/// ```
/// use erased_serde::serialize_trait_object;
///
/// trait Event: erased_serde::Serialize {
///     /* ... */
/// }
///
/// erased_serde::serialize_trait_object!(Event);
/// ```
///
/// The macro supports traits that have type parameters and/or `where` clauses.
///
/// ```
/// # use erased_serde::serialize_trait_object;
/// #
/// trait Difficult<T>: erased_serde::Serialize where T: Copy {
///     /* ... */
/// }
///
/// serialize_trait_object!(<T> Difficult<T> where T: Copy);
/// ```
#[macro_export]
macro_rules! serialize_trait_object {
    ($($path:tt)+) => {
        $crate::__internal_serialize_trait_object!(begin $($path)+);
    };
}

#[doc(hidden)]
#[macro_export]
macro_rules! __internal_serialize_trait_object {
    // Invocation started with `<`, parse generics.
    (begin < $($rest:tt)*) => {
        $crate::__internal_serialize_trait_object!(generics () () $($rest)*);
    };

    // Invocation did not start with `<`.
    (begin $first:tt $($rest:tt)*) => {
        $crate::__internal_serialize_trait_object!(path () ($first) $($rest)*);
    };

    // End of generics.
    (generics ($($generics:tt)*) () > $($rest:tt)*) => {
        $crate::__internal_serialize_trait_object!(path ($($generics)*) () $($rest)*);
    };

    // Generics open bracket.
    (generics ($($generics:tt)*) ($($brackets:tt)*) < $($rest:tt)*) => {
        $crate::__internal_serialize_trait_object!(generics ($($generics)* <) ($($brackets)* <) $($rest)*);
    };

    // Generics close bracket.
    (generics ($($generics:tt)*) (< $($brackets:tt)*) > $($rest:tt)*) => {
        $crate::__internal_serialize_trait_object!(generics ($($generics)* >) ($($brackets)*) $($rest)*);
    };

    // Token inside of generics.
    (generics ($($generics:tt)*) ($($brackets:tt)*) $first:tt $($rest:tt)*) => {
        $crate::__internal_serialize_trait_object!(generics ($($generics)* $first) ($($brackets)*) $($rest)*);
    };

    // End with `where` clause.
    (path ($($generics:tt)*) ($($path:tt)*) where $($rest:tt)*) => {
        $crate::__internal_serialize_trait_object!(sendsync ($($generics)*) ($($path)*) ($($rest)*));
    };

    // End without `where` clause.
    (path ($($generics:tt)*) ($($path:tt)*)) => {
        $crate::__internal_serialize_trait_object!(sendsync ($($generics)*) ($($path)*) ());
    };

    // Token inside of path.
    (path ($($generics:tt)*) ($($path:tt)*) $first:tt $($rest:tt)*) => {
        $crate::__internal_serialize_trait_object!(path ($($generics)*) ($($path)* $first) $($rest)*);
    };

    // Expand into four impls.
    (sendsync ($($generics:tt)*) ($($path:tt)*) ($($bound:tt)*)) => {
        $crate::__internal_serialize_trait_object!(impl ($($generics)*) ($($path)*) ($($bound)*));
        $crate::__internal_serialize_trait_object!(impl ($($generics)*) ($($path)* + $crate::private::Send) ($($bound)*));
        $crate::__internal_serialize_trait_object!(impl ($($generics)*) ($($path)* + $crate::private::Sync) ($($bound)*));
        $crate::__internal_serialize_trait_object!(impl ($($generics)*) ($($path)* + $crate::private::Send + $crate::private::Sync) ($($bound)*));
    };

    // The impl.
    (impl ($($generics:tt)*) ($($path:tt)*) ($($bound:tt)*)) => {
        impl<'erased, $($generics)*> $crate::private::serde::Serialize for dyn $($path)* + 'erased
        where
            $($bound)*
        {
            fn serialize<S>(&self, serializer: S) -> $crate::private::Result<S::Ok, S::Error>
            where
                S: $crate::private::serde::Serializer,
            {
                $crate::serialize(self, serializer)
            }
        }
    };
}

// TEST ////////////////////////////////////////////////////////////////////////

#[cfg(test)]
mod tests {
    use crate::Serialize;

    fn assert_serialize<T: ?Sized + serde::Serialize>() {}

    #[test]
    fn test_plain() {
        trait Trait: Serialize {}

        serialize_trait_object!(Trait);
        assert_serialize::<dyn Trait>();
        assert_serialize::<dyn Trait + Send>();
    }

    #[test]
    fn test_type_parameter() {
        trait Trait<T>: Serialize {}

        serialize_trait_object!(<T> Trait<T>);
        assert_serialize::<dyn Trait<u32>>();
        assert_serialize::<dyn Trait<u32> + Send>();
    }

    #[test]
    fn test_generic_bound() {
        trait Trait<T: PartialEq<T>, U>: Serialize {}

        serialize_trait_object!(<T: PartialEq<T>, U> Trait<T, U>);
        assert_serialize::<dyn Trait<u32, ()>>();
        assert_serialize::<dyn Trait<u32, ()> + Send>();
    }

    #[test]
    fn test_where_clause() {
        trait Trait<T>: Serialize
        where
            T: Clone,
        {
        }

        serialize_trait_object!(<T> Trait<T> where T: Clone);
        assert_serialize::<dyn Trait<u32>>();
        assert_serialize::<dyn Trait<u32> + Send>();
    }
}
<|endoftext|>


<commit_before>// Vector/Point macros
macro_rules! n_pointvector {
    (ops $lhs:ident; $rhs:ident {$($field:ident),*}) => {
        impl<F: $crate::traitdefs::Float> ::std::ops::Add<$rhs<F>> for $lhs<F> {
            type Output = $lhs<F>;

            fn add(self, rhs: $rhs<F>) -> $lhs<F> {
                $lhs {
                    $($field: self.$field + rhs.$field),*
                }
            }
        }

        impl<F: $crate::traitdefs::Float> ::std::ops::Sub<$rhs<F>> for $lhs<F> {
            type Output = $lhs<F>;

            fn sub(self, rhs: $rhs<F>) -> $lhs<F> {
                $lhs {
                    $($field: self.$field - rhs.$field),*
                }
            }
        }
    };

    (float ops $name:ident {$($field:ident),+}) => {
        impl<F: $crate::traitdefs::Float> ::std::ops::Mul<F> for $name<F> {
            type Output = $name<F>;

            fn mul(self, rhs: F) -> $name<F> {
                $name {
                    $($field: self.$field * rhs),+
                }
            }
        }

        impl<F: $crate::traitdefs::Float> ::std::ops::Div<F> for $name<F> {
            type Output = $name<F>;

            fn div(self, rhs: F) -> $name<F> {
                $name {
                    $($field: self.$field / rhs),+
                }
            }
        }

        impl<F: $crate::traitdefs::Float> ::std::ops::Neg for $name<F> {
            type Output = $name<F>;

            fn neg(self) -> $name<F> {
                $name {
                    $($field: -self.$field),+
                }
            }
        }
    };

    (struct $doc:expr, $dims:expr; $name:ident {$($field:ident: $f_ty:ident),+} $sibling:ident) => {
        #[derive(Debug, Clone, Copy)]
        #[doc=$doc]
        pub struct $name<F: $crate::traitdefs::Float> {
            $(pub $field: F),+
        }

        impl<F: $crate::traitdefs::Float> $name<F> {
            pub fn new($($field: F),+) -> $name<F> {
                $name {
                    $($field: $field),+
                }
            }
        }

        impl<F: $crate::traitdefs::Float> ::std::convert::From<[F; $dims]> for $name<F> {
            fn from(array: [F; $dims]) -> $name<F> {
                let mut index = -1;
                $name{$($field: {
                    index += 1;
                    array[index as usize]
                }),+}
            }
        }

        impl<F: $crate::traitdefs::Float> ::std::convert::Into<[F; $dims]> for $name<F> {
            fn into(self) -> [F; $dims] {
                [$(self.$field),*]
            }
        }

        impl<F: $crate::traitdefs::Float> ::std::convert::Into<($($f_ty),*)> for $name<F> {
            fn into(self) -> ($($f_ty),*) {
                ($(self.$field),*)
            }
        }

        impl<F: $crate::traitdefs::Float> ::std::convert::From<$sibling<F>> for $name<F> {
            fn from(sib: $sibling<F>) -> $name<F> {
                $name {
                    $($field: sib.$field),*
                }
            }
        }

        impl<F: $crate::traitdefs::Float> ::std::convert::AsRef<[F]> for $name<F> {
            fn as_ref(&self) -> &[F] {
                use std::slice;
                unsafe {
                    slice::from_raw_parts(self as *const $name<F> as *const F, $dims)
                }
            }
        }

        impl<F: $crate::traitdefs::Float> ::std::convert::AsMut<[F]> for $name<F> {
            fn as_mut(&mut self) -> &mut [F] {
                use std::slice;
                unsafe {
                    slice::from_raw_parts_mut(self as *mut $name<F> as *mut F, $dims)
                }
            }
        }

        n_pointvector!(ops $name; $sibling {$($field),+});
        n_pointvector!(ops $name; $name {$($field),+});
        n_pointvector!(float ops $name {$($field),+});
    };

    ($p_doc:expr, $v_doc:expr, $dims:expr; $p_name:ident, $v_name:ident {$($field:ident),+}) => {
        n_pointvector!(struct $p_doc, $dims; $p_name {$($field: F),+} $v_name);
        n_pointvector!(struct $v_doc, $dims; $v_name {$($field: F),+} $p_name);

        impl<F: $crate::traitdefs::Float> $v_name<F> {
            pub fn len(self) -> F {
                ($(self.$field.powi(2) +)+ F::from_f32(0.0).unwrap()).sqrt()
            }

            pub fn normalize(self) -> $v_name<F> {
                self / self.len()
            }
        }
    }
}

macro_rules! check_t_bounds {
    ($t: expr) => {{
        let zero = F::from_f32(0.0).unwrap();
        let one  = F::from_f32(1.0).unwrap();
        if !(zero <= $t && $t <= one) {
            return None;
        }
    }}
}

// Polynomial Macros
macro_rules! n_bezier {
    ($doc:expr, $order:expr; $name:ident {
        $($field:ident: $weight:expr),+
    } {
        $start:ident, $next:ident;
        $($left:ident, $right:ident: $dweight:expr),+;
        $penu:ident, $end:ident;
    } elevated $elevated:ident<$($est:ty),+>) => {
        #[derive(Debug, Clone, Copy)]
        #[doc=$doc]
        pub struct $name<F> where F: $crate::traitdefs::Float {
            $(pub $field: F),+
        }

        impl<F> $name<F> where F: $crate::traitdefs::Float {
            pub fn new($($field: F),+) -> $name<F> {
                $name {
                    $($field: $field),+
                }
            }
        }

        impl<F> $crate::BezCurve<F> for $name<F>
                where F: $crate::traitdefs::Float {
            type Point = F;
            type Vector = F;
            type Elevated = $elevated<$($est),+>;

            fn from_slice(slice: &[F]) -> Option<$name<F>> {
                use $crate::OrderStatic;
                if slice.len() - 1 != $name::<F>::order_static() {
                    None
                } else {
                    let mut index = -1;
                    Some($name {$($field: {
                        index += 1;
                        slice[index as usize]
                    }),+})
                }
            }

            fn interp_unbounded(&self, t: F) -> F {
                let t1 = F::from_f32(1.0).unwrap() - t;
                const COUNT: i32 = $order;
                let mut factor = COUNT + 1;

                $(
                    factor -= 1;
                    let $field =
                        t1.powi(factor) *
                        t.powi(COUNT-factor) *
                        self.$field *
                        F::from_i32($weight).unwrap();
                )+
                $($field +)+ F::from_f32(0.0).unwrap()
            }

            fn slope_unbounded(&self, t: F) -> F {
                let t1 = F::from_f32(1.0).unwrap() - t;
                const COUNT: i32 = $order - 1;
                let mut factor = COUNT + 1;

                $(
                    factor -= 1;
                    let $right =
                        t1.powi(factor) *
                        t.powi(COUNT-factor) *
                        (self.$right - self.$left) *
                        F::from_i32($dweight * (COUNT + 1)).unwrap();
                )+
                $($right +)+ F::from_f32(0.0).unwrap()
            }

            fn elevate(&self) -> $elevated<$($est),+> {
                let mut factor = 0.0;
                let order = F::from_usize(self.order() + 1).unwrap();
                $elevated::from([self.$start,
                    $({
                        factor += 1.0;
                        let factor = F::from_f32(factor).unwrap();
                        (self.$left * factor +
                        self.$right * (order - factor)) / order
                    },)+
                    self.$end])
            }

            fn split(&self, _: F) -> Option<($name<F>, $name<F>)> {
                unimplemented!()
            }

            fn order(&self) -> usize {
                use $crate::OrderStatic;
                $name::<F>::order_static()
            }
        }

        impl<F> $crate::OrderStatic for $name<F>
                where F: $crate::traitdefs::Float {
            #[inline]
            fn order_static() -> usize {
                $order
            }
        }

        impl<F> ::std::convert::From<[F; $order + 1]> for $name<F>
                where F: $crate::traitdefs::Float {
            fn from(array: [F; $order + 1]) -> $name<F> {
                use $crate::BezCurve;
                $name::from_slice(&array[..]).unwrap()
            }
        }

        impl<F> ::std::convert::AsRef<[F]> for $name<F>
                where F: $crate::traitdefs::Float {
            fn as_ref(&self) -> &[F] {
                use std::slice;
                unsafe {
                    slice::from_raw_parts(self as *const $name<F> as *const F, $order + 1)
                }
            }
        }

        impl<F> ::std::convert::AsMut<[F]> for $name<F>
                where F: $crate::traitdefs::Float {
            fn as_mut(&mut self) -> &mut [F] {
                use std::slice;
                unsafe {
                    slice::from_raw_parts_mut(self as *mut $name<F> as *mut F, $order + 1)
                }
            }
        }
    }
}

macro_rules! bez_composite {
    ($doc:expr, $order:expr; $name:ident<$poly:ident> {
        $($field:ident: $($n_field:ident),+;)+
    } -> <$point:ident; $vector:ident> {
        $($dim:ident = $($dfield:ident),+;)+
    } elevated $elevated:ident<$($est:ty),+> {
        $($eindex:expr => $($edim:ident),+;)+
    } chained $chain:ident) =>
    {
        #[derive(Debug, Clone, Copy)]
        #[doc=$doc]
        pub struct $name<F: $crate::traitdefs::Float> {
            $(pub $field: $point<F>),+
        }

        impl<F: $crate::traitdefs::Float> $name<F> {
            pub fn new($($($n_field: F),+),+) -> $name<F> {
                $name {
                    $($field: $point::new($($n_field),+)),+
                }
            }

            $(
                pub fn $dim(&self) -> $poly<F> {
                    $poly::new($(self.$dfield.$dim),+)
                }
            )+
        }

        impl<F> $crate::BezCurve<F> for $name<F>
                where F: $crate::traitdefs::Float {
            type Point = $point<F>;
            type Vector = $vector<F>;
            type Elevated = $elevated<$($est),+>;

            fn from_slice(slice: &[$point<F>]) -> Option<$name<F>> {
                use $crate::OrderStatic;
                if slice.len() - 1 != $name::<F>::order_static() {
                    None
                } else {
                    let mut index = -1;
                    Some($name {$($field: {
                        index += 1;
                        slice[index as usize]
                    }),+})
                }
            }

            fn interp_unbounded(&self, t: F) -> $point<F> {
                use $crate::BezCurve;

                $point::new($(self.$dim().interp_unbounded(t)),+)
            }

            fn slope_unbounded(&self, t: F) -> $vector<F> {
                use $crate::BezCurve;

                $vector::new($(self.$dim().slope_unbounded(t)),+)
            }

            fn elevate(&self) -> $elevated<$($est),+> {
                use $crate::BezCurve;

                $(let $dim = self.$dim().elevate();)+
                $elevated::from([$($point::new($($edim.as_ref()[$eindex]),+)),+])
            }

            fn split(&self, _: F) -> Option<($name<F>, $name<F>)> {
                unimplemented!()
            }

            fn order(&self) -> usize {
                use $crate::OrderStatic;
                $poly::<F>::order_static()
            }
        }

        impl<F> $crate::OrderStatic for $name<F>
                where F: $crate::traitdefs::Float {
            #[inline]
            fn order_static() -> usize {
                use $crate::OrderStatic;
                $poly::<F>::order_static()
            }
        }

        impl<F> ::std::convert::From<[$point<F>; $order + 1]> for $name<F>
                where F: $crate::traitdefs::Float {
            fn from(array: [$point<F>; $order + 1]) -> $name<F> {
                use $crate::BezCurve;
                $name::from_slice(&array[..]).unwrap()
            }
        }

        impl<F> ::std::convert::AsRef<[$point<F>]> for $name<F>
                where F: $crate::traitdefs::Float {
            fn as_ref(&self) -> &[$point<F>] {
                use std::slice;
                unsafe {
                    slice::from_raw_parts(self as *const $name<F> as *const $point<F>, $order + 1)
                }
            }
        }

        impl<F> ::std::convert::AsMut<[$point<F>]> for $name<F>
                where F: $crate::traitdefs::Float {
            fn as_mut(&mut self) -> &mut [$point<F>] {
                use std::slice;
                unsafe {
                    slice::from_raw_parts_mut(self as *mut $name<F> as *mut $point<F>, $order + 1)
                }
            }
        }
    };
}<commit_msg>Fixed some unused imports for rustc 1.10<commit_after>// Vector/Point macros
macro_rules! n_pointvector {
    (ops $lhs:ident; $rhs:ident {$($field:ident),*}) => {
        impl<F: $crate::traitdefs::Float> ::std::ops::Add<$rhs<F>> for $lhs<F> {
            type Output = $lhs<F>;

            fn add(self, rhs: $rhs<F>) -> $lhs<F> {
                $lhs {
                    $($field: self.$field + rhs.$field),*
                }
            }
        }

        impl<F: $crate::traitdefs::Float> ::std::ops::Sub<$rhs<F>> for $lhs<F> {
            type Output = $lhs<F>;

            fn sub(self, rhs: $rhs<F>) -> $lhs<F> {
                $lhs {
                    $($field: self.$field - rhs.$field),*
                }
            }
        }
    };

    (float ops $name:ident {$($field:ident),+}) => {
        impl<F: $crate::traitdefs::Float> ::std::ops::Mul<F> for $name<F> {
            type Output = $name<F>;

            fn mul(self, rhs: F) -> $name<F> {
                $name {
                    $($field: self.$field * rhs),+
                }
            }
        }

        impl<F: $crate::traitdefs::Float> ::std::ops::Div<F> for $name<F> {
            type Output = $name<F>;

            fn div(self, rhs: F) -> $name<F> {
                $name {
                    $($field: self.$field / rhs),+
                }
            }
        }

        impl<F: $crate::traitdefs::Float> ::std::ops::Neg for $name<F> {
            type Output = $name<F>;

            fn neg(self) -> $name<F> {
                $name {
                    $($field: -self.$field),+
                }
            }
        }
    };

    (struct $doc:expr, $dims:expr; $name:ident {$($field:ident: $f_ty:ident),+} $sibling:ident) => {
        #[derive(Debug, Clone, Copy)]
        #[doc=$doc]
        pub struct $name<F: $crate::traitdefs::Float> {
            $(pub $field: F),+
        }

        impl<F: $crate::traitdefs::Float> $name<F> {
            pub fn new($($field: F),+) -> $name<F> {
                $name {
                    $($field: $field),+
                }
            }
        }

        impl<F: $crate::traitdefs::Float> ::std::convert::From<[F; $dims]> for $name<F> {
            fn from(array: [F; $dims]) -> $name<F> {
                let mut index = -1;
                $name{$($field: {
                    index += 1;
                    array[index as usize]
                }),+}
            }
        }

        impl<F: $crate::traitdefs::Float> ::std::convert::Into<[F; $dims]> for $name<F> {
            fn into(self) -> [F; $dims] {
                [$(self.$field),*]
            }
        }

        impl<F: $crate::traitdefs::Float> ::std::convert::Into<($($f_ty),*)> for $name<F> {
            fn into(self) -> ($($f_ty),*) {
                ($(self.$field),*)
            }
        }

        impl<F: $crate::traitdefs::Float> ::std::convert::From<$sibling<F>> for $name<F> {
            fn from(sib: $sibling<F>) -> $name<F> {
                $name {
                    $($field: sib.$field),*
                }
            }
        }

        impl<F: $crate::traitdefs::Float> ::std::convert::AsRef<[F]> for $name<F> {
            fn as_ref(&self) -> &[F] {
                use std::slice;
                unsafe {
                    slice::from_raw_parts(self as *const $name<F> as *const F, $dims)
                }
            }
        }

        impl<F: $crate::traitdefs::Float> ::std::convert::AsMut<[F]> for $name<F> {
            fn as_mut(&mut self) -> &mut [F] {
                use std::slice;
                unsafe {
                    slice::from_raw_parts_mut(self as *mut $name<F> as *mut F, $dims)
                }
            }
        }

        n_pointvector!(ops $name; $sibling {$($field),+});
        n_pointvector!(ops $name; $name {$($field),+});
        n_pointvector!(float ops $name {$($field),+});
    };

    ($p_doc:expr, $v_doc:expr, $dims:expr; $p_name:ident, $v_name:ident {$($field:ident),+}) => {
        n_pointvector!(struct $p_doc, $dims; $p_name {$($field: F),+} $v_name);
        n_pointvector!(struct $v_doc, $dims; $v_name {$($field: F),+} $p_name);

        impl<F: $crate::traitdefs::Float> $v_name<F> {
            pub fn len(self) -> F {
                ($(self.$field.powi(2) +)+ F::from_f32(0.0).unwrap()).sqrt()
            }

            pub fn normalize(self) -> $v_name<F> {
                self / self.len()
            }
        }
    }
}

macro_rules! check_t_bounds {
    ($t: expr) => {{
        let zero = F::from_f32(0.0).unwrap();
        let one  = F::from_f32(1.0).unwrap();
        if !(zero <= $t && $t <= one) {
            return None;
        }
    }}
}

// Polynomial Macros
macro_rules! n_bezier {
    ($doc:expr, $order:expr; $name:ident {
        $($field:ident: $weight:expr),+
    } {
        $start:ident, $next:ident;
        $($left:ident, $right:ident: $dweight:expr),+;
        $penu:ident, $end:ident;
    } elevated $elevated:ident<$($est:ty),+>) => {
        #[derive(Debug, Clone, Copy)]
        #[doc=$doc]
        pub struct $name<F> where F: $crate::traitdefs::Float {
            $(pub $field: F),+
        }

        impl<F> $name<F> where F: $crate::traitdefs::Float {
            pub fn new($($field: F),+) -> $name<F> {
                $name {
                    $($field: $field),+
                }
            }
        }

        impl<F> $crate::BezCurve<F> for $name<F>
                where F: $crate::traitdefs::Float {
            type Point = F;
            type Vector = F;
            type Elevated = $elevated<$($est),+>;

            fn from_slice(slice: &[F]) -> Option<$name<F>> {
                use $crate::OrderStatic;
                if slice.len() - 1 != $name::<F>::order_static() {
                    None
                } else {
                    let mut index = -1;
                    Some($name {$($field: {
                        index += 1;
                        slice[index as usize]
                    }),+})
                }
            }

            fn interp_unbounded(&self, t: F) -> F {
                let t1 = F::from_f32(1.0).unwrap() - t;
                const COUNT: i32 = $order;
                let mut factor = COUNT + 1;

                $(
                    factor -= 1;
                    let $field =
                        t1.powi(factor) *
                        t.powi(COUNT-factor) *
                        self.$field *
                        F::from_i32($weight).unwrap();
                )+
                $($field +)+ F::from_f32(0.0).unwrap()
            }

            fn slope_unbounded(&self, t: F) -> F {
                let t1 = F::from_f32(1.0).unwrap() - t;
                const COUNT: i32 = $order - 1;
                let mut factor = COUNT + 1;

                $(
                    factor -= 1;
                    let $right =
                        t1.powi(factor) *
                        t.powi(COUNT-factor) *
                        (self.$right - self.$left) *
                        F::from_i32($dweight * (COUNT + 1)).unwrap();
                )+
                $($right +)+ F::from_f32(0.0).unwrap()
            }

            fn elevate(&self) -> $elevated<$($est),+> {
                let mut factor = 0.0;
                let order = F::from_usize(self.order() + 1).unwrap();
                $elevated::from([self.$start,
                    $({
                        factor += 1.0;
                        let factor = F::from_f32(factor).unwrap();
                        (self.$left * factor +
                        self.$right * (order - factor)) / order
                    },)+
                    self.$end])
            }

            fn split(&self, _: F) -> Option<($name<F>, $name<F>)> {
                unimplemented!()
            }

            fn order(&self) -> usize {
                use $crate::OrderStatic;
                $name::<F>::order_static()
            }
        }

        impl<F> $crate::OrderStatic for $name<F>
                where F: $crate::traitdefs::Float {
            #[inline]
            fn order_static() -> usize {
                $order
            }
        }

        impl<F> ::std::convert::From<[F; $order + 1]> for $name<F>
                where F: $crate::traitdefs::Float {
            fn from(array: [F; $order + 1]) -> $name<F> {
                use $crate::BezCurve;
                $name::from_slice(&array[..]).unwrap()
            }
        }

        impl<F> ::std::convert::AsRef<[F]> for $name<F>
                where F: $crate::traitdefs::Float {
            fn as_ref(&self) -> &[F] {
                use std::slice;
                unsafe {
                    slice::from_raw_parts(self as *const $name<F> as *const F, $order + 1)
                }
            }
        }

        impl<F> ::std::convert::AsMut<[F]> for $name<F>
                where F: $crate::traitdefs::Float {
            fn as_mut(&mut self) -> &mut [F] {
                use std::slice;
                unsafe {
                    slice::from_raw_parts_mut(self as *mut $name<F> as *mut F, $order + 1)
                }
            }
        }
    }
}

macro_rules! bez_composite {
    ($doc:expr, $order:expr; $name:ident<$poly:ident> {
        $($field:ident: $($n_field:ident),+;)+
    } -> <$point:ident; $vector:ident> {
        $($dim:ident = $($dfield:ident),+;)+
    } elevated $elevated:ident<$($est:ty),+> {
        $($eindex:expr => $($edim:ident),+;)+
    } chained $chain:ident) =>
    {
        #[derive(Debug, Clone, Copy)]
        #[doc=$doc]
        pub struct $name<F: $crate::traitdefs::Float> {
            $(pub $field: $point<F>),+
        }

        impl<F: $crate::traitdefs::Float> $name<F> {
            pub fn new($($($n_field: F),+),+) -> $name<F> {
                $name {
                    $($field: $point::new($($n_field),+)),+
                }
            }

            $(
                pub fn $dim(&self) -> $poly<F> {
                    $poly::new($(self.$dfield.$dim),+)
                }
            )+
        }

        impl<F> $crate::BezCurve<F> for $name<F>
                where F: $crate::traitdefs::Float {
            type Point = $point<F>;
            type Vector = $vector<F>;
            type Elevated = $elevated<$($est),+>;

            fn from_slice(slice: &[$point<F>]) -> Option<$name<F>> {
                use $crate::OrderStatic;
                if slice.len() - 1 != $name::<F>::order_static() {
                    None
                } else {
                    let mut index = -1;
                    Some($name {$($field: {
                        index += 1;
                        slice[index as usize]
                    }),+})
                }
            }

            fn interp_unbounded(&self, t: F) -> $point<F> {
                $point::new($(self.$dim().interp_unbounded(t)),+)
            }

            fn slope_unbounded(&self, t: F) -> $vector<F> {
                $vector::new($(self.$dim().slope_unbounded(t)),+)
            }

            fn elevate(&self) -> $elevated<$($est),+> {
                $(let $dim = self.$dim().elevate();)+
                $elevated::from([$($point::new($($edim.as_ref()[$eindex]),+)),+])
            }

            fn split(&self, _: F) -> Option<($name<F>, $name<F>)> {
                unimplemented!()
            }

            fn order(&self) -> usize {
                use $crate::OrderStatic;
                $poly::<F>::order_static()
            }
        }

        impl<F> $crate::OrderStatic for $name<F>
                where F: $crate::traitdefs::Float {
            #[inline]
            fn order_static() -> usize {
                $poly::<F>::order_static()
            }
        }

        impl<F> ::std::convert::From<[$point<F>; $order + 1]> for $name<F>
                where F: $crate::traitdefs::Float {
            fn from(array: [$point<F>; $order + 1]) -> $name<F> {
                use $crate::BezCurve;
                $name::from_slice(&array[..]).unwrap()
            }
        }

        impl<F> ::std::convert::AsRef<[$point<F>]> for $name<F>
                where F: $crate::traitdefs::Float {
            fn as_ref(&self) -> &[$point<F>] {
                use std::slice;
                unsafe {
                    slice::from_raw_parts(self as *const $name<F> as *const $point<F>, $order + 1)
                }
            }
        }

        impl<F> ::std::convert::AsMut<[$point<F>]> for $name<F>
                where F: $crate::traitdefs::Float {
            fn as_mut(&mut self) -> &mut [$point<F>] {
                use std::slice;
                unsafe {
                    slice::from_raw_parts_mut(self as *mut $name<F> as *mut $point<F>, $order + 1)
                }
            }
        }
    };
}<|endoftext|>


<commit_before>/*
 * Copyright (c) 2017 Boucher, Antoni <bouanto@zoho.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/// Connect events to sending a message.
///
/// ## Rules
/// 1. Send `$msg` to `$other_component` when the GTK+ `$event` is emitted on `$widget`.
///
/// 2. Optionally send `$msg.0` when the GTK+ `$event` is emitted on `$widget`.
/// Return `$msg.1` in the GTK+ callback.
/// This variant gives more control to the caller since it expects a `$msg` returning `(Option<MSG>,
/// ReturnValue)` where the `ReturnValue` is the value to return in the GTK+ callback.
/// Option<MSG> can be None if no message needs to be emitted.
///
/// 3. Send `$msg` when the GTK+ `$event` is emitted on `$widget`.
///
/// 4. Send `$msg` to `$widget` when the `$message` is received on `$stream`.
#[macro_export]
macro_rules! connect {
    // Connect to a GTK+ widget event, sending a message to another widget.
    ($widget:expr, $event:ident($($args:pat),*), $other_component:expr, $msg:expr) => {
        connect_stream!($widget, $event($($args),*), $other_component.stream(), $msg);
    };

    // Connect to a GTK+ widget event.
    // This variant gives more control to the caller since it expects a `$msg` returning (Option<MSG>,
    // ReturnValue) where the ReturnValue is the value to return in the GTK+ callback.
    // Option<MSG> can be None if no message needs to be emitted.
    ($relm:expr, $widget:expr, $event:ident($($args:pat),*), return $msg:expr) => {{
        connect_stream!(return $relm.stream(), $widget, $event($($args),*), $msg);
    }};

    // Connect to a GTK+ widget event.
    ($relm:expr, $widget:expr, $event:ident($($args:pat),*), $msg:expr) => {{
        let stream = $relm.stream().clone();
        let _ = $widget.$event(move |$($args),*| {
            let msg: Option<_> = $crate::IntoOption::into_option($msg);
            if let Some(msg) = msg {
                stream.emit(msg);
            }
        });
    }};

    // Connect to a message reception.
    // TODO: create another macro rule accepting multiple patterns.
    ($src_component:ident @ $message:pat, $dst_component:expr, $msg:expr) => {
        let stream = $src_component.stream().clone();
        connect_stream!(stream@$message, $dst_component.stream(), $msg);
    };
}

/// Connect events to sending a message.
/// Similar to `connect!` but wants a stream instead of a component.
///
/// ## Rules
/// 1. Send `$msg` to `$other_stream` when the GTK+ `$event` is emitted on `$widget`.
///
/// 2. Send `$msg` to `$widget` when the `$message` is received on `$stream`.
#[macro_export]
macro_rules! connect_stream {
    // Connect to a GTK+ widget event.
    // This variant gives more control to the caller since it expects a `$msg` returning (Option<MSG>,
    // ReturnValue) where the ReturnValue is the value to return in the GTK+ callback.
    // Option<MSG> can be None if no message needs to be emitted.
    (return $stream:expr, $widget:expr, $event:ident($($args:pat),*), $msg:expr) => {{
        let stream = $stream.clone();
        let _ = $widget.$event(move |$($args),*| {
            let (msg, return_value) = $crate::IntoPair::into_pair($msg);
            let msg: Option<_> = $crate::IntoOption::into_option(msg);
            if let Some(msg) = msg {
                stream.emit(msg);
            }
            return_value
        });
    }};

    // Connect to a GTK+ widget event, sending a message to another widget.
    ($widget:expr, $event:ident($($args:pat),*), $other_stream:expr, $msg:expr) => {
        let stream = $other_stream.clone();
        let _ = $widget.$event(move |$($args),*| {
            let msg: Option<_> = $crate::IntoOption::into_option($msg);
            if let Some(msg) = msg {
                stream.emit(msg);
            }
        });
    };

    // Connect to a message reception.
    // TODO: create another macro rule accepting multiple patterns.
    ($src_stream:ident @ $message:pat, $dst_stream:expr, $msg:expr) => {
        let stream = $dst_stream.clone();
        $src_stream.observe(move |msg| {
            #[allow(unreachable_patterns)]
            match msg {
                &$message =>  {
                    let msg: Option<_> = $crate::IntoOption::into_option($msg);
                    if let Some(msg) = msg {
                        stream.emit(msg);
                    }
                },
                _ => (),
            }
        });
    };
}

/// Connect an asynchronous method call to send a message.
/// The variants with `$fail_msg` will send this message when there's an error.
/// Those without this argument will ignore the error.
#[macro_export]
macro_rules! connect_async {
    ($object:expr, $async_method:ident, $relm:expr, $msg:expr) => {
        connect_async!($object, $async_method(), $relm, $msg)
    };
    ($object:expr, $async_method:ident ( $($args:expr),* ), $relm:expr, $msg:expr) => {{
        let stream = $relm.stream().clone();
        $object.$async_method($($args,)* None, move |result| {
            if let Ok(result) = result {
                stream.emit($msg(result));
            }
        });
    }};
    ($object:expr, $async_method:ident, $relm:expr, $msg:expr, $fail_msg:expr) => {
        connect_async!($object, $async_method(), $relm, $msg, $fail_msg)
    };
    ($object:expr, $async_method:ident ( $($args:expr),* ), $relm:expr, $msg:expr, $fail_msg:expr) => {{
        let event_stream = $relm.stream().clone();
        let fail_event_stream = $relm.stream().clone();
        $object.$async_method($($args,)* None, move |result| {
            match result {
                Ok(value) => event_stream.emit($msg(value)),
                Err(error) => fail_event_stream.emit($fail_msg(error)),
            }
        });
    }};
}

/// Connect an asynchronous function call to send a message.
/// The variants with `$fail_msg` will send this message when there's an error.
/// Those without this argument will ignore the error.
#[macro_export]
macro_rules! connect_async_func {
    ($class:ident :: $async_function:ident, $relm:expr, $msg:expr) => {
        connect_async_func!($class::$async_func(), $relm, $msg)
    };
    ($class:ident :: $async_func:ident ( $($args:expr),* ), $relm:expr, $msg:expr) => {{
        let stream = $relm.stream().clone();
        $class::$async_func($($args,)* None, move |result| {
            if let Ok(result) = result {
                stream.emit($msg(result));
            }
        });
    }};
    ($class:ident :: $async_func:ident, $relm:expr, $msg:expr, $fail_msg:expr) => {
        connect_async_func!($class::$async_func(), $relm, $msg, $fail_msg)
    };
    ($class:ident :: $async_func:ident ( $($args:expr),* ), $relm:expr, $msg:expr, $fail_msg:expr) => {{
        let event_stream = $relm.stream().clone();
        let fail_event_stream = $relm.stream().clone();
        $class::$async_func($($args,)* None, move |result| {
            match result {
                Ok(value) => event_stream.emit($msg(value)),
                Err(error) => fail_event_stream.emit($fail_msg(error)),
            }
        });

    }};
}

/// Like `connect_async!`, but also return a `Cancellable` to control the asynchronous request.
#[macro_export]
macro_rules! connect_async_full {
    ($object:expr, $async_method:ident, $relm:expr, $msg:expr) => {
        connect_async_full!($object, $async_method(), $relm, $msg)
    };
    ($object:expr, $async_method:ident ( $($args:expr),* ), $relm:expr, $msg:expr) => {{
        let cancellable = ::gio::Cancellable::new();
        let stream = $relm.stream().clone();
        $object.$async_method($($args,)* Some(&cancellable), move |result| {
            if let Ok(result) = result {
                stream.emit($msg(result));
            }
        });
        cancellable
    }};
    ($object:expr, $async_method:ident, $relm:expr, $msg:expr, $fail_msg:expr) => {
        connect_async_full!($object, $async_method(), $relm, $msg, $fail_msg)
    };
    ($object:expr, $async_method:ident ( $($args:expr),* ), $relm:expr, $msg:expr, $fail_msg:expr) => {{
        let cancellable = ::gio::Cancellable::new();
        let event_stream = $relm.stream().clone();
        let fail_event_stream = $relm.stream().clone();
        $object.$async_method($($args,)* Some(&cancellable), move |result| {
            match result {
                Ok(value) => event_stream.emit($msg(value)),
                Err(error) => fail_event_stream.emit($fail_msg(error)),
            }
        });

        cancellable
    }};
}

/// Like `connect_async_func!`, but also return a `Cancellable` to control the asynchronous request.
#[macro_export]
macro_rules! connect_async_func_full {
    ($class:ident :: $async_function:ident, $relm:expr, $msg:expr) => {
        connect_async!($async_func(), $relm, $msg)
    };
    ($class:ident :: $async_func:ident ( $($args:expr),* ), $relm:expr, $msg:expr) => {{
        let cancellable = ::gio::Cancellable::new();
        let stream = $relm.stream().clone();
        $class::$async_func($($args,)* Some(&cancellable), move |result| {
            if let Ok(result) = result {
                stream.emit($msg(result));
            }
        });
        cancellable
    }};
    ($class:ident :: $async_func:ident, $relm:expr, $msg:expr, $fail_msg:expr) => {
        connect_async!($async_func(), $relm, $msg, $fail_msg)
    };
    ($class:ident :: $async_func:ident ( $($args:expr),* ), $relm:expr, $msg:expr, $fail_msg:expr) => {{
        let cancellable = ::gio::Cancellable::new();
        let event_stream = $relm.stream().clone();
        let fail_event_stream = $relm.stream().clone();
        $class::$async_func($($args,)* Some(&cancellable), move |result| {
            match result {
                Ok(value) => event_stream.emit($msg(value)),
                Err(error) => fail_event_stream.emit($fail_msg(error)),
            }
        });

        cancellable
    }};
}
<commit_msg>Revert "Temporary fix to publish the crate"<commit_after>/*
 * Copyright (c) 2017 Boucher, Antoni <bouanto@zoho.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

include!("../relm-state/src/macros.rs");
<|endoftext|>


<commit_before>/// Given a `BTreeMap<String, Value>`, return a `Vec<_>` that
/// contains all the items wrapped inside the `Value`s.
///
/// Since `iron/params` returns `Result<Map, ParamsError>` (where
/// `Map` is defined as `BTreeMap<String, Value>`) and we're asked to
/// provide `VectorOfTerms<String>::build_terms()` a `Vec<String>`,
/// we need to assert that it `is_ok()` and eventually retrieving
/// its value using the convertion trait `FromValue`.
///
/// Either if the convertion result `is_none()` because of an error
/// or we originally got a `ParamsError`, an empty `Vec<String>` will
/// be returned.
///
/// Otherwise, the output will be a `Vec<String>` fill with all the
/// returned `String`s found inside the query string.
///
/// ```
/// # #[macro_use] extern crate honeysearch;
/// # extern crate params;
/// # use params::*;
///
/// # fn main() {
/// let mut params = Map::new();
/// params.assign("work_roles[]", Value::String("Fullstack".into())).unwrap();
/// params.assign("work_roles[]", Value::String("DevOps".into())).unwrap();
///
/// let work_roles: Vec<String> = vec_from_params!(params, "work_roles");
/// assert_eq!(work_roles, vec!["Fullstack", "DevOps"]);
/// # }
/// ```
///
/// ```
/// # #[macro_use] extern crate honeysearch;
/// # extern crate params;
/// # use params::*;
///
/// # fn main() {
/// let work_roles: Vec<String> = vec_from_params!(Map::new(), "work_roles");
/// assert_eq!(work_roles, Vec::<String>::new());
/// # }
/// ```
#[macro_export]
macro_rules! vec_from_params {
  ($params:expr, $param:expr) => {
    match $params.find(&[$param]) {
      Some(val) => Vec::from_value(val)
                       .unwrap_or(vec![]),
      None => vec![]
    }
  }
}

/// Like vec_from_params!, but all the elements are casted
/// to i32 (or discarded if the type conversion is impossibile).
#[macro_export]
macro_rules! i32_vec_from_params {
  ($params:expr, $param:expr) => {
    match $params.find(&[$param]) {
      Some(company_id) => i32::from_value(company_id)
                              .map(|id| vec![id])
                              .unwrap_or(vec![]),
      None => vec![]
    }
  }
}

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

  #[test]
  fn test_vec_from_params() {
    {
      let mut params = Map::new();
      params.assign("work_roles[]", Value::String("Fullstack".into())).unwrap();
      params.assign("work_roles[]", Value::String("DevOps".into())).unwrap();

      let work_roles: Vec<String> = vec_from_params!(params, "work_roles");
      assert_eq!(work_roles, vec!["Fullstack", "DevOps"]);
    }

    {
      let mut params = Map::new();
      params.assign("work_roles[]", Value::String("".into())).unwrap();

      let work_roles: Vec<String> = vec_from_params!(params, "work_roles");
      assert_eq!(work_roles, vec![""]); // TODO: `vec![]`?
    }

    {
      let work_roles: Vec<String> = vec_from_params!(Map::new(), "work_roles");
      assert_eq!(work_roles, Vec::<String>::new());
    }
  }

  #[test]
  fn test_i32_vec_from_params() {
    {
      let mut params = Map::new();
      params.assign("company_id", Value::String("4".into())).unwrap();

      let company_id: Vec<i32> = i32_vec_from_params!(params, "company_id");
      assert_eq!(company_id, vec![4]);
    }

    {
      let mut params = Map::new();
      params.assign("company_id", Value::String("".into())).unwrap();

      let company_id: Vec<i32> = i32_vec_from_params!(params, "company_id");
      assert_eq!(company_id, vec![]);
    }

    {
      let mut params = Map::new();
      params.assign("company_id", Value::String("madukapls".into())).unwrap();

      let company_id: Vec<i32> = i32_vec_from_params!(params, "company_id");
      assert_eq!(company_id, vec![]);
    }

    {
      let mut params = Map::new();
      params.assign("company_id[]", Value::String("madukapls".into())).unwrap();

      let company_id: Vec<i32> = i32_vec_from_params!(params, "company_id");
      assert_eq!(company_id, vec![]);
    }

    {
      let company_id: Vec<i32> = i32_vec_from_params!(Map::new(), "company_id");
      assert_eq!(company_id, vec![]);
    }
  }
}
<commit_msg>macros: remove terms redundancy in the doc of vec_from_params!<commit_after>/// Given a `Map`, return a `Vec<_>` that contains all the items
/// wrapped inside the `Value`s.
///
/// Since `iron/params` returns `Result<Map, ParamsError>` (where
/// `Map` is defined as `BTreeMap<String, Value>`) and we're asked to
/// provide `VectorOfTerms<String>::build_terms()` a `Vec<String>`,
/// we need to assert that it `is_ok()` and eventually retrieving
/// its value using the convertion trait `FromValue`.
///
/// Either if the convertion result `is_none()` because of an error
/// or we originally got a `ParamsError`, an empty `Vec<String>` will
/// be returned.
///
/// Otherwise, the output will be a `Vec<String>` fill with all the
/// returned `String`s found inside the query string.
///
/// ```
/// # #[macro_use] extern crate honeysearch;
/// # extern crate params;
/// # use params::*;
///
/// # fn main() {
/// let mut params = Map::new();
/// params.assign("work_roles[]", Value::String("Fullstack".into())).unwrap();
/// params.assign("work_roles[]", Value::String("DevOps".into())).unwrap();
///
/// let work_roles: Vec<String> = vec_from_params!(params, "work_roles");
/// assert_eq!(work_roles, vec!["Fullstack", "DevOps"]);
/// # }
/// ```
///
/// ```
/// # #[macro_use] extern crate honeysearch;
/// # extern crate params;
/// # use params::*;
///
/// # fn main() {
/// let work_roles: Vec<String> = vec_from_params!(Map::new(), "work_roles");
/// assert_eq!(work_roles, Vec::<String>::new());
/// # }
/// ```
#[macro_export]
macro_rules! vec_from_params {
  ($params:expr, $param:expr) => {
    match $params.find(&[$param]) {
      Some(val) => Vec::from_value(val)
                       .unwrap_or(vec![]),
      None => vec![]
    }
  }
}

/// Like vec_from_params!, but all the elements are casted
/// to i32 (or discarded if the type conversion is impossibile).
#[macro_export]
macro_rules! i32_vec_from_params {
  ($params:expr, $param:expr) => {
    match $params.find(&[$param]) {
      Some(company_id) => i32::from_value(company_id)
                              .map(|id| vec![id])
                              .unwrap_or(vec![]),
      None => vec![]
    }
  }
}

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

  #[test]
  fn test_vec_from_params() {
    {
      let mut params = Map::new();
      params.assign("work_roles[]", Value::String("Fullstack".into())).unwrap();
      params.assign("work_roles[]", Value::String("DevOps".into())).unwrap();

      let work_roles: Vec<String> = vec_from_params!(params, "work_roles");
      assert_eq!(work_roles, vec!["Fullstack", "DevOps"]);
    }

    {
      let mut params = Map::new();
      params.assign("work_roles[]", Value::String("".into())).unwrap();

      let work_roles: Vec<String> = vec_from_params!(params, "work_roles");
      assert_eq!(work_roles, vec![""]); // TODO: `vec![]`?
    }

    {
      let work_roles: Vec<String> = vec_from_params!(Map::new(), "work_roles");
      assert_eq!(work_roles, Vec::<String>::new());
    }
  }

  #[test]
  fn test_i32_vec_from_params() {
    {
      let mut params = Map::new();
      params.assign("company_id", Value::String("4".into())).unwrap();

      let company_id: Vec<i32> = i32_vec_from_params!(params, "company_id");
      assert_eq!(company_id, vec![4]);
    }

    {
      let mut params = Map::new();
      params.assign("company_id", Value::String("".into())).unwrap();

      let company_id: Vec<i32> = i32_vec_from_params!(params, "company_id");
      assert_eq!(company_id, vec![]);
    }

    {
      let mut params = Map::new();
      params.assign("company_id", Value::String("madukapls".into())).unwrap();

      let company_id: Vec<i32> = i32_vec_from_params!(params, "company_id");
      assert_eq!(company_id, vec![]);
    }

    {
      let mut params = Map::new();
      params.assign("company_id[]", Value::String("madukapls".into())).unwrap();

      let company_id: Vec<i32> = i32_vec_from_params!(params, "company_id");
      assert_eq!(company_id, vec![]);
    }

    {
      let company_id: Vec<i32> = i32_vec_from_params!(Map::new(), "company_id");
      assert_eq!(company_id, vec![]);
    }
  }
}
<|endoftext|>


<commit_before><commit_msg>Use hashable type in `Geometry` example.<commit_after><|endoftext|>


<commit_before><commit_msg>Break out of loop after finding what we're looking for<commit_after><|endoftext|>


<commit_before>use parser::Node;
use std::str;

struct Generator {
    buf: String,
}

impl Generator {

    fn new() -> Generator {
        Generator { buf: String::new() }
    }

    fn init(&mut self, name: &str) {
        self.write("impl askama::Template for ");
        self.write(name);
        self.write(" {\n");
        self.write("    fn render(&self) -> String {\n");
        self.write("        let mut buf = String::new();\n");
    }

    fn write(&mut self, s: &str) {
        self.buf.push_str(s);
    }

    fn visit_lit(&mut self, s: &[u8]) {
        self.write("        buf.push_str(");
        self.write(&format!("{:#?}", str::from_utf8(s).unwrap()));
        self.write(");\n");
    }

    fn visit_expr(&mut self, s: &[u8]) {
        self.write("        buf.push_str(");
        self.write(&format!("&self.{}", str::from_utf8(s).unwrap()));
        self.write(");\n");
    }

    fn handle(&mut self, tokens: &Vec<Node>) {
        for n in tokens {
            match n {
                &Node::Lit(val) => { self.visit_lit(val); },
                &Node::Expr(val) => { self.visit_expr(val); },
            }
        }
    }

    fn finalize(&mut self) {
        self.write("        buf");
        self.write("    }\n");
        self.write("}\n\n");
    }

    fn result(self) -> String {
        self.buf
    }

}

pub fn generate(ctx_name: &str, tokens: &Vec<Node>) -> String {
    let mut gen = Generator::new();
    gen.init(ctx_name);
    gen.handle(tokens);
    gen.finalize();
    gen.result()
}
<commit_msg>Add some helper methods to Generator impl<commit_after>use parser::Node;
use std::str;

struct Generator {
    buf: String,
    indent: u8,
    start: bool,
}

impl Generator {

    fn new() -> Generator {
        Generator { buf: String::new(), indent: 0, start: true }
    }

    fn init(&mut self, name: &str) {
        self.write("impl askama::Template for ");
        self.write(name);
        self.writeln(" {");
        self.indent();
        self.writeln("fn render(&self) -> String {");
        self.indent();
        self.writeln("let mut buf = String::new();");
    }

    fn indent(&mut self) {
        self.indent += 1;
    }

    fn dedent(&mut self) {
        self.indent -= 1;
    }

    fn write(&mut self, s: &str) {
        if self.start {
            for _ in 0..(self.indent * 4) {
                self.buf.push(' ');
            }
            self.start = false;
        }
        self.buf.push_str(s);
    }

    fn writeln(&mut self, s: &str) {
        if s.is_empty() {
            return;
        }
        self.write(s);
        self.buf.push('\n');
        self.start = true;
    }

    fn visit_lit(&mut self, s: &[u8]) {
        self.write("buf.push_str(");
        self.write(&format!("{:#?}", str::from_utf8(s).unwrap()));
        self.writeln(");");
    }

    fn visit_expr(&mut self, s: &[u8]) {
        self.write("buf.push_str(");
        self.write(&format!("&self.{}", str::from_utf8(s).unwrap()));
        self.writeln(");");
    }

    fn handle(&mut self, tokens: &Vec<Node>) {
        for n in tokens {
            match n {
                &Node::Lit(val) => { self.visit_lit(val); },
                &Node::Expr(val) => { self.visit_expr(val); },
            }
        }
    }

    fn finalize(&mut self) {
        self.writeln("buf");
        self.dedent();
        self.writeln("}");
        self.dedent();
        self.writeln("}");
    }

    fn result(self) -> String {
        self.buf
    }

}

pub fn generate(ctx_name: &str, tokens: &Vec<Node>) -> String {
    let mut gen = Generator::new();
    gen.init(ctx_name);
    gen.handle(tokens);
    gen.finalize();
    gen.result()
}
<|endoftext|>