<commit_before>//! Wrapper for `std::io::Read`.

use std::fmt;
use std::mem;
use std::io;

macro_rules! impl_read_little_endian_integer {
    ($ty:ident, $name:ident, $size:expr) => {
/// Reads a little-endian value and returns it.
        fn $name(&mut self) -> io::Result<$ty> {
            assert_eq!($size, mem::size_of::<$ty>());

            let mut data: $ty = 0;
            let mut slice = unsafe {
                ::std::slice::from_raw_parts_mut(&mut data as *mut $ty as *mut u8, $size)
            };
            self.read_exact(slice)?;
            Ok($ty::from_le(data))
        }
    }
}

macro_rules! impl_read_little_endian_integer_array {
    ($ty:ident, $name:ident, $size:expr) => {
/// Reads a little-endian values into the given buffer.
        fn $name(&mut self, buf: &mut [$ty]) -> io::Result<()> {
            assert_eq!($size, mem::size_of::<$ty>());

            {
                let mut slice = unsafe {
                    ::std::slice::from_raw_parts_mut(buf.as_mut_ptr() as *mut u8, $size * buf.len())
                };
                self.read_exact(slice)?;
            }
            for elem in buf {
                *elem = $ty::from_le(*elem);
            }
            Ok(())
        }
    }
}

/// The `ReadLittleEndian` trait allows for reading little-endian primitive type values from a
/// source.
pub trait ReadLittleEndian: io::Read {
    impl_read_little_endian_integer!(u8, read_u8, 1);
    impl_read_little_endian_integer!(u32, read_u32, 4);
    impl_read_little_endian_integer!(u64, read_u64, 8);
    impl_read_little_endian_integer!(i16, read_i16, 2);
    impl_read_little_endian_integer!(i32, read_i32, 4);
    impl_read_little_endian_integer!(i64, read_i64, 8);

    /// Reads a little-endian value and returns it.
    fn read_f32(&mut self) -> io::Result<f32> {
        let integer = self.read_u32()?;
        let val = unsafe { mem::transmute(integer) };
        Ok(val)
    }

    /// Reads a little-endian value and returns it.
    fn read_f64(&mut self) -> io::Result<f64> {
        let integer = self.read_u64()?;
        let val = unsafe { mem::transmute(integer) };
        Ok(val)
    }

    impl_read_little_endian_integer_array!(u8, read_u8_arr, 1);
    impl_read_little_endian_integer_array!(u32, read_u32_arr, 4);
    impl_read_little_endian_integer_array!(u64, read_u64_arr, 8);
    impl_read_little_endian_integer_array!(i16, read_i16_arr, 2);
    impl_read_little_endian_integer_array!(i32, read_i32_arr, 4);
    impl_read_little_endian_integer_array!(i64, read_i64_arr, 8);

    /// Reads a little-endian values into the given buffer.
    fn read_f32_arr(&mut self, buf: &mut [f32]) -> io::Result<()> {
        self.read_u32_arr(unsafe { mem::transmute(buf) })
    }

    /// Reads a little-endian values into the given buffer.
    fn read_f64_arr(&mut self, buf: &mut [f64]) -> io::Result<()> {
        self.read_u64_arr(unsafe { mem::transmute(buf) })
    }
}

impl<R: io::Read> ReadLittleEndian for R {}

/// Source stream for `RootParser`.
pub trait ParserSource: fmt::Debug + io::Read {
    /// Returns the current position from the start of the stream.
    fn position(&self) -> u64;

    /// Skips to the given position.
    ///
    /// # Panics
    /// Panics if a byte at the given position has been already read.
    fn skip_to(&mut self, dest_pos: u64) -> io::Result<()>;
}

/// Reader with position info.
pub struct BasicSource<R> {
    /// Source reader.
    source: R,
    /// Current position from the start of the stream..
    position: u64,
}

impl<R: io::Read> BasicSource<R> {
    /// Creates a new `BasicSource`.
    pub fn new(source: R) -> Self {
        BasicSource {
            source: source,
            position: 0,
        }
    }
}

impl<R: io::Read> io::Read for BasicSource<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let read_len = self.source.read(buf)?;
        self.position += read_len as u64;
        Ok(read_len)
    }

    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
        self.source.read_exact(buf)?;
        self.position += buf.len() as u64;
        Ok(())
    }
}

impl<R: io::BufRead> io::BufRead for BasicSource<R> {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        self.source.fill_buf()
    }

    fn consume(&mut self, amt: usize) {
        self.position += amt as u64;
        self.source.consume(amt);
    }
}

impl<R> fmt::Debug for BasicSource<R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("BasicSource")
            .field("position", &self.position)
            .finish()
    }
}

impl<R: io::Read> ParserSource for BasicSource<R> {
    fn position(&self) -> u64 {
        self.position
    }

    fn skip_to(&mut self, dest_pos: u64) -> io::Result<()> {
        use std::io::Read;

        assert!(dest_pos >= self.position(),
                "Destination position should be after current position: dest_pos={}, position={}",
                dest_pos,
                self.position());
        const TEMP_BUF_LEN: usize = 256;
        let mut temp_buf = [0u8; TEMP_BUF_LEN];
        let mut rest_len = dest_pos - self.position();
        while rest_len > TEMP_BUF_LEN as u64 {
            self.read_exact(&mut temp_buf)?;
            rest_len -= TEMP_BUF_LEN as u64;
        }
        self.read_exact(&mut temp_buf[0..rest_len as usize])?;

        assert_eq!(self.position(), dest_pos);
        Ok(())
    }
}

/// Reader with position info and seek feature.
///
/// This wrapper doesn't manage offset, i.e. the start of the source stream should be the start of
/// the FBX data.
pub struct SeekableSource<R> {
    /// Source reader.
    source: R,
    /// Current position from the start of the stream..
    position: u64,
}

impl<R: io::Read + io::Seek> SeekableSource<R> {
    /// Creates a new `SeekableSource`.
    pub fn new(source: R) -> Self {
        SeekableSource {
            source: source,
            position: 0,
        }
    }
}

impl<R: io::Read> io::Read for SeekableSource<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let read_len = self.source.read(buf)?;
        self.position += read_len as u64;
        Ok(read_len)
    }

    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
        self.source.read_exact(buf)?;
        self.position += buf.len() as u64;
        Ok(())
    }
}

impl<R: io::Read + io::Seek> io::Seek for SeekableSource<R> {
    fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
        self.position = self.source.seek(pos)?;
        Ok(self.position)
    }
}

impl<R> fmt::Debug for SeekableSource<R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("SeekableSource")
            .field("position", &self.position)
            .finish()
    }
}

impl<R: io::Read + io::Seek> ParserSource for SeekableSource<R> {
    fn position(&self) -> u64 {
        self.position
    }

    fn skip_to(&mut self, dest_pos: u64) -> io::Result<()> {
        use std::io::{Seek, SeekFrom};

        assert!(dest_pos >= self.position(),
                "Destination position should be after current position: dest_pos={}, position={}",
                dest_pos,
                self.position());
        self.seek(SeekFrom::Start(dest_pos))?;

        assert_eq!(self.position(), dest_pos);
        Ok(())
    }
}

impl<R: io::BufRead> io::BufRead for SeekableSource<R> {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        self.source.fill_buf()
    }

    fn consume(&mut self, amt: usize) {
        self.position += amt as u64;
        self.source.consume(amt);
    }
}

/// Reader which can read and seek limited area of a stream.
pub struct LimitedSeekReader<R> {
    /// Source stream.
    source: R,
    /// Current position
    current: u64,
    /// Start position.
    begin: u64,
    /// End position.
    end: u64,
}

impl<R: io::Read> LimitedSeekReader<R> {
    /// Creates a new `LimitedSeekReader`.
    pub fn new(source: R, current: u64, begin: u64, end: u64) -> Self {
        assert!(begin <= end);
        assert!(begin <= current);
        assert!(current <= end);

        LimitedSeekReader {
            source: source,
            current: current,
            begin: begin,
            end: end,
        }
    }
}

impl<R> LimitedSeekReader<R> {
    /// Returns length of region allowed to be read in bytes.
    pub fn len(&self) -> u64 {
        assert!(self.begin <= self.end);
        self.end - self.begin
    }

    /// Returns `true` if the reader can read no data.
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    /// Returns rest length of region allowed to be read in bytes.
    fn rest_len(&self) -> u64 {
        assert!(self.current <= self.end);
        self.end - self.current
    }

    /// Returns the current position relative to the start of the limited region.
    fn rel_pos(&self) -> u64 {
        assert!(self.begin <= self.current);
        self.current - self.begin
    }
}

impl<R: io::Read> io::Read for LimitedSeekReader<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let limit = self.rest_len();
        let size = self.source.by_ref().take(limit).read(buf)?;
        self.current += size as u64;
        Ok(size)
    }
}

impl<R: io::BufRead> io::BufRead for LimitedSeekReader<R> {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        self.source.fill_buf()
    }

    fn consume(&mut self, amt: usize) {
        self.current += amt as u64;
        self.source.consume(amt);
    }
}

impl<R: io::Seek> io::Seek for LimitedSeekReader<R> {
    fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
        match pos {
            io::SeekFrom::Start(val) => {
                let offset = ::std::cmp::min(self.len(), val);
                let target = self.begin + offset;
                assert!(target >= self.begin);
                assert!(target <= self.end);
                self.current = self.source.seek(io::SeekFrom::Start(target))?;
            },
            io::SeekFrom::Current(val) => {
                let offset = if val < 0 {
                    ::std::cmp::max(-(self.rel_pos() as i64), val)
                } else {
                    ::std::cmp::min(self.rest_len(), val as u64) as i64
                };
                let target = self.current as i64 + offset;
                assert!(target as u64 >= self.begin);
                assert!(target as u64 <= self.end);
                self.current = self.source.seek(io::SeekFrom::Current(offset))?;
            },
            io::SeekFrom::End(val) => {
                let offset = ::std::cmp::max(-(self.len() as i64), ::std::cmp::min(0, val));
                let target = (self.end as i64 + offset) as u64;
                assert!(target >= self.begin);
                assert!(target <= self.end);
                self.current = self.source.seek(io::SeekFrom::Start(target))?;
            },
        }
        Ok(self.rel_pos())
    }
}

impl<R> fmt::Debug for LimitedSeekReader<R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("LimitedSeekReader")
            .field("current", &self.current)
            .field("begin", &self.begin)
            .field("end", &self.end)
            .finish()
    }
}

#[cfg(test)]
mod tests {
    use std::io::{Cursor, Seek, SeekFrom};
    use super::{ParserSource, BasicSource, SeekableSource};

    fn do_test_skip_to(buf_size: usize, skip_dest: u64) {
        do_test_basic_skip_to(buf_size, skip_dest);
        do_test_seekable_skip_to(buf_size, skip_dest);
    }

    fn do_test_basic_skip_to(buf_size: usize, skip_dest: u64) {
        let mut short_buf = Cursor::new(vec![0; buf_size]);
        let short_count = {
            let mut reader = BasicSource::new(&mut short_buf);
            reader.skip_to(skip_dest).expect("Failed to skip");
            reader.position()
        };
        assert_eq!(short_count, skip_dest);
        assert_eq!(short_count,
                   short_buf.seek(SeekFrom::Current(0)).expect("Failed to seek"));
    }

    fn do_test_seekable_skip_to(buf_size: usize, skip_dest: u64) {
        let mut short_buf = Cursor::new(vec![0; buf_size]);
        let mut reader = SeekableSource::new(&mut short_buf);
        reader.skip_to(skip_dest).expect("Failed to skip");
        assert_eq!(reader.position(), skip_dest);
        reader.seek(SeekFrom::End(0)).expect("Failed to seek");;
        assert_eq!(reader.position(), buf_size as u64);
        reader.seek(SeekFrom::Start(0)).expect("Failed to seek");
        assert_eq!(reader.position(), 0);
    }

