<commit_before>#![allow(unused)]

//! Implements a map from integer indices to data.
//! Rather than storing data for every index, internally, this maps entire ranges to the data.
//! To this end, the APIs all work on ranges, not on individual integers. Ranges are split as
//! necessary (e.g. when [0,5) is first associated with X, and then [1,2) is mutated).
//! Users must not depend on whether a range is coalesced or not, even though this is observable
//! via the iteration APIs.
use std::collections::BTreeMap;
use std::ops;

use rustc::ty::layout::Size;

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RangeMap<T> {
    map: BTreeMap<Range, T>,
}

// The derived `Ord` impl sorts first by the first field, then, if the fields are the same,
// by the second field.
// This is exactly what we need for our purposes, since a range query on a BTReeSet/BTreeMap will give us all
// `MemoryRange`s whose `start` is <= than the one we're looking for, but not > the end of the range we're checking.
// At the same time the `end` is irrelevant for the sorting and range searching, but used for the check.
// This kind of search breaks, if `end < start`, so don't do that!
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
struct Range {
    start: u64,
    end: u64, // Invariant: end > start
}

impl Range {
    /// Compute a range of ranges that contains all ranges overlaping with [offset, offset+len)
    fn range(offset: u64, len: u64) -> ops::Range<Range> {
        if len == 0 {
            // We can produce an empty range, nothing overlaps with this.
            let r = Range { start: 0, end: 1 };
            return r..r;
        }
        // We select all elements that are within
        // the range given by the offset into the allocation and the length.
        // This is sound if all ranges that intersect with the argument range, are in the
        // resulting range of ranges.
        let left = Range {
            // lowest range to include `offset`
            start: 0,
            end: offset + 1,
        };
        let right = Range {
            // lowest (valid) range not to include `offset+len`
            start: offset + len,
            end: offset + len + 1,
        };
        left..right
    }

    /// Tests if any element of [offset, offset+len) is contained in this range.
    #[inline(always)]
    fn overlaps(&self, offset: u64, len: u64) -> bool {
        if len == 0 {
            // `offset` totally does not matter, we cannot overlap with an empty interval
            false
        } else {
            offset < self.end && offset.checked_add(len).unwrap() >= self.start
        }
    }
}

impl<T> RangeMap<T> {
    /// Create a new RangeMap for the given size, and with the given initial value used for
    /// the entire range.
    #[inline(always)]
    pub fn new(size: Size, init: T) -> RangeMap<T> {
        let mut map = RangeMap { map: BTreeMap::new() };
        if size.bytes() > 0 {
            map.map.insert(Range { start: 0, end: size.bytes() }, init);
        }
        map
    }

    fn iter_with_range<'a>(
        &'a self,
        offset: u64,
        len: u64,
    ) -> impl Iterator<Item = (&'a Range, &'a T)> + 'a {
        self.map.range(Range::range(offset, len)).filter_map(
            move |(range, data)| {
                debug_assert!(len > 0);
                if range.overlaps(offset, len) {
                    Some((range, data))
                } else {
                    None
                }
            },
        )
    }

    /// Provide read-only iteration over everything in the given range.  This does
    /// *not* split items if they overlap with the edges.  Do not use this to mutate
    /// through interior mutability.
    pub fn iter<'a>(&'a self, offset: Size, len: Size) -> impl Iterator<Item = &'a T> + 'a {
        self.iter_with_range(offset.bytes(), len.bytes()).map(|(_, data)| data)
    }

    pub fn iter_mut_all<'a>(&'a mut self) -> impl Iterator<Item = &'a mut T> + 'a {
        self.map.values_mut()
    }

    fn split_entry_at(&mut self, offset: u64)
    where
        T: Clone,
    {
        let range = match self.iter_with_range(offset, 1).next() {
            Some((&range, _)) => range,
            None => return,
        };
        assert!(
            range.start <= offset && range.end > offset,
            "We got a range that doesn't even contain what we asked for."
        );
        // There is an entry overlapping this position, see if we have to split it
        if range.start < offset {
            let data = self.map.remove(&range).unwrap();
            let old = self.map.insert(
                Range {
                    start: range.start,
                    end: offset,
                },
                data.clone(),
            );
            assert!(old.is_none());
            let old = self.map.insert(
                Range {
                    start: offset,
                    end: range.end,
                },
                data,
            );
            assert!(old.is_none());
        }
    }

    /// Provide mutable iteration over everything in the given range.  As a side-effect,
    /// this will split entries in the map that are only partially hit by the given range,
    /// to make sure that when they are mutated, the effect is constrained to the given range.
    pub fn iter_mut<'a>(
        &'a mut self,
        offset: Size,
        len: Size,
    ) -> impl Iterator<Item = &'a mut T> + 'a
    where
        T: Clone,
    {
        let offset = offset.bytes();
        let len = len.bytes();

        if len > 0 {
            // Preparation: Split first and last entry as needed.
            self.split_entry_at(offset);
            self.split_entry_at(offset + len);
        }
        // Now we can provide a mutable iterator
        self.map.range_mut(Range::range(offset, len)).filter_map(
            move |(&range, data)| {
                debug_assert!(len > 0);
                if range.overlaps(offset, len) {
                    assert!(
                        offset <= range.start && offset + len >= range.end,
                        "The splitting went wrong"
                    );
                    Some(data)
                } else {
                    // Skip this one
                    None
                }
            },
        )
    }
}

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

    /// Query the map at every offset in the range and collect the results.
    fn to_vec<T: Copy>(map: &RangeMap<T>, offset: u64, len: u64) -> Vec<T> {
        (offset..offset + len)
            .into_iter()
            .map(|i| map
                .iter(Size::from_bytes(i), Size::from_bytes(1))
                .next()
                .map(|&t| t)
                .unwrap()
            )
            .collect()
    }

    #[test]
    fn basic_insert() {
        let mut map = RangeMap::<i32>::new(Size::from_bytes(20), -1);
        // Insert
        for x in map.iter_mut(Size::from_bytes(10), Size::from_bytes(1)) {
            *x = 42;
        }
        // Check
        assert_eq!(to_vec(&map, 10, 1), vec![42]);
        assert_eq!(map.map.len(), 3);

        // Insert with size 0
        for x in map.iter_mut(Size::from_bytes(10), Size::from_bytes(0)) {
            *x = 19;
        }
        for x in map.iter_mut(Size::from_bytes(11), Size::from_bytes(0)) {
            *x = 19;
        }
        assert_eq!(to_vec(&map, 10, 2), vec![42, -1]);
        assert_eq!(map.map.len(), 3);
    }

    #[test]
    fn gaps() {
        let mut map = RangeMap::<i32>::new(Size::from_bytes(20), -1);
        for x in map.iter_mut(Size::from_bytes(11), Size::from_bytes(1)) {
            *x = 42;
        }
        for x in map.iter_mut(Size::from_bytes(15), Size::from_bytes(1)) {
            *x = 43;
        }
        assert_eq!(map.map.len(), 5);
        assert_eq!(
            to_vec(&map, 10, 10),
            vec![-1, 42, -1, -1, -1, 43, -1, -1, -1, -1]
        );

        for x in map.iter_mut(Size::from_bytes(10), Size::from_bytes(10)) {
            if *x < 42 {
                *x = 23;
            }
        }
        assert_eq!(map.map.len(), 6);

        assert_eq!(
            to_vec(&map, 10, 10),
            vec![23, 42, 23, 23, 23, 43, 23, 23, 23, 23]
        );
        assert_eq!(to_vec(&map, 13, 5), vec![23, 23, 43, 23, 23]);

        // Now request a range that goes beyond the initial size
        for x in map.iter_mut(Size::from_bytes(15), Size::from_bytes(10)) {
            *x = 19;
        }
        assert_eq!(map.map.len(), 6);
        assert_eq!(map.iter(Size::from_bytes(19), Size::from_bytes(1))
            .map(|&t| t).collect::<Vec<_>>(), vec![19]);
        assert_eq!(map.iter(Size::from_bytes(20), Size::from_bytes(1))
            .map(|&t| t).collect::<Vec<_>>(), vec![]);
    }
}
<commit_msg>rewrite RangeMap to use a sorted Vec instead of a RangeMap<commit_after>#![allow(unused)]

//! Implements a map from integer indices to data.
//! Rather than storing data for every index, internally, this maps entire ranges to the data.
//! To this end, the APIs all work on ranges, not on individual integers. Ranges are split as
//! necessary (e.g. when [0,5) is first associated with X, and then [1,2) is mutated).
//! Users must not depend on whether a range is coalesced or not, even though this is observable
//! via the iteration APIs.

use std::ops;
use std::num::NonZeroU64;

use rustc::ty::layout::Size;

// Representation: offset-length-data tuples, sorted by offset.
#[derive(Clone, Debug)]
struct Elem<T> {
    offset: u64,
    len: NonZeroU64,
    data: T,
}
// Length is always > 0.
#[derive(Clone, Debug)]
pub struct RangeMap<T> {
    v: Vec<Elem<T>>,
}

impl<T> Elem<T> {
    #[inline(always)]
    fn contains(&self, offset: u64) -> bool {
        offset >= self.offset && offset < self.offset + self.len.get()
    }
}

impl<T> RangeMap<T> {
    /// Create a new RangeMap for the given size, and with the given initial value used for
    /// the entire range.
    #[inline(always)]
    pub fn new(size: Size, init: T) -> RangeMap<T> {
        let size = size.bytes();
        let mut map = RangeMap { v: Vec::new() };
        if size > 0 {
            map.v.push(Elem {
                offset: 0,
                len: NonZeroU64::new(size).unwrap(),
                data: init
            });
        }
        map
    }

    /// Find the index containing the given offset.
    fn find_offset(&self, offset: u64) -> usize {
        debug_assert!(self.v.len() > 0);
        let mut left = 0usize; // inclusive
        let mut right = self.v.len(); // exclusive
        loop {
            let candidate = left.checked_add(right).unwrap() / 2;
            let elem = &self.v[candidate];
            if elem.offset > offset {
                // we are too far right (offset is further left)
                debug_assert!(candidate < right); // we are making progress
                right = candidate;
            } else if offset >= elem.offset + elem.len.get() {
                // we are too far left (offset is further right)
                debug_assert!(candidate >= left); // we are making progress
                left = candidate+1;
                debug_assert!(left < right, "find_offset: offset {} is out-of-bounds", offset);
            } else {
                // This is it!
                return candidate;
            }
        }
    }