    #[test]
    fn test_skip_to() {
        do_test_skip_to(0, 0);
        do_test_skip_to(15, 0);
        do_test_skip_to(30, 23);
        do_test_skip_to(512, 401);
        do_test_skip_to(64, 64);
    }
}
<commit_msg>Implement `ParserSource` for `&mut R where R: ParserSource`<commit_after>//! Wrapper for `std::io::Read`.

use std::fmt;
use std::mem;
use std::io;

macro_rules! impl_read_little_endian_integer {
    ($ty:ident, $name:ident, $size:expr) => {
/// Reads a little-endian value and returns it.
        fn $name(&mut self) -> io::Result<$ty> {
            assert_eq!($size, mem::size_of::<$ty>());

            let mut data: $ty = 0;
            let mut slice = unsafe {
                ::std::slice::from_raw_parts_mut(&mut data as *mut $ty as *mut u8, $size)
            };
            self.read_exact(slice)?;
            Ok($ty::from_le(data))
        }
    }
}

macro_rules! impl_read_little_endian_integer_array {
    ($ty:ident, $name:ident, $size:expr) => {
/// Reads a little-endian values into the given buffer.
        fn $name(&mut self, buf: &mut [$ty]) -> io::Result<()> {
            assert_eq!($size, mem::size_of::<$ty>());

            {
                let mut slice = unsafe {
                    ::std::slice::from_raw_parts_mut(buf.as_mut_ptr() as *mut u8, $size * buf.len())
                };
                self.read_exact(slice)?;
            }
            for elem in buf {
                *elem = $ty::from_le(*elem);
            }
            Ok(())
        }
    }
}

/// The `ReadLittleEndian` trait allows for reading little-endian primitive type values from a
/// source.
pub trait ReadLittleEndian: io::Read {
    impl_read_little_endian_integer!(u8, read_u8, 1);
    impl_read_little_endian_integer!(u32, read_u32, 4);
    impl_read_little_endian_integer!(u64, read_u64, 8);
    impl_read_little_endian_integer!(i16, read_i16, 2);
    impl_read_little_endian_integer!(i32, read_i32, 4);
    impl_read_little_endian_integer!(i64, read_i64, 8);

    /// Reads a little-endian value and returns it.
    fn read_f32(&mut self) -> io::Result<f32> {
        let integer = self.read_u32()?;
        let val = unsafe { mem::transmute(integer) };
        Ok(val)
    }

    /// Reads a little-endian value and returns it.
    fn read_f64(&mut self) -> io::Result<f64> {
        let integer = self.read_u64()?;
        let val = unsafe { mem::transmute(integer) };
        Ok(val)
    }

    impl_read_little_endian_integer_array!(u8, read_u8_arr, 1);
    impl_read_little_endian_integer_array!(u32, read_u32_arr, 4);
    impl_read_little_endian_integer_array!(u64, read_u64_arr, 8);
    impl_read_little_endian_integer_array!(i16, read_i16_arr, 2);
    impl_read_little_endian_integer_array!(i32, read_i32_arr, 4);
    impl_read_little_endian_integer_array!(i64, read_i64_arr, 8);

    /// Reads a little-endian values into the given buffer.
    fn read_f32_arr(&mut self, buf: &mut [f32]) -> io::Result<()> {
        self.read_u32_arr(unsafe { mem::transmute(buf) })
    }

    /// Reads a little-endian values into the given buffer.
    fn read_f64_arr(&mut self, buf: &mut [f64]) -> io::Result<()> {
        self.read_u64_arr(unsafe { mem::transmute(buf) })
    }
}

impl<R: io::Read> ReadLittleEndian for R {}

/// Source stream for `RootParser`.
pub trait ParserSource: fmt::Debug + io::Read {
    /// Returns the current position from the start of the stream.
    fn position(&self) -> u64;

    /// Skips to the given position.
    ///
    /// # Panics
    /// Panics if a byte at the given position has been already read.
    fn skip_to(&mut self, dest_pos: u64) -> io::Result<()>;
}

impl<'a, R: ParserSource> ParserSource for &'a mut R {
    fn position(&self) -> u64 {
        (**self).position()
    }

    fn skip_to(&mut self, dest_pos: u64) -> io::Result<()> {
        (**self).skip_to(dest_pos)
    }
}

/// Reader with position info.
pub struct BasicSource<R> {
    /// Source reader.
    source: R,
    /// Current position from the start of the stream..
    position: u64,
}

impl<R: io::Read> BasicSource<R> {
    /// Creates a new `BasicSource`.
    pub fn new(source: R) -> Self {
        BasicSource {
            source: source,
            position: 0,
        }
    }
}

impl<R: io::Read> io::Read for BasicSource<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let read_len = self.source.read(buf)?;
        self.position += read_len as u64;
        Ok(read_len)
    }

    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
        self.source.read_exact(buf)?;
        self.position += buf.len() as u64;
        Ok(())
    }
}

impl<R: io::BufRead> io::BufRead for BasicSource<R> {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        self.source.fill_buf()
    }

    fn consume(&mut self, amt: usize) {
        self.position += amt as u64;
        self.source.consume(amt);
    }
}

impl<R> fmt::Debug for BasicSource<R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("BasicSource")
            .field("position", &self.position)
            .finish()
    }
}

impl<R: io::Read> ParserSource for BasicSource<R> {
    fn position(&self) -> u64 {
        self.position
    }

    fn skip_to(&mut self, dest_pos: u64) -> io::Result<()> {
        use std::io::Read;

        assert!(dest_pos >= self.position(),
                "Destination position should be after current position: dest_pos={}, position={}",
                dest_pos,
                self.position());
        const TEMP_BUF_LEN: usize = 256;
        let mut temp_buf = [0u8; TEMP_BUF_LEN];
        let mut rest_len = dest_pos - self.position();
        while rest_len > TEMP_BUF_LEN as u64 {
            self.read_exact(&mut temp_buf)?;
            rest_len -= TEMP_BUF_LEN as u64;
        }
        self.read_exact(&mut temp_buf[0..rest_len as usize])?;

        assert_eq!(self.position(), dest_pos);
        Ok(())
    }
}

/// Reader with position info and seek feature.
///
/// This wrapper doesn't manage offset, i.e. the start of the source stream should be the start of
/// the FBX data.
pub struct SeekableSource<R> {
    /// Source reader.
    source: R,
    /// Current position from the start of the stream..
    position: u64,
}

impl<R: io::Read + io::Seek> SeekableSource<R> {
    /// Creates a new `SeekableSource`.
    pub fn new(source: R) -> Self {
        SeekableSource {
            source: source,
            position: 0,
        }
    }
}

impl<R: io::Read> io::Read for SeekableSource<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let read_len = self.source.read(buf)?;
        self.position += read_len as u64;
        Ok(read_len)
    }

    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
        self.source.read_exact(buf)?;
        self.position += buf.len() as u64;
        Ok(())
    }
}

impl<R: io::Read + io::Seek> io::Seek for SeekableSource<R> {
    fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
        self.position = self.source.seek(pos)?;
        Ok(self.position)
    }
}

impl<R> fmt::Debug for SeekableSource<R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("SeekableSource")
            .field("position", &self.position)
            .finish()
    }
}

impl<R: io::Read + io::Seek> ParserSource for SeekableSource<R> {
    fn position(&self) -> u64 {
        self.position
    }

    fn skip_to(&mut self, dest_pos: u64) -> io::Result<()> {
        use std::io::{Seek, SeekFrom};

        assert!(dest_pos >= self.position(),
                "Destination position should be after current position: dest_pos={}, position={}",
                dest_pos,
                self.position());
        self.seek(SeekFrom::Start(dest_pos))?;

        assert_eq!(self.position(), dest_pos);
        Ok(())
    }
}

impl<R: io::BufRead> io::BufRead for SeekableSource<R> {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        self.source.fill_buf()
    }

    fn consume(&mut self, amt: usize) {
        self.position += amt as u64;
        self.source.consume(amt);
    }
}

/// Reader which can read and seek limited area of a stream.
pub struct LimitedSeekReader<R> {
    /// Source stream.
    source: R,
    /// Current position
    current: u64,
    /// Start position.
    begin: u64,
    /// End position.
    end: u64,
}

impl<R: io::Read> LimitedSeekReader<R> {
    /// Creates a new `LimitedSeekReader`.
    pub fn new(source: R, current: u64, begin: u64, end: u64) -> Self {
        assert!(begin <= end);
        assert!(begin <= current);
        assert!(current <= end);

        LimitedSeekReader {
            source: source,
            current: current,
            begin: begin,
            end: end,
        }
    }
}

impl<R> LimitedSeekReader<R> {
    /// Returns length of region allowed to be read in bytes.
    pub fn len(&self) -> u64 {
        assert!(self.begin <= self.end);
        self.end - self.begin
    }

    /// Returns `true` if the reader can read no data.
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    /// Returns rest length of region allowed to be read in bytes.
    fn rest_len(&self) -> u64 {
        assert!(self.current <= self.end);
        self.end - self.current
    }

    /// Returns the current position relative to the start of the limited region.
    fn rel_pos(&self) -> u64 {
        assert!(self.begin <= self.current);
        self.current - self.begin
    }
}

impl<R: io::Read> io::Read for LimitedSeekReader<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        let limit = self.rest_len();
        let size = self.source.by_ref().take(limit).read(buf)?;
        self.current += size as u64;
        Ok(size)
    }
}

impl<R: io::BufRead> io::BufRead for LimitedSeekReader<R> {
    fn fill_buf(&mut self) -> io::Result<&[u8]> {
        self.source.fill_buf()
    }

    fn consume(&mut self, amt: usize) {
        self.current += amt as u64;
        self.source.consume(amt);
    }
}

impl<R: io::Seek> io::Seek for LimitedSeekReader<R> {
    fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
        match pos {
            io::SeekFrom::Start(val) => {
                let offset = ::std::cmp::min(self.len(), val);
                let target = self.begin + offset;
                assert!(target >= self.begin);
                assert!(target <= self.end);
                self.current = self.source.seek(io::SeekFrom::Start(target))?;
            },
            io::SeekFrom::Current(val) => {
                let offset = if val < 0 {
                    ::std::cmp::max(-(self.rel_pos() as i64), val)
                } else {
                    ::std::cmp::min(self.rest_len(), val as u64) as i64
                };
                let target = self.current as i64 + offset;
                assert!(target as u64 >= self.begin);
                assert!(target as u64 <= self.end);
                self.current = self.source.seek(io::SeekFrom::Current(offset))?;
            },
            io::SeekFrom::End(val) => {
                let offset = ::std::cmp::max(-(self.len() as i64), ::std::cmp::min(0, val));
                let target = (self.end as i64 + offset) as u64;
                assert!(target >= self.begin);
                assert!(target <= self.end);
                self.current = self.source.seek(io::SeekFrom::Start(target))?;
            },
        }
        Ok(self.rel_pos())
    }
}

impl<R> fmt::Debug for LimitedSeekReader<R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_struct("LimitedSeekReader")
            .field("current", &self.current)
            .field("begin", &self.begin)
            .field("end", &self.end)
            .finish()
    }
}

#[cfg(test)]
mod tests {
    use std::io::{Cursor, Seek, SeekFrom};
    use super::{ParserSource, BasicSource, SeekableSource};

    fn do_test_skip_to(buf_size: usize, skip_dest: u64) {
        do_test_basic_skip_to(buf_size, skip_dest);
        do_test_seekable_skip_to(buf_size, skip_dest);
    }

    fn do_test_basic_skip_to(buf_size: usize, skip_dest: u64) {
        let mut short_buf = Cursor::new(vec![0; buf_size]);
        let short_count = {
            let mut reader = BasicSource::new(&mut short_buf);
            reader.skip_to(skip_dest).expect("Failed to skip");
            reader.position()
        };
        assert_eq!(short_count, skip_dest);
        assert_eq!(short_count,
                   short_buf.seek(SeekFrom::Current(0)).expect("Failed to seek"));
    }

    fn do_test_seekable_skip_to(buf_size: usize, skip_dest: u64) {
        let mut short_buf = Cursor::new(vec![0; buf_size]);
        let mut reader = SeekableSource::new(&mut short_buf);
        reader.skip_to(skip_dest).expect("Failed to skip");
        assert_eq!(reader.position(), skip_dest);
        reader.seek(SeekFrom::End(0)).expect("Failed to seek");;
        assert_eq!(reader.position(), buf_size as u64);
        reader.seek(SeekFrom::Start(0)).expect("Failed to seek");
        assert_eq!(reader.position(), 0);
    }

    #[test]
    fn test_skip_to() {
        do_test_skip_to(0, 0);
        do_test_skip_to(15, 0);
        do_test_skip_to(30, 23);
        do_test_skip_to(512, 401);
        do_test_skip_to(64, 64);
    }
}
<|endoftext|>


<commit_before><commit_msg>fix `get_plan` regressions<commit_after><|endoftext|>


<commit_before>#[macro_use]
extern crate criterion;
extern crate pdatastructs;

use std::collections::HashSet;

use criterion::{Bencher, Criterion, Fun, ParameterizedBenchmark};
use pdatastructs::filters::bloomfilter::BloomFilter;
use pdatastructs::filters::cuckoofilter::CuckooFilter;
use pdatastructs::filters::quotientfilter::QuotientFilter;
use pdatastructs::filters::Filter;
use pdatastructs::rand::SeedableRng;
use rand_chacha::ChaChaRng;

fn setup_bloomfilter() -> BloomFilter<u64> {
    let false_positive_rate = 0.02; // = 2%
    let expected_elements = 10_000;
    BloomFilter::with_properties(expected_elements, false_positive_rate)
}

fn setup_cuckoofilter() -> CuckooFilter<u64, ChaChaRng> {
    let false_positive_rate = 0.02; // = 2%
    let expected_elements = 10_000;
    let rng = ChaChaRng::from_seed([0; 32]);
    CuckooFilter::with_properties_8(false_positive_rate, expected_elements, rng)
}

fn setup_hashset() -> HashSet<u64> {
    HashSet::new()
}

fn setup_quotientfilter() -> QuotientFilter<u64> {
    let bits_quotient = 15;
    let bits_remainder = 4;
    QuotientFilter::with_params(bits_quotient, bits_remainder)
}

fn run_setup<F, S>(setup: S, b: &mut Bencher)
where
    S: Fn() -> F,
    F: Filter<u64>,
{
    b.iter(setup)
}

fn run_insert_many<F, S>(setup: S, b: &mut Bencher, n: u64)
where
    S: Fn() -> F,
    F: Filter<u64>,
{
    b.iter_with_setup(setup, |mut filter| {
        for i in 0..n {
            filter.insert(&i).unwrap();
        }
    })
}

fn benchmarks_setup(c: &mut Criterion) {
    let functions = vec![
        Fun::new("bloomfilter", |b, _| run_setup(setup_bloomfilter, b)),
        Fun::new("cuckoofilter", |b, _| run_setup(setup_cuckoofilter, b)),
        Fun::new("hashset", |b, _| run_setup(setup_hashset, b)),
        Fun::new("quotientfilter", |b, _| run_setup(setup_quotientfilter, b)),
    ];
    c.bench_functions("setup", functions, ());
}

fn benchmarks_insert_many(c: &mut Criterion) {
    let parameters = vec![4_000, 8_000, 12_000, 16_000, 20_000];
    let benchmark = ParameterizedBenchmark::new(
        "bloomfilter",
        |b, n| run_insert_many(setup_bloomfilter, b, *n),
        parameters,
    )
    .with_function("cuckoofilter", |b, n| {
        run_insert_many(setup_cuckoofilter, b, *n)
    })
    .with_function("hashset", |b, n| run_insert_many(setup_hashset, b, *n))
    .with_function("quotientfilter", |b, n| {
        run_insert_many(setup_quotientfilter, b, *n)
    })
    .sample_size(20);
    c.bench("insert_many", benchmark);
}

criterion_group!(benches, benchmarks_setup, benchmarks_insert_many,);
criterion_main!(benches);
<commit_msg>filters: add query benchmarks<commit_after>#[macro_use]
extern crate criterion;
extern crate pdatastructs;

use std::collections::HashSet;

use criterion::{Bencher, Criterion, Fun, ParameterizedBenchmark};
use pdatastructs::filters::bloomfilter::BloomFilter;
use pdatastructs::filters::cuckoofilter::CuckooFilter;
use pdatastructs::filters::quotientfilter::QuotientFilter;
use pdatastructs::filters::Filter;
use pdatastructs::rand::SeedableRng;
use rand_chacha::ChaChaRng;

fn setup_bloomfilter() -> BloomFilter<u64> {
    let false_positive_rate = 0.02; // = 2%
    let expected_elements = 10_000;
    BloomFilter::with_properties(expected_elements, false_positive_rate)
}

fn setup_cuckoofilter() -> CuckooFilter<u64, ChaChaRng> {
    let false_positive_rate = 0.02; // = 2%
    let expected_elements = 10_000;
    let rng = ChaChaRng::from_seed([0; 32]);
    CuckooFilter::with_properties_8(false_positive_rate, expected_elements, rng)
}

fn setup_hashset() -> HashSet<u64> {
    HashSet::new()
}

fn setup_quotientfilter() -> QuotientFilter<u64> {
    let bits_quotient = 15;
    let bits_remainder = 4;
    QuotientFilter::with_params(bits_quotient, bits_remainder)
}

fn run_setup<F, S>(setup: S, b: &mut Bencher)
where
    S: Fn() -> F,
    F: Filter<u64>,
{
    b.iter(setup)
}

fn run_insert_many<F, S>(setup: S, b: &mut Bencher, n: u64)
where
    S: Fn() -> F,
    F: Filter<u64>,
{
    b.iter_with_setup(setup, |mut filter| {
        for i in 0..n {
            filter.insert(&i).unwrap();
        }
    })
}

fn run_query_single<F, S>(setup: S, b: &mut Bencher, n: u64)
where
    S: Fn() -> F,
    F: Filter<u64>,
{
    let setup_and_fill = || {
        let mut filter = setup();
        for i in 0..n {
            filter.insert(&i).unwrap();
        }
        filter
    };
    b.iter_with_setup(setup_and_fill, |filter| filter.query(&0))
}

fn benchmarks_setup(c: &mut Criterion) {
    let functions = vec![
        Fun::new("bloomfilter", |b, _| run_setup(setup_bloomfilter, b)),
        Fun::new("cuckoofilter", |b, _| run_setup(setup_cuckoofilter, b)),
        Fun::new("hashset", |b, _| run_setup(setup_hashset, b)),
        Fun::new("quotientfilter", |b, _| run_setup(setup_quotientfilter, b)),
    ];
    c.bench_functions("setup", functions, ());
}

fn benchmarks_insert_many(c: &mut Criterion) {
    let parameters = vec![4_000, 8_000, 12_000, 16_000, 20_000];
    let benchmark = ParameterizedBenchmark::new(
        "bloomfilter",
        |b, n| run_insert_many(setup_bloomfilter, b, *n),
        parameters,
    )
    .with_function("cuckoofilter", |b, n| {
        run_insert_many(setup_cuckoofilter, b, *n)
    })
    .with_function("hashset", |b, n| run_insert_many(setup_hashset, b, *n))
    .with_function("quotientfilter", |b, n| {
        run_insert_many(setup_quotientfilter, b, *n)
    })
    .sample_size(20);
    c.bench("insert_many", benchmark);
}

fn benchmarks_query_single(c: &mut Criterion) {
    let parameters = vec![4_000, 8_000];
    let benchmark = ParameterizedBenchmark::new(
        "bloomfilter",
        |b, n| run_query_single(setup_bloomfilter, b, *n),
        parameters,
    )
    .with_function("cuckoofilter", |b, n| {
        run_query_single(setup_cuckoofilter, b, *n)
    })
    .with_function("hashset", |b, n| run_query_single(setup_hashset, b, *n))
    .with_function("quotientfilter", |b, n| {
        run_query_single(setup_quotientfilter, b, *n)
    })
    .sample_size(20);
    c.bench("query_single", benchmark);
}

criterion_group!(
    benches,
    benchmarks_setup,
    benchmarks_insert_many,
    benchmarks_query_single,
);
criterion_main!(benches);
<|endoftext|>


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

use anyhow::Result;
use log::debug;

use crate::{
    analysis::{cfg, dis},
    aspace::AddressSpace,
    module::Module,
    RVA, VA,
};

#[derive(Default)]
pub struct CallGraph {
    // call instruction indexes...
    /// map from function start to the addresses that call here.
    /// lookup via `call_instruction_functions` to figure out the functions that
    /// call here.
    pub calls_to:   BTreeMap<VA, Vec<VA>>,
    /// map from an instruction to the addresses that it calls (usually one).
    pub calls_from: BTreeMap<VA, Vec<VA>>,

    // instruction membership indexes...
    /// map from function start to the instructions in its CFG that call
    /// elsewhere. lookup via `calls_to` to figoure out the functions that
    /// this function calls.
    pub function_call_instructions: BTreeMap<VA, Vec<VA>>,
    /// map from instruction to starts of functions whose CFGs contain the
    /// instruction (usually one).
    pub call_instruction_functions: BTreeMap<VA, Vec<VA>>,
}

pub fn build_call_graph(module: &Module, cfgs: &BTreeMap<VA, cfg::CFG>) -> Result<CallGraph> {
    debug!("call graph");

    let mut cg: CallGraph = Default::default();
    let decoder = dis::get_disassembler(module)?;

    for (&function, cfg) in cfgs.iter() {
        debug!("call graph: {:#x}", function);

        // ensure there are at least (empty) entries for all the keys in `functions`
        cg.function_call_instructions.entry(function).or_default();
        cg.calls_to.entry(function).or_default();

        for basic_block in cfg.basic_blocks.values() {
            let buf = module
                .address_space
                .read_bytes(basic_block.address, basic_block.length as usize)?;

            for (offset, insn) in dis::linear_disassemble(&decoder, &buf) {
                if let Ok(Some(insn)) = insn {
                    if matches!(insn.mnemonic, zydis::enums::Mnemonic::CALL) {
                        let va = basic_block.address + offset as RVA;
                        for flow in cfg::get_call_insn_flow(module, va, &insn)?.iter() {
                            if let cfg::Flow::Call(target) = *flow {
                                cg.calls_from.entry(va).or_default().push(target);
                                cg.calls_to.entry(target).or_default().push(va);
                                cg.function_call_instructions.entry(function).or_default().push(va);
                                cg.call_instruction_functions.entry(va).or_default().push(function);
                            }
                        }
                    }
                }
            }
        }
    }

    Ok(cg)
}

#[cfg(test)]
mod tests {
    use crate::{
        analysis::{call_graph, cfg::CFG, pe},
        rsrc::*,
        VA,
    };
    use anyhow::Result;
    use std::collections::BTreeMap;

    #[test]
    fn k32() -> Result<()> {
        let buf = get_buf(Rsrc::K32);
        let pe = crate::loader::pe::PE::from_bytes(&buf)?;

        let mut cfgs: BTreeMap<VA, CFG> = Default::default();
        for &function in pe::find_function_starts(&pe)?.iter() {
            if let Ok(cfg) = crate::analysis::cfg::build_cfg(&pe.module, function) {
                cfgs.insert(function, cfg);
            }
        }

        let cg = call_graph::build_call_graph(&pe.module, &cfgs)?;

        assert_eq!(cg.calls_to[&0x180001068].len(), 2);
        assert!(cg.calls_to[&0x180001068].iter().find(|&&v| v == 0x18000F775).is_some());
        assert!(cg.calls_to[&0x180001068].iter().find(|&&v| v == 0x180060504).is_some());
        assert!(cg.calls_from[&0x180060504]
            .iter()
            .find(|&&v| v == 0x180001068)
            .is_some());
        assert!(cg.call_instruction_functions[&0x180060504]
            .iter()
            .find(|&&v| v == 0x1800602C0)
            .is_some());
        assert!(cg.function_call_instructions[&0x1800602C0]
            .iter()
            .find(|&&v| v == 0x180060504)
            .is_some());

        Ok(())
    }
}
<commit_msg>analysis: call graph: add test for a couple functions in mimi<commit_after>use std::collections::BTreeMap;