    /// Provide read-only iteration over everything in the given range.  This does
    /// *not* split items if they overlap with the edges.  Do not use this to mutate
    /// through interior mutability.
    pub fn iter<'a>(&'a self, offset: Size, len: Size) -> impl Iterator<Item = &'a T> + 'a {
        let offset = offset.bytes();
        let len = len.bytes();
        // Compute a slice starting with the elements we care about
        let slice: &[Elem<T>] = if len == 0 {
                // We just need any empty iterator.  We don't even want to
                // yield the element that surrounds this position.
                &[]
            } else {
                let first = self.find_offset(offset);
                &self.v[first..]
            };
        let end = offset + len; // the first offset that is not included any more
        slice.iter()
            .take_while(move |elem| elem.offset < end)
            .map(|elem| &elem.data)
    }

    pub fn iter_mut_all<'a>(&'a mut self) -> impl Iterator<Item = &'a mut T> + 'a {
        self.v.iter_mut().map(|elem| &mut elem.data)
    }

    // Split the element situated at the given `index`, such that the 2nd one starts at offset `split_offset`.
    // Do nothing if the element already starts there.
    // Return whether a split was necessary.
    fn split_index(&mut self, index: usize, split_offset: u64) -> bool
    where
        T: Clone,
    {
        let elem = &mut self.v[index];
        let first_len = split_offset.checked_sub(elem.offset)
            .expect("The split_offset is before the element to be split");
        assert!(first_len <= elem.len.get(),
            "The split_offset is after the element to be split");
        if first_len == 0 || first_len == elem.len.get() {
            // Nothing to do
            return false;
        }

        // Now we really have to split.  Reduce length of first element.
        let second_len = elem.len.get() - first_len;
        elem.len = NonZeroU64::new(first_len).unwrap();
        // Copy the data, and insert 2nd element
        let second = Elem {
            offset: split_offset,
            len: NonZeroU64::new(second_len).unwrap(),
            data: elem.data.clone(),
        };
        self.v.insert(index+1, second);
        return true;
    }

    /// Provide mutable iteration over everything in the given range.  As a side-effect,
    /// this will split entries in the map that are only partially hit by the given range,
    /// to make sure that when they are mutated, the effect is constrained to the given range.
    pub fn iter_mut<'a>(
        &'a mut self,
        offset: Size,
        len: Size,
    ) -> impl Iterator<Item = &'a mut T> + 'a
    where
        T: Clone,
    {
        let offset = offset.bytes();
        let len = len.bytes();
        // Compute a slice containing exactly the elements we care about
        let slice: &mut [Elem<T>] = if len == 0 {
                // We just need any empty iterator.  We don't even want to
                // yield the element that surrounds this position, nor do
                // any splitting.
                &mut []
            } else {
                // Make sure we got a clear beginning
                let mut first = self.find_offset(offset);
                if self.split_index(first, offset) {
                    // The newly created 2nd element is ours
                    first += 1;
                }
                let first = first; // no more mutation
                // Find our end.  Linear scan, but that's okay because the iteration
                // is doing the same linear scan anyway -- no increase in complexity.
                let mut end = first; // the last element to be included
                loop {
                    let elem = &self.v[end];
                    if elem.offset+elem.len.get() < offset+len {
                        // We need to scan further.
                        end += 1;
                        debug_assert!(end < self.v.len(), "iter_mut: end-offset {} is out-of-bounds", offset+len);
                    } else {
                        // `elem` is the last included element.  Stop search.
                        break;
                    }
                }
                let end = end; // no more mutation
                // We need to split the end as well.  Even if this performs a
                // split, we don't have to adjust our index as we only care about
                // the first part of the split.
                self.split_index(end, offset+len);
                // Now we yield the slice. `end` is inclusive.
                &mut self.v[first..=end]
            };
        slice.iter_mut().map(|elem| &mut elem.data)
    }
}

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

    /// Query the map at every offset in the range and collect the results.
    fn to_vec<T: Copy>(map: &RangeMap<T>, offset: u64, len: u64) -> Vec<T> {
        (offset..offset + len)
            .into_iter()
            .map(|i| map
                .iter(Size::from_bytes(i), Size::from_bytes(1))
                .next()
                .map(|&t| t)
                .unwrap()
            )
            .collect()
    }

    #[test]
    fn basic_insert() {
        let mut map = RangeMap::<i32>::new(Size::from_bytes(20), -1);
        // Insert
        for x in map.iter_mut(Size::from_bytes(10), Size::from_bytes(1)) {
            *x = 42;
        }
        // Check
        assert_eq!(to_vec(&map, 10, 1), vec![42]);
        assert_eq!(map.v.len(), 3);

        // Insert with size 0
        for x in map.iter_mut(Size::from_bytes(10), Size::from_bytes(0)) {
            *x = 19;
        }
        for x in map.iter_mut(Size::from_bytes(11), Size::from_bytes(0)) {
            *x = 19;
        }
        assert_eq!(to_vec(&map, 10, 2), vec![42, -1]);
        assert_eq!(map.v.len(), 3);
    }

    #[test]
    fn gaps() {
        let mut map = RangeMap::<i32>::new(Size::from_bytes(20), -1);
        for x in map.iter_mut(Size::from_bytes(11), Size::from_bytes(1)) {
            *x = 42;
        }
        for x in map.iter_mut(Size::from_bytes(15), Size::from_bytes(1)) {
            *x = 43;
        }
        assert_eq!(map.v.len(), 5);
        assert_eq!(
            to_vec(&map, 10, 10),
            vec![-1, 42, -1, -1, -1, 43, -1, -1, -1, -1]
        );

        for x in map.iter_mut(Size::from_bytes(10), Size::from_bytes(10)) {
            if *x < 42 {
                *x = 23;
            }
        }
        assert_eq!(map.v.len(), 6);

        assert_eq!(
            to_vec(&map, 10, 10),
            vec![23, 42, 23, 23, 23, 43, 23, 23, 23, 23]
        );
        assert_eq!(to_vec(&map, 13, 5), vec![23, 23, 43, 23, 23]);

        for x in map.iter_mut(Size::from_bytes(15), Size::from_bytes(5)) {
            *x = 19;
        }
        assert_eq!(map.v.len(), 6);
        assert_eq!(map.iter(Size::from_bytes(19), Size::from_bytes(1))
            .map(|&t| t).collect::<Vec<_>>(), vec![19]);
    }
}
<|endoftext|>


<commit_before>pub use self::inner::*;

#[cfg(feature = "nightly")]
mod inner {
    use crate::alloc::alloc::Layout;
    pub use crate::alloc::alloc::{AllocRef, Global};
    use core::ptr::NonNull;

    pub fn do_alloc<A: AllocRef>(alloc: &A, layout: Layout) -> Result<NonNull<u8>, ()> {
        alloc
            .alloc(layout)
            .map(|ptr| ptr.as_non_null_ptr())
            .map_err(|_| ())
    }
}

#[cfg(not(feature = "nightly"))]
mod inner {
    use crate::alloc::alloc::{alloc, dealloc, Layout};
    use core::ptr::NonNull;

    pub struct AllocError;

    pub unsafe trait AllocRef {
        fn alloc(&self, layout: Layout) -> Result<NonNull<u8>, AllocError>;
        unsafe fn dealloc(&self, ptr: NonNull<u8>, layout: Layout);
    }

    #[derive(Copy, Clone)]
    pub struct Global;
    unsafe impl AllocRef for Global {
        fn alloc(&self, layout: Layout) -> Result<NonNull<u8>, AllocError> {
            unsafe { NonNull::new(alloc(layout)).ok_or(AllocError) }
        }
        unsafe fn dealloc(&self, ptr: NonNull<u8>, layout: Layout) {
            dealloc(ptr.as_ptr(), layout)
        }
    }
    impl Default for Global {
        fn default() -> Self {
            Global
        }
    }

    pub fn do_alloc<A: AllocRef>(alloc: &A, layout: Layout) -> Result<NonNull<u8>, ()> {
        alloc.alloc(layout).map_err(|_| ())
    }
}
<commit_msg>ignore clippy warnings<commit_after>pub use self::inner::*;

#[cfg(feature = "nightly")]
mod inner {
    use crate::alloc::alloc::Layout;
    pub use crate::alloc::alloc::{AllocRef, Global};
    use core::ptr::NonNull;

    #[allow(clippy::map_err_ignore)]
    pub fn do_alloc<A: AllocRef>(alloc: &A, layout: Layout) -> Result<NonNull<u8>, ()> {
        alloc
            .alloc(layout)
            .map(|ptr| ptr.as_non_null_ptr())
            .map_err(|_| ())
    }
}

#[cfg(not(feature = "nightly"))]
mod inner {
    use crate::alloc::alloc::{alloc, dealloc, Layout};
    use core::ptr::NonNull;

    pub struct AllocError;

    pub unsafe trait AllocRef {
        fn alloc(&self, layout: Layout) -> Result<NonNull<u8>, AllocError>;
        unsafe fn dealloc(&self, ptr: NonNull<u8>, layout: Layout);
    }

    #[derive(Copy, Clone)]
    pub struct Global;
    unsafe impl AllocRef for Global {
        fn alloc(&self, layout: Layout) -> Result<NonNull<u8>, AllocError> {
            unsafe { NonNull::new(alloc(layout)).ok_or(AllocError) }
        }
        unsafe fn dealloc(&self, ptr: NonNull<u8>, layout: Layout) {
            dealloc(ptr.as_ptr(), layout)
        }
    }
    impl Default for Global {
        fn default() -> Self {
            Global
        }
    }

    #[allow(clippy::map_err_ignore)]
    pub fn do_alloc<A: AllocRef>(alloc: &A, layout: Layout) -> Result<NonNull<u8>, ()> {
        alloc.alloc(layout).map_err(|_| ())
    }
}
<|endoftext|>