use anyhow::Result;
use log::debug;

use crate::{
    analysis::{cfg, dis},
    aspace::AddressSpace,
    module::Module,
    RVA, VA,
};

#[derive(Default)]
pub struct CallGraph {
    // call instruction indexes...
    /// map from function start to the addresses that call here.
    /// lookup via `call_instruction_functions` to figure out the functions that
    /// call here.
    pub calls_to:   BTreeMap<VA, Vec<VA>>,
    /// map from an instruction to the addresses that it calls (usually one).
    pub calls_from: BTreeMap<VA, Vec<VA>>,

    // instruction membership indexes...
    /// map from function start to the instructions in its CFG that call
    /// elsewhere. lookup via `calls_to` to figoure out the functions that
    /// this function calls.
    pub function_call_instructions: BTreeMap<VA, Vec<VA>>,
    /// map from instruction to starts of functions whose CFGs contain the
    /// instruction (usually one).
    pub call_instruction_functions: BTreeMap<VA, Vec<VA>>,
}

pub fn build_call_graph(module: &Module, cfgs: &BTreeMap<VA, cfg::CFG>) -> Result<CallGraph> {
    debug!("call graph");

    let mut cg: CallGraph = Default::default();
    let decoder = dis::get_disassembler(module)?;

    for (&function, cfg) in cfgs.iter() {
        debug!("call graph: {:#x}", function);

        // ensure there are at least (empty) entries for all the keys in `functions`
        cg.function_call_instructions.entry(function).or_default();
        cg.calls_to.entry(function).or_default();

        for basic_block in cfg.basic_blocks.values() {
            let buf = module
                .address_space
                .read_bytes(basic_block.address, basic_block.length as usize)?;

            for (offset, insn) in dis::linear_disassemble(&decoder, &buf) {
                if let Ok(Some(insn)) = insn {
                    if matches!(insn.mnemonic, zydis::enums::Mnemonic::CALL) {
                        let va = basic_block.address + offset as RVA;
                        for flow in cfg::get_call_insn_flow(module, va, &insn)?.iter() {
                            if let cfg::Flow::Call(target) = *flow {
                                cg.calls_from.entry(va).or_default().push(target);
                                cg.calls_to.entry(target).or_default().push(va);
                                cg.function_call_instructions.entry(function).or_default().push(va);
                                cg.call_instruction_functions.entry(va).or_default().push(function);
                            }
                        }
                    }
                }
            }
        }
    }

    Ok(cg)
}

#[cfg(test)]
mod tests {
    use crate::{
        analysis::{call_graph, cfg::CFG, pe},
        rsrc::*,
        VA,
    };
    use anyhow::Result;
    use std::collections::BTreeMap;

    #[test]
    fn k32() -> Result<()> {
        let buf = get_buf(Rsrc::K32);
        let pe = crate::loader::pe::PE::from_bytes(&buf)?;

        let mut cfgs: BTreeMap<VA, CFG> = Default::default();
        for &function in pe::find_function_starts(&pe)?.iter() {
            if let Ok(cfg) = crate::analysis::cfg::build_cfg(&pe.module, function) {
                cfgs.insert(function, cfg);
            }
        }

        let cg = call_graph::build_call_graph(&pe.module, &cfgs)?;

        assert_eq!(cg.calls_to[&0x180001068].len(), 2);
        assert!(cg.calls_to[&0x180001068].iter().find(|&&v| v == 0x18000F775).is_some());
        assert!(cg.calls_to[&0x180001068].iter().find(|&&v| v == 0x180060504).is_some());
        assert!(cg.calls_from[&0x180060504]
            .iter()
            .find(|&&v| v == 0x180001068)
            .is_some());
        assert!(cg.call_instruction_functions[&0x180060504]
            .iter()
            .find(|&&v| v == 0x1800602C0)
            .is_some());
        assert!(cg.function_call_instructions[&0x1800602C0]
            .iter()
            .find(|&&v| v == 0x180060504)
            .is_some());

        Ok(())
    }

    #[test]
    fn mimi() -> Result<()> {
        let buf = get_buf(Rsrc::MIMI);
        let pe = crate::loader::pe::PE::from_bytes(&buf)?;

        let mut cfgs: BTreeMap<VA, CFG> = Default::default();
        for &function in pe::find_function_starts(&pe)?.iter() {
            if let Ok(cfg) = crate::analysis::cfg::build_cfg(&pe.module, function) {
                cfgs.insert(function, cfg);
            }
        }

        let cg = call_graph::build_call_graph(&pe.module, &cfgs)?;

        assert!(cg.function_call_instructions.get(&0x45CC62).is_some());
        assert!(cg.function_call_instructions.get(&0x45D028).is_some());
        assert!(cg.function_call_instructions.get(&0x45D16A).is_some());

        assert_eq!(cg.calls_to[&0x40B1F1].len(), 3);

        assert!(cg.calls_to[&0x40B1F1].iter().find(|&&v| v == 0x45CC9D).is_some());
        assert!(cg.calls_to[&0x40B1F1].iter().find(|&&v| v == 0x45D080).is_some());
        assert!(cg.calls_to[&0x40B1F1].iter().find(|&&v| v == 0x45D1B7).is_some());

        Ok(())
    }
}
<|endoftext|>


<commit_before>use dsl::Select;
use expression::Expression;
use query_dsl::methods::SelectDsl;
use super::delete_statement::DeleteStatement;
use super::insert_statement::{Insert, InsertOrIgnore, Replace};
use super::{IncompleteInsertStatement, IncompleteUpdateStatement, IntoUpdateTarget,
            SelectStatement, SqlQuery};

/// Creates an `UPDATE` statement.
///
/// When a table is passed to `update`, every row in the table will be updated.
/// You can narrow this scope by calling [`filter`] on the table before passing it in,
/// which will result in `UPDATE your_table SET ... WHERE args_to_filter`.
///
/// Passing a type which implements `Identifiable` is the same as passing
/// `some_table.find(some_struct.id())`.
///
/// [`filter`]: query_builder/update_statement/struct.IncompleteUpdateStatement.html#method.filter
///
/// # Examples
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// #
/// # #[cfg(feature = "postgres")]
/// # fn main() {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// let updated_row = diesel::update(users.filter(id.eq(1)))
///     .set(name.eq("James"))
///     .get_result(&connection);
/// // On backends that support it, you can call `get_result` instead of `execute`
/// // to have `RETURNING *` automatically appended to the query. Alternatively, you
/// // can explicitly return an expression by using the `returning` method before
/// // getting the result.
/// assert_eq!(Ok((1, "James".to_string())), updated_row);
/// # }
/// # #[cfg(not(feature = "postgres"))]
/// # fn main() {}
/// ```
///
/// To update multiple columns, give [`set`] a tuple argument:
///
/// [`set`]: query_builder/struct.IncompleteUpdateStatement.html#method.set
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// #
/// # table! {
/// #     users {
/// #         id -> Integer,
/// #         name -> VarChar,
/// #         surname -> VarChar,
/// #     }
/// # }
/// #
/// # #[cfg(feature = "postgres")]
/// # fn main() {
/// # use users::dsl::*;
/// # let connection = establish_connection();
/// # connection.execute("DROP TABLE users").unwrap();
/// # connection.execute("CREATE TABLE users (
/// #     id SERIAL PRIMARY KEY,
/// #     name VARCHAR,
/// #     surname VARCHAR)").unwrap();
/// # connection.execute("INSERT INTO users(name, surname) VALUES('Sean', 'Griffin')").unwrap();
///
/// let updated_row = diesel::update(users.filter(id.eq(1)))
///     .set((name.eq("James"), surname.eq("Bond")))
///     .get_result(&connection);
///
/// assert_eq!(Ok((1, "James".to_string(), "Bond".to_string())), updated_row);
/// # }
/// # #[cfg(not(feature = "postgres"))]
/// # fn main() {}
/// ```
pub fn update<T: IntoUpdateTarget>(
    source: T,
) -> IncompleteUpdateStatement<T::Table, T::WhereClause> {
    IncompleteUpdateStatement::new(source.into_update_target())
}

/// Creates a `DELETE` statement.
///
/// When a table is passed to `delete`,
/// every row in the table will be deleted.
/// This scope can be narrowed by calling [`filter`]
/// on the table before it is passed in.
///
/// [`filter`]: query_builder/struct.DeleteStatement.html#method.filter
///
/// # Examples
///
/// ### Deleting a single record:
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// #     delete();
/// # }
/// #
/// # fn delete() -> QueryResult<()> {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// #     let get_count = || users.count().first::<i64>(&connection);
/// let old_count = get_count();
/// try!(diesel::delete(users.filter(id.eq(1))).execute(&connection));
/// assert_eq!(old_count.map(|count| count - 1), get_count());
/// # Ok(())
/// # }
/// ```
///
/// ### Deleting a whole table:
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// #     delete();
/// # }
/// #
/// # fn delete() -> QueryResult<()> {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// #     let get_count = || users.count().first::<i64>(&connection);
/// try!(diesel::delete(users).execute(&connection));
/// assert_eq!(Ok(0), get_count());
/// # Ok(())
/// # }
/// ```
pub fn delete<T: IntoUpdateTarget>(source: T) -> DeleteStatement<T::Table, T::WhereClause> {
    let target = source.into_update_target();
    DeleteStatement::new(target.table, target.where_clause)
}

/// Creates an `INSERT` statement for the target table.
///
/// You may add data by calling [`values()`] or [`default_values()`]
/// as shown in the examples.
///
/// [`values()`]: query_builder/struct.IncompleteInsertStatement.html#method.values
/// [`default_values()`]: query_builder/struct.IncompleteInsertStatement.html#method.default_values
///
/// Backends that support the `RETURNING` clause, such as PostgreSQL,
/// can return the inserted rows by calling [`.get_results`] instead of [`.execute`].
///
/// [`.get_results`]: query_dsl/trait.RunQueryDsl.html#method.get_results
/// [`.execute`]: query_dsl/trait.RunQueryDsl.html#tymethod.execute
///
/// # Examples
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// let rows_inserted = diesel::insert_into(users)
///     .values(&name.eq("Sean"))
///     .execute(&connection);
///
/// assert_eq!(Ok(1), rows_inserted);
///
/// let new_users = vec![
///     name.eq("Tess"),
///     name.eq("Jim"),
/// ];
///
/// let rows_inserted = diesel::insert_into(users)
///     .values(&new_users)
///     .execute(&connection);
///
/// assert_eq!(Ok(2), rows_inserted);
/// # }
/// ```
///
/// ### Using a tuple for values
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// #     diesel::delete(users).execute(&connection).unwrap();
/// let new_user = (id.eq(1), name.eq("Sean"));
/// let rows_inserted = diesel::insert_into(users)
///     .values(&new_user)
///     .execute(&connection);
///
/// assert_eq!(Ok(1), rows_inserted);
///
/// let new_users = vec![
///     (id.eq(2), name.eq("Tess")),
///     (id.eq(2), name.eq("Jim")),
/// ];
///
/// let rows_inserted = diesel::insert_into(users)
///     .values(&new_users)
///     .execute(&connection);
///
/// // assert_eq!(Ok(2), rows_inserted);
/// # }
/// ```
///
/// ### Using struct for values
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// # use schema::users;
/// #
/// #[derive(Insertable)]
/// #[table_name = "users"]
/// struct NewUser<'a> {
///     name: &'a str,
/// }
///
/// # fn main() {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// // Insert one record at a time
///
/// let new_user = NewUser { name: "Ruby Rhod" };
///
/// diesel::insert_into(users)
///     .values(&new_user)
///     .execute(&connection)
///     .unwrap();
///
/// // Insert many records
///
/// let new_users = vec![
///     NewUser { name: "Leeloo Multipass", },
///     NewUser { name: "Korben Dallas", },
/// ];
///
/// let inserted_names = diesel::insert_into(users)
///     .values(&new_users)
///     .execute(&connection)
///     .unwrap();
/// # }
/// ```
///
/// ### With return value
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// #
/// # #[cfg(feature = "postgres")]
/// # fn main() {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// let inserted_names = diesel::insert_into(users)
///     .values(&vec![
///         name.eq("Diva Plavalaguna"),
///         name.eq("Father Vito Cornelius"),
///     ])
///     .returning(name)
///     .get_results(&connection);
/// assert_eq!(Ok(vec!["Diva Plavalaguna".to_string(), "Father Vito Cornelius".to_string()]), inserted_names);
/// # }
/// # #[cfg(not(feature = "postgres"))]
/// # fn main() {}
/// ```
pub fn insert_into<T>(target: T) -> IncompleteInsertStatement<T, Insert> {
    IncompleteInsertStatement::new(target, Insert)
}

/// Creates an `INSERT [OR] IGNORE` statement.
///
/// If a constraint violation fails, the database will ignore the offending
/// row and continue processing any subsequent rows. This function is only
/// available with MySQL and SQLite.
///
/// With PostgreSQL, similar functionality is provided by [`on_conflict_do_nothing`].
///
/// [`on_conflict_do_nothing`]: query_builder/insert_statement/struct.InsertStatement.html#method.on_conflict_do_nothing
///
/// # Example
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// #     run_test().unwrap();
/// # }
/// #
/// # #[cfg(not(feature = "postgres"))]
/// # fn run_test() -> QueryResult<()> {
/// #     use schema::users::dsl::*;
/// #     use diesel::{delete, insert_or_ignore_into};
/// #
/// #     let connection = establish_connection();
/// #     diesel::delete(users).execute(&connection)?;
/// insert_or_ignore_into(users)
///     .values((id.eq(1), name.eq("Jim")))
///     .execute(&connection)?;
///
/// insert_or_ignore_into(users)
///     .values(&vec![
///         (id.eq(1), name.eq("Sean")),
///         (id.eq(2), name.eq("Tess")),
///     ])
///     .execute(&connection)?;
///
/// let names = users.select(name).order(id).load::<String>(&connection)?;
/// assert_eq!(vec![String::from("Jim"), String::from("Tess")], names);
/// #     Ok(())
/// # }
/// #
/// # #[cfg(feature = "postgres")]
/// # fn run_test() -> QueryResult<()> {
/// #     Ok(())
/// # }
/// ```
pub fn insert_or_ignore_into<T>(target: T) -> IncompleteInsertStatement<T, InsertOrIgnore> {
    IncompleteInsertStatement::new(target, InsertOrIgnore)
}

/// Creates a bare select statement, with no from clause. Primarily used for
/// testing diesel itself, but likely useful for third party crates as well. The
/// given expressions must be selectable from anywhere.
pub fn select<T>(expression: T) -> Select<SelectStatement<()>, T>
where
    T: Expression,
    SelectStatement<()>: SelectDsl<T>,
{
    SelectStatement::simple(()).select(expression)
}

/// Creates a `REPLACE` statement.
///
/// If a constraint violation fails, the database will attempt to replace the
/// offending row instead. This function is only available with MySQL and
/// SQLite.
///
/// # Example
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// #
/// # #[cfg(not(feature = "postgres"))]
/// # fn main() {
/// #     use schema::users::dsl::*;
/// #     use diesel::{insert_into, replace_into};
/// #
/// #     let conn = establish_connection();
/// #     conn.execute("DELETE FROM users").unwrap();
/// replace_into(users)
///     .values(&vec![
///         (id.eq(1), name.eq("Sean")),
///         (id.eq(2), name.eq("Tess")),
///     ])
///     .execute(&conn)
///     .unwrap();
///
/// replace_into(users)
///     .values((id.eq(1), name.eq("Jim")))
///     .execute(&conn)
///     .unwrap();
///
/// let names = users.select(name).order(id).load::<String>(&conn);
/// assert_eq!(Ok(vec!["Jim".into(), "Tess".into()]), names);
/// # }
/// # #[cfg(feature = "postgres")] fn main() {}
pub fn replace_into<T>(target: T) -> IncompleteInsertStatement<T, Replace> {
    IncompleteInsertStatement::new(target, Replace)
}

/// Construct a full SQL query using raw SQL.
///
/// This function exists for cases where a query needs to be written that is not
/// supported by the query builder. Unlike most queries in Diesel, `sql_query`
/// will deserialize its data by name, not by index. That means that you cannot
/// deserialize into a tuple, and structs which you deserialize from this
/// function will need to have `#[derive(QueryableByName)]`
///
/// # Safety
///
/// The implementation of `QueryableByName` will assume that columns with a
/// given name will have a certain type. The compiler will be unable to verify
/// that the given type is correct. If your query returns a column of an
/// unexpected type, the result may have the wrong value, or return an error.
///
/// # Example
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// #
/// # use schema::users;
/// #
/// # #[derive(QueryableByName, Debug, PartialEq)]
/// # #[table_name="users"]
/// # struct User {
/// #     id: i32,
/// #     name: String,
/// # }
/// #
/// # fn main() {
/// #     use diesel::sql_query;
/// #
/// #     let connection = establish_connection();
/// let users = sql_query("SELECT * FROM users ORDER BY id")
///     .load(&connection);
/// let expected_users = vec![
///     User { id: 1, name: "Sean".into() },
///     User { id: 2, name: "Tess".into() },
/// ];
/// assert_eq!(Ok(expected_users), users);
/// # }
/// ```
pub fn sql_query<T: Into<String>>(query: T) -> SqlQuery {
    SqlQuery::new(query.into())
}
<commit_msg>Why was this commented out<commit_after>use dsl::Select;
use expression::Expression;
use query_dsl::methods::SelectDsl;
use super::delete_statement::DeleteStatement;
use super::insert_statement::{Insert, InsertOrIgnore, Replace};
use super::{IncompleteInsertStatement, IncompleteUpdateStatement, IntoUpdateTarget,
            SelectStatement, SqlQuery};

/// Creates an `UPDATE` statement.
///
/// When a table is passed to `update`, every row in the table will be updated.
/// You can narrow this scope by calling [`filter`] on the table before passing it in,
/// which will result in `UPDATE your_table SET ... WHERE args_to_filter`.
///
/// Passing a type which implements `Identifiable` is the same as passing
/// `some_table.find(some_struct.id())`.
///
/// [`filter`]: query_builder/update_statement/struct.IncompleteUpdateStatement.html#method.filter
///
/// # Examples
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// #
/// # #[cfg(feature = "postgres")]
/// # fn main() {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// let updated_row = diesel::update(users.filter(id.eq(1)))
///     .set(name.eq("James"))
///     .get_result(&connection);
/// // On backends that support it, you can call `get_result` instead of `execute`
/// // to have `RETURNING *` automatically appended to the query. Alternatively, you
/// // can explicitly return an expression by using the `returning` method before
/// // getting the result.
/// assert_eq!(Ok((1, "James".to_string())), updated_row);
/// # }
/// # #[cfg(not(feature = "postgres"))]
/// # fn main() {}
/// ```
///
/// To update multiple columns, give [`set`] a tuple argument:
///
/// [`set`]: query_builder/struct.IncompleteUpdateStatement.html#method.set
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// #
/// # table! {
/// #     users {
/// #         id -> Integer,
/// #         name -> VarChar,
/// #         surname -> VarChar,
/// #     }
/// # }
/// #
/// # #[cfg(feature = "postgres")]
/// # fn main() {
/// # use users::dsl::*;
/// # let connection = establish_connection();
/// # connection.execute("DROP TABLE users").unwrap();
/// # connection.execute("CREATE TABLE users (
/// #     id SERIAL PRIMARY KEY,
/// #     name VARCHAR,
/// #     surname VARCHAR)").unwrap();
/// # connection.execute("INSERT INTO users(name, surname) VALUES('Sean', 'Griffin')").unwrap();
///
/// let updated_row = diesel::update(users.filter(id.eq(1)))
///     .set((name.eq("James"), surname.eq("Bond")))
///     .get_result(&connection);
///
/// assert_eq!(Ok((1, "James".to_string(), "Bond".to_string())), updated_row);
/// # }
/// # #[cfg(not(feature = "postgres"))]
/// # fn main() {}
/// ```
pub fn update<T: IntoUpdateTarget>(
    source: T,
) -> IncompleteUpdateStatement<T::Table, T::WhereClause> {
    IncompleteUpdateStatement::new(source.into_update_target())
}

/// Creates a `DELETE` statement.
///
/// When a table is passed to `delete`,
/// every row in the table will be deleted.
/// This scope can be narrowed by calling [`filter`]
/// on the table before it is passed in.
///
/// [`filter`]: query_builder/struct.DeleteStatement.html#method.filter
///
/// # Examples
///
/// ### Deleting a single record:
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// #     delete();
/// # }
/// #
/// # fn delete() -> QueryResult<()> {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// #     let get_count = || users.count().first::<i64>(&connection);
/// let old_count = get_count();
/// try!(diesel::delete(users.filter(id.eq(1))).execute(&connection));
/// assert_eq!(old_count.map(|count| count - 1), get_count());
/// # Ok(())
/// # }
/// ```
///
/// ### Deleting a whole table:
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// #     delete();
/// # }
/// #
/// # fn delete() -> QueryResult<()> {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// #     let get_count = || users.count().first::<i64>(&connection);
/// try!(diesel::delete(users).execute(&connection));
/// assert_eq!(Ok(0), get_count());
/// # Ok(())
/// # }
/// ```
pub fn delete<T: IntoUpdateTarget>(source: T) -> DeleteStatement<T::Table, T::WhereClause> {
    let target = source.into_update_target();
    DeleteStatement::new(target.table, target.where_clause)
}

/// Creates an `INSERT` statement for the target table.
///
/// You may add data by calling [`values()`] or [`default_values()`]
/// as shown in the examples.
///
/// [`values()`]: query_builder/struct.IncompleteInsertStatement.html#method.values
/// [`default_values()`]: query_builder/struct.IncompleteInsertStatement.html#method.default_values
///
/// Backends that support the `RETURNING` clause, such as PostgreSQL,
/// can return the inserted rows by calling [`.get_results`] instead of [`.execute`].
///
/// [`.get_results`]: query_dsl/trait.RunQueryDsl.html#method.get_results
/// [`.execute`]: query_dsl/trait.RunQueryDsl.html#tymethod.execute
///
/// # Examples
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// let rows_inserted = diesel::insert_into(users)
///     .values(&name.eq("Sean"))
///     .execute(&connection);
///
/// assert_eq!(Ok(1), rows_inserted);
///
/// let new_users = vec![
///     name.eq("Tess"),
///     name.eq("Jim"),
/// ];
///
/// let rows_inserted = diesel::insert_into(users)
///     .values(&new_users)
///     .execute(&connection);
///
/// assert_eq!(Ok(2), rows_inserted);
/// # }
/// ```
///
/// ### Using a tuple for values
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// #     diesel::delete(users).execute(&connection).unwrap();
/// let new_user = (id.eq(1), name.eq("Sean"));
/// let rows_inserted = diesel::insert_into(users)
///     .values(&new_user)
///     .execute(&connection);
///
/// assert_eq!(Ok(1), rows_inserted);
///
/// let new_users = vec![
///     (id.eq(2), name.eq("Tess")),
///     (id.eq(3), name.eq("Jim")),
/// ];
///
/// let rows_inserted = diesel::insert_into(users)
///     .values(&new_users)
///     .execute(&connection);
///
/// assert_eq!(Ok(2), rows_inserted);
/// # }
/// ```
///
/// ### Using struct for values
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// # use schema::users;
/// #
/// #[derive(Insertable)]
/// #[table_name = "users"]
/// struct NewUser<'a> {
///     name: &'a str,
/// }
///
/// # fn main() {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// // Insert one record at a time
///
/// let new_user = NewUser { name: "Ruby Rhod" };
///
/// diesel::insert_into(users)
///     .values(&new_user)
///     .execute(&connection)
///     .unwrap();
///
/// // Insert many records
///
/// let new_users = vec![
///     NewUser { name: "Leeloo Multipass", },
///     NewUser { name: "Korben Dallas", },
/// ];
///
/// let inserted_names = diesel::insert_into(users)
///     .values(&new_users)
///     .execute(&connection)
///     .unwrap();
/// # }
/// ```
///
/// ### With return value
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// #
/// # #[cfg(feature = "postgres")]
/// # fn main() {
/// #     use schema::users::dsl::*;
/// #     let connection = establish_connection();
/// let inserted_names = diesel::insert_into(users)
///     .values(&vec![
///         name.eq("Diva Plavalaguna"),
///         name.eq("Father Vito Cornelius"),
///     ])
///     .returning(name)
///     .get_results(&connection);
/// assert_eq!(Ok(vec!["Diva Plavalaguna".to_string(), "Father Vito Cornelius".to_string()]), inserted_names);
/// # }
/// # #[cfg(not(feature = "postgres"))]
/// # fn main() {}
/// ```
pub fn insert_into<T>(target: T) -> IncompleteInsertStatement<T, Insert> {
    IncompleteInsertStatement::new(target, Insert)
}