<commit_before>use std::fmt;

pub type NSSResult<T> = Result<T, NSSError>;

#[derive(Copy)]
pub enum NSSError
{
    /// An error generated by NSPR or NSS
    NSS(i32),
}

#[allow(unstable)]
impl fmt::Show for NSSError
{
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error>
    {
        match *self
        {
            NSSError::NSS(code) => {
                match ::ffi::nspr::get_error_message(code)
                {
                    Some(message) => {
                        let message_str = String::from_utf8_lossy(message.as_bytes());
                        formatter.write_str(&*message_str)
                    },
                    None => write!(formatter, "Unknown error {}", code),
                }
            },
        }
    }
}
<commit_msg>Implement Debug and Display<commit_after>use std::fmt;

pub type NSSResult<T> = Result<T, NSSError>;

#[derive(Copy)]
pub enum NSSError
{
    /// An error generated by NSPR or NSS
    NSS(i32),
}

#[allow(unstable)]
impl fmt::Display for NSSError
{
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error>
    {
        match *self
        {
            NSSError::NSS(code) => {
                match ::ffi::nspr::get_error_message(code)
                {
                    Some(message) => {
                        let message_str = String::from_utf8_lossy(message.as_bytes());
                        formatter.write_str(&*message_str)
                    },
                    None => write!(formatter, "Unknown error {}", code),
                }
            },
        }
    }
}

#[allow(unstable)]
impl fmt::Debug for NSSError
{
    fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error>
    {
        ::std::fmt::Display::fmt(self, fmt)
    }
}
<|endoftext|>


<commit_before>// Claxon -- A FLAC decoding library in Rust
// Copyright (C) 2015 Ruud van Asseldonk
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License, version 3,
// as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

//! The `sample` module provides the `Sample` trait and its implementations.
//!
//! The purpose of this module is similar to that of `num::traits` in the `num`
//! crate, but the `Sample` type has been specialised more towards FLAC in
//! particular. For instance, it is only implemented for types that can be
//! encountered in a FLAC stream. (This excludes `i64` and unsigned integers.)

use std::cmp::Eq;
use std::fmt;
use std::ops::{Add, BitAnd, BitOr, Mul, Neg, Shl, Shr, Sub};
use std::num::Zero;

/// A trait that allows decoding into integers of various widths.
///
/// A few observations are important here:
///
/// - In the FLAC format, samples are always signed.
/// - FLAC does not support more than 32 bits per sample.
///   Therefore, converting a sample to `i32` or `i64` can never fail.
///
/// This trait should only be implemented for `i8`, `i16` and `i32`.
pub trait Sample: Copy + Clone + Eq + fmt::Debug +
    Neg<Output = Self> +
    Add<Output = Self> +
    Sub<Output = Self> +
    Shl<usize, Output = Self> +
    Shr<usize, Output = Self> +
    BitOr<Self, Output = Self> +
    BitAnd<Self, Output = Self> {

    /// The signed integer type that is wide enough to store differences.
    ///
    /// The difference between two values of the sample type might not fit in
    /// a sample type any more, so a wider integer type is required. The wide
    /// type must be able to store at least twice a difference, so it must be
    /// two bits wider than the sample type itself.
    type Wide: WideSample;

    /// The zero sample.
    // TODO: associated constants, once those land.
    fn zero() -> Self;

    /// Tries to narrow the sample, returning `None` on overflow.
    fn from_wide(wide: Self::Wide) -> Option<Self>;

    /// Casts the sample to its wide type.
    fn widen(self) -> Self::Wide;
}

pub trait WideSample: Copy + Clone + Eq + fmt::Debug +
    Zero +
    Neg<Output = Self> +
    Add<Output = Self> +
    Sub<Output = Self> +
    Mul<Output = Self> +
    Shl<usize, Output = Self> +
    Shr<usize, Output = Self> +
    BitOr<Self, Output = Self> +
    BitAnd<Self, Output = Self> {

    /// The one sample.
    fn one() -> Self;

    /// The maximum value of the wide sample type.
    fn max() -> Self;

    /// The number of bits that this type can store at most.
    fn width() -> u8;

    /// Casts a `i8` to the wide sample type.
    fn from_i8(from: i8) -> Self;

    /// Casts a `u16` to the wide sample type.
    fn from_u16(from: u16) -> Self;

    /// Casts a `i32` to the wide sample type, assuming it will not overflow.
    fn from_i32_nofail(from: i32) -> Self;

    /// Tries to cast an `i64` to the wide sample type.
    ///
    /// This will return `None` if `2 * from` would overflow the wide sample type.
    fn from_i64_spare_bit(from: i64) -> Option<Self>;

    /// Casts the sample to an `i64`.
    fn to_i64(self) -> i64;
}

macro_rules! impl_sample {
    ($narrow: ident, $wide: ident, $width: expr) => {
        impl Sample for $narrow {
            type Wide = $wide;

            fn zero() -> $narrow {
                0
            }

            fn from_wide(wide: $wide) -> Option<$narrow> {
                use std::$narrow;
                if wide < $narrow::MIN as $wide { return None; }
                if wide > $narrow::MAX as $wide { return None; }
                Some(wide as $narrow)
            }

            fn widen(self) -> $wide {
                self as $wide
            }
        }

        impl WideSample for $wide {

            fn one() -> $wide {
                1
            }

            fn max() -> $wide {
                use std::$wide;
                $wide::MAX
            }

            fn width() -> u8 {
                $width * 2
            }

            fn from_i8(from: i8) -> $wide {
                from as $wide
            }

            fn from_u16(from: u16) -> $wide {
                from as $wide
            }

            fn from_i32_nofail(from: i32) -> $wide {
                from as $wide
            }

            fn from_i64_spare_bit(from: i64) -> Option<$wide> {
                use std::$wide;
                if from < ($wide::MIN as i64) >> 1 { return None; }
                if from > ($wide::MAX as i64) >> 1 { return None; }
                Some(from as $wide)
            }

            fn to_i64(self) -> i64 {
                self as i64
            }
        }
    };
}

impl_sample!(i8, i16, 8);
impl_sample!(i16, i32, 16);
impl_sample!(i32, i64, 32);
<commit_msg>clarify impl_sample! macro<commit_after>// Claxon -- A FLAC decoding library in Rust
// Copyright (C) 2015 Ruud van Asseldonk
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License, version 3,
// as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

//! The `sample` module provides the `Sample` trait and its implementations.
//!
//! The purpose of this module is similar to that of `num::traits` in the `num`
//! crate, but the `Sample` type has been specialised more towards FLAC in
//! particular. For instance, it is only implemented for types that can be
//! encountered in a FLAC stream. (This excludes `i64` and unsigned integers.)

use std::cmp::Eq;
use std::fmt;
use std::ops::{Add, BitAnd, BitOr, Mul, Neg, Shl, Shr, Sub};
use std::num::Zero;

/// A trait that allows decoding into integers of various widths.
///
/// A few observations are important here:
///
/// - In the FLAC format, samples are always signed.
/// - FLAC does not support more than 32 bits per sample.
///   Therefore, converting a sample to `i32` or `i64` can never fail.
///
/// This trait should only be implemented for `i8`, `i16` and `i32`.
pub trait Sample: Copy + Clone + Eq + fmt::Debug +
    Neg<Output = Self> +
    Add<Output = Self> +
    Sub<Output = Self> +
    Shl<usize, Output = Self> +
    Shr<usize, Output = Self> +
    BitOr<Self, Output = Self> +
    BitAnd<Self, Output = Self> {

    /// The signed integer type that is wide enough to store differences.
    ///
    /// The difference between two values of the sample type might not fit in
    /// a sample type any more, so a wider integer type is required. The wide
    /// type must be able to store at least twice a difference, so it must be
    /// two bits wider than the sample type itself.
    type Wide: WideSample;

    /// The zero sample.
    // TODO: associated constants, once those land.
    fn zero() -> Self;

    /// Tries to narrow the sample, returning `None` on overflow.
    fn from_wide(wide: Self::Wide) -> Option<Self>;

    /// Casts the sample to its wide type.
    fn widen(self) -> Self::Wide;
}

pub trait WideSample: Copy + Clone + Eq + fmt::Debug +
    Zero +
    Neg<Output = Self> +
    Add<Output = Self> +
    Sub<Output = Self> +
    Mul<Output = Self> +
    Shl<usize, Output = Self> +
    Shr<usize, Output = Self> +
    BitOr<Self, Output = Self> +
    BitAnd<Self, Output = Self> {

    /// The one sample.
    fn one() -> Self;

    /// The maximum value of the wide sample type.
    fn max() -> Self;

    /// The number of bits that this type can store at most.
    fn width() -> u8;

    /// Casts a `i8` to the wide sample type.
    fn from_i8(from: i8) -> Self;

    /// Casts a `u16` to the wide sample type.
    fn from_u16(from: u16) -> Self;

    /// Casts a `i32` to the wide sample type, assuming it will not overflow.
    fn from_i32_nofail(from: i32) -> Self;

    /// Tries to cast an `i64` to the wide sample type.
    ///
    /// This will return `None` if `2 * from` would overflow the wide sample type.
    fn from_i64_spare_bit(from: i64) -> Option<Self>;

    /// Casts the sample to an `i64`.
    fn to_i64(self) -> i64;
}

macro_rules! impl_sample {
    ($narrow: ident, $wide: ident, $wide_width: expr) => {
        impl Sample for $narrow {
            type Wide = $wide;

            fn zero() -> $narrow {
                0
            }

            fn from_wide(wide: $wide) -> Option<$narrow> {
                use std::$narrow;
                if wide < $narrow::MIN as $wide { return None; }
                if wide > $narrow::MAX as $wide { return None; }
                Some(wide as $narrow)
            }

            fn widen(self) -> $wide {
                self as $wide
            }
        }

        impl WideSample for $wide {

            fn one() -> $wide {
                1
            }

            fn max() -> $wide {
                use std::$wide;
                $wide::MAX
            }

            fn width() -> u8 {
                $wide_width
            }

            fn from_i8(from: i8) -> $wide {
                from as $wide
            }

            fn from_u16(from: u16) -> $wide {
                from as $wide
            }

            fn from_i32_nofail(from: i32) -> $wide {
                from as $wide
            }

            fn from_i64_spare_bit(from: i64) -> Option<$wide> {
                use std::$wide;
                if from < ($wide::MIN as i64) >> 1 { return None; }
                if from > ($wide::MAX as i64) >> 1 { return None; }
                Some(from as $wide)
            }

            fn to_i64(self) -> i64 {
                self as i64
            }
        }
    };
}