/// Creates an `INSERT [OR] IGNORE` statement.
///
/// If a constraint violation fails, the database will ignore the offending
/// row and continue processing any subsequent rows. This function is only
/// available with MySQL and SQLite.
///
/// With PostgreSQL, similar functionality is provided by [`on_conflict_do_nothing`].
///
/// [`on_conflict_do_nothing`]: query_builder/insert_statement/struct.InsertStatement.html#method.on_conflict_do_nothing
///
/// # Example
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// #
/// # fn main() {
/// #     run_test().unwrap();
/// # }
/// #
/// # #[cfg(not(feature = "postgres"))]
/// # fn run_test() -> QueryResult<()> {
/// #     use schema::users::dsl::*;
/// #     use diesel::{delete, insert_or_ignore_into};
/// #
/// #     let connection = establish_connection();
/// #     diesel::delete(users).execute(&connection)?;
/// insert_or_ignore_into(users)
///     .values((id.eq(1), name.eq("Jim")))
///     .execute(&connection)?;
///
/// insert_or_ignore_into(users)
///     .values(&vec![
///         (id.eq(1), name.eq("Sean")),
///         (id.eq(2), name.eq("Tess")),
///     ])
///     .execute(&connection)?;
///
/// let names = users.select(name).order(id).load::<String>(&connection)?;
/// assert_eq!(vec![String::from("Jim"), String::from("Tess")], names);
/// #     Ok(())
/// # }
/// #
/// # #[cfg(feature = "postgres")]
/// # fn run_test() -> QueryResult<()> {
/// #     Ok(())
/// # }
/// ```
pub fn insert_or_ignore_into<T>(target: T) -> IncompleteInsertStatement<T, InsertOrIgnore> {
    IncompleteInsertStatement::new(target, InsertOrIgnore)
}

/// Creates a bare select statement, with no from clause. Primarily used for
/// testing diesel itself, but likely useful for third party crates as well. The
/// given expressions must be selectable from anywhere.
pub fn select<T>(expression: T) -> Select<SelectStatement<()>, T>
where
    T: Expression,
    SelectStatement<()>: SelectDsl<T>,
{
    SelectStatement::simple(()).select(expression)
}

/// Creates a `REPLACE` statement.
///
/// If a constraint violation fails, the database will attempt to replace the
/// offending row instead. This function is only available with MySQL and
/// SQLite.
///
/// # Example
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// #
/// # #[cfg(not(feature = "postgres"))]
/// # fn main() {
/// #     use schema::users::dsl::*;
/// #     use diesel::{insert_into, replace_into};
/// #
/// #     let conn = establish_connection();
/// #     conn.execute("DELETE FROM users").unwrap();
/// replace_into(users)
///     .values(&vec![
///         (id.eq(1), name.eq("Sean")),
///         (id.eq(2), name.eq("Tess")),
///     ])
///     .execute(&conn)
///     .unwrap();
///
/// replace_into(users)
///     .values((id.eq(1), name.eq("Jim")))
///     .execute(&conn)
///     .unwrap();
///
/// let names = users.select(name).order(id).load::<String>(&conn);
/// assert_eq!(Ok(vec!["Jim".into(), "Tess".into()]), names);
/// # }
/// # #[cfg(feature = "postgres")] fn main() {}
pub fn replace_into<T>(target: T) -> IncompleteInsertStatement<T, Replace> {
    IncompleteInsertStatement::new(target, Replace)
}

/// Construct a full SQL query using raw SQL.
///
/// This function exists for cases where a query needs to be written that is not
/// supported by the query builder. Unlike most queries in Diesel, `sql_query`
/// will deserialize its data by name, not by index. That means that you cannot
/// deserialize into a tuple, and structs which you deserialize from this
/// function will need to have `#[derive(QueryableByName)]`
///
/// # Safety
///
/// The implementation of `QueryableByName` will assume that columns with a
/// given name will have a certain type. The compiler will be unable to verify
/// that the given type is correct. If your query returns a column of an
/// unexpected type, the result may have the wrong value, or return an error.
///
/// # Example
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("../doctest_setup.rs");
/// #
/// # use schema::users;
/// #
/// # #[derive(QueryableByName, Debug, PartialEq)]
/// # #[table_name="users"]
/// # struct User {
/// #     id: i32,
/// #     name: String,
/// # }
/// #
/// # fn main() {
/// #     use diesel::sql_query;
/// #
/// #     let connection = establish_connection();
/// let users = sql_query("SELECT * FROM users ORDER BY id")
///     .load(&connection);
/// let expected_users = vec![
///     User { id: 1, name: "Sean".into() },
///     User { id: 2, name: "Tess".into() },
/// ];
/// assert_eq!(Ok(expected_users), users);
/// # }
/// ```
pub fn sql_query<T: Into<String>>(query: T) -> SqlQuery {
    SqlQuery::new(query.into())
}
<|endoftext|>


<commit_before>// Testing the display of Mutex and MutexGuard in cdb.

// cdb-only
// min-cdb-version: 10.0.21287.1005
// compile-flags:-g
// FIXME: Failed on update to 10.0.22000.1
// ignore-windows

// === CDB TESTS ==================================================================================
//
// cdb-command:g
//
// cdb-command:dx m,d
// cdb-check:m,d              [Type: std::sync::mutex::Mutex<i32>]
// cdb-check:    [...] inner            [Type: std::sys_common::mutex::MovableMutex]
// cdb-check:    [...] poison           [Type: std::sync::poison::Flag]
// cdb-check:    [...] data             [Type: core::cell::UnsafeCell<i32>]

//
// cdb-command:dx m.data,d
// cdb-check:m.data,d         [Type: core::cell::UnsafeCell<i32>]
// cdb-check:    [...] value            : 0 [Type: int]

//
// cdb-command:dx lock,d
// cdb-check:lock,d           : Ok [Type: enum$<core::result::Result<std::sync::mutex::MutexGuard<i32>, enum$<std::sync::poison::TryLockError<std::sync::mutex::MutexGuard<i32> >, 0, 1, Poisoned> > >]
// cdb-check:    [...] variant$         : Ok (0) [Type: core::result::Result]
// cdb-check:    [...] __0              [Type: std::sync::mutex::MutexGuard<i32>]

use std::sync::Mutex;

#[allow(unused_variables)]
fn main()
{
    let m = Mutex::new(0);
    let lock = m.try_lock();
    zzz(); // #break
}

fn zzz() {}
<commit_msg>Rollup merge of #89127 - wesleywiser:reenable_mutex_debuginfo_test, r=ehuss<commit_after>// Testing the display of Mutex and MutexGuard in cdb.

// cdb-only
// min-cdb-version: 10.0.21287.1005
// compile-flags:-g

// === CDB TESTS ==================================================================================
//
// cdb-command:g
//
// cdb-command:dx m,d
// cdb-check:m,d              [Type: std::sync::mutex::Mutex<i32>]
// cdb-check:    [...] inner            [Type: std::sys_common::mutex::MovableMutex]
// cdb-check:    [...] poison           [Type: std::sync::poison::Flag]
// cdb-check:    [...] data             : 0 [Type: core::cell::UnsafeCell<i32>]

//
// cdb-command:dx m.data,d
// cdb-check:m.data,d         : 0 [Type: core::cell::UnsafeCell<i32>]
// cdb-check:    [<Raw View>]     [Type: core::cell::UnsafeCell<i32>]

//
// cdb-command:dx lock,d
// cdb-check:lock,d           : Ok [Type: enum$<core::result::Result<std::sync::mutex::MutexGuard<i32>,enum$<std::sync::poison::TryLockError<std::sync::mutex::MutexGuard<i32> >, 0, 1, Poisoned> > >]
// cdb-check:    [variant]        : Ok
// cdb-check:    [...] __0              [Type: std::sync::mutex::MutexGuard<i32>]

use std::sync::Mutex;

#[allow(unused_variables)]
fn main()
{
    let m = Mutex::new(0);
    let lock = m.try_lock();
    zzz(); // #break
}

fn zzz() {}
<|endoftext|>


<commit_before>
/// Should be implemented by contexts that have rectangle information.
pub trait RelativeRectangle<'a> {
    /// Shrinks the current rectangle equally by all sides.
    fn margin(&'a self, m: f64) -> Self;

    /// Expands the current rectangle equally by all sides.
    #[inline(always)]
    fn expand(&'a self, m: f64) -> Self {
        self.margin(-m)
    }

    /// Moves to a relative rectangle using the current rectangle as tile.
    fn rel(&'a self, x: f64, y: f64) -> Self;

    /// Moves to the above rectangle using the current rectangle as tile.
    #[inline(always)]
    fn up(&'a self) -> Self {
        self.rel(0.0, 1.0)
    }
}

<commit_msg>Added `left`<commit_after>
/// Should be implemented by contexts that have rectangle information.
pub trait RelativeRectangle<'a> {
    /// Shrinks the current rectangle equally by all sides.
    fn margin(&'a self, m: f64) -> Self;

    /// Expands the current rectangle equally by all sides.
    #[inline(always)]
    fn expand(&'a self, m: f64) -> Self {
        self.margin(-m)
    }

    /// Moves to a relative rectangle using the current rectangle as tile.
    fn rel(&'a self, x: f64, y: f64) -> Self;

    /// Moves to the above rectangle using the current rectangle as tile.
    #[inline(always)]
    fn up(&'a self) -> Self {
        self.rel(0.0, 1.0)
    }

    /// Moves to the left rectangle using the current rectangle as tile.
    #[inline(always)]
    fn left(&'a self) -> Self {
        self.rel(-1.0, 0.0)
    }
}

<|endoftext|>


<commit_before>use ra_text_edit::AtomTextEdit;
use ra_syntax::{TextUnit, TextRange};
use crate::{LineIndex, LineCol};
use superslice::Ext;

#[derive(Debug)]
struct OffsetNewlineIter<'a> {
    text: &'a str,
    offset: TextUnit,
}

impl<'a> Iterator for OffsetNewlineIter<'a> {
    type Item = TextUnit;
    fn next(&mut self) -> Option<TextUnit> {
        let next_idx = self
            .text
            .char_indices()
            .filter_map(|(i, c)| if c == '\n' { Some(i + 1) } else { None })
            .next()?;
        let next = self.offset + TextUnit::from_usize(next_idx);
        self.text = &self.text[next_idx..];
        self.offset = next;
        Some(next)
    }
}

#[derive(Debug)]
enum NextNewlines<'a> {
    Use,
    ReplaceMany(OffsetNewlineIter<'a>),
    AddMany(OffsetNewlineIter<'a>),
}

#[derive(Debug)]
struct TranslatedEdit<'a> {
    delete: TextRange,
    insert: &'a str,
    diff: i64,
}

struct Edits<'a, 'b> {
    edits: &'b [&'a AtomTextEdit],
    current: Option<TranslatedEdit<'a>>,
    acc_diff: i64,
}