impl_sample!(i8, i16, 16);
impl_sample!(i16, i32, 32);
impl_sample!(i32, i64, 64);
<|endoftext|>


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

/// top level document
#[derive(Debug, Deserialize, Serialize, PartialEq)]
pub struct Spec {
    /// version string
    pub swagger: String,
    pub info: Info,
    pub paths: BTreeMap<String, Operations>, // / -> get -> op
    pub definitions: BTreeMap<String, Schema>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub schemes: Option<Vec<String>>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub host: Option<String>,
    #[serde(skip_serializing_if="Option::is_none")]
    #[serde(rename="basePath")]
    pub base_path: Option<String>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub consumes: Option<Vec<String>>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub produces: Option<Vec<String>>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub parameters: Option<BTreeMap<String, Parameter>>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub responses: Option<BTreeMap<String, Response>>,
    #[serde(skip_serializing_if="Option::is_none")]
    #[serde(rename="securityDefinitions")]
    pub security_definitions: Option<BTreeMap<String, Security>>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub tags: Option<Vec<Tag>>,
}

#[derive(Debug, Deserialize, Serialize, PartialEq)]
pub struct Tag {
    pub name: String,
    #[serde(skip_serializing_if="Option::is_none")]
    pub description: Option<String>,
    #[serde(skip_serializing_if="Option::is_none")]
    #[serde(rename="externalDocs")]
    pub external_docs: Option<Vec<ExternalDoc>>,
}

#[derive(Debug, Deserialize, Serialize, PartialEq)]
pub struct ExternalDoc {
    pub url: String,
    #[serde(skip_serializing_if="Option::is_none")]
    pub description: Option<String>,
}

#[derive(Debug, Deserialize, Serialize, PartialEq)]
pub struct Info {
    pub title: String,
    pub version: String,
    #[serde(skip_serializing_if="Option::is_none")]
    #[serde(rename="termsOfService")]
    pub terms_of_service: Option<String>,
}

#[derive(Debug, Deserialize, Serialize, PartialEq)]
pub struct Operations {
    #[serde(skip_serializing_if="Option::is_none")]
    pub get: Option<Operation>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub post: Option<Operation>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub put: Option<Operation>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub patch: Option<Operation>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub delete: Option<Operation>,
}

#[derive(Debug, Deserialize, Serialize, PartialEq)]
pub struct Operation {
    #[serde(skip_serializing_if="Option::is_none")]
    pub summary: Option<String>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub description: Option<String>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub consumes: Option<Vec<String>>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub produces: Option<Vec<String>>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub schemes: Option<Vec<String>>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub tags: Option<Vec<String>>,
    #[serde(skip_serializing_if="Option::is_none")]
    #[serde(rename="operationId")]
    pub operation_id: Option<String>,
    pub responses: BTreeMap<String, Response>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub parameters: Option<Vec<Parameter>>,
}

#[derive(Debug, Deserialize, Serialize, PartialEq)]
pub struct Parameter {
    pub name: String,
    #[serde(rename="in")]
    pub location: String,
    #[serde(skip_serializing_if="Option::is_none")]
    pub required: Option<bool>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub schema: Option<Schema>,
    #[serde(skip_serializing_if="Option::is_none")]
    #[serde(rename="uniqueItems")]
    pub unique_items: Option<bool>,
    #[serde(skip_serializing_if="Option::is_none")]
    #[serde(rename="type")]
    pub param_type: Option<String>,
}

#[derive(Debug, Deserialize, Serialize, PartialEq)]
pub struct Response {
    pub description: String,
    #[serde(skip_serializing_if="Option::is_none")]
    pub schema: Option<Schema>,
}

#[derive(Debug, Deserialize, Serialize, PartialEq)]
pub struct Security {
    #[serde(rename="type")]
    pub security_type: String, // todo:
}

#[derive(Debug, Deserialize, Serialize, PartialEq)]
pub struct Schema {
    #[serde(skip_serializing_if="Option::is_none")]
    #[serde(rename="$ref")]
    pub ref_path: Option<String>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub description: Option<String>,
    #[serde(skip_serializing_if="Option::is_none")]
    #[serde(rename="type")]
    pub schema_type: Option<String>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub items: Option<Box<Schema>>, // if scheme_type array (box is for recursion)
    #[serde(skip_serializing_if="Option::is_none")]
    pub properties: Option<BTreeMap<String, Schema>>, // implies object
}
<commit_msg>making note<commit_after>use std::collections::BTreeMap;

/// top level document
#[derive(Debug, Deserialize, Serialize, PartialEq)]
pub struct Spec {
    /// version string
    pub swagger: String,
    pub info: Info,
    pub paths: BTreeMap<String, Operations>, // / -> get -> op
    pub definitions: BTreeMap<String, Schema>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub schemes: Option<Vec<String>>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub host: Option<String>,
    #[serde(skip_serializing_if="Option::is_none")]
    #[serde(rename="basePath")]
    pub base_path: Option<String>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub consumes: Option<Vec<String>>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub produces: Option<Vec<String>>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub parameters: Option<BTreeMap<String, Parameter>>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub responses: Option<BTreeMap<String, Response>>,
    #[serde(skip_serializing_if="Option::is_none")]
    #[serde(rename="securityDefinitions")]
    pub security_definitions: Option<BTreeMap<String, Security>>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub tags: Option<Vec<Tag>>,
}

#[derive(Debug, Deserialize, Serialize, PartialEq)]
pub struct Tag {
    pub name: String,
    #[serde(skip_serializing_if="Option::is_none")]
    pub description: Option<String>,
    #[serde(skip_serializing_if="Option::is_none")]
    #[serde(rename="externalDocs")]
    pub external_docs: Option<Vec<ExternalDoc>>,
}

#[derive(Debug, Deserialize, Serialize, PartialEq)]
pub struct ExternalDoc {
    pub url: String,
    #[serde(skip_serializing_if="Option::is_none")]
    pub description: Option<String>,
}

#[derive(Debug, Deserialize, Serialize, PartialEq)]
pub struct Info {
    pub title: String,
    pub version: String,
    #[serde(skip_serializing_if="Option::is_none")]
    #[serde(rename="termsOfService")]
    pub terms_of_service: Option<String>,
}

// note: this should really just be a BTreeMap<String, Operation>
#[derive(Debug, Deserialize, Serialize, PartialEq)]
pub struct Operations {
    #[serde(skip_serializing_if="Option::is_none")]
    pub get: Option<Operation>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub post: Option<Operation>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub put: Option<Operation>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub patch: Option<Operation>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub delete: Option<Operation>,
}

#[derive(Debug, Deserialize, Serialize, PartialEq)]
pub struct Operation {
    #[serde(skip_serializing_if="Option::is_none")]
    pub summary: Option<String>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub description: Option<String>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub consumes: Option<Vec<String>>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub produces: Option<Vec<String>>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub schemes: Option<Vec<String>>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub tags: Option<Vec<String>>,
    #[serde(skip_serializing_if="Option::is_none")]
    #[serde(rename="operationId")]
    pub operation_id: Option<String>,
    pub responses: BTreeMap<String, Response>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub parameters: Option<Vec<Parameter>>,
}

#[derive(Debug, Deserialize, Serialize, PartialEq)]
pub struct Parameter {
    pub name: String,
    #[serde(rename="in")]
    pub location: String,
    #[serde(skip_serializing_if="Option::is_none")]
    pub required: Option<bool>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub schema: Option<Schema>,
    #[serde(skip_serializing_if="Option::is_none")]
    #[serde(rename="uniqueItems")]
    pub unique_items: Option<bool>,
    #[serde(skip_serializing_if="Option::is_none")]
    #[serde(rename="type")]
    pub param_type: Option<String>,
}

#[derive(Debug, Deserialize, Serialize, PartialEq)]
pub struct Response {
    pub description: String,
    #[serde(skip_serializing_if="Option::is_none")]
    pub schema: Option<Schema>,
}

#[derive(Debug, Deserialize, Serialize, PartialEq)]
pub struct Security {
    #[serde(rename="type")]
    pub security_type: String, // todo:
}

#[derive(Debug, Deserialize, Serialize, PartialEq)]
pub struct Schema {
    #[serde(skip_serializing_if="Option::is_none")]
    #[serde(rename="$ref")]
    pub ref_path: Option<String>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub description: Option<String>,
    #[serde(skip_serializing_if="Option::is_none")]
    #[serde(rename="type")]
    pub schema_type: Option<String>,
    #[serde(skip_serializing_if="Option::is_none")]
    pub items: Option<Box<Schema>>, // if scheme_type array (box is for recursion)
    #[serde(skip_serializing_if="Option::is_none")]
    pub properties: Option<BTreeMap<String, Schema>>, // implies object
}
<|endoftext|>


<commit_before>use ncurses as nc;
use std::ffi::CString;

use libc_aux;
use screen_data::ScreenData;
use window::{Rect, Window};
use window::{Gutter, ListView, MiniBuf, StatusLine};

pub struct Screen {
    gutter: Window,
    list_view: Window,
    mini_buf: Window,
    status_line: Window,
}

impl Screen {
    pub fn new() -> Self {
        let layout = Layout::new();
        let gutter = Window::new(Gutter, layout.gutter_rect);
        let list_view = Window::new(ListView, layout.list_view_rect);
        let mini_buf = Window::new(MiniBuf, layout.mini_buf_rect);
        let status_line = Window::new(StatusLine, layout.status_line_rect);
        Screen {
            gutter: gutter,
            list_view: list_view,
            mini_buf: mini_buf,
            status_line: status_line,
        }
    }

    pub fn update(&self, sd: ScreenData) {
        for win in [&self.gutter, &self.list_view, &self.mini_buf, &self.status_line].iter() {
            win.clear();
            win.draw(&sd);
            win.noutrefresh();
        }
        MiniBuf::set_cursor(&self.mini_buf, sd.cursor_index as i32);
        nc::doupdate();
    }

    pub fn list_view_height(&self) -> usize {
        self.list_view.rect().height as usize
    }
}

struct Layout {
    gutter_rect: Rect,
    list_view_rect: Rect,
    mini_buf_rect: Rect,
    status_line_rect: Rect,
}

impl Layout {
    fn new() -> Layout {
        let mut max_y = 0i32;
        let mut max_x = 0i32;
        nc::getmaxyx(nc::stdscr, &mut max_y, &mut max_x);

        let gutter_width = 2;
        let mini_buf_height = 1;
        let status_line_height = 1;

        let gutter_rect = Rect {
            height: max_y - mini_buf_height - status_line_height,
            width: gutter_width,
            y: mini_buf_height + status_line_height,
            x: 0,
        };

        let list_view_rect = Rect {
            height: max_y - mini_buf_height - status_line_height,
            width: max_x - gutter_width,
            y: mini_buf_height + status_line_height,
            x: gutter_width,
        };

        let mini_buf_rect = Rect {
            height: mini_buf_height,
            width: max_x,
            y: 0,
            x: 0,
        };

        let status_line_rect = Rect {
            height: status_line_height,
            width: max_x - gutter_width,
            y: mini_buf_height,
            x: gutter_width,
        };

        Layout {
            gutter_rect: gutter_rect,
            list_view_rect: list_view_rect,
            mini_buf_rect: mini_buf_rect,
            status_line_rect: status_line_rect,
        }
    }
}

pub fn initialize() {
    let s = CString::new("").unwrap();
    unsafe { libc_aux::setlocale(libc_aux::LC_ALL, s.as_ptr()); }
    nc::initscr();
    nc::noecho();
    nc::raw();
}

pub fn finalize() {
    nc::endwin();
}
<commit_msg>Make it able to pipe to another process<commit_after>use ncurses as nc;
use std::ffi::CString;

use libc;
use libc_aux;
use screen_data::ScreenData;
use window::{Rect, Window};
use window::{Gutter, ListView, MiniBuf, StatusLine};

pub struct Screen {
    gutter: Window,
    list_view: Window,
    mini_buf: Window,
    status_line: Window,
}

impl Screen {
    pub fn new() -> Self {
        let layout = Layout::new();
        let gutter = Window::new(Gutter, layout.gutter_rect);
        let list_view = Window::new(ListView, layout.list_view_rect);
        let mini_buf = Window::new(MiniBuf, layout.mini_buf_rect);
        let status_line = Window::new(StatusLine, layout.status_line_rect);
        Screen {
            gutter: gutter,
            list_view: list_view,
            mini_buf: mini_buf,
            status_line: status_line,
        }
    }

    pub fn update(&self, sd: ScreenData) {
        for win in [&self.gutter, &self.list_view, &self.mini_buf, &self.status_line].iter() {
            win.clear();
            win.draw(&sd);
            win.noutrefresh();
        }
        MiniBuf::set_cursor(&self.mini_buf, sd.cursor_index as i32);
        nc::doupdate();
    }

    pub fn list_view_height(&self) -> usize {
        self.list_view.rect().height as usize
    }
}

struct Layout {
    gutter_rect: Rect,
    list_view_rect: Rect,
    mini_buf_rect: Rect,
    status_line_rect: Rect,
}

impl Layout {
    fn new() -> Layout {
        let mut max_y = 0i32;
        let mut max_x = 0i32;
        nc::getmaxyx(nc::stdscr, &mut max_y, &mut max_x);

        let gutter_width = 2;
        let mini_buf_height = 1;
        let status_line_height = 1;

        let gutter_rect = Rect {
            height: max_y - mini_buf_height - status_line_height,
            width: gutter_width,
            y: mini_buf_height + status_line_height,
            x: 0,
        };

        let list_view_rect = Rect {
            height: max_y - mini_buf_height - status_line_height,
            width: max_x - gutter_width,
            y: mini_buf_height + status_line_height,
            x: gutter_width,
        };

        let mini_buf_rect = Rect {
            height: mini_buf_height,
            width: max_x,
            y: 0,
            x: 0,
        };

        let status_line_rect = Rect {
            height: status_line_height,
            width: max_x - gutter_width,
            y: mini_buf_height,
            x: gutter_width,
        };

        Layout {
            gutter_rect: gutter_rect,
            list_view_rect: list_view_rect,
            mini_buf_rect: mini_buf_rect,
            status_line_rect: status_line_rect,
        }
    }
}

pub fn initialize() {
    let s = CString::new("").unwrap();
    unsafe {
        libc_aux::setlocale(libc_aux::LC_ALL, s.as_ptr());
        libc::dup2(1, 3);
        libc::dup2(2, 1);
    }
    nc::initscr();
    nc::noecho();
    nc::raw();
}

pub fn finalize() {
    nc::endwin();
    unsafe {
        libc::dup2(3, 1);
    }
}
<|endoftext|>


<commit_before>use sentry::{ClientInitGuard, ClientOptions, IntoDsn};

/// Initializes the Sentry SDK from the environment variables.
///
/// If `SENTRY_DSN_API` is not set then Sentry will not be initialized,
/// otherwise it is required to be a valid DSN string. `SENTRY_ENV_API` must
/// be set if a DSN is provided.
///
/// `HEROKU_SLUG_COMMIT`, if present, will be used as the `release` property
/// on all events.
pub fn init() -> ClientInitGuard {
    let dsn = dotenv::var("SENTRY_DSN_API")
        .ok()
        .into_dsn()
        .expect("SENTRY_DSN_API is not a valid Sentry DSN value");

    let environment = dsn.as_ref().map(|_| {
        dotenv::var("SENTRY_ENV_API")
            .expect("SENTRY_ENV_API must be set when using SENTRY_DSN_API")
            .into()
    });

    let release = dotenv::var("HEROKU_SLUG_COMMIT").ok().map(Into::into);

    let opts = ClientOptions {
        dsn,
        environment,
        release,
        ..Default::default()
    };

    sentry::init(opts)
}
<commit_msg>sentry: Enable `auto_session_tracking`<commit_after>use sentry::{ClientInitGuard, ClientOptions, IntoDsn};

/// Initializes the Sentry SDK from the environment variables.
///
/// If `SENTRY_DSN_API` is not set then Sentry will not be initialized,
/// otherwise it is required to be a valid DSN string. `SENTRY_ENV_API` must
/// be set if a DSN is provided.
///
/// `HEROKU_SLUG_COMMIT`, if present, will be used as the `release` property
/// on all events.
pub fn init() -> ClientInitGuard {
    let dsn = dotenv::var("SENTRY_DSN_API")
        .ok()
        .into_dsn()
        .expect("SENTRY_DSN_API is not a valid Sentry DSN value");

    let environment = dsn.as_ref().map(|_| {
        dotenv::var("SENTRY_ENV_API")
            .expect("SENTRY_ENV_API must be set when using SENTRY_DSN_API")
            .into()
    });

    let release = dotenv::var("HEROKU_SLUG_COMMIT").ok().map(Into::into);

    let opts = ClientOptions {
        auto_session_tracking: true,
        dsn,
        environment,
        release,
        session_mode: sentry::SessionMode::Request,
        ..Default::default()
    };

    sentry::init(opts)
}
<|endoftext|>


<commit_before>use std::net::{TcpStream, TcpListener};
use std::io::Write;
use std::thread;
use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering, ATOMIC_USIZE_INIT, ATOMIC_BOOL_INIT};

pub static PORT: AtomicUsize = ATOMIC_USIZE_INIT;
pub static SERVER_THREAD_SPAWNED: AtomicBool = ATOMIC_BOOL_INIT;

pub fn start() {
    if is_server_thread_spawned() { return }

    thread::spawn(move || {
        let listener = TcpListener::bind("127.0.0.1:0").unwrap();
        let port     = listener.local_addr().unwrap().port() as usize;

        PORT.store(port, Ordering::SeqCst);

        for stream in listener.incoming() {
            match stream {
                Ok(stream) => handle_client(stream),
                Err(e)     => println!("Error: {}", e)
            }
        }

        drop(listener);
    });

    SERVER_THREAD_SPAWNED.store(true, Ordering::SeqCst);

    while !is_running() {}
}

pub fn is_server_thread_spawned() -> bool {
    SERVER_THREAD_SPAWNED.load(Ordering::SeqCst)
}

pub fn is_running() -> bool {
    port() != 0
}

pub fn port() -> usize {
    PORT.load(Ordering::SeqCst)
}

pub fn host() -> String {
    format!("127.0.0.1:{}", port())
}

pub fn host_with_protocol() -> String {
    format!("http://127.0.0.1:{}", port())
}

fn handle_client(mut stream: TcpStream) {
    let response = "HTTP/1.1 200 OK\n\nHello world";

    stream.write(response.as_bytes()).unwrap();
}

#[cfg(test)]
mod tests {
    use server;

    #[test]
    fn test_start_server() {
        server::start();

        assert!(server::is_server_thread_spawned());
        assert!(server::is_running());
        assert!(server::port() != 0);
    }
}
<commit_msg>server_thread_spawned<commit_after>use std::net::{TcpStream, TcpListener};
use std::io::Write;
use std::thread;
use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering, ATOMIC_USIZE_INIT, ATOMIC_BOOL_INIT};

pub static PORT: AtomicUsize = ATOMIC_USIZE_INIT;
pub static SERVER_THREAD_SPAWNED: AtomicBool = ATOMIC_BOOL_INIT;