impl<'a, 'b> Edits<'a, 'b> {
    fn new(sorted_edits: &'b [&'a AtomTextEdit]) -> Edits<'a, 'b> {
        let mut x = Edits {
            edits: sorted_edits,
            current: None,
            acc_diff: 0,
        };
        x.advance_edit();
        x
    }
    fn advance_edit(&mut self) {
        self.acc_diff += self.current.as_ref().map_or(0, |x| x.diff);
        match self.edits.split_first() {
            Some((next, rest)) => {
                let delete = self.translate_range(next.delete);
                let diff = next.insert.len() as i64 - next.delete.len().to_usize() as i64;
                self.current = Some(TranslatedEdit {
                    delete,
                    insert: &next.insert,
                    diff,
                });
                self.edits = rest;
            }
            None => {
                self.current = None;
            }
        }
    }

    fn next_inserted_newlines(&mut self) -> Option<OffsetNewlineIter<'a>> {
        let cur = self.current.as_ref()?;
        let res = Some(OffsetNewlineIter {
            offset: cur.delete.start(),
            text: &cur.insert,
        });
        self.advance_edit();
        res
    }

    fn next_newlines(&mut self, candidate: TextUnit) -> NextNewlines {
        let res = match &mut self.current {
            Some(edit) => {
                if candidate <= edit.delete.start() {
                    NextNewlines::Use
                } else if candidate <= edit.delete.end() {
                    let iter = OffsetNewlineIter {
                        offset: edit.delete.start(),
                        text: &edit.insert,
                    };
                    // empty slice
                    edit.insert = &edit.insert[edit.insert.len()..];
                    NextNewlines::ReplaceMany(iter)
                } else {
                    let iter = OffsetNewlineIter {
                        offset: edit.delete.start(),
                        text: &edit.insert,
                    };
                    // empty slice
                    edit.insert = &edit.insert[edit.insert.len()..];
                    self.advance_edit();
                    NextNewlines::AddMany(iter)
                }
            }
            None => NextNewlines::Use,
        };
        res
    }

    fn translate_range(&self, range: TextRange) -> TextRange {
        if self.acc_diff == 0 {
            range
        } else {
            let start = self.translate(range.start());
            let end = self.translate(range.end());
            TextRange::from_to(start, end)
        }
    }

    fn translate(&self, x: TextUnit) -> TextUnit {
        if self.acc_diff == 0 {
            x
        } else {
            TextUnit::from((x.to_usize() as i64 + self.acc_diff) as u32)
        }
    }
}

pub fn count_newlines(offset: TextUnit, line_index: &LineIndex, edits: &[AtomTextEdit]) -> u32 {
    let mut sorted_edits: Vec<&AtomTextEdit> = Vec::with_capacity(edits.len());
    for edit in edits {
        let insert_index =
            sorted_edits.upper_bound_by_key(&edit.delete.start(), |x| x.delete.start());
        sorted_edits.insert(insert_index, &edit);
    }

    let mut state = Edits::new(&sorted_edits);

    let mut lines: u32 = 0;

    for &orig_newline in line_index.newlines() {
        loop {
            let translated_newline = state.translate(orig_newline);
            match state.next_newlines(translated_newline) {
                NextNewlines::Use => {
                    if offset < translated_newline {
                        return lines;
                    } else {
                        lines += 1;
                    }
                    break;
                }
                NextNewlines::ReplaceMany(ns) => {
                    for n in ns {
                        if offset < n {
                            return lines;
                        } else {
                            lines += 1;
                        }
                    }
                    break;
                }
                NextNewlines::AddMany(ns) => {
                    for n in ns {
                        if offset < n {
                            return lines;
                        } else {
                            lines += 1;
                        }
                    }
                }
            }
        }
    }

    loop {
        match state.next_inserted_newlines() {
            None => break,
            Some(ns) => {
                for n in ns {
                    if offset < n {
                        return lines;
                    } else {
                        lines += 1;
                    }
                }
            }
        }
    }

    lines
}

// for bench
pub fn translate_after_edit(
    pre_edit_text: &str,
    offset: TextUnit,
    edits: Vec<AtomTextEdit>,
) -> LineCol {
    let text = edit_text(pre_edit_text, edits);
    let line_index = LineIndex::new(&text);
    line_index.line_col(offset)
}

fn edit_text(pre_edit_text: &str, mut edits: Vec<AtomTextEdit>) -> String {
    // apply edits ordered from last to first
    // since they should not overlap we can just use start()
    edits.sort_by_key(|x| -(x.delete.start().to_usize() as isize));

    let mut text = pre_edit_text.to_owned();

    for edit in &edits {
        let range = edit.delete.start().to_usize()..edit.delete.end().to_usize();
        text.replace_range(range, &edit.insert);
    }

    text
}

#[cfg(test)]
mod test {
    use proptest::{prelude::*, proptest, proptest_helper};
    use super::*;
    use ra_text_edit::test_utils::{arb_text, arb_offset, arb_edits};

    #[derive(Debug)]
    struct ArbTextWithOffsetAndEdits {
        text: String,
        offset: TextUnit,
        edits: Vec<AtomTextEdit>,
    }

    fn arb_text_with_offset_and_edits() -> BoxedStrategy<ArbTextWithOffsetAndEdits> {
        arb_text()
            .prop_flat_map(|text| {
                (arb_offset(&text), arb_edits(&text), Just(text)).prop_map(
                    |(offset, edits, text)| ArbTextWithOffsetAndEdits {
                        text,
                        offset,
                        edits,
                    },
                )
            })
            .boxed()
    }

    proptest! {
        #[test]
        fn test_translate_offset_with_edit(x in arb_text_with_offset_and_edits()) {
            let line_index = LineIndex::new(&x.text);
            let expected = translate_after_edit(&x.text, x.offset, x.edits.clone());
            let actual_lines = count_newlines(x.offset, &line_index, &x.edits);
            assert_eq!(actual_lines, expected.line);
        }
    }
}
<commit_msg>simplify newline check with macro<commit_after>use ra_text_edit::AtomTextEdit;
use ra_syntax::{TextUnit, TextRange};
use crate::{LineIndex, LineCol};
use superslice::Ext;

#[derive(Debug)]
struct OffsetNewlineIter<'a> {
    text: &'a str,
    offset: TextUnit,
}

impl<'a> Iterator for OffsetNewlineIter<'a> {
    type Item = TextUnit;
    fn next(&mut self) -> Option<TextUnit> {
        let next_idx = self
            .text
            .char_indices()
            .filter_map(|(i, c)| if c == '\n' { Some(i + 1) } else { None })
            .next()?;
        let next = self.offset + TextUnit::from_usize(next_idx);
        self.text = &self.text[next_idx..];
        self.offset = next;
        Some(next)
    }
}

#[derive(Debug)]
enum NextNewlines<'a> {
    Use,
    ReplaceMany(OffsetNewlineIter<'a>),
    AddMany(OffsetNewlineIter<'a>),
}

#[derive(Debug)]
struct TranslatedEdit<'a> {
    delete: TextRange,
    insert: &'a str,
    diff: i64,
}

struct Edits<'a, 'b> {
    edits: &'b [&'a AtomTextEdit],
    current: Option<TranslatedEdit<'a>>,
    acc_diff: i64,
}

impl<'a, 'b> Edits<'a, 'b> {
    fn new(sorted_edits: &'b [&'a AtomTextEdit]) -> Edits<'a, 'b> {
        let mut x = Edits {
            edits: sorted_edits,
            current: None,
            acc_diff: 0,
        };
        x.advance_edit();
        x
    }
    fn advance_edit(&mut self) {
        self.acc_diff += self.current.as_ref().map_or(0, |x| x.diff);
        match self.edits.split_first() {
            Some((next, rest)) => {
                let delete = self.translate_range(next.delete);
                let diff = next.insert.len() as i64 - next.delete.len().to_usize() as i64;
                self.current = Some(TranslatedEdit {
                    delete,
                    insert: &next.insert,
                    diff,
                });
                self.edits = rest;
            }
            None => {
                self.current = None;
            }
        }
    }

    fn next_inserted_newlines(&mut self) -> Option<OffsetNewlineIter<'a>> {
        let cur = self.current.as_ref()?;
        let res = Some(OffsetNewlineIter {
            offset: cur.delete.start(),
            text: &cur.insert,
        });
        self.advance_edit();
        res
    }

    fn next_newlines(&mut self, candidate: TextUnit) -> NextNewlines {
        let res = match &mut self.current {
            Some(edit) => {
                if candidate <= edit.delete.start() {
                    NextNewlines::Use
                } else if candidate <= edit.delete.end() {
                    let iter = OffsetNewlineIter {
                        offset: edit.delete.start(),
                        text: &edit.insert,
                    };
                    // empty slice
                    edit.insert = &edit.insert[edit.insert.len()..];
                    NextNewlines::ReplaceMany(iter)
                } else {
                    let iter = OffsetNewlineIter {
                        offset: edit.delete.start(),
                        text: &edit.insert,
                    };
                    // empty slice
                    edit.insert = &edit.insert[edit.insert.len()..];
                    self.advance_edit();
                    NextNewlines::AddMany(iter)
                }
            }
            None => NextNewlines::Use,
        };
        res
    }

    fn translate_range(&self, range: TextRange) -> TextRange {
        if self.acc_diff == 0 {
            range
        } else {
            let start = self.translate(range.start());
            let end = self.translate(range.end());
            TextRange::from_to(start, end)
        }
    }

    fn translate(&self, x: TextUnit) -> TextUnit {
        if self.acc_diff == 0 {
            x
        } else {
            TextUnit::from((x.to_usize() as i64 + self.acc_diff) as u32)
        }
    }
}

pub fn count_newlines(offset: TextUnit, line_index: &LineIndex, edits: &[AtomTextEdit]) -> u32 {
    let mut sorted_edits: Vec<&AtomTextEdit> = Vec::with_capacity(edits.len());
    for edit in edits {
        let insert_index =
            sorted_edits.upper_bound_by_key(&edit.delete.start(), |x| x.delete.start());
        sorted_edits.insert(insert_index, &edit);
    }

    let mut state = Edits::new(&sorted_edits);

    let mut lines: u32 = 0;

    macro_rules! test_newline {
        ($x:ident) => {
            if offset < $x {
                return lines;
            } else {
                lines += 1;
            }
        };
    }

    for &orig_newline in line_index.newlines() {
        loop {
            let translated_newline = state.translate(orig_newline);
            match state.next_newlines(translated_newline) {
                NextNewlines::Use => {
                    test_newline!(translated_newline);
                    break;
                }
                NextNewlines::ReplaceMany(ns) => {
                    for n in ns {
                        test_newline!(n);
                    }
                    break;
                }
                NextNewlines::AddMany(ns) => {
                    for n in ns {
                        test_newline!(n);
                    }
                }
            }
        }
    }

    loop {
        match state.next_inserted_newlines() {
            None => break,
            Some(ns) => {
                for n in ns {
                    test_newline!(n);
                }
            }
        }
    }

    lines
}

// for bench
pub fn translate_after_edit(
    pre_edit_text: &str,
    offset: TextUnit,
    edits: Vec<AtomTextEdit>,
) -> LineCol {
    let text = edit_text(pre_edit_text, edits);
    let line_index = LineIndex::new(&text);
    line_index.line_col(offset)
}

fn edit_text(pre_edit_text: &str, mut edits: Vec<AtomTextEdit>) -> String {
    // apply edits ordered from last to first
    // since they should not overlap we can just use start()
    edits.sort_by_key(|x| -(x.delete.start().to_usize() as isize));

    let mut text = pre_edit_text.to_owned();

    for edit in &edits {
        let range = edit.delete.start().to_usize()..edit.delete.end().to_usize();
        text.replace_range(range, &edit.insert);
    }

    text
}

#[cfg(test)]
mod test {
    use proptest::{prelude::*, proptest, proptest_helper};
    use super::*;
    use ra_text_edit::test_utils::{arb_text, arb_offset, arb_edits};