pub fn start() {
    // Ensures only one server is running.
    if is_server_thread_spawned() { return }

    thread::spawn(move || {
        SERVER_THREAD_SPAWNED.store(true, Ordering::SeqCst);

        let listener = TcpListener::bind("127.0.0.1:0").unwrap();
        let port     = listener.local_addr().unwrap().port() as usize;

        PORT.store(port, Ordering::SeqCst);

        for stream in listener.incoming() {
            match stream {
                Ok(stream) => handle_client(stream),
                Err(e)     => println!("Error: {}", e)
            }
        }

        drop(listener);
    });

    while !is_running() {}
}

pub fn is_server_thread_spawned() -> bool {
    SERVER_THREAD_SPAWNED.load(Ordering::SeqCst)
}

pub fn is_running() -> bool {
    port() != 0
}

pub fn port() -> usize {
    PORT.load(Ordering::SeqCst)
}

pub fn host() -> String {
    format!("127.0.0.1:{}", port())
}

pub fn host_with_protocol() -> String {
    format!("http://127.0.0.1:{}", port())
}

fn handle_client(mut stream: TcpStream) {
    let response = "HTTP/1.1 200 OK\n\nHello world";

    stream.write(response.as_bytes()).unwrap();
}

#[cfg(test)]
mod tests {
    use server;

    #[test]
    fn test_start_server() {
        server::start();

        assert!(server::is_server_thread_spawned());
        assert!(server::is_running());
        assert!(server::port() != 0);
    }
}
<|endoftext|>


<commit_before>use std::thread;
use std::path::Path;
use std::cell::RefCell;

use websocket::{Server, Message, Sender, Receiver};
use websocket::message::Type;
use websocket::header::WebSocketProtocol;

extern crate md5;

extern crate git2;
use self::git2::Repository;
use self::git2::Reference;
use self::git2::Statuses;
use self::git2::StatusOptions;
use self::git2::Delta;
use self::git2::ObjectType;

extern crate yaml_rust;
use self::yaml_rust::YamlLoader;

use project;

use serde_xml as xml;

#[derive(Debug, Serialize, Deserialize)]
struct Commit {
    message: String,
    include: Vec<String>
}

impl Commit {
}

pub fn start() {
    let server = Server::bind("127.0.0.1:2794").unwrap();
    thread::spawn(move || {
        for connection in server {
            thread::spawn(move || {
                let request = connection.unwrap().read_request().unwrap();
                let headers = request.headers.clone();
                request.validate().unwrap();
                let mut response = request.accept();
                println!("Connected");

                if let Some(&WebSocketProtocol(ref protocols)) = headers.get() {
                    if protocols.contains(&("rust-websocket".to_string())) {
                        response.headers.set(WebSocketProtocol(vec!["superconductor".to_string()]));
                    }
                }

                let mut client = response.send().unwrap();
                let message = Message::text(generate_payload());
                client.send_message(&message).unwrap();

                let (mut sender, mut receiver) = client.split();
                for message in receiver.incoming_messages() {
                    let message: Message = message.unwrap();
                    match message.opcode {
                        Type::Close => {
                            let message = Message::close();
                            sender.send_message(&message).unwrap();
                            println!("Client disconnected");
                            return;
                        },
                        Type::Ping => {
                            let message = Message::pong(message.payload);
                            sender.send_message(&message).unwrap();
                        },
                        _ => {
                            let payload = String::from_utf8_lossy(message.payload.as_ref());
                            let commit: Commit = xml::from_str(&payload).unwrap();
                            println!("{:?}", commit);
                            let repo = Repository::discover(".").unwrap();
                            let head = repo.head().unwrap().peel(ObjectType::Commit).unwrap();
                            let mut index = repo.index().unwrap();

                            let to_remove = index.iter().fold(vec![], |mut acc, entry| {
                                let entry_path = String::from_utf8_lossy(entry.path.as_ref());
                                match commit.include.iter().find(|i| i.as_ref() == entry_path) {
                                    None => acc.push(entry_path.into_owned()),
                                    _ => {}
                                };
                                acc
                            });

                            println!("removed: {:?}", to_remove);
                            repo.reset_default(Some(&head), to_remove.iter());
                            //for change in to_remove {
                            //    let path = Path::new(&change);
                            //    index.remove(path, 1);
                            //}
                            for change in commit.include {
                                let path = Path::new(&change);
                                index.add_path(path);
                            }
                            index.write().unwrap();
                            let message = Message::text(generate_payload());
                            sender.send_message(&message).unwrap();
                        }
                    }
                }
            });
        }
    });
}