    #[derive(Debug)]
    struct ArbTextWithOffsetAndEdits {
        text: String,
        offset: TextUnit,
        edits: Vec<AtomTextEdit>,
    }

    fn arb_text_with_offset_and_edits() -> BoxedStrategy<ArbTextWithOffsetAndEdits> {
        arb_text()
            .prop_flat_map(|text| {
                (arb_offset(&text), arb_edits(&text), Just(text)).prop_map(
                    |(offset, edits, text)| ArbTextWithOffsetAndEdits {
                        text,
                        offset,
                        edits,
                    },
                )
            })
            .boxed()
    }

    proptest! {
        #[test]
        fn test_translate_offset_with_edit(x in arb_text_with_offset_and_edits()) {
            let line_index = LineIndex::new(&x.text);
            let expected = translate_after_edit(&x.text, x.offset, x.edits.clone());
            let actual_lines = count_newlines(x.offset, &line_index, &x.edits);
            assert_eq!(actual_lines, expected.line);
        }
    }
}
<|endoftext|>


<commit_before>pub struct Brackets {
    ok: bool,
    brack: i64,
    brace: i64,
    paren: i64,
    seen: Vec<char>,
}

impl Default for Brackets {
    fn default() -> Self {
        Brackets {
            ok: true,
            brack: 0,
            brace: 0,
            paren: 0,
            seen: Vec::new(),
        }
    }
}

impl<'a> From<&'a str> for Brackets {
    fn from(input: &str) -> Self {
        let mut b = Brackets::default();
        for c in input.chars() {
            match c {
                '[' => {
                    b.brack += 1;
                    b.seen.push('[');
                }
                ']' => {
                    b.brack -= 1;
                    b.ok = b.seen.pop().map_or(false, |x| x == '[');
                }
                '{' => {
                    b.brace += 1;
                    b.seen.push('{');
                }
                '}' => {
                    b.brace -= 1;
                    b.ok = b.seen.pop().map_or(false, |x| x == '{');
                }
                '(' => {
                    b.paren += 1;
                    b.seen.push('(');
                }
                ')' => {
                    b.paren -= 1;
                    b.ok = b.seen.pop().map_or(false, |x| x == '(');
                }
                _ => (),
            }
        }
        b
    }
}

impl Brackets {
    pub fn are_balanced(&self) -> bool {
        self.ok && self.brack == 0 && self.brace == 0 && self.paren == 0
    }
}
<commit_msg>fixed with suggestions from mentor<commit_after>pub struct Brackets {
    ok: bool,
    seen: Vec<char>,
}

impl Default for Brackets {
    fn default() -> Self {
        Brackets {
            ok: true,
            seen: Vec::new(),
        }
    }
}

impl<'a> From<&'a str> for Brackets {
    fn from(input: &str) -> Self {
        let mut b = Brackets::default();
        for c in input.chars() {
            match c {
                '[' | '{' | '(' => b.seen.push(c),
                ']' | '}' | ')' => b.pop_and_pair(c),
                _ => (),
            }
            if !b.ok {
                break;
            }
        }
        b.ok &= b.seen.is_empty();
        b
    }
}

impl Brackets {
    pub fn are_balanced(&self) -> bool {
        self.ok
    }
    fn pop_and_pair(&mut self, c: char) {
        self.ok = self.seen.pop().map_or(false, |x| match c {
            ']' => x == '[',
            '}' => x == '{',
            ')' => x == '(',
            _ => panic!("Not a bracket pair character"),
        });
    }
}
<|endoftext|>


<commit_before>use std::rc::Rc;
use glium::{self, DrawParameters, IndexBuffer, Program, VertexBuffer};
use glium::index::PrimitiveType;
use GameContext;
use Camera;
use glium::draw_parameters::DepthTest;
use util::ToArr;
use base::math::*;

pub struct Sun {
    vertex_buffer: VertexBuffer<Vertex>,
    index_buffer: IndexBuffer<u32>,
    program: Program,
    position: Vector3f,
    context: Rc<GameContext>,
}

impl Sun {
    pub fn new(context: Rc<GameContext>) -> Self {
        const SUN_SIZE: f32 = 35.0;
        const SUN_POS: f32 = 300.0;
        let raw_vertex_buffer = vec![
            Vertex { i_position: [SUN_SIZE, SUN_SIZE, SUN_POS], i_unit_coords: [1.0, 1.0, 0.0]},
            Vertex { i_position: [-SUN_SIZE, -SUN_SIZE, SUN_POS], i_unit_coords: [-1.0, -1.0, 0.0]},
            Vertex { i_position: [-SUN_SIZE, SUN_SIZE, SUN_POS], i_unit_coords: [-1.0, 1.0, 0.0]},
            Vertex { i_position: [SUN_SIZE, -SUN_SIZE, SUN_POS], i_unit_coords: [1.0, -1.0, 0.0]},
];

        let vbuf = VertexBuffer::new(context.get_facade(), &raw_vertex_buffer).unwrap();

        let raw_index_buffer = [2, 1, 0, 3]; //TrianglesStrip

        let ibuf = IndexBuffer::new(context.get_facade(),
                                    PrimitiveType::TriangleStrip,
                                    &raw_index_buffer)
            .unwrap();

        let prog = Program::from_source(context.get_facade(),
                                        include_str!("sun.vert"),
                                        include_str!("sun.frag"),
                                        None)
            .unwrap();

        Sun {
            vertex_buffer: vbuf,
            index_buffer: ibuf,
            program: prog,
            position: Vector3f::new(0.0, 0.0, 0.0),
            context: context,
        }
    }

    pub fn draw_sun<S: glium::Surface>(&self, surface: &mut S, camera: &Camera) {

        let pos = Point3::new(0.0, 0.0, 0.0);

        let view_matrix =
            Matrix4::look_at(pos, pos + camera.get_look_at_vector(), Vector3::unit_z());

        let uniforms = uniform! {
            u_proj_matrix: camera.proj_matrix().to_arr(),
            u_view_matrix: view_matrix.to_arr(),
        };
        let params = DrawParameters {
            depth: glium::Depth {
                write: false,
                test: DepthTest::IfLess,
                ..Default::default()
            },
            ..Default::default()
        };

        surface.draw(&self.vertex_buffer,
                  &self.index_buffer,
                  &self.program,
                  &uniforms,
                  &params)
            .unwrap();
    }

    pub fn update(&mut self, pos: Vector3f) {

        const SUN_SIZE: f32 = 35.0;
        self.position = pos;
        let raw_vertex_buffer = vec![
            Vertex { i_position: [self.position.x+SUN_SIZE,
                                  self.position.y+SUN_SIZE,
                                  self.position.z],
                                  i_unit_coords: [1.0, 1.0, 0.0]},

            Vertex { i_position: [self.position.x-SUN_SIZE,
                                  self.position.y-SUN_SIZE,
                                  self.position.z],
                                  i_unit_coords: [-1.0, -1.0, 0.0]
                              },
            Vertex { i_position: [self.position.x-SUN_SIZE,
                                  self.position.y+SUN_SIZE,
                                  self.position.z],
                                  i_unit_coords: [-1.0, 1.0, 0.0]}
                                  ,
            Vertex { i_position: [self.position.x+SUN_SIZE,
                                  self.position.y-SUN_SIZE,
                                  self.position.z],
                                  i_unit_coords: [1.0, -1.0, 0.0]}
                                  ,
];

        self.vertex_buffer = VertexBuffer::new(self.context.get_facade(), &raw_vertex_buffer)
            .unwrap();

    }
}
#[derive(Debug, Copy, Clone)]
struct Vertex {
    pub i_position: [f32; 3],
    pub i_unit_coords: [f32; 3],
}

implement_vertex!(Vertex, i_position, i_unit_coords);
<commit_msg>fix format...<commit_after>use std::rc::Rc;
use glium::{self, DrawParameters, IndexBuffer, Program, VertexBuffer};
use glium::index::PrimitiveType;
use GameContext;
use Camera;
use glium::draw_parameters::DepthTest;
use util::ToArr;
use base::math::*;

pub struct Sun {
    vertex_buffer: VertexBuffer<Vertex>,
    index_buffer: IndexBuffer<u32>,
    program: Program,
    position: Vector3f,
    context: Rc<GameContext>,
}

impl Sun {
    pub fn new(context: Rc<GameContext>) -> Self {
        const SUN_SIZE: f32 = 35.0;
        const SUN_POS: f32 = 300.0;
        let raw_vertex_buffer = vec![
            Vertex { i_position: [SUN_SIZE, SUN_SIZE, SUN_POS], i_unit_coords: [1.0, 1.0, 0.0]},
            Vertex { i_position: [-SUN_SIZE, -SUN_SIZE, SUN_POS], i_unit_coords: [-1.0, -1.0, 0.0]},
            Vertex { i_position: [-SUN_SIZE, SUN_SIZE, SUN_POS], i_unit_coords: [-1.0, 1.0, 0.0]},
            Vertex { i_position: [SUN_SIZE, -SUN_SIZE, SUN_POS], i_unit_coords: [1.0, -1.0, 0.0]},
];

        let vbuf = VertexBuffer::new(context.get_facade(), &raw_vertex_buffer).unwrap();

        let raw_index_buffer = [2, 1, 0, 3]; //TrianglesStrip

        let ibuf = IndexBuffer::new(context.get_facade(),
                                    PrimitiveType::TriangleStrip,
                                    &raw_index_buffer)
            .unwrap();

        let prog = Program::from_source(context.get_facade(),
                                        include_str!("sun.vert"),
                                        include_str!("sun.frag"),
                                        None)
            .unwrap();

        Sun {
            vertex_buffer: vbuf,
            index_buffer: ibuf,
            program: prog,
            position: Vector3f::new(0.0, 0.0, 0.0),
            context: context,
        }
    }

    pub fn draw_sun<S: glium::Surface>(&self, surface: &mut S, camera: &Camera) {

        let pos = Point3::new(0.0, 0.0, 0.0);

        let view_matrix =
            Matrix4::look_at(pos, pos + camera.get_look_at_vector(), Vector3::unit_z());

        let uniforms = uniform! {
            u_proj_matrix: camera.proj_matrix().to_arr(),
            u_view_matrix: view_matrix.to_arr(),
        };
        let params = DrawParameters {
            depth: glium::Depth {
                write: false,
                test: DepthTest::IfLess,
                ..Default::default()
            },
            ..Default::default()
        };

        surface.draw(&self.vertex_buffer,
                  &self.index_buffer,
                  &self.program,
                  &uniforms,
                  &params)
            .unwrap();
    }

    pub fn update(&mut self, pos: Vector3f) {

        const SUN_SIZE: f32 = 35.0;
        self.position = pos;
        let raw_vertex_buffer = vec![
            Vertex { i_position: [self.position.x+SUN_SIZE,
                                  self.position.y+SUN_SIZE,
                                  self.position.z],
                                  i_unit_coords: [1.0, 1.0, 0.0]},

            Vertex { i_position: [self.position.x-SUN_SIZE,
                                  self.position.y-SUN_SIZE,
                                  self.position.z],
                                  i_unit_coords: [-1.0, -1.0, 0.0]
                              },
            Vertex { i_position: [self.position.x-SUN_SIZE,
                                  self.position.y+SUN_SIZE,
                                  self.position.z],
                                  i_unit_coords: [-1.0, 1.0, 0.0 ]}
                                  ,
            Vertex { i_position: [self.position.x+SUN_SIZE,
                                  self.position.y-SUN_SIZE,
                                  self.position.z],
                                  i_unit_coords: [1.0, -1.0, 0.0]}
                                  ,
];

        self.vertex_buffer = VertexBuffer::new(self.context.get_facade(), &raw_vertex_buffer)
            .unwrap();

    }
}
#[derive(Debug, Copy, Clone)]
struct Vertex {
    pub i_position: [f32; 3],
    pub i_unit_coords: [f32; 3],
}

implement_vertex!(Vertex, i_position, i_unit_coords);
<|endoftext|>