fn generate_payload() -> String {
    let current = project::current();
    let repo = Repository::discover(".").unwrap();
    let mut revwalk = repo.revwalk().unwrap();
    revwalk.set_sorting(git2::SORT_REVERSE);
    revwalk.push_head();
    let mut status_opts = StatusOptions::new();
    status_opts.include_untracked(true);

    let payload = html! {
        state {
            user {
                name  (current.user.name)
                    email (current.user.email)
            }
            task {
                id (current.task.id)
            }
            log {
                @for rev in revwalk {
                    @let commit = repo.find_commit(rev.unwrap()).unwrap() {
                        commit {
                            id (commit.id())
                            user {
                                @let author = commit.author() {
                                    name  (author.name().unwrap())
                                        @let email = author.email().unwrap().trim() {
                                            email (email)
                                            image (format!("https://www.gravatar.com/avatar/{:x}?s=64", md5::compute(email.to_lowercase())))
                                        }
                                }
                            }
                            @let mut message = commit.message().unwrap().split("\n---") {
                                message (message.next().unwrap())
                                @if let Some(yaml) = message.next() {
                                    @for (objective, values) in YamlLoader::load_from_str(yaml).unwrap()[0].as_hash().unwrap() {
                                        objective {
                                            name (objective.as_str().unwrap_or("None"))
                                            @for (name, value) in values.as_hash().unwrap() {
                                                property {
                                                    name (name.as_str().unwrap_or("None"))
                                                    after (value.as_str().unwrap_or("None"))
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            changes {
                @for change in repo.statuses(Some(&mut status_opts)).unwrap().iter() {
                    change {
                        path (change.path().unwrap())
                        included @match change.head_to_index().map(|d| d.status()).unwrap_or(Delta::Unreadable) {
                            Delta::Modified | Delta::Added | Delta::Deleted => "true",
                            _ => "false"
                        }
                        removal @match change.head_to_index().map(|d| d.status()).unwrap_or(Delta::Unreadable) {
                            Delta::Deleted => "true",
                            _ => "false"
                        }
                    }
                }
            }
        }
    }.into_string();
    payload
}
<commit_msg>unchecking changes resets the index<commit_after>use std::thread;
use std::path::Path;
use std::cell::RefCell;

use websocket::{Server, Message, Sender, Receiver};
use websocket::message::Type;
use websocket::header::WebSocketProtocol;

extern crate md5;

extern crate git2;
use self::git2::Repository;
use self::git2::Reference;
use self::git2::Statuses;
use self::git2::StatusOptions;
use self::git2::Delta;
use self::git2::ObjectType;

extern crate yaml_rust;
use self::yaml_rust::YamlLoader;

use project;

use serde_xml as xml;

#[derive(Debug, Serialize, Deserialize)]
struct Commit {
    message: String,
    include: Vec<String>
}

impl Commit {
}

pub fn start() {
    let server = Server::bind("127.0.0.1:2794").unwrap();
    thread::spawn(move || {
        for connection in server {
            thread::spawn(move || {
                let request = connection.unwrap().read_request().unwrap();
                let headers = request.headers.clone();
                request.validate().unwrap();
                let mut response = request.accept();
                println!("Connected");

                if let Some(&WebSocketProtocol(ref protocols)) = headers.get() {
                    if protocols.contains(&("rust-websocket".to_string())) {
                        response.headers.set(WebSocketProtocol(vec!["superconductor".to_string()]));
                    }
                }

                let mut client = response.send().unwrap();
                let message = Message::text(generate_payload());
                client.send_message(&message).unwrap();

                let (mut sender, mut receiver) = client.split();
                for message in receiver.incoming_messages() {
                    let message: Message = message.unwrap();
                    match message.opcode {
                        Type::Close => {
                            let message = Message::close();
                            sender.send_message(&message).unwrap();
                            println!("Client disconnected");
                            return;
                        },
                        Type::Ping => {
                            let message = Message::pong(message.payload);
                            sender.send_message(&message).unwrap();
                        },
                        _ => {
                            let payload = String::from_utf8_lossy(message.payload.as_ref());
                            let commit: Commit = xml::from_str(&payload).unwrap();
                            println!("{:?}", commit);
                            let repo = Repository::discover(".").unwrap();
                            let head = repo.head().unwrap().peel(ObjectType::Commit).unwrap();
                            let mut index = repo.index().unwrap();

                            let to_remove = index.iter().fold(vec![], |mut acc, entry| {
                                let entry_path = String::from_utf8_lossy(entry.path.as_ref());
                                match commit.include.iter().find(|i| i.as_ref() == entry_path) {
                                    None => acc.push(entry_path.into_owned()),
                                    _ => {}
                                };
                                acc
                            });

                            println!("removed: {:?}", to_remove);
                            repo.reset_default(Some(&head), to_remove.iter());
                            for change in commit.include {
                                let path = Path::new(&change);
                                index.add_path(path);
                            }
                            index.write().unwrap();
                            let message = Message::text(generate_payload());
                            sender.send_message(&message).unwrap();
                        }
                    }
                }
            });
        }
    });
}

fn generate_payload() -> String {
    let current = project::current();
    let repo = Repository::discover(".").unwrap();
    let mut revwalk = repo.revwalk().unwrap();
    revwalk.set_sorting(git2::SORT_REVERSE);
    revwalk.push_head();
    let mut status_opts = StatusOptions::new();
    status_opts.include_untracked(true);

    let payload = html! {
        state {
            user {
                name  (current.user.name)
                    email (current.user.email)
            }
            task {
                id (current.task.id)
            }
            log {
                @for rev in revwalk {
                    @let commit = repo.find_commit(rev.unwrap()).unwrap() {
                        commit {
                            id (commit.id())
                            user {
                                @let author = commit.author() {
                                    name  (author.name().unwrap())
                                        @let email = author.email().unwrap().trim() {
                                            email (email)
                                            image (format!("https://www.gravatar.com/avatar/{:x}?s=64", md5::compute(email.to_lowercase())))
                                        }
                                }
                            }
                            @let mut message = commit.message().unwrap().split("\n---") {
                                message (message.next().unwrap())
                                @if let Some(yaml) = message.next() {
                                    @for (objective, values) in YamlLoader::load_from_str(yaml).unwrap()[0].as_hash().unwrap() {
                                        objective {
                                            name (objective.as_str().unwrap_or("None"))
                                            @for (name, value) in values.as_hash().unwrap() {
                                                property {
                                                    name (name.as_str().unwrap_or("None"))
                                                    after (value.as_str().unwrap_or("None"))
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            changes {
                @for change in repo.statuses(Some(&mut status_opts)).unwrap().iter() {
                    change {
                        path (change.path().unwrap())
                        included @match change.head_to_index().map(|d| d.status()).unwrap_or(Delta::Unreadable) {
                            Delta::Modified | Delta::Added | Delta::Deleted => "true",
                            _ => "false"
                        }
                        removal @match change.head_to_index().map(|d| d.status()).unwrap_or(Delta::Unreadable) {
                            Delta::Deleted => "true",
                            _ => "false"
                        }
                    }
                }
            }
        }
    }.into_string();
    payload
}
<|endoftext|>


<commit_before>use crate::future::Future;
use crate::pin::Pin;
use crate::task::{Context, Poll};

/// Creates a future that is immediately ready with a value.
///
/// This `struct` is created by [`ready()`]. See its
/// documentation for more.
#[stable(feature = "future_readiness_fns", since = "1.48.0")]
#[derive(Debug, Clone)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Ready<T>(Option<T>);

#[stable(feature = "future_readiness_fns", since = "1.48.0")]
impl<T> Unpin for Ready<T> {}

#[stable(feature = "future_readiness_fns", since = "1.48.0")]
impl<T> Future for Ready<T> {
    type Output = T;

    #[inline]
    fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<T> {
        Poll::Ready(self.0.take().expect("Ready polled after completion"))
    }
}

/// Creates a future that is immediately ready with a value.
///
/// Futures created through this function are functionally similar to those
/// created through `async {}`. The main difference is that futures created
/// through this function are named and implement `Unpin`.
///
/// # Examples
///
/// ```
/// use std::future;
///
/// # async fn run() {
/// let a = future::ready(1);
/// assert_eq!(a.await, 1);
/// # }
/// ```
#[stable(feature = "future_readiness_fns", since = "1.48.0")]
pub fn ready<T>(t: T) -> Ready<T> {
    Ready(Some(t))
}
<commit_msg>Use backticks when referring to `core::future::Ready` in panic message<commit_after>use crate::future::Future;
use crate::pin::Pin;
use crate::task::{Context, Poll};

/// Creates a future that is immediately ready with a value.
///
/// This `struct` is created by [`ready()`]. See its
/// documentation for more.
#[stable(feature = "future_readiness_fns", since = "1.48.0")]
#[derive(Debug, Clone)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Ready<T>(Option<T>);

#[stable(feature = "future_readiness_fns", since = "1.48.0")]
impl<T> Unpin for Ready<T> {}

#[stable(feature = "future_readiness_fns", since = "1.48.0")]
impl<T> Future for Ready<T> {
    type Output = T;

    #[inline]
    fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<T> {
        Poll::Ready(self.0.take().expect("`Ready` polled after completion"))
    }
}

/// Creates a future that is immediately ready with a value.
///
/// Futures created through this function are functionally similar to those
/// created through `async {}`. The main difference is that futures created
/// through this function are named and implement `Unpin`.
///
/// # Examples
///
/// ```
/// use std::future;
///
/// # async fn run() {
/// let a = future::ready(1);
/// assert_eq!(a.await, 1);
/// # }
/// ```
#[stable(feature = "future_readiness_fns", since = "1.48.0")]
pub fn ready<T>(t: T) -> Ready<T> {
    Ready(Some(t))
}
<|endoftext|>


<commit_before>use std;

fn find_pyrhagorean(sum: u64) -> [(u64, u64, u64)] {
    let answer = [];
    uint::range(2u64, sum - 2u) { |c|
        uint::range(1u64, (sum - c) / 2u) { |a|
            let b = sum - c - a;
            if a * a + b * b == c * c {
                answer += [(a, b, c)];
            }
        }
    }
    ret answer;
}

fn main() {
    for (a, b, c) in find_pyrhagorean(1000u) {
        std::io::println(#fmt("%u^2 + %u^2 = %u^2", a, b, c));
        std::io::println(#fmt("prod: %u", a * b * c));
    }
}
<commit_msg>Reduce extra check<commit_after>use std;

fn isqrt(n: u64) -> u64 {
    let (min, max) = (0u64, n);
    while min < max {
        let mid = (min + max + 1u64) / 2u64;
        if (mid * mid) == n {
            ret mid;
        } else if (mid * mid) >= n {
            max = mid - 1u64;
        } else {
            min = mid;
        }
    }
    ret min;
}

fn find_pyrhagorean(sum: u64) -> [(u64, u64, u64)] {
    let answer = [];
    uint::range(2u64, sum - 2u) { |c|
        uint::range(1u64, uint::min((sum - c) / 2u, isqrt(c*c / 2u))) { |a|
            let b = sum - c - a;
            if a * a + b * b == c * c {
                answer += [(a, b, c)];
            }
        }
    }
    ret answer;
}

fn main() {
    for (a, b, c) in find_pyrhagorean(1000u) {
        std::io::println(#fmt("%u^2 + %u^2 = %u^2", a, b, c));
        std::io::println(#fmt("prod: %u", a * b * c));
    }
}
<|endoftext|>


<commit_before>enum OptionalInt {
    Value(int),
    Missing,
}

fn _9_1(){
    println!("guide 9-1");
    let x = OptionalInt::Value(5);
    let y = OptionalInt::Missing;

    match x {
        OptionalInt::Value(n) => println!("x is {}", n),
        OptionalInt::Missing  => println!("x is missing!"),
    }

    match y {
        OptionalInt::Value(n) => println!("y is {}", n),
        OptionalInt::Missing  => println!("y is missing!"),
    }
}

fn cmp(a: int, b: int) -> Ordering {
    if a < b { Less }
    else if a > b { Greater }
    else { Equal }
}

fn _9_2(){
    println!("guide 9-2");
    let x = 5i;
    let y = 10i;

    println!("{}", match cmp(x, y) {
        Less    => "less",
        Greater => "greater",
        Equal   => "equal",
    });
}

fn main(){
    println!("guide-9");
    _9_1();
    _9_2();
}
<commit_msg>fix types<commit_after>use std::cmp::Ordering;
use std::cmp::Ordering::{Less, Greater, Equal};

enum OptionalInt {
    Value(i32),
    Missing,
}

fn _9_1(){
    println!("guide 9-1");
    let x = OptionalInt::Value(5);
    let y = OptionalInt::Missing;

    match x {
        OptionalInt::Value(n) => println!("x is {}", n),
        OptionalInt::Missing  => println!("x is missing!"),
    }

    match y {
        OptionalInt::Value(n) => println!("y is {}", n),
        OptionalInt::Missing  => println!("y is missing!"),
    }
}

fn cmp(a: i32, b: i32) -> Ordering {
    if a < b { Less }
    else if a > b { Greater }
    else { Equal }
}

fn _9_2(){
    println!("guide 9-2");
    let x = 5i32;
    let y = 10i32;

    println!("{}", match cmp(x, y) {
        Less    => "less",
        Greater => "greater",
        Equal   => "equal",
    });
}

fn main(){
    println!("guide-9");
    _9_1();
    _9_2();
}
<|endoftext|>


<commit_before>// Original implementation taken from rust-memchr.
// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch

// ignore-tidy-undocumented-unsafe

use crate::cmp;
use crate::mem;

const LO_U64: u64 = 0x0101010101010101;
const HI_U64: u64 = 0x8080808080808080;

// Use truncation.
const LO_USIZE: usize = LO_U64 as usize;
const HI_USIZE: usize = HI_U64 as usize;
const USIZE_BYTES: usize = mem::size_of::<usize>();

/// Returns `true` if `x` contains any zero byte.
///
/// From *Matters Computational*, J. Arndt:
///
/// "The idea is to subtract one from each of the bytes and then look for
/// bytes where the borrow propagated all the way to the most significant
/// bit."
#[inline]
fn contains_zero_byte(x: usize) -> bool {
    x.wrapping_sub(LO_USIZE) & !x & HI_USIZE != 0
}

#[cfg(target_pointer_width = "16")]
#[inline]
fn repeat_byte(b: u8) -> usize {
    (b as usize) << 8 | b as usize
}

#[cfg(not(target_pointer_width = "16"))]
#[inline]
fn repeat_byte(b: u8) -> usize {
    (b as usize) * (usize::MAX / 255)
}

/// Returns the first index matching the byte `x` in `text`.
#[inline]
pub fn memchr(x: u8, text: &[u8]) -> Option<usize> {
    // Fast path for small slices
    if text.len() < 2 * USIZE_BYTES {
        return text.iter().position(|elt| *elt == x);
    }

    memchr_general_case(x, text)
}

fn memchr_general_case(x: u8, text: &[u8]) -> Option<usize> {
    // Scan for a single byte value by reading two `usize` words at a time.
    //
    // Split `text` in three parts
    // - unaligned initial part, before the first word aligned address in text
    // - body, scan by 2 words at a time
    // - the last remaining part, < 2 word size

    // search up to an aligned boundary
    let len = text.len();
    let ptr = text.as_ptr();
    let mut offset = ptr.align_offset(USIZE_BYTES);

    if offset > 0 {
        offset = cmp::min(offset, len);
        if let Some(index) = text[..offset].iter().position(|elt| *elt == x) {
            return Some(index);
        }
    }

    // search the body of the text
    let repeated_x = repeat_byte(x);
    while offset <= len - 2 * USIZE_BYTES {
        unsafe {
            let u = *(ptr.add(offset) as *const usize);
            let v = *(ptr.add(offset + USIZE_BYTES) as *const usize);

            // break if there is a matching byte
            let zu = contains_zero_byte(u ^ repeated_x);
            let zv = contains_zero_byte(v ^ repeated_x);
            if zu || zv {
                break;
            }
        }
        offset += USIZE_BYTES * 2;
    }

    // Find the byte after the point the body loop stopped.
    text[offset..].iter().position(|elt| *elt == x).map(|i| offset + i)
}

/// Returns the last index matching the byte `x` in `text`.
pub fn memrchr(x: u8, text: &[u8]) -> Option<usize> {
    // Scan for a single byte value by reading two `usize` words at a time.
    //
    // Split `text` in three parts:
    // - unaligned tail, after the last word aligned address in text,
    // - body, scanned by 2 words at a time,
    // - the first remaining bytes, < 2 word size.
    let len = text.len();
    let ptr = text.as_ptr();
    type Chunk = usize;

    let (min_aligned_offset, max_aligned_offset) = {
        // We call this just to obtain the length of the prefix and suffix.
        // In the middle we always process two chunks at once.
        let (prefix, _, suffix) = unsafe { text.align_to::<(Chunk, Chunk)>() };
        (prefix.len(), len - suffix.len())
    };

    let mut offset = max_aligned_offset;
    if let Some(index) = text[offset..].iter().rposition(|elt| *elt == x) {
        return Some(offset + index);
    }

    // Search the body of the text, make sure we don't cross min_aligned_offset.
    // offset is always aligned, so just testing `>` is sufficient and avoids possible
    // overflow.
    let repeated_x = repeat_byte(x);
    let chunk_bytes = mem::size_of::<Chunk>();

    while offset > min_aligned_offset {
        unsafe {
            let u = *(ptr.offset(offset as isize - 2 * chunk_bytes as isize) as *const Chunk);
            let v = *(ptr.offset(offset as isize - chunk_bytes as isize) as *const Chunk);

            // Break if there is a matching byte.
            let zu = contains_zero_byte(u ^ repeated_x);
            let zv = contains_zero_byte(v ^ repeated_x);
            if zu || zv {
                break;
            }
        }
        offset -= 2 * chunk_bytes;
    }

    // Find the byte before the point the body loop stopped.
    text[..offset].iter().rposition(|elt| *elt == x)
}
<commit_msg>Auto merge of #76688 - yokodake:patch-2, r=kodrAus<commit_after>// Original implementation taken from rust-memchr.
// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch

use crate::cmp;
use crate::mem;

const LO_U64: u64 = 0x0101010101010101;
const HI_U64: u64 = 0x8080808080808080;

// Use truncation.
const LO_USIZE: usize = LO_U64 as usize;
const HI_USIZE: usize = HI_U64 as usize;
const USIZE_BYTES: usize = mem::size_of::<usize>();

/// Returns `true` if `x` contains any zero byte.
///
/// From *Matters Computational*, J. Arndt:
///
/// "The idea is to subtract one from each of the bytes and then look for
/// bytes where the borrow propagated all the way to the most significant
/// bit."
#[inline]
fn contains_zero_byte(x: usize) -> bool {
    x.wrapping_sub(LO_USIZE) & !x & HI_USIZE != 0
}

#[cfg(target_pointer_width = "16")]
#[inline]
fn repeat_byte(b: u8) -> usize {
    (b as usize) << 8 | b as usize
}

#[cfg(not(target_pointer_width = "16"))]
#[inline]
fn repeat_byte(b: u8) -> usize {
    (b as usize) * (usize::MAX / 255)
}

/// Returns the first index matching the byte `x` in `text`.
#[inline]
pub fn memchr(x: u8, text: &[u8]) -> Option<usize> {
    // Fast path for small slices
    if text.len() < 2 * USIZE_BYTES {
        return text.iter().position(|elt| *elt == x);
    }

    memchr_general_case(x, text)
}

fn memchr_general_case(x: u8, text: &[u8]) -> Option<usize> {
    // Scan for a single byte value by reading two `usize` words at a time.
    //
    // Split `text` in three parts
    // - unaligned initial part, before the first word aligned address in text
    // - body, scan by 2 words at a time
    // - the last remaining part, < 2 word size

    // search up to an aligned boundary
    let len = text.len();
    let ptr = text.as_ptr();
    let mut offset = ptr.align_offset(USIZE_BYTES);

    if offset > 0 {
        offset = cmp::min(offset, len);
        if let Some(index) = text[..offset].iter().position(|elt| *elt == x) {
            return Some(index);
        }
    }

    // search the body of the text
    let repeated_x = repeat_byte(x);
    while offset <= len - 2 * USIZE_BYTES {
        // SAFETY: the while's predicate guarantees a distance of at least 2 * usize_bytes
        // between the offset and the end of the slice.
        unsafe {
            let u = *(ptr.add(offset) as *const usize);
            let v = *(ptr.add(offset + USIZE_BYTES) as *const usize);

            // break if there is a matching byte
            let zu = contains_zero_byte(u ^ repeated_x);
            let zv = contains_zero_byte(v ^ repeated_x);
            if zu || zv {
                break;
            }
        }
        offset += USIZE_BYTES * 2;
    }

    // Find the byte after the point the body loop stopped.
    text[offset..].iter().position(|elt| *elt == x).map(|i| offset + i)
}

/// Returns the last index matching the byte `x` in `text`.
pub fn memrchr(x: u8, text: &[u8]) -> Option<usize> {
    // Scan for a single byte value by reading two `usize` words at a time.
    //
    // Split `text` in three parts:
    // - unaligned tail, after the last word aligned address in text,
    // - body, scanned by 2 words at a time,
    // - the first remaining bytes, < 2 word size.
    let len = text.len();
    let ptr = text.as_ptr();
    type Chunk = usize;

    let (min_aligned_offset, max_aligned_offset) = {
        // We call this just to obtain the length of the prefix and suffix.
        // In the middle we always process two chunks at once.
        // SAFETY: transmuting `[u8]` to `[usize]` is safe except for size differences
        // which are handled by `align_to`.
        let (prefix, _, suffix) = unsafe { text.align_to::<(Chunk, Chunk)>() };
        (prefix.len(), len - suffix.len())
    };

    let mut offset = max_aligned_offset;
    if let Some(index) = text[offset..].iter().rposition(|elt| *elt == x) {
        return Some(offset + index);
    }

    // Search the body of the text, make sure we don't cross min_aligned_offset.
    // offset is always aligned, so just testing `>` is sufficient and avoids possible
    // overflow.
    let repeated_x = repeat_byte(x);
    let chunk_bytes = mem::size_of::<Chunk>();

    while offset > min_aligned_offset {
        // SAFETY: offset starts at len - suffix.len(), as long as it is greater than
        // min_aligned_offset (prefix.len()) the remaining distance is at least 2 * chunk_bytes.
        unsafe {
            let u = *(ptr.offset(offset as isize - 2 * chunk_bytes as isize) as *const Chunk);
            let v = *(ptr.offset(offset as isize - chunk_bytes as isize) as *const Chunk);

            // Break if there is a matching byte.
            let zu = contains_zero_byte(u ^ repeated_x);
            let zv = contains_zero_byte(v ^ repeated_x);
            if zu || zv {
                break;
            }
        }
        offset -= 2 * chunk_bytes;
    }

    // Find the byte before the point the body loop stopped.
    text[..offset].iter().rposition(|elt| *elt == x)
}
<|endoftext|>


<commit_before>pub fn find_duplicate(paths: Vec<String>) -> Vec<Vec<String>> {
    use std::collections::HashMap;
    let mut record: HashMap<String, Vec<String>> = HashMap::new();

    for a in paths {
        let mut split = a.split_ascii_whitespace();
        //Or let mut split = a.split_whitespace();
        let this_path = split.next().unwrap();

        for file in split {
            //println!("{:?}", file);
            let content = file.split(|x| x == '(' || x == ')').collect::<Vec<&str>>();
            //println!("{:?}", content);
            let v = record.entry(String::from(content[1])).or_insert(vec![]);
            v.push(String::from(this_path) + "/" + content[0]);
        }
    }

    let mut result = vec![];
    for v in record.values() {
        if v.len() > 1 {
            result.push(v.clone());
        }
    }

    result
}

fn main() {
    println!(
        "{:?}",
        find_duplicate(vec![
            String::from("root/a 1.txt(abcd) 2.txt(efgh)"),
            String::from("root/c 3.txt(abcd)"),
            String::from("root/c/d 4.txt(efgh)"),
            String::from("root 4.txt(efgh)")
        ])
    )
}
<commit_msg>test time cost between lisp and rust<commit_after>pub fn find_duplicate(paths: Vec<String>) -> Vec<Vec<String>> {
    use std::collections::HashMap;
    let mut record: HashMap<String, Vec<String>> = HashMap::new();

    for a in paths {
        let mut split = a.split_ascii_whitespace();
        //Or let mut split = a.split_whitespace();
        let this_path = split.next().unwrap();

        for file in split {
            //println!("{:?}", file);
            let content = file.split(|x| x == '(' || x == ')').collect::<Vec<&str>>();
            //println!("{:?}", content);
            let v = record.entry(String::from(content[1])).or_insert(vec![]);
            v.push(String::from(this_path) + "/" + content[0]);
        }
    }

    let mut result = vec![];
    for v in record.values() {
        if v.len() > 1 {
            result.push(v.clone());
        }
    }

    result
}

fn main() {
    use std::time::Instant;
    let a = Instant::now();
    find_duplicate(vec![
        String::from("root/a 1.txt(abcd) 2.txt(efgh)"),
        String::from("root/c 3.txt(abcd)"),
        String::from("root/c/d 4.txt(efgh)"),
        String::from("root 4.txt(efgh)"),
    ]);
    let b = a.elapsed();
    println!("{}", b.as_micros());

    println!(
        "{:?}",
        find_duplicate(vec![
            String::from("root/a 1.txt(abcd) 2.txt(efgh)"),
            String::from("root/c 3.txt(abcd)"),
            String::from("root/c/d 4.txt(efgh)"),
            String::from("root 4.txt(efgh)")
        ])
    )
}
<|endoftext|>