<commit_before>use futures_core::future::{FusedFuture, Future};
use futures_core::task::{Context, Poll, Waker};
use slab::Slab;
use std::{fmt, mem};
use std::cell::UnsafeCell;
use std::ops::{Deref, DerefMut};
use std::pin::Pin;
use std::sync::Mutex as StdMutex;
use std::sync::atomic::{AtomicUsize, Ordering};

/// A futures-aware mutex.
pub struct Mutex<T: ?Sized> {
    state: AtomicUsize,
    waiters: StdMutex<Slab<Waiter>>,
    value: UnsafeCell<T>,
}

impl<T: ?Sized> fmt::Debug for Mutex<T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let state = self.state.load(Ordering::SeqCst);
        f.debug_struct("Mutex")
            .field("is_locked", &((state & IS_LOCKED) != 0))
            .field("has_waiters", &((state & HAS_WAITERS) != 0))
            .finish()
    }
}

impl<T> From<T> for Mutex<T> {
    fn from(t: T) -> Self {
        Self::new(t)
    }
}

impl<T: Default> Default for Mutex<T> {
    fn default() -> Mutex<T> {
        Mutex::new(Default::default())
    }
}

enum Waiter {
    Waiting(Waker),
    Woken,
}

impl Waiter {
    fn register(&mut self, waker: &Waker) {
        match self {
            Waiter::Waiting(w) if waker.will_wake(w) => {},
            _ => *self = Waiter::Waiting(waker.clone()),
        }
    }

    fn wake(&mut self) {
        match mem::replace(self, Waiter::Woken) {
            Waiter::Waiting(waker) => waker.wake(),
            Waiter::Woken => {},
        }
    }
}

#[allow(clippy::identity_op)] // https://github.com/rust-lang/rust-clippy/issues/3445
const IS_LOCKED: usize = 1 << 0;
const HAS_WAITERS: usize = 1 << 1;

impl<T> Mutex<T> {
    /// Creates a new futures-aware mutex.
    pub fn new(t: T) -> Mutex<T> {
        Mutex {
            state: AtomicUsize::new(0),
            waiters: StdMutex::new(Slab::new()),
            value: UnsafeCell::new(t),
        }
    }

    /// Consumes this mutex, returning the underlying data.
    ///
    /// # Examples
    ///
    /// ```
    /// use futures::lock::Mutex;
    ///
    /// let mutex = Mutex::new(0);
    /// assert_eq!(mutex.into_inner(), 0);
    /// ```
    pub fn into_inner(self) -> T {
        self.value.into_inner()
    }
}

impl<T: ?Sized> Mutex<T> {
    /// Attempt to acquire the lock immediately.
    ///
    /// If the lock is currently held, this will return `None`.
    pub fn try_lock(&self) -> Option<MutexGuard<'_, T>> {
        let old_state = self.state.fetch_or(IS_LOCKED, Ordering::Acquire);
        if (old_state & IS_LOCKED) == 0 {
            Some(MutexGuard { mutex: self })
        } else {
            None
        }
    }

    /// Acquire the lock asynchronously.
    ///
    /// This method returns a future that will resolve once the lock has been
    /// successfully acquired.
    pub fn lock(&self) -> MutexLockFuture<'_, T> {
        MutexLockFuture {
            mutex: Some(self),
            wait_key: WAIT_KEY_NONE,
        }
    }

    /// Returns a mutable reference to the underlying data.
    ///
    /// Since this call borrows the `Mutex` mutably, no actual locking needs to
    /// take place -- the mutable borrow statically guarantees no locks exist.
    ///
    /// # Examples
    ///
    /// ```
    /// # futures::executor::block_on(async {
    /// use futures::lock::Mutex;
    ///
    /// let mut mutex = Mutex::new(0);
    /// *mutex.get_mut() = 10;
    /// assert_eq!(*mutex.lock().await, 10);
    /// # });
    /// ```
    pub fn get_mut(&mut self) -> &mut T {
        // We know statically that there are no other references to `self`, so
        // there's no need to lock the inner mutex.
        unsafe { &mut *self.value.get() }
    }

    fn remove_waker(&self, wait_key: usize, wake_another: bool) {
        if wait_key != WAIT_KEY_NONE {
            let mut waiters = self.waiters.lock().unwrap();
            match waiters.remove(wait_key) {
                Waiter::Waiting(_) => {},
                Waiter::Woken => {
                    // We were awoken, but then dropped before we could
                    // wake up to acquire the lock. Wake up another
                    // waiter.
                    if wake_another {
                        if let Some((_i, waiter)) = waiters.iter_mut().next() {
                            waiter.wake();
                        }
                    }
                }
            }
            if waiters.is_empty() {
                self.state.fetch_and(!HAS_WAITERS, Ordering::Relaxed); // released by mutex unlock
            }
        }
    }

    // Unlocks the mutex. Called by MutexGuard and MappedMutexGuard when they are
    // dropped.
    fn unlock(&self) {
        let old_state = self.state.fetch_and(!IS_LOCKED, Ordering::AcqRel);
        if (old_state & HAS_WAITERS) != 0 {
            let mut waiters = self.waiters.lock().unwrap();
            if let Some((_i, waiter)) = waiters.iter_mut().next() {
                waiter.wake();
            }
        }
    }
}

// Sentinel for when no slot in the `Slab` has been dedicated to this object.
const WAIT_KEY_NONE: usize = usize::max_value();

/// A future which resolves when the target mutex has been successfully acquired.
pub struct MutexLockFuture<'a, T: ?Sized> {
    // `None` indicates that the mutex was successfully acquired.
    mutex: Option<&'a Mutex<T>>,
    wait_key: usize,
}

impl<T: ?Sized> fmt::Debug for MutexLockFuture<'_, T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("MutexLockFuture")
            .field("was_acquired", &self.mutex.is_none())
            .field("mutex", &self.mutex)
            .field("wait_key", &(
                    if self.wait_key == WAIT_KEY_NONE {
                        None
                    } else {
                        Some(self.wait_key)
                    }
                ))
            .finish()
    }
}

impl<T: ?Sized> FusedFuture for MutexLockFuture<'_, T> {
    fn is_terminated(&self) -> bool {
        self.mutex.is_none()
    }
}

impl<'a, T: ?Sized> Future for MutexLockFuture<'a, T> {
    type Output = MutexGuard<'a, T>;

    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        let mutex = self.mutex.expect("polled MutexLockFuture after completion");

        if let Some(lock) = mutex.try_lock() {
            mutex.remove_waker(self.wait_key, false);
            self.mutex = None;
            return Poll::Ready(lock);
        }

        {
            let mut waiters = mutex.waiters.lock().unwrap();
            if self.wait_key == WAIT_KEY_NONE {
                self.wait_key = waiters.insert(Waiter::Waiting(cx.waker().clone()));
                if waiters.len() == 1 {
                    mutex.state.fetch_or(HAS_WAITERS, Ordering::Relaxed); // released by mutex unlock
                }
            } else {
                waiters[self.wait_key].register(cx.waker());
            }
        }

        // Ensure that we haven't raced `MutexGuard::drop`'s unlock path by
        // attempting to acquire the lock again.
        if let Some(lock) = mutex.try_lock() {
            mutex.remove_waker(self.wait_key, false);
            self.mutex = None;
            return Poll::Ready(lock);
        }

        Poll::Pending
    }
}

impl<T: ?Sized> Drop for MutexLockFuture<'_, T> {
    fn drop(&mut self) {
        if let Some(mutex) = self.mutex {
            // This future was dropped before it acquired the mutex.
            //
            // Remove ourselves from the map, waking up another waiter if we
            // had been awoken to acquire the lock.
            mutex.remove_waker(self.wait_key, true);
        }
    }
}

/// An RAII guard returned by the `lock` and `try_lock` methods.
/// When this structure is dropped (falls out of scope), the lock will be
/// unlocked.
pub struct MutexGuard<'a, T: ?Sized> {
    mutex: &'a Mutex<T>,
}

impl<'a, T: ?Sized> MutexGuard<'a, T> {
    /// Returns a locked view over a portion of the locked data.
    ///
    /// # Example
    ///
    /// ```
    /// # futures::executor::block_on(async {
    /// use futures::lock::{Mutex, MutexGuard};
    ///
    /// let data = Mutex::new(Some("value".to_string()));
    /// {
    ///     let locked_str = MutexGuard::map(data.lock().await, |opt| opt.as_mut().unwrap());
    ///     assert_eq!(&*locked_str, "value");
    /// }
    /// # });
    /// ```
    #[inline]
    pub fn map<U: ?Sized, F>(this: Self, f: F) -> MappedMutexGuard<'a, T, U>
    where
        F: FnOnce(&mut T) -> &mut U,
    {
        let mutex = this.mutex;
        let value = f(unsafe { &mut *this.mutex.value.get() });
        // Don't run the `drop` method for MutexGuard. The ownership of the underlying
        // locked state is being moved to the returned MappedMutexGuard.
        mem::forget(this);
        MappedMutexGuard { mutex, value }
    }
}

impl<T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'_, T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("MutexGuard")
            .field("value", &&**self)
            .field("mutex", &self.mutex)
            .finish()
    }
}

impl<T: ?Sized> Drop for MutexGuard<'_, T> {
    fn drop(&mut self) {
        self.mutex.unlock()
    }
}

impl<T: ?Sized> Deref for MutexGuard<'_, T> {
    type Target = T;
    fn deref(&self) -> &T {
        unsafe { &*self.mutex.value.get() }
    }
}

impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
    fn deref_mut(&mut self) -> &mut T {
        unsafe { &mut *self.mutex.value.get() }
    }
}

/// An RAII guard returned by the `MutexGuard::map` and `MappedMutexGuard::map` methods.
/// When this structure is dropped (falls out of scope), the lock will be unlocked.
pub struct MappedMutexGuard<'a, T: ?Sized, U: ?Sized> {
    mutex: &'a Mutex<T>,
    value: *mut U,
}

impl<'a, T: ?Sized, U: ?Sized> MappedMutexGuard<'a, T, U> {
    /// Returns a locked view over a portion of the locked data.
    ///
    /// # Example
    ///
    /// ```
    /// # futures::executor::block_on(async {
    /// use futures::lock::{MappedMutexGuard, Mutex, MutexGuard};
    ///
    /// let data = Mutex::new(Some("value".to_string()));
    /// {
    ///     let locked_str = MutexGuard::map(data.lock().await, |opt| opt.as_mut().unwrap());
    ///     let locked_char = MappedMutexGuard::map(locked_str, |s| s.get_mut(0..1).unwrap());
    ///     assert_eq!(&*locked_char, "v");
    /// }
    /// # });
    /// ```
    #[inline]
    pub fn map<V: ?Sized, F>(this: Self, f: F) -> MappedMutexGuard<'a, T, V>
    where
        F: FnOnce(&mut U) -> &mut V,
    {
        let mutex = this.mutex;
        let value = f(unsafe { &mut *this.value });
        // Don't run the `drop` method for MappedMutexGuard. The ownership of the underlying
        // locked state is being moved to the returned MappedMutexGuard.
        mem::forget(this);
        MappedMutexGuard { mutex, value }
    }
}

impl<T: ?Sized, U: ?Sized + fmt::Debug> fmt::Debug for MappedMutexGuard<'_, T, U> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("MappedMutexGuard")
            .field("value", &&**self)
            .field("mutex", &self.mutex)
            .finish()
    }
}

impl<T: ?Sized, U: ?Sized> Drop for MappedMutexGuard<'_, T, U> {
    fn drop(&mut self) {
        self.mutex.unlock()
    }
}

impl<T: ?Sized, U: ?Sized> Deref for MappedMutexGuard<'_, T, U> {
    type Target = U;
    fn deref(&self) -> &U {
        unsafe { &*self.value }
    }
}

impl<T: ?Sized, U: ?Sized> DerefMut for MappedMutexGuard<'_, T, U> {
    fn deref_mut(&mut self) -> &mut U {
        unsafe { &mut *self.value }
    }
}

// Mutexes can be moved freely between threads and acquired on any thread so long
// as the inner value can be safely sent between threads.
unsafe impl<T: ?Sized + Send> Send for Mutex<T> {}
unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}

// It's safe to switch which thread the acquire is being attempted on so long as
// `T` can be accessed on that thread.
unsafe impl<T: ?Sized + Send> Send for MutexLockFuture<'_, T> {}
// doesn't have any interesting `&self` methods (only Debug)
unsafe impl<T: ?Sized> Sync for MutexLockFuture<'_, T> {}

// Safe to send since we don't track any thread-specific details-- the inner
// lock is essentially spinlock-equivalent (attempt to flip an atomic bool)
unsafe impl<T: ?Sized + Send> Send for MutexGuard<'_, T> {}
unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}
unsafe impl<T: ?Sized + Send, U: ?Sized> Send for MappedMutexGuard<'_, T, U> {}
unsafe impl<T: ?Sized + Sync, U: ?Sized> Sync for MappedMutexGuard<'_, T, U> {}

#[test]
fn test_mutex_guard_debug_not_recurse() {
    let mutex = Mutex::new(42);
    let guard = mutex.try_lock().unwrap();
    let _ = format!("{:?}", guard);
    let guard = MutexGuard::map(guard, |n| n);
    let _ = format!("{:?}", guard);
}
<commit_msg>Document unfairness in futures-aware mutex<commit_after>use futures_core::future::{FusedFuture, Future};
use futures_core::task::{Context, Poll, Waker};
use slab::Slab;
use std::{fmt, mem};
use std::cell::UnsafeCell;
use std::ops::{Deref, DerefMut};
use std::pin::Pin;
use std::sync::Mutex as StdMutex;
use std::sync::atomic::{AtomicUsize, Ordering};

/// A futures-aware mutex.
///
/// # Fairness
///
/// This mutex provides no fairness guarantees. Tasks may not acquire the mutex
/// in the order that they requested the lock, and it's possible for a single task
/// which repeatedly takes the lock to starve other tasks, which may be left waiting
/// indefinitely.
pub struct Mutex<T: ?Sized> {
    state: AtomicUsize,
    waiters: StdMutex<Slab<Waiter>>,
    value: UnsafeCell<T>,
}

impl<T: ?Sized> fmt::Debug for Mutex<T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        let state = self.state.load(Ordering::SeqCst);
        f.debug_struct("Mutex")
            .field("is_locked", &((state & IS_LOCKED) != 0))
            .field("has_waiters", &((state & HAS_WAITERS) != 0))
            .finish()
    }
}

impl<T> From<T> for Mutex<T> {
    fn from(t: T) -> Self {
        Self::new(t)
    }
}

impl<T: Default> Default for Mutex<T> {
    fn default() -> Mutex<T> {
        Mutex::new(Default::default())
    }
}

enum Waiter {
    Waiting(Waker),
    Woken,
}

impl Waiter {
    fn register(&mut self, waker: &Waker) {
        match self {
            Waiter::Waiting(w) if waker.will_wake(w) => {},
            _ => *self = Waiter::Waiting(waker.clone()),
        }
    }

    fn wake(&mut self) {
        match mem::replace(self, Waiter::Woken) {
            Waiter::Waiting(waker) => waker.wake(),
            Waiter::Woken => {},
        }
    }
}

#[allow(clippy::identity_op)] // https://github.com/rust-lang/rust-clippy/issues/3445
const IS_LOCKED: usize = 1 << 0;
const HAS_WAITERS: usize = 1 << 1;

impl<T> Mutex<T> {
    /// Creates a new futures-aware mutex.
    pub fn new(t: T) -> Mutex<T> {
        Mutex {
            state: AtomicUsize::new(0),
            waiters: StdMutex::new(Slab::new()),
            value: UnsafeCell::new(t),
        }
    }

    /// Consumes this mutex, returning the underlying data.
    ///
    /// # Examples
    ///
    /// ```
    /// use futures::lock::Mutex;
    ///
    /// let mutex = Mutex::new(0);
    /// assert_eq!(mutex.into_inner(), 0);
    /// ```
    pub fn into_inner(self) -> T {
        self.value.into_inner()
    }
}

impl<T: ?Sized> Mutex<T> {
    /// Attempt to acquire the lock immediately.
    ///
    /// If the lock is currently held, this will return `None`.
    pub fn try_lock(&self) -> Option<MutexGuard<'_, T>> {
        let old_state = self.state.fetch_or(IS_LOCKED, Ordering::Acquire);
        if (old_state & IS_LOCKED) == 0 {
            Some(MutexGuard { mutex: self })
        } else {
            None
        }
    }

    /// Acquire the lock asynchronously.
    ///
    /// This method returns a future that will resolve once the lock has been
    /// successfully acquired.
    pub fn lock(&self) -> MutexLockFuture<'_, T> {
        MutexLockFuture {
            mutex: Some(self),
            wait_key: WAIT_KEY_NONE,
        }
    }

    /// Returns a mutable reference to the underlying data.
    ///
    /// Since this call borrows the `Mutex` mutably, no actual locking needs to
    /// take place -- the mutable borrow statically guarantees no locks exist.
    ///
    /// # Examples
    ///
    /// ```
    /// # futures::executor::block_on(async {
    /// use futures::lock::Mutex;
    ///
    /// let mut mutex = Mutex::new(0);
    /// *mutex.get_mut() = 10;
    /// assert_eq!(*mutex.lock().await, 10);
    /// # });
    /// ```
    pub fn get_mut(&mut self) -> &mut T {
        // We know statically that there are no other references to `self`, so
        // there's no need to lock the inner mutex.
        unsafe { &mut *self.value.get() }
    }

    fn remove_waker(&self, wait_key: usize, wake_another: bool) {
        if wait_key != WAIT_KEY_NONE {
            let mut waiters = self.waiters.lock().unwrap();
            match waiters.remove(wait_key) {
                Waiter::Waiting(_) => {},
                Waiter::Woken => {
                    // We were awoken, but then dropped before we could
                    // wake up to acquire the lock. Wake up another
                    // waiter.
                    if wake_another {
                        if let Some((_i, waiter)) = waiters.iter_mut().next() {
                            waiter.wake();
                        }
                    }
                }
            }
            if waiters.is_empty() {
                self.state.fetch_and(!HAS_WAITERS, Ordering::Relaxed); // released by mutex unlock
            }
        }
    }

    // Unlocks the mutex. Called by MutexGuard and MappedMutexGuard when they are
    // dropped.
    fn unlock(&self) {
        let old_state = self.state.fetch_and(!IS_LOCKED, Ordering::AcqRel);
        if (old_state & HAS_WAITERS) != 0 {
            let mut waiters = self.waiters.lock().unwrap();
            if let Some((_i, waiter)) = waiters.iter_mut().next() {
                waiter.wake();
            }
        }
    }
}

// Sentinel for when no slot in the `Slab` has been dedicated to this object.
const WAIT_KEY_NONE: usize = usize::max_value();

/// A future which resolves when the target mutex has been successfully acquired.
pub struct MutexLockFuture<'a, T: ?Sized> {
    // `None` indicates that the mutex was successfully acquired.
    mutex: Option<&'a Mutex<T>>,
    wait_key: usize,
}

impl<T: ?Sized> fmt::Debug for MutexLockFuture<'_, T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("MutexLockFuture")
            .field("was_acquired", &self.mutex.is_none())
            .field("mutex", &self.mutex)
            .field("wait_key", &(
                    if self.wait_key == WAIT_KEY_NONE {
                        None
                    } else {
                        Some(self.wait_key)
                    }
                ))
            .finish()
    }
}

impl<T: ?Sized> FusedFuture for MutexLockFuture<'_, T> {
    fn is_terminated(&self) -> bool {
        self.mutex.is_none()
    }
}

impl<'a, T: ?Sized> Future for MutexLockFuture<'a, T> {
    type Output = MutexGuard<'a, T>;

    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        let mutex = self.mutex.expect("polled MutexLockFuture after completion");

        if let Some(lock) = mutex.try_lock() {
            mutex.remove_waker(self.wait_key, false);
            self.mutex = None;
            return Poll::Ready(lock);
        }

        {
            let mut waiters = mutex.waiters.lock().unwrap();
            if self.wait_key == WAIT_KEY_NONE {
                self.wait_key = waiters.insert(Waiter::Waiting(cx.waker().clone()));
                if waiters.len() == 1 {
                    mutex.state.fetch_or(HAS_WAITERS, Ordering::Relaxed); // released by mutex unlock
                }
            } else {
                waiters[self.wait_key].register(cx.waker());
            }
        }

        // Ensure that we haven't raced `MutexGuard::drop`'s unlock path by
        // attempting to acquire the lock again.
        if let Some(lock) = mutex.try_lock() {
            mutex.remove_waker(self.wait_key, false);
            self.mutex = None;
            return Poll::Ready(lock);
        }

        Poll::Pending
    }
}

impl<T: ?Sized> Drop for MutexLockFuture<'_, T> {
    fn drop(&mut self) {
        if let Some(mutex) = self.mutex {
            // This future was dropped before it acquired the mutex.
            //
            // Remove ourselves from the map, waking up another waiter if we
            // had been awoken to acquire the lock.
            mutex.remove_waker(self.wait_key, true);
        }
    }
}

/// An RAII guard returned by the `lock` and `try_lock` methods.
/// When this structure is dropped (falls out of scope), the lock will be
/// unlocked.
pub struct MutexGuard<'a, T: ?Sized> {
    mutex: &'a Mutex<T>,
}

impl<'a, T: ?Sized> MutexGuard<'a, T> {
    /// Returns a locked view over a portion of the locked data.
    ///
    /// # Example
    ///
    /// ```
    /// # futures::executor::block_on(async {
    /// use futures::lock::{Mutex, MutexGuard};
    ///
    /// let data = Mutex::new(Some("value".to_string()));
    /// {
    ///     let locked_str = MutexGuard::map(data.lock().await, |opt| opt.as_mut().unwrap());
    ///     assert_eq!(&*locked_str, "value");
    /// }
    /// # });
    /// ```
    #[inline]
    pub fn map<U: ?Sized, F>(this: Self, f: F) -> MappedMutexGuard<'a, T, U>
    where
        F: FnOnce(&mut T) -> &mut U,
    {
        let mutex = this.mutex;
        let value = f(unsafe { &mut *this.mutex.value.get() });
        // Don't run the `drop` method for MutexGuard. The ownership of the underlying
        // locked state is being moved to the returned MappedMutexGuard.
        mem::forget(this);
        MappedMutexGuard { mutex, value }
    }
}

impl<T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'_, T> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("MutexGuard")
            .field("value", &&**self)
            .field("mutex", &self.mutex)
            .finish()
    }
}

impl<T: ?Sized> Drop for MutexGuard<'_, T> {
    fn drop(&mut self) {
        self.mutex.unlock()
    }
}

impl<T: ?Sized> Deref for MutexGuard<'_, T> {
    type Target = T;
    fn deref(&self) -> &T {
        unsafe { &*self.mutex.value.get() }
    }
}

impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
    fn deref_mut(&mut self) -> &mut T {
        unsafe { &mut *self.mutex.value.get() }
    }
}

/// An RAII guard returned by the `MutexGuard::map` and `MappedMutexGuard::map` methods.
/// When this structure is dropped (falls out of scope), the lock will be unlocked.
pub struct MappedMutexGuard<'a, T: ?Sized, U: ?Sized> {
    mutex: &'a Mutex<T>,
    value: *mut U,
}

impl<'a, T: ?Sized, U: ?Sized> MappedMutexGuard<'a, T, U> {
    /// Returns a locked view over a portion of the locked data.
    ///
    /// # Example
    ///
    /// ```
    /// # futures::executor::block_on(async {
    /// use futures::lock::{MappedMutexGuard, Mutex, MutexGuard};
    ///
    /// let data = Mutex::new(Some("value".to_string()));
    /// {
    ///     let locked_str = MutexGuard::map(data.lock().await, |opt| opt.as_mut().unwrap());
    ///     let locked_char = MappedMutexGuard::map(locked_str, |s| s.get_mut(0..1).unwrap());
    ///     assert_eq!(&*locked_char, "v");
    /// }
    /// # });
    /// ```
    #[inline]
    pub fn map<V: ?Sized, F>(this: Self, f: F) -> MappedMutexGuard<'a, T, V>
    where
        F: FnOnce(&mut U) -> &mut V,
    {
        let mutex = this.mutex;
        let value = f(unsafe { &mut *this.value });
        // Don't run the `drop` method for MappedMutexGuard. The ownership of the underlying
        // locked state is being moved to the returned MappedMutexGuard.
        mem::forget(this);
        MappedMutexGuard { mutex, value }
    }
}

impl<T: ?Sized, U: ?Sized + fmt::Debug> fmt::Debug for MappedMutexGuard<'_, T, U> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("MappedMutexGuard")
            .field("value", &&**self)
            .field("mutex", &self.mutex)
            .finish()
    }
}

impl<T: ?Sized, U: ?Sized> Drop for MappedMutexGuard<'_, T, U> {
    fn drop(&mut self) {
        self.mutex.unlock()
    }
}

impl<T: ?Sized, U: ?Sized> Deref for MappedMutexGuard<'_, T, U> {
    type Target = U;
    fn deref(&self) -> &U {
        unsafe { &*self.value }
    }
}

impl<T: ?Sized, U: ?Sized> DerefMut for MappedMutexGuard<'_, T, U> {
    fn deref_mut(&mut self) -> &mut U {
        unsafe { &mut *self.value }
    }
}

// Mutexes can be moved freely between threads and acquired on any thread so long
// as the inner value can be safely sent between threads.
unsafe impl<T: ?Sized + Send> Send for Mutex<T> {}
unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}

// It's safe to switch which thread the acquire is being attempted on so long as
// `T` can be accessed on that thread.
unsafe impl<T: ?Sized + Send> Send for MutexLockFuture<'_, T> {}
// doesn't have any interesting `&self` methods (only Debug)
unsafe impl<T: ?Sized> Sync for MutexLockFuture<'_, T> {}

// Safe to send since we don't track any thread-specific details-- the inner
// lock is essentially spinlock-equivalent (attempt to flip an atomic bool)
unsafe impl<T: ?Sized + Send> Send for MutexGuard<'_, T> {}
unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}
unsafe impl<T: ?Sized + Send, U: ?Sized> Send for MappedMutexGuard<'_, T, U> {}
unsafe impl<T: ?Sized + Sync, U: ?Sized> Sync for MappedMutexGuard<'_, T, U> {}

#[test]
fn test_mutex_guard_debug_not_recurse() {
    let mutex = Mutex::new(42);
    let guard = mutex.try_lock().unwrap();
    let _ = format!("{:?}", guard);
    let guard = MutexGuard::map(guard, |n| n);
    let _ = format!("{:?}", guard);
}
<|endoftext|>


<commit_before>//!
//! The script interpreter runs scripts directly from their parse tree. This is
//! a fairly slow way to run scripts but comparatively simple to implement.
//!

use std::result::Result;
use serde_json::*;

use silkthread_base::*;

use super::script::*;

///
/// A tool representing a script that will be interepreted
///
pub struct InterpretedScriptTool {
    statements: Vec<Script>
}

///
/// Creates an unquoted version of a string
///
fn unquote_string(string: &str) -> String {
    let chars: Vec<char>    = string.chars().collect();
    let mut result          = String::new();
    let mut index           = 1;
    while index < chars.len()-1 {
        // Push character
        let chr = chars[index];

        match chr {
            '\\' => {
                let quoted = chars[index+1];
                match quoted {
                    'n' => result.push('\n'),
                    'r' => result.push('\r'),
                    't' => result.push('\t'),
                    quoted => result.push(quoted)
                }
            },
            chr => result.push(chr)
        }

        // Next character
        index += 1;
    }

    result
}

///
/// Script evaluation error
///
#[derive(Serialize, Deserialize)]
pub enum ScriptEvaluationError {
    /// Tried to evaluate an expression type that's not implemented yet
    ExpressionNotImplemented,

    /// Tried to look up a tool and it couldn't be found
    ToolNameNotFound,

    /// Found an expression that can't be treated as a tool where a tool name was expected
    ExpressionDoesNotEvaluateToTool
}

///
/// Creates an execution error
///
fn generate_expression_error(error: ScriptEvaluationError, expr: &Expression) -> Value {
    json![{
        "error":                error,
        "failed-expression":    expr
    }]
}

impl InterpretedScriptTool {
    ///
    /// Creates a new interpreted script tool from a set of statements
    ///
    pub fn from_statements(statements: Vec<Script>) -> InterpretedScriptTool {
        InterpretedScriptTool { statements: statements }
    }

    ///
    /// Attempts to evaluate an expression to a tool
    ///
    pub fn evaluate_expression_to_tool(expression: &Expression, environment: &mut ScriptExecutionEnvironment) -> Result<Box<Tool>, Value> {
        match expression {
            &Expression::Identifier(ref name)   => environment.parent_environment.get_json_tool(&name.matched).map_err(|_| generate_expression_error(ScriptEvaluationError::ToolNameNotFound, expression)),
            _                                   => Err(generate_expression_error(ScriptEvaluationError::ExpressionDoesNotEvaluateToTool, expression))
        }
    }

    ///
    /// Calls an expression representing a tool and calls it with the specified parameters
    ///
    pub fn call_tool(tool_name: &Expression, parameters: Value, environment: &mut ScriptExecutionEnvironment) -> Result<Value, Value> {
        InterpretedScriptTool::evaluate_expression_to_tool(tool_name, environment).and_then(|tool| {
            // TODO: create environment for the tool to run in

            // Invoke the tool and generate the final result
            tool.invoke_json(parameters, environment.parent_environment)
        })
    }

    ///
    /// Evaluates a single expression
    ///
    pub fn evaluate_expression(expression: &Expression, environment: &mut ScriptExecutionEnvironment) -> Result<Value, Value> {
        match expression {
            &Expression::String(ref s)          => Ok(Value::String(unquote_string(&s.matched))),

            &Expression::Identifier(_)          => InterpretedScriptTool::call_tool(expression, Value::Null, environment),

            _                                   => Err(generate_expression_error(ScriptEvaluationError::ExpressionNotImplemented, expression))
        }
    }

    ///
    /// Evaluates the result of executing a single statement
    ///
    pub fn evaluate_statement(statement: &Script, environment: &mut ScriptExecutionEnvironment) -> Result<Value, Value> {
        unimplemented!()
    }
}

impl Tool for InterpretedScriptTool {
    fn invoke_json(&self, input: Value, environment: &Environment) -> Result<Value, Value> {
        // Make the environment that this script will run in
        let mut script_environment = ScriptExecutionEnvironment::new(environment);

        // Execute the script
        let mut result = vec![];
        for statement in self.statements.iter() {
            // Evaluate the next statement
            let next_result = match Self::evaluate_statement(statement, &mut script_environment) {
                Ok(result) => result,

                // Fail immediately if any statement generates an error
                Err(fail) => return Err(fail)
            };

            // The script result is built up from the result of each statement
            // TODO: unless there's something like a return statement?
            result.push(next_result);
        }

        // Script is done
        Ok(Value::Array(result))
    }
}

///
/// Represents an execution environment for a running script
///
pub struct ScriptExecutionEnvironment<'a> {
    /// The environment where tools are drawn from
    parent_environment: &'a Environment
}

impl<'a> ScriptExecutionEnvironment<'a> {
    ///
    /// Creates a new script execution environment
    ///
    pub fn new(parent_environment: &'a Environment) -> ScriptExecutionEnvironment<'a> {
        ScriptExecutionEnvironment { parent_environment: parent_environment }
    }
}

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

    #[test]
    fn can_evaluate_string() {
        let string_expr         = Expression::string("\"Foo\"");
        let empty_environment   = EmptyEnvironment::new();
        let mut env             = ScriptExecutionEnvironment::new(&empty_environment);
        let result              = InterpretedScriptTool::evaluate_expression(&string_expr, &mut env);

        assert!(result == Ok(Value::String(String::from("Foo"))));
    }

    #[test]
    fn can_call_tool() {
        let tool_expr           = Expression::identifier("test");
        let tool_environment    = DynamicEnvironment::new();

        tool_environment.define("test", Box::new(make_pure_tool(|_: ()| "Success")));

        let mut env             = ScriptExecutionEnvironment::new(&tool_environment);
        let result              = InterpretedScriptTool::call_tool(&tool_expr, Value::Null, &mut env);

        assert!(result == Ok(Value::String(String::from("Success"))));
    }

    #[test]
    fn can_evaluate_tool_call() {
        let tool_expr           = Expression::identifier("test");
        let tool_environment    = DynamicEnvironment::new();

        tool_environment.define("test", Box::new(make_pure_tool(|_: ()| "Success")));

        let mut env             = ScriptExecutionEnvironment::new(&tool_environment);
        let result              = InterpretedScriptTool::evaluate_expression(&tool_expr, &mut env);

        assert!(result == Ok(Value::String(String::from("Success"))));
    }
}
<commit_msg>Implement the ‘apply’ expression type<commit_after>//!
//! The script interpreter runs scripts directly from their parse tree. This is
//! a fairly slow way to run scripts but comparatively simple to implement.
//!

use std::result::Result;
use serde_json::*;

use silkthread_base::*;

use super::script::*;

///
/// A tool representing a script that will be interepreted
///
pub struct InterpretedScriptTool {
    statements: Vec<Script>
}

///
/// Creates an unquoted version of a string
///
fn unquote_string(string: &str) -> String {
    let chars: Vec<char>    = string.chars().collect();
    let mut result          = String::new();
    let mut index           = 1;
    while index < chars.len()-1 {
        // Push character
        let chr = chars[index];

        match chr {
            '\\' => {
                let quoted = chars[index+1];
                match quoted {
                    'n' => result.push('\n'),
                    'r' => result.push('\r'),
                    't' => result.push('\t'),
                    quoted => result.push(quoted)
                }
            },
            chr => result.push(chr)
        }

        // Next character
        index += 1;
    }

    result
}

///
/// Script evaluation error
///
#[derive(Serialize, Deserialize)]
pub enum ScriptEvaluationError {
    /// Tried to evaluate an expression type that's not implemented yet
    ExpressionNotImplemented,

    /// Tried to look up a tool and it couldn't be found
    ToolNameNotFound,

    /// Found an expression that can't be treated as a tool where a tool name was expected
    ExpressionDoesNotEvaluateToTool
}

///
/// Creates an execution error
///
fn generate_expression_error(error: ScriptEvaluationError, expr: &Expression) -> Value {
    json![{
        "error":                error,
        "failed-expression":    expr
    }]
}

impl InterpretedScriptTool {
    ///
    /// Creates a new interpreted script tool from a set of statements
    ///
    pub fn from_statements(statements: Vec<Script>) -> InterpretedScriptTool {
        InterpretedScriptTool { statements: statements }
    }

    ///
    /// Attempts to evaluate an expression to a tool
    ///
    pub fn evaluate_expression_to_tool(expression: &Expression, environment: &mut ScriptExecutionEnvironment) -> Result<Box<Tool>, Value> {
        match expression {
            &Expression::Identifier(ref name)   => environment.parent_environment.get_json_tool(&name.matched).map_err(|_| generate_expression_error(ScriptEvaluationError::ToolNameNotFound, expression)),
            _                                   => Err(generate_expression_error(ScriptEvaluationError::ExpressionDoesNotEvaluateToTool, expression))
        }
    }

    ///
    /// Calls an expression representing a tool and calls it with the specified parameters
    ///
    pub fn call_tool(tool_name: &Expression, parameters: Value, environment: &mut ScriptExecutionEnvironment) -> Result<Value, Value> {
        InterpretedScriptTool::evaluate_expression_to_tool(tool_name, environment).and_then(|tool| {
            // TODO: create environment for the tool to run in

            // Invoke the tool and generate the final result
            tool.invoke_json(parameters, environment.parent_environment)
        })
    }

    ///
    /// Evaluates an 'apply' expression
    ///
    pub fn apply(&(ref tool, ref parameters): &(Expression, Expression), environment: &mut ScriptExecutionEnvironment) -> Result<Value, Value> {
        InterpretedScriptTool::evaluate_expression(&parameters, environment).and_then(|parameters| {
            InterpretedScriptTool::call_tool(&tool, parameters, environment)
        })
    }

    ///
    /// Evaluates a single expression
    ///
    pub fn evaluate_expression(expression: &Expression, environment: &mut ScriptExecutionEnvironment) -> Result<Value, Value> {
        match expression {
            &Expression::String(ref s)          => Ok(Value::String(unquote_string(&s.matched))),

            &Expression::Identifier(_)          => InterpretedScriptTool::call_tool(expression, Value::Null, environment),
            &Expression::Apply(ref expr)        => InterpretedScriptTool::apply(&*expr, environment),

            _                                   => Err(generate_expression_error(ScriptEvaluationError::ExpressionNotImplemented, expression))
        }
    }

    ///
    /// Evaluates the result of executing a single statement
    ///
    pub fn evaluate_statement(statement: &Script, environment: &mut ScriptExecutionEnvironment) -> Result<Value, Value> {
        unimplemented!()
    }
}

impl Tool for InterpretedScriptTool {
    fn invoke_json(&self, input: Value, environment: &Environment) -> Result<Value, Value> {
        // Make the environment that this script will run in
        let mut script_environment = ScriptExecutionEnvironment::new(environment);

        // Execute the script
        let mut result = vec![];
        for statement in self.statements.iter() {
            // Evaluate the next statement
            let next_result = match Self::evaluate_statement(statement, &mut script_environment) {
                Ok(result) => result,

                // Fail immediately if any statement generates an error
                Err(fail) => return Err(fail)
            };

            // The script result is built up from the result of each statement
            // TODO: unless there's something like a return statement?
            result.push(next_result);
        }

        // Script is done
        Ok(Value::Array(result))
    }
}

///
/// Represents an execution environment for a running script
///
pub struct ScriptExecutionEnvironment<'a> {
    /// The environment where tools are drawn from
    parent_environment: &'a Environment
}

impl<'a> ScriptExecutionEnvironment<'a> {
    ///
    /// Creates a new script execution environment
    ///
    pub fn new(parent_environment: &'a Environment) -> ScriptExecutionEnvironment<'a> {
        ScriptExecutionEnvironment { parent_environment: parent_environment }
    }
}

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

    #[test]
    fn can_evaluate_string() {
        let string_expr         = Expression::string("\"Foo\"");
        let empty_environment   = EmptyEnvironment::new();
        let mut env             = ScriptExecutionEnvironment::new(&empty_environment);
        let result              = InterpretedScriptTool::evaluate_expression(&string_expr, &mut env);

        assert!(result == Ok(Value::String(String::from("Foo"))));
    }

    #[test]
    fn can_call_tool() {
        let tool_expr           = Expression::identifier("test");
        let tool_environment    = DynamicEnvironment::new();

        tool_environment.define("test", Box::new(make_pure_tool(|_: ()| "Success")));

        let mut env             = ScriptExecutionEnvironment::new(&tool_environment);
        let result              = InterpretedScriptTool::call_tool(&tool_expr, Value::Null, &mut env);

        assert!(result == Ok(Value::String(String::from("Success"))));
    }

    #[test]
    fn can_evaluate_tool_call() {
        let tool_expr           = Expression::identifier("test");
        let tool_environment    = DynamicEnvironment::new();

        tool_environment.define("test", Box::new(make_pure_tool(|_: ()| "Success")));

        let mut env             = ScriptExecutionEnvironment::new(&tool_environment);
        let result              = InterpretedScriptTool::evaluate_expression(&tool_expr, &mut env);

        assert!(result == Ok(Value::String(String::from("Success"))));
    }

    #[test]
    fn can_evaluate_apply_expression() {
        let tool_expr           = Expression::Apply(Box::new((Expression::identifier("test"), Expression::string("\"Success\""))));
        let tool_environment    = DynamicEnvironment::new();

        tool_environment.define("test", Box::new(make_pure_tool(|s: String| s)));

        let mut env             = ScriptExecutionEnvironment::new(&tool_environment);
        let result              = InterpretedScriptTool::evaluate_expression(&tool_expr, &mut env);

        assert!(result == Ok(Value::String(String::from("Success"))));
    }
}
<|endoftext|>


<commit_before>//! Support for the KDE Idle Protocol

use wayland_sys::server::wl_display as wl_server_display;
use wlroots_sys::{wl_display, wlr_idle, wlr_idle_create,
                  wlr_idle_destroy, wlr_idle_notify_activity,
                  wlr_idle_set_enabled};
pub use wlroots_sys::protocols::idle
::server::org_kde_kwin_idle::Request;

#[derive(Debug)]
pub struct Manager {
    manager: *mut wlr_idle
}

impl Manager {
    pub(crate) unsafe fn new(display: *mut wl_server_display) -> Option<Self> {
        let manager_raw = wlr_idle_create(display as *mut wl_display);

        if !manager_raw.is_null() {
            Some(Manager { manager: manager_raw })
        } else {
            None
        }
    }

    /// Restart the timers for the seat
    pub fn notify_activity(&mut self, Seat: Request::GetIdleTimeout::seat) {
        unsafe { wlr_idle_notify_activity(self.manager, Seat) }
    }

    /// If we are passed a null pointer,
    /// update timers for all seats.
    pub fn set_enabled(&mut self, Seat: Request::GetIdleTimeout::seat, enabled: bool) {
        wlr_log!(WLR_INFO, "Idle timer status: {:?}", enabled);
        unsafe { wlr_idle_set_enabled(self.manager, Seat, enabled) }
    }
}

impl Drop for Manager {
    fn drop(&mut self) {
        unsafe { wlr_idle_destroy(self.manager) }
    }
}
<commit_msg>we compile good now<commit_after>//! Support for the KDE Idle Protocol

use wayland_sys::server::wl_display as wl_server_display;
use wlroots_sys::{wl_display, wlr_seat, wlr_idle, wlr_idle_create,
                  wlr_idle_destroy, wlr_idle_notify_activity,
                  wlr_idle_set_enabled};

#[derive(Debug)]
pub struct Manager {
    manager: *mut wlr_idle
}

impl Manager {
    pub(crate) unsafe fn new(display: *mut wl_server_display) -> Option<Self> {
        let manager_raw = wlr_idle_create(display as *mut wl_display);

        if !manager_raw.is_null() {
            Some(Manager { manager: manager_raw })
        } else {
            None
        }
    }

    /// Restart the timers for the seat
    pub fn notify_activity(&mut self, seat: *mut wlr_seat) {
        unsafe { wlr_idle_notify_activity(self.manager, seat as *mut wlr_seat) }
    }

    /// If we are passed a null pointer,
    /// update timers for all seats.
    pub fn set_enabled(&mut self, seat: *mut wlr_seat, enabled: bool) {
        wlr_log!(WLR_INFO, "Idle timer status: {:?}", enabled);
        unsafe { wlr_idle_set_enabled(self.manager, seat as *mut wlr_seat, enabled) }
    }
}

impl Drop for Manager {
    fn drop(&mut self) {
        unsafe { wlr_idle_destroy(self.manager) }
    }
}
<|endoftext|>


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

#![feature(std_misc)]

pub type HANDLE = u32;
pub type DWORD = u32;
pub type SIZE_T = u32;
pub type LPVOID = usize;
pub type BOOL = u8;

#[cfg(windows)]
mod kernel32 {
    use super::{HANDLE, DWORD, SIZE_T, LPVOID, BOOL};

    extern "system" {
        pub fn GetProcessHeap() -> HANDLE;
        pub fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T)
                      -> LPVOID;
        pub fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL;
    }
}

#[cfg(windows)]
pub fn main() {
    let heap = unsafe { kernel32::GetProcessHeap() };
    let mem = unsafe { kernel32::HeapAlloc(heap, 0, 100) };
    assert!(mem != 0);
    let res = unsafe { kernel32::HeapFree(heap, 0, mem) };
    assert!(res != 0);
}

#[cfg(not(windows))]
pub fn main() { }
<commit_msg>Auto merge of #28457 - VHaravy:test-run-pass-x86stdcall2, r=huonw<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(std_misc)]

pub type HANDLE = usize;
pub type DWORD = u32;
pub type SIZE_T = u32;
pub type LPVOID = usize;
pub type BOOL = u8;

#[cfg(windows)]
mod kernel32 {
    use super::{HANDLE, DWORD, SIZE_T, LPVOID, BOOL};

    extern "system" {
        pub fn GetProcessHeap() -> HANDLE;
        pub fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T)
                      -> LPVOID;
        pub fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL;
    }
}

#[cfg(windows)]
pub fn main() {
    let heap = unsafe { kernel32::GetProcessHeap() };
    let mem = unsafe { kernel32::HeapAlloc(heap, 0, 100) };
    assert!(mem != 0);
    let res = unsafe { kernel32::HeapFree(heap, 0, mem) };
    assert!(res != 0);
}

#[cfg(not(windows))]
pub fn main() { }
<|endoftext|>


<commit_before>// Copyright (c) 2017-2019, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

use crate::frame::*;
use crate::tiling::*;
use crate::util::*;

#[derive(Debug, Default, Clone)]
pub struct ActivityMask {
  variances: Vec<Vec<f64>>,
  // Width and height of the original frame that is masked
  width: usize,
  height: usize,
  // Side of unit (square) activity block in log2
  granularity: usize,
}

impl ActivityMask {
  pub fn from_plane<T: Pixel>(luma_plane: &Plane<T>) -> ActivityMask {
    let PlaneConfig { width, height, .. } = luma_plane.cfg;

    let granularity = 3;

    let aligned_luma = Rect {
      x: 0_isize,
      y: 0_isize,
      width: (width >> granularity) << granularity,
      height: (height >> granularity) << granularity,
    };
    let luma = PlaneRegion::new(luma_plane, aligned_luma);

    let mut variances = Vec::new();

    for y in 0..height >> granularity {
      let mut row = Vec::new();
      for x in 0..width >> granularity {
        let block_rect = Area::Rect {
          x: (x << granularity) as isize,
          y: (y << granularity) as isize,
          width: 8,
          height: 8,
        };

        let block = luma.subregion(block_rect);

        let mean: f64 = block
          .rows_iter()
          .flatten()
          .map(|&pix| {
            let pix: i16 = CastFromPrimitive::cast_from(pix);
            pix as f64
          })
          .sum::<f64>()
          / 64.0_f64;
        let variance: f64 = block
          .rows_iter()
          .flatten()
          .map(|&pix| {
            let pix: i16 = CastFromPrimitive::cast_from(pix);
            (pix as f64 - mean).powi(2)
          })
          .sum::<f64>();
        row.push(variance);
      }

      variances.push(row)
    }
    ActivityMask { variances, width, height, granularity }
  }

  pub fn variance_at(&self, x: usize, y: usize) -> Option<f64> {
    if x > self.width >> self.granularity
      || y > self.height >> self.granularity
    {
      None
    } else {
      Some(*self.variances.get(x).unwrap().get(y).unwrap())
    }
  }

  pub fn mean_activity_of(&self, rect: Rect) -> Option<f64> {
    let Rect { x, y, width, height } = rect;
    let (x, y) = (x as usize, y as usize);
    let granularity = self.granularity;
    let (dec_x, dec_y) = (x >> granularity, y >> granularity);
    let (dec_width, dec_height) =
      (width >> granularity, height >> granularity);

    if x > self.width
      || y > self.height
      || (x + width) > self.width
      || (y + height) > self.height
      || dec_width == 0
      || dec_height == 0
    {
      // Region lies out of the frame or is smaller than 8x8 on some axis
      None
    } else {
      let activity = self
        .variances
        .iter()
        .skip(dec_x)
        .take(dec_height)
        .map(|row| row.iter().skip(dec_y).take(dec_width).sum::<f64>())
        .sum::<f64>()
        / (dec_width as f64 * dec_height as f64);

      Some(activity.cbrt().sqrt())
    }
  }
}
<commit_msg>Reduce number of allocations for ActivityMask<commit_after>// Copyright (c) 2017-2019, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

use crate::frame::*;
use crate::tiling::*;
use crate::util::*;

#[derive(Debug, Default, Clone)]
pub struct ActivityMask {
  variances: Vec<f64>,
  // Width and height of the original frame that is masked
  width: usize,
  height: usize,
  // Side of unit (square) activity block in log2
  granularity: usize,
}

impl ActivityMask {
  pub fn from_plane<T: Pixel>(luma_plane: &Plane<T>) -> ActivityMask {
    let PlaneConfig { width, height, .. } = luma_plane.cfg;

    let granularity = 3;

    let aligned_luma = Rect {
      x: 0_isize,
      y: 0_isize,
      width: (width >> granularity) << granularity,
      height: (height >> granularity) << granularity,
    };
    let luma = PlaneRegion::new(luma_plane, aligned_luma);

    let mut variances =
      Vec::with_capacity((height >> granularity) * (width >> granularity));

    for y in 0..height >> granularity {
      for x in 0..width >> granularity {
        let block_rect = Area::Rect {
          x: (x << granularity) as isize,
          y: (y << granularity) as isize,
          width: 8,
          height: 8,
        };

        let block = luma.subregion(block_rect);

        let mean: f64 = block
          .rows_iter()
          .flatten()
          .map(|&pix| {
            let pix: i16 = CastFromPrimitive::cast_from(pix);
            pix as f64
          })
          .sum::<f64>()
          / 64.0_f64;
        let variance: f64 = block
          .rows_iter()
          .flatten()
          .map(|&pix| {
            let pix: i16 = CastFromPrimitive::cast_from(pix);
            (pix as f64 - mean).powi(2)
          })
          .sum::<f64>();
        variances.push(variance);
      }
    }
    ActivityMask { variances, width, height, granularity }
  }

  pub fn variance_at(&self, x: usize, y: usize) -> Option<f64> {
    let (dec_width, dec_height) =
      (self.width >> self.granularity, self.height >> self.granularity);
    if x > dec_width || y > dec_height {
      None
    } else {
      Some(*self.variances.get(x + dec_width * y).unwrap())
    }
  }

  pub fn mean_activity_of(&self, rect: Rect) -> Option<f64> {
    let Rect { x, y, width, height } = rect;
    let (x, y) = (x as usize, y as usize);
    let granularity = self.granularity;
    let (dec_x, dec_y) = (x >> granularity, y >> granularity);
    let (dec_width, dec_height) =
      (width >> granularity, height >> granularity);

    if x > self.width
      || y > self.height
      || (x + width) > self.width
      || (y + height) > self.height
      || dec_width == 0
      || dec_height == 0
    {
      // Region lies out of the frame or is smaller than 8x8 on some axis
      None
    } else {
      let activity = self
        .variances
        .chunks_exact(self.width >> granularity)
        .skip(dec_y)
        .take(dec_height)
        .map(|row| row.iter().skip(dec_x).take(dec_width).sum::<f64>())
        .sum::<f64>()
        / (dec_width as f64 * dec_height as f64);

      Some(activity.cbrt().sqrt())
    }
  }
}
<|endoftext|>


<commit_before>use regex::Regex;

//pub struct Collection {
//    pub backup_chain : Vec<BackupSet>
//}
//
//pub struct BackupSet {
//    files : Vec<FileName>
//}
//
//impl Collection {
//    pub fn open(path : &str) -> Self {
//        Collection{ backup_chain : Vec::new() }
//    }
//}

#[derive(Eq, PartialEq, Debug)]
pub enum FileType {
    //FullSig,
    //NewSig,
    //Inc,
    Full
}

#[derive(Eq, PartialEq, Debug)]
pub struct FileName {
    pub ftype : FileType,
    pub manifest : bool,
    pub volume_number : i32,
    pub time : String,
    // TODO enable those fields
    //start_time : String,
    //end_time : String,
    //compressed : bool,
    //encrypted : bool,
    pub partial : bool
}

pub struct FileNameParser {
    full_vol_re : Regex,
    full_manifest_re : Regex
}

impl FileNameParser {
    pub fn new() -> Self {
        FileNameParser {
            full_vol_re : Regex::new(r"^duplicity-full\.(?P<time>.*?)\.vol(?P<num>[0-9]+)\.difftar(?P<partial>(\.part))?($|\.)").unwrap(),
            full_manifest_re : Regex::new(r"^duplicity-full\.(?P<time>.*?)\.manifest(?P<partial>(\.part))?($|\.)").unwrap()
        }
    }

    pub fn parse(&self, filename : &str) -> Option<FileName> {
        use std::ascii::AsciiExt;

        let lower_fname = filename.to_ascii_lowercase();
        self.check_full(&lower_fname)
    }

    fn check_full(&self, filename : &str) -> Option<FileName> {
        if let Some(captures) = self.full_vol_re.captures(filename) {
            let time = captures.name("time").unwrap();
            // TODO: str2time
            if let Some(vol_num) = self.get_vol_num(captures.name("num").unwrap()) {
                return Some(FileName{ftype : FileType::Full,
                                     manifest : false,
                                     volume_number : vol_num,
                                     time : time.to_owned(),
                                     partial : false});
            }
            return None;
        }
        if let Some(captures) = self.full_manifest_re.captures(filename) {
            let time = captures.name("time").unwrap();
            // TODO: str2time
            return Some(FileName{ftype : FileType::Full,
                                 manifest : true,
                                 volume_number : 0,
                                 time : time.to_owned(),
                                 partial : captures.name("partial").is_some()});
        }
        return None;
    }

    fn get_vol_num(&self, s : &str) -> Option<i32> {
        s.parse::<i32>().ok()
    }
}

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

    #[test]
    fn parser_test() {
        let parser = FileNameParser::new();
        assert_eq!(parser.parse("invalid"), None);
        assert_eq!(parser.parse("duplicity-full.20150617T182545Z.vol1.difftar.gz"),
                   Some(FileName{ftype : FileType::Full,
                                 manifest : false,
                                 volume_number : 1,
                                 time : "20150617t182545z".to_owned(),
                                 partial : false}));
    }
}
<commit_msg>Problems with Option :(<commit_after>use regex::Regex;

//pub struct Collection {
//    pub backup_chain : Vec<BackupSet>
//}
//
//pub struct BackupSet {
//    files : Vec<FileName>
//}
//
//impl Collection {
//    pub fn open(path : &str) -> Self {
//        Collection{ backup_chain : Vec::new() }
//    }
//}

#[derive(Eq, PartialEq, Debug)]
pub enum FileType {
    //FullSig,
    //NewSig,
    //Inc,
    Full
}

#[derive(Eq, PartialEq, Debug)]
pub struct FileName {
    pub file_type : FileType,
    pub manifest : bool,
    pub volume_number : i32,
    pub time : String,
    // TODO enable those fields
    //start_time : String,
    //end_time : String,
    compressed : bool,
    //encrypted : bool,
    pub partial : bool
}

pub struct FileNameParser {
    full_vol_re : Regex,
    full_manifest_re : Regex
}

impl FileName {
    /// Builder pattern for FileName
    pub fn new() -> Self {
        FileName{file_type : FileType::Full,
                 manifest : false,
                 volume_number : 0,
                 time : "".to_owned(),
                 // TODO enable those fields
                 //start_time : "".to_owned(),
                 //end_time : "".to_owned(),
                 compressed : false,
                 //encrypted : false,
                 partial : false}
    }

    pub fn file_type(mut self, file_type : FileType) -> Self {
        self.file_type = file_type;
        self
    }

    pub fn manifest(mut self, manifest : bool) -> Self {
        self.manifest = manifest;
        self
    }

    pub fn volume_number(mut self, volume_number : i32) -> Self {
        self.volume_number = volume_number;
        self
    }

    pub fn time(mut self, time : String) -> Self {
        self.time = time;
        self
    }

    pub fn compressed(&mut self, compressed : bool) -> &mut Self {
        self.compressed = compressed;
        self
    }

    pub fn partial(mut self, partial : bool) -> Self {
        self.partial = partial;
        self
    }
}

impl FileNameParser {
    pub fn new() -> Self {
        FileNameParser {
            full_vol_re : Regex::new(r"^duplicity-full\.(?P<time>.*?)\.vol(?P<num>[0-9]+)\.difftar(?P<partial>(\.part))?($|\.)").unwrap(),
            full_manifest_re : Regex::new(r"^duplicity-full\.(?P<time>.*?)\.manifest(?P<partial>(\.part))?($|\.)").unwrap()
        }
    }

    pub fn parse(&self, filename : &str) -> Option<FileName> {
        use std::ascii::AsciiExt;

        let lower_fname = filename.to_ascii_lowercase();
        self.check_full(&lower_fname)
            .map(|f| f.compressed(self.is_compressed(filename)))
    }

    fn check_full(&self, filename : &str) -> Option<FileName> {
        if let Some(captures) = self.full_vol_re.captures(filename) {
            let time = captures.name("time").unwrap();
            // TODO: str2time
            if let Some(vol_num) = self.get_vol_num(captures.name("num").unwrap()) {
                return Some(FileName::new().file_type(FileType::Full)
                            .volume_number(vol_num)
                            .time(time.to_owned()));
            }
            return None;
        }
        if let Some(captures) = self.full_manifest_re.captures(filename) {
            let time = captures.name("time").unwrap();
            // TODO: str2time
            return Some(FileName::new().file_type(FileType::Full)
                        .manifest(true)
                        .time(time.to_owned())
                        .partial(captures.name("partial").is_some()));
        }
        return None;
    }

    fn get_vol_num(&self, s : &str) -> Option<i32> {
        s.parse::<i32>().ok()
    }

    fn is_encrypted(&self, s : &str) -> bool {
        s.ends_with(".gpg") || s.ends_with(".g")
    }

    fn is_compressed(&self, s : &str) -> bool {
        s.ends_with(".gz") || s.ends_with(".z")
    }
}

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

    #[test]
    fn parser_test() {
        let parser = FileNameParser::new();
        assert_eq!(parser.parse("invalid"), None);
        assert_eq!(parser.parse("duplicity-full.20150617T182545Z.vol1.difftar.gz"),
                   Some(FileName{file_type : FileType::Full,
                                 manifest : false,
                                 volume_number : 1,
                                 time : "20150617t182545z".to_owned(),
                                 compressed : false,
                                 partial : false}));
    }
}
<|endoftext|>


<commit_before>// Copyright 2013-2016 Simon Sapin.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Parser and serializer for the [`application/x-www-form-urlencoded` syntax](
//! http://url.spec.whatwg.org/#application/x-www-form-urlencoded),
//! as used by HTML forms.
//!
//! Converts between a string (such as an URL’s query string)
//! and a sequence of (name, value) pairs.

use encoding::EncodingOverride;
use percent_encoding::{percent_encode_byte, percent_decode};
use std::borrow::{Borrow, Cow};
use std::iter;
use std::str;

/// Convert a byte string in the `application/x-www-form-urlencoded` syntax
/// into a iterator of (name, value) pairs.
///
/// Use `parse(input.as_bytes())` to parse a `&str` string.
///
/// The names and values are percent-decoded. For instance, `%23first=%25try%25` will be
/// converted to `[("#first", "%try%")]`.
#[inline]
pub fn parse(input: &[u8]) -> Parse {
    Parse {
        input: input,
        encoding: EncodingOverride::utf8(),
    }
}

/// Convert a byte string in the `application/x-www-form-urlencoded` syntax
/// into a iterator of (name, value) pairs.
///
/// Use `parse(input.as_bytes())` to parse a `&str` string.
///
/// This function is only available if the `query_encoding` Cargo feature is enabled.
///
/// Arguments:
///
/// * `encoding_override`: The character encoding each name and values is decoded as
///    after percent-decoding. Defaults to UTF-8.
/// * `use_charset`: The *use _charset_ flag*. If in doubt, set to `false`.
#[cfg(feature = "query_encoding")]
pub fn parse_with_encoding<'a>(input: &'a [u8],
                               encoding_override: Option<::encoding::EncodingRef>,
                               use_charset: bool)
                               -> Result<Parse<'a>, ()> {
    use std::ascii::AsciiExt;

    let mut encoding = EncodingOverride::from_opt_encoding(encoding_override);
    if !(encoding.is_utf8() || input.is_ascii()) {
        return Err(())
    }
    if use_charset {
        for sequence in input.split(|&b| b == b'&') {
            // No '+' in "_charset_" to replace with ' '.
            if sequence.starts_with(b"_charset_=") {
                let value = &sequence[b"_charset_=".len()..];
                // Skip replacing '+' with ' ' in value since no encoding label contains either:
                // https://encoding.spec.whatwg.org/#names-and-labels
                if let Some(e) = EncodingOverride::lookup(value) {
                    encoding = e;
                    break
                }
            }
        }
    }
    Ok(Parse {
        input: input,
        encoding: encoding,
    })
}

/// The return type of `parse()`.
#[derive(Copy, Clone)]
pub struct Parse<'a> {
    input: &'a [u8],
    encoding: EncodingOverride,
}

impl<'a> Iterator for Parse<'a> {
    type Item = (Cow<'a, str>, Cow<'a, str>);

    fn next(&mut self) -> Option<Self::Item> {
        loop {
            if self.input.is_empty() {
                return None
            }
            let mut split2 = self.input.splitn(2, |&b| b == b'&');
            let sequence = split2.next().unwrap();
            self.input = split2.next().unwrap_or(&[][..]);
            if sequence.is_empty() {
                continue
            }
            let mut split2 = sequence.splitn(2, |&b| b == b'=');
            let name = split2.next().unwrap();
            let value = split2.next().unwrap_or(&[][..]);
            return Some((
                decode(name, self.encoding),
                decode(value, self.encoding),
            ))
        }
    }
}

fn decode(input: &[u8], encoding: EncodingOverride) -> Cow<str> {
    let replaced = replace_plus(input);
    encoding.decode(match percent_decode(&replaced).if_any() {
        Some(vec) => Cow::Owned(vec),
        None => replaced,
    })
}

/// Replace b'+' with b' '
fn replace_plus<'a>(input: &'a [u8]) -> Cow<'a, [u8]> {
    match input.iter().position(|&b| b == b'+') {
        None => Cow::Borrowed(input),
        Some(first_position) => {
            let mut replaced = input.to_owned();
            replaced[first_position] = b' ';
            for byte in &mut replaced[first_position + 1..] {
                if *byte == b'+' {
                    *byte = b' ';
                }
            }
            Cow::Owned(replaced)
        }
    }
}

impl<'a> Parse<'a> {
    /// Return a new iterator that yields pairs of `String` instead of pair of `Cow<str>`.
    pub fn into_owned(self) -> iter::Map<Parse<'a>, fn((Cow<str>, Cow<str>)) -> (String, String)> {
        fn into_owned((k, v): (Cow<str>, Cow<str>)) -> (String, String) {
            (k.into_owned(), v.into_owned())
        }
        self.map(into_owned)
    }
}

/// The [`application/x-www-form-urlencoded` byte serializer](
/// https://url.spec.whatwg.org/#concept-urlencoded-byte-serializer).
///
/// Return an iterator of `&str` slices.
pub fn byte_serialize(input: &[u8]) -> ByteSerialize {
    ByteSerialize {
        bytes: input,
    }
}

/// Return value of `byte_serialize()`.
pub struct ByteSerialize<'a> {
    bytes: &'a [u8],
}

fn byte_serialized_unchanged(byte: u8) -> bool {
    matches!(byte, b'*' | b'-' | b'.' | b'0' ... b'9' | b'A' ... b'Z' | b'_' | b'a' ... b'z')
}

impl<'a> Iterator for ByteSerialize<'a> {
    type Item = &'a str;

    fn next(&mut self) -> Option<&'a str> {
        if let Some((&first, tail)) = self.bytes.split_first() {
            if !byte_serialized_unchanged(first) {
                self.bytes = tail;
                return Some(if first == b' ' { "+" } else { percent_encode_byte(first) })
            }
            let position = tail.iter().position(|&b| !byte_serialized_unchanged(b));
            let (unchanged_slice, remaining) = match position {
                // 1 for first_byte + i unchanged in tail
                Some(i) => self.bytes.split_at(1 + i),
                None => (self.bytes, &[][..]),
            };
            self.bytes = remaining;
            Some(unsafe { str::from_utf8_unchecked(unchanged_slice) })
        } else {
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        if self.bytes.is_empty() {
            (0, Some(0))
        } else {
            (1, Some(self.bytes.len()))
        }
    }
}

/// The [`application/x-www-form-urlencoded` serializer](
/// https://url.spec.whatwg.org/#concept-urlencoded-serializer).
pub struct Serializer<T: Target> {
    target: Option<T>,
    start_position: usize,
    encoding: EncodingOverride,
}

pub trait Target {
    fn as_mut_string(&mut self) -> &mut String;
    fn finish(self) -> Self::Finished;
    type Finished;
}

impl Target for String {
    fn as_mut_string(&mut self) -> &mut String { self }
    fn finish(self) -> Self { self }
    type Finished = Self;
}

impl<'a> Target for &'a mut String {
    fn as_mut_string(&mut self) -> &mut String { &mut **self }
    fn finish(self) -> Self { self }
    type Finished = Self;
}

// `as_mut_string` string here exposes the internal serialization of an `Url`,
// which should not be exposed to users.
// We achieve that by not giving users direct access to `UrlQuery`:
// * Its fields are private
//   (and so can not be constructed with struct literal syntax outside of this crate),
// * It has no constructor
// * It is only visible (on the type level) to users in the return type of
//   `Url::mutate_query_pairs` which is `Serializer<UrlQuery>`
// * `Serializer` keeps its target in a private field
// * Unlike in other `Target` impls, `UrlQuery::finished` does not return `Self`.
impl<'a> Target for ::UrlQuery<'a> {
    fn as_mut_string(&mut self) -> &mut String { &mut self.url.serialization }
    fn finish(self) -> &'a mut ::Url { self.url }
    type Finished = &'a mut ::Url;
}

impl<T: Target> Serializer<T> {
    /// Create a new `application/x-www-form-urlencoded` serializer for the given target.
    ///
    /// If the target is non-empty,
    /// its content is assumed to already be in `application/x-www-form-urlencoded` syntax.
    pub fn new(target: T) -> Self {
        Self::for_suffix(target, 0)
    }

    /// Create a new `application/x-www-form-urlencoded` serializer
    /// for a suffix of the given target.
    ///
    /// If that suffix is non-empty,
    /// its content is assumed to already be in `application/x-www-form-urlencoded` syntax.
    pub fn for_suffix(mut target: T, start_position: usize) -> Self {
        &target.as_mut_string()[start_position..];  // Panic if out of bounds
        Serializer {
            target: Some(target),
            start_position: start_position,
            encoding: EncodingOverride::utf8(),
        }
    }

    /// Remove any existing name/value pair.
    ///
    /// Panics if called after `.finish()`.
    pub fn clear(&mut self) -> &mut Self {
        string(&mut self.target).truncate(self.start_position);
        self
    }

    /// Set the character encoding to be used for names and values before percent-encoding.
    #[cfg(feature = "query_encoding")]
    pub fn encoding_override(&mut self, new: Option<::encoding::EncodingRef>) -> &mut Self {
        self.encoding = EncodingOverride::from_opt_encoding(new).to_output_encoding();
        self
    }

    /// Serialize and append a name/value pair.
    ///
    /// Panics if called after `.finish()`.
    pub fn append_pair(&mut self, name: &str, value: &str) -> &mut Self {
        append_pair(string(&mut self.target), self.start_position, self.encoding, name, value);
        self
    }

    /// Serialize and append a number of name/value pairs.
    ///
    /// This simply calls `append_pair` repeatedly.
    /// This can be more convenient, so the user doesn’t need to introduce a block
    /// to limit the scope of `Serializer`’s borrow of its string.
    ///
    /// Panics if called after `.finish()`.
    pub fn extend_pairs<I, K, V>(&mut self, iter: I) -> &mut Self
    where I: IntoIterator, I::Item: Borrow<(K, V)>, K: AsRef<str>, V: AsRef<str> {
        {
            let string = string(&mut self.target);
            for pair in iter {
                let &(ref k, ref v) = pair.borrow();
                append_pair(string, self.start_position, self.encoding, k.as_ref(), v.as_ref());
            }
        }
        self
    }

    /// Add a name/value pair whose name is `_charset_`
    /// and whose value is the character encoding’s name.
    /// (See the `encoding_override()` method.)
    ///
    /// Panics if called after `.finish()`.
    #[cfg(feature = "query_encoding")]
    pub fn append_charset(&mut self) -> &mut Self {
        {
            let string = string(&mut self.target);
            append_separator_if_needed(string, self.start_position);
            string.push_str("_charset_=");
            string.push_str(self.encoding.name());
        }
        self
    }

    /// If this serializer was constructed with a string, take and return that string.
    ///
    /// ```rust
    /// use url::form_urlencoded;
    /// let encoded: String = form_urlencoded::Serializer::new(String::new())
    ///     .append_pair("foo", "bar & baz")
    ///     .append_pair("saison", "Été+hiver")
    ///     .finish();
    /// assert_eq!(encoded, "foo=bar+%26+baz&saison=%C3%89t%C3%A9%2Bhiver");
    /// ```
    ///
    /// Panics if called more than once.
    pub fn finish(&mut self) -> T::Finished {
        self.target.take().expect("url::form_urlencoded::Serializer double finish").finish()
    }
}

fn append_separator_if_needed(string: &mut String, start_position: usize) {
    if string.len() > start_position {
        string.push('&')
    }
}

fn string<T: Target>(target: &mut Option<T>) -> &mut String {
    target.as_mut().expect("url::form_urlencoded::Serializer finished").as_mut_string()
}

fn append_pair(string: &mut String, start_position: usize, encoding: EncodingOverride,
               name: &str, value: &str) {
    append_separator_if_needed(string, start_position);
    string.extend(byte_serialize(&encoding.encode(name.into())));
    string.push('=');
    string.extend(byte_serialize(&encoding.encode(value.into())));
}
<commit_msg>form_urlencoded::Parse::into_owned returns a dedicated type<commit_after>// Copyright 2013-2016 Simon Sapin.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Parser and serializer for the [`application/x-www-form-urlencoded` syntax](
//! http://url.spec.whatwg.org/#application/x-www-form-urlencoded),
//! as used by HTML forms.
//!
//! Converts between a string (such as an URL’s query string)
//! and a sequence of (name, value) pairs.

use encoding::EncodingOverride;
use percent_encoding::{percent_encode_byte, percent_decode};
use std::borrow::{Borrow, Cow};
use std::str;

/// Convert a byte string in the `application/x-www-form-urlencoded` syntax
/// into a iterator of (name, value) pairs.
///
/// Use `parse(input.as_bytes())` to parse a `&str` string.
///
/// The names and values are percent-decoded. For instance, `%23first=%25try%25` will be
/// converted to `[("#first", "%try%")]`.
#[inline]
pub fn parse(input: &[u8]) -> Parse {
    Parse {
        input: input,
        encoding: EncodingOverride::utf8(),
    }
}

/// Convert a byte string in the `application/x-www-form-urlencoded` syntax
/// into a iterator of (name, value) pairs.
///
/// Use `parse(input.as_bytes())` to parse a `&str` string.
///
/// This function is only available if the `query_encoding` Cargo feature is enabled.
///
/// Arguments:
///
/// * `encoding_override`: The character encoding each name and values is decoded as
///    after percent-decoding. Defaults to UTF-8.
/// * `use_charset`: The *use _charset_ flag*. If in doubt, set to `false`.
#[cfg(feature = "query_encoding")]
pub fn parse_with_encoding<'a>(input: &'a [u8],
                               encoding_override: Option<::encoding::EncodingRef>,
                               use_charset: bool)
                               -> Result<Parse<'a>, ()> {
    use std::ascii::AsciiExt;

    let mut encoding = EncodingOverride::from_opt_encoding(encoding_override);
    if !(encoding.is_utf8() || input.is_ascii()) {
        return Err(())
    }
    if use_charset {
        for sequence in input.split(|&b| b == b'&') {
            // No '+' in "_charset_" to replace with ' '.
            if sequence.starts_with(b"_charset_=") {
                let value = &sequence[b"_charset_=".len()..];
                // Skip replacing '+' with ' ' in value since no encoding label contains either:
                // https://encoding.spec.whatwg.org/#names-and-labels
                if let Some(e) = EncodingOverride::lookup(value) {
                    encoding = e;
                    break
                }
            }
        }
    }
    Ok(Parse {
        input: input,
        encoding: encoding,
    })
}

/// The return type of `parse()`.
#[derive(Copy, Clone)]
pub struct Parse<'a> {
    input: &'a [u8],
    encoding: EncodingOverride,
}

impl<'a> Iterator for Parse<'a> {
    type Item = (Cow<'a, str>, Cow<'a, str>);

    fn next(&mut self) -> Option<Self::Item> {
        loop {
            if self.input.is_empty() {
                return None
            }
            let mut split2 = self.input.splitn(2, |&b| b == b'&');
            let sequence = split2.next().unwrap();
            self.input = split2.next().unwrap_or(&[][..]);
            if sequence.is_empty() {
                continue
            }
            let mut split2 = sequence.splitn(2, |&b| b == b'=');
            let name = split2.next().unwrap();
            let value = split2.next().unwrap_or(&[][..]);
            return Some((
                decode(name, self.encoding),
                decode(value, self.encoding),
            ))
        }
    }
}

fn decode(input: &[u8], encoding: EncodingOverride) -> Cow<str> {
    let replaced = replace_plus(input);
    encoding.decode(match percent_decode(&replaced).if_any() {
        Some(vec) => Cow::Owned(vec),
        None => replaced,
    })
}

/// Replace b'+' with b' '
fn replace_plus<'a>(input: &'a [u8]) -> Cow<'a, [u8]> {
    match input.iter().position(|&b| b == b'+') {
        None => Cow::Borrowed(input),
        Some(first_position) => {
            let mut replaced = input.to_owned();
            replaced[first_position] = b' ';
            for byte in &mut replaced[first_position + 1..] {
                if *byte == b'+' {
                    *byte = b' ';
                }
            }
            Cow::Owned(replaced)
        }
    }
}

impl<'a> Parse<'a> {
    /// Return a new iterator that yields pairs of `String` instead of pairs of `Cow<str>`.
    pub fn into_owned(self) -> ParseIntoOwned<'a> {
        ParseIntoOwned { inner: self }
    }
}

/// Like `Parse`, but yields pairs of `String` instead of pairs of `Cow<str>`.
pub struct ParseIntoOwned<'a> {
    inner: Parse<'a>
}

impl<'a> Iterator for ParseIntoOwned<'a> {
    type Item = (String, String);

    fn next(&mut self) -> Option<Self::Item> {
        self.inner.next().map(|(k, v)| (k.into_owned(), v.into_owned()))
    }
}

/// The [`application/x-www-form-urlencoded` byte serializer](
/// https://url.spec.whatwg.org/#concept-urlencoded-byte-serializer).
///
/// Return an iterator of `&str` slices.
pub fn byte_serialize(input: &[u8]) -> ByteSerialize {
    ByteSerialize {
        bytes: input,
    }
}

/// Return value of `byte_serialize()`.
pub struct ByteSerialize<'a> {
    bytes: &'a [u8],
}

fn byte_serialized_unchanged(byte: u8) -> bool {
    matches!(byte, b'*' | b'-' | b'.' | b'0' ... b'9' | b'A' ... b'Z' | b'_' | b'a' ... b'z')
}

impl<'a> Iterator for ByteSerialize<'a> {
    type Item = &'a str;

    fn next(&mut self) -> Option<&'a str> {
        if let Some((&first, tail)) = self.bytes.split_first() {
            if !byte_serialized_unchanged(first) {
                self.bytes = tail;
                return Some(if first == b' ' { "+" } else { percent_encode_byte(first) })
            }
            let position = tail.iter().position(|&b| !byte_serialized_unchanged(b));
            let (unchanged_slice, remaining) = match position {
                // 1 for first_byte + i unchanged in tail
                Some(i) => self.bytes.split_at(1 + i),
                None => (self.bytes, &[][..]),
            };
            self.bytes = remaining;
            Some(unsafe { str::from_utf8_unchecked(unchanged_slice) })
        } else {
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        if self.bytes.is_empty() {
            (0, Some(0))
        } else {
            (1, Some(self.bytes.len()))
        }
    }
}

/// The [`application/x-www-form-urlencoded` serializer](
/// https://url.spec.whatwg.org/#concept-urlencoded-serializer).
pub struct Serializer<T: Target> {
    target: Option<T>,
    start_position: usize,
    encoding: EncodingOverride,
}

pub trait Target {
    fn as_mut_string(&mut self) -> &mut String;
    fn finish(self) -> Self::Finished;
    type Finished;
}

impl Target for String {
    fn as_mut_string(&mut self) -> &mut String { self }
    fn finish(self) -> Self { self }
    type Finished = Self;
}

impl<'a> Target for &'a mut String {
    fn as_mut_string(&mut self) -> &mut String { &mut **self }
    fn finish(self) -> Self { self }
    type Finished = Self;
}

// `as_mut_string` string here exposes the internal serialization of an `Url`,
// which should not be exposed to users.
// We achieve that by not giving users direct access to `UrlQuery`:
// * Its fields are private
//   (and so can not be constructed with struct literal syntax outside of this crate),
// * It has no constructor
// * It is only visible (on the type level) to users in the return type of
//   `Url::mutate_query_pairs` which is `Serializer<UrlQuery>`
// * `Serializer` keeps its target in a private field
// * Unlike in other `Target` impls, `UrlQuery::finished` does not return `Self`.
impl<'a> Target for ::UrlQuery<'a> {
    fn as_mut_string(&mut self) -> &mut String { &mut self.url.serialization }
    fn finish(self) -> &'a mut ::Url { self.url }
    type Finished = &'a mut ::Url;
}

impl<T: Target> Serializer<T> {
    /// Create a new `application/x-www-form-urlencoded` serializer for the given target.
    ///
    /// If the target is non-empty,
    /// its content is assumed to already be in `application/x-www-form-urlencoded` syntax.
    pub fn new(target: T) -> Self {
        Self::for_suffix(target, 0)
    }

    /// Create a new `application/x-www-form-urlencoded` serializer
    /// for a suffix of the given target.
    ///
    /// If that suffix is non-empty,
    /// its content is assumed to already be in `application/x-www-form-urlencoded` syntax.
    pub fn for_suffix(mut target: T, start_position: usize) -> Self {
        &target.as_mut_string()[start_position..];  // Panic if out of bounds
        Serializer {
            target: Some(target),
            start_position: start_position,
            encoding: EncodingOverride::utf8(),
        }
    }

    /// Remove any existing name/value pair.
    ///
    /// Panics if called after `.finish()`.
    pub fn clear(&mut self) -> &mut Self {
        string(&mut self.target).truncate(self.start_position);
        self
    }

    /// Set the character encoding to be used for names and values before percent-encoding.
    #[cfg(feature = "query_encoding")]
    pub fn encoding_override(&mut self, new: Option<::encoding::EncodingRef>) -> &mut Self {
        self.encoding = EncodingOverride::from_opt_encoding(new).to_output_encoding();
        self
    }

    /// Serialize and append a name/value pair.
    ///
    /// Panics if called after `.finish()`.
    pub fn append_pair(&mut self, name: &str, value: &str) -> &mut Self {
        append_pair(string(&mut self.target), self.start_position, self.encoding, name, value);
        self
    }

    /// Serialize and append a number of name/value pairs.
    ///
    /// This simply calls `append_pair` repeatedly.
    /// This can be more convenient, so the user doesn’t need to introduce a block
    /// to limit the scope of `Serializer`’s borrow of its string.
    ///
    /// Panics if called after `.finish()`.
    pub fn extend_pairs<I, K, V>(&mut self, iter: I) -> &mut Self
    where I: IntoIterator, I::Item: Borrow<(K, V)>, K: AsRef<str>, V: AsRef<str> {
        {
            let string = string(&mut self.target);
            for pair in iter {
                let &(ref k, ref v) = pair.borrow();
                append_pair(string, self.start_position, self.encoding, k.as_ref(), v.as_ref());
            }
        }
        self
    }

    /// Add a name/value pair whose name is `_charset_`
    /// and whose value is the character encoding’s name.
    /// (See the `encoding_override()` method.)
    ///
    /// Panics if called after `.finish()`.
    #[cfg(feature = "query_encoding")]
    pub fn append_charset(&mut self) -> &mut Self {
        {
            let string = string(&mut self.target);
            append_separator_if_needed(string, self.start_position);
            string.push_str("_charset_=");
            string.push_str(self.encoding.name());
        }
        self
    }

    /// If this serializer was constructed with a string, take and return that string.
    ///
    /// ```rust
    /// use url::form_urlencoded;
    /// let encoded: String = form_urlencoded::Serializer::new(String::new())
    ///     .append_pair("foo", "bar & baz")
    ///     .append_pair("saison", "Été+hiver")
    ///     .finish();
    /// assert_eq!(encoded, "foo=bar+%26+baz&saison=%C3%89t%C3%A9%2Bhiver");
    /// ```
    ///
    /// Panics if called more than once.
    pub fn finish(&mut self) -> T::Finished {
        self.target.take().expect("url::form_urlencoded::Serializer double finish").finish()
    }
}

fn append_separator_if_needed(string: &mut String, start_position: usize) {
    if string.len() > start_position {
        string.push('&')
    }
}

fn string<T: Target>(target: &mut Option<T>) -> &mut String {
    target.as_mut().expect("url::form_urlencoded::Serializer finished").as_mut_string()
}

fn append_pair(string: &mut String, start_position: usize, encoding: EncodingOverride,
               name: &str, value: &str) {
    append_separator_if_needed(string, start_position);
    string.extend(byte_serialize(&encoding.encode(name.into())));
    string.push('=');
    string.extend(byte_serialize(&encoding.encode(value.into())));
}
<|endoftext|>


<commit_before>/*!
 * Helper to decompose a packet of binary data into multiple arbitrary data
 * structures.
 */

use std::{cast, str, sys};
use std::libc::c_char;

/// An iterator that can be used to fetch typed arguments from a byte vector
pub struct ArgumentIterator<'self> {
	priv data: &'self [u8],
	priv pos: uint,
}

impl<'self> ArgumentIterator<'self> {
	/// Create a new argument iterator for the given byte vector
	pub fn new (data: &'self [u8]) -> ArgumentIterator<'self> {
		ArgumentIterator { data: data, pos: 0 }
	}

	/// Fetch a typed argument
	pub fn fetch<T> (&mut self) -> &'self T {
		do self.data.as_imm_buf |dataptr, _| {
			let value = unsafe { cast::transmute(dataptr.offset(self.pos as int)) };
			self.pos += sys::size_of::<T>();
			assert!(self.pos <= self.data.len(), "trying to get argument behind data");
			value
		}
	}

	/// Fetch a (zero-terminated) string
	pub fn fetch_str (&mut self) -> &'self str {
		do self.data.as_imm_buf |dataptr, _| {
			// FIXME: this fails if data contains non-utf8 garbage (c_str_to_static_slice asserts an utf8 string)
			let text = unsafe { str::raw::c_str_to_static_slice(dataptr.offset(self.pos as int) as *c_char) };
			self.pos += text.len() + 1;
			assert!(self.pos <= self.data.len(), "trying to get argument behind data");
			text
		}
	}

	/// Fetch a slice of the remaining data
	pub fn fetch_data (&mut self) -> &'self [u8] {
		let bytes = self.data.tailn(self.pos);
		self.pos = self.data.len();
		bytes
	}
}

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

	static test_data: [u8, ..12] = [0x66, 0x6f, 0x6f, 0x00, 0x62, 0x61, 0x72, 0x00, 0x62, 0x61, 0x7a, 0x00];
	struct test_argument_t { p1: u8, p2: u8, p3: u16 }

	#[test]
	fn test_argument_type () {
		let mut it = ArgumentIterator::new(test_data);
		let arg: &test_argument_t = it.fetch();
		assert!(arg.p1 == 0x66, "argument iterator should fetch typed argument from data");
		assert!(arg.p2 == 0x6f, "argument iterator should fetch typed argument from data");
		assert!(arg.p3 == 0x006f, "argument iterator should fetch typed argument from data");
		let arg: &test_argument_t = it.fetch();
		assert!(arg.p1 == 0x62, "argument iterator should fetch typed argument from data");
		assert!(arg.p2 == 0x61, "argument iterator should fetch typed argument from data");
		assert!(arg.p3 == 0x0072, "argument iterator should fetch typed argument from data");
	}

	#[test]
	fn test_argument_string () {
		let mut it = ArgumentIterator::new(test_data);
		let arg = it.fetch_str();
		assert!(arg == "foo", "argument iterator should fetch string from data");
		let arg = it.fetch_str();
		assert!(arg == "bar", "argument iterator should fetch string from data");
	}

	#[test]
	fn test_argument_data () {
		let mut it = ArgumentIterator::new(test_data);
		it.fetch_str();
		it.fetch_str();
		let arg = it.fetch_data();
		assert!(arg == [0x62, 0x61, 0x7a, 0x00], "argument iterator should fetch data from data");
	}

	#[test]
	fn test_argument_mixed () {
		let mut it = ArgumentIterator::new(test_data);
		let arg: &test_argument_t = it.fetch();
		assert!(arg.p1 == 0x66, "argument iterator should fetch typed argument from data");
		assert!(arg.p2 == 0x6f, "argument iterator should fetch typed argument from data");
		assert!(arg.p3 == 0x006f, "argument iterator should fetch typed argument from data");
		let arg = it.fetch_str();
		assert!(arg == "bar", "argument iterator should fetch string from data");
		let arg = it.fetch_data();
		assert!(arg == [0x62, 0x61, 0x7a, 0x00], "argument iterator should fetch data from data");
	}
}
<commit_msg>Small comment fixes<commit_after>/*!
 * Helper to decompose a packet of binary data into multiple arbitrary data
 * structures.
 */

use std::{cast, str, sys};
use std::libc::c_char;

/// An iterator that can be used to fetch typed arguments from a byte slice
pub struct ArgumentIterator<'self> {
	priv data: &'self [u8],
	priv pos: uint,
}

impl<'self> ArgumentIterator<'self> {
	/// Create a new argument iterator for the given byte slice
	pub fn new (data: &'self [u8]) -> ArgumentIterator<'self> {
		ArgumentIterator { data: data, pos: 0 }
	}

	/// Fetch a typed argument
	pub fn fetch<T> (&mut self) -> &'self T {
		do self.data.as_imm_buf |dataptr, _| {
			let value = unsafe { cast::transmute(dataptr.offset(self.pos as int)) };
			self.pos += sys::size_of::<T>();
			assert!(self.pos <= self.data.len(), "trying to get argument behind data");
			value
		}
	}

	/// Fetch a (zero-terminated) string
	pub fn fetch_str (&mut self) -> &'self str {
		do self.data.as_imm_buf |dataptr, _| {
			// FIXME: this fails if data contains non-utf8 garbage (c_str_to_static_slice asserts an utf8 string)
			let text = unsafe { str::raw::c_str_to_static_slice(dataptr.offset(self.pos as int) as *c_char) };
			self.pos += text.len() + 1;
			assert!(self.pos <= self.data.len(), "trying to get argument behind data");
			text
		}
	}

	/// Fetch a slice of the remaining data
	pub fn fetch_data (&mut self) -> &'self [u8] {
		let bytes = self.data.tailn(self.pos);
		self.pos = self.data.len();
		bytes
	}
}

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

	static test_data: [u8, ..12] = [0x66, 0x6f, 0x6f, 0x00, 0x62, 0x61, 0x72, 0x00, 0x62, 0x61, 0x7a, 0x00];
	struct test_argument_t { p1: u8, p2: u8, p3: u16 }

	#[test]
	fn test_argument_type () {
		let mut it = ArgumentIterator::new(test_data);
		let arg: &test_argument_t = it.fetch();
		assert!(arg.p1 == 0x66, "argument iterator should fetch typed argument from data");
		assert!(arg.p2 == 0x6f, "argument iterator should fetch typed argument from data");
		assert!(arg.p3 == 0x006f, "argument iterator should fetch typed argument from data");
		let arg: &test_argument_t = it.fetch();
		assert!(arg.p1 == 0x62, "argument iterator should fetch typed argument from data");
		assert!(arg.p2 == 0x61, "argument iterator should fetch typed argument from data");
		assert!(arg.p3 == 0x0072, "argument iterator should fetch typed argument from data");
	}

	#[test]
	fn test_argument_string () {
		let mut it = ArgumentIterator::new(test_data);
		let arg = it.fetch_str();
		assert!(arg == "foo", "argument iterator should fetch string from data");
		let arg = it.fetch_str();
		assert!(arg == "bar", "argument iterator should fetch string from data");
	}

	#[test]
	fn test_argument_data () {
		let mut it = ArgumentIterator::new(test_data);
		it.fetch_str();
		it.fetch_str();
		let arg = it.fetch_data();
		assert!(arg == [0x62, 0x61, 0x7a, 0x00], "argument iterator should fetch data from data");
	}

	#[test]
	fn test_argument_mixed () {
		let mut it = ArgumentIterator::new(test_data);
		let arg: &test_argument_t = it.fetch();
		assert!(arg.p1 == 0x66, "argument iterator should fetch typed argument from data");
		assert!(arg.p2 == 0x6f, "argument iterator should fetch typed argument from data");
		assert!(arg.p3 == 0x006f, "argument iterator should fetch typed argument from data");
		let arg = it.fetch_str();
		assert!(arg == "bar", "argument iterator should fetch string from data");
		let arg = it.fetch_data();
		assert!(arg == [0x62, 0x61, 0x7a, 0x00], "argument iterator should fetch data from data");
	}
}
<|endoftext|>


<commit_before>use pest::prelude::*;

use std::vec::Vec;
use std::string::String;

impl_rdp! {
    grammar! {
        program = { instruction ~ (["\n"] ~ instruction)* }
        instruction = { opcode ~ operand ~ operand ~ operand }
        opcode = _{ number }
        operand = _{ number }

        number = @{ (['0'..'9'] | ['a'..'f'] | ['A'..'F'])+ }

        whitespace = _{ [" "] }
    }
}

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

    #[test]
    fn it_parses_programs_as_machine_code() {
        let mut parser = Rdp::new(StringInput::new("0 a b c\n1 2 3 4"));

        assert!(parser.program());
        assert!(parser.end());

        let tokens = vec![
            Token::new(Rule::program, 0, 15),
            Token::new(Rule::instruction, 0, 7),
            Token::new(Rule::number, 0, 1),
            Token::new(Rule::number, 2, 3),
            Token::new(Rule::number, 4, 5),
            Token::new(Rule::number, 6, 7),
            Token::new(Rule::instruction, 8, 15),
            Token::new(Rule::number, 8, 9),
            Token::new(Rule::number, 10, 11),
            Token::new(Rule::number, 12, 13),
            Token::new(Rule::number, 14, 15),
        ];

        assert_eq!(parser.queue(), &tokens);
    }
}
<commit_msg>Compile assembly into machine code.<commit_after>use pest::prelude::*;

use std::vec::Vec;
use std::string::String;
use std::collections::LinkedList;

impl_rdp! {
    grammar! {
        program = _{ instruction ~ (["\n"] ~ instruction)* }
        instruction = _{ opcode ~ operand ~ operand ~ operand }
        opcode = _{ number }
        operand = _{ number }

        number = @{ (['0'..'9'] | ['a'..'f'] | ['A'..'F'])+ }

        whitespace = _{ [" "] }
    }

    process! {
        compile(&self) -> Vec<u32> {
            (list: _numbers()) => {
                let mut instructions = Vec::new();
                instructions.extend(list.iter());
                instructions
            }
        }

        _numbers(&self) -> LinkedList<u32> {
            (&head: number, mut tail: _numbers()) => {
                tail.push_front(u32::from_str_radix(head, 16).unwrap());
                tail
            },
            () => {
                LinkedList::new()
            }
        }
    }
}

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

    #[test]
    fn it_parses_programs_as_machine_code() {
        let mut parser = Rdp::new(StringInput::new("0 a b c\n1 2 3 4"));

        assert!(parser.program());
        assert!(parser.end());

        let tokens = vec![
            // Token::new(Rule::program, 0, 15),
            // Token::new(Rule::instruction, 0, 7),
            Token::new(Rule::number, 0, 1),
            Token::new(Rule::number, 2, 3),
            Token::new(Rule::number, 4, 5),
            Token::new(Rule::number, 6, 7),
            // Token::new(Rule::instruction, 8, 15),
            Token::new(Rule::number, 8, 9),
            Token::new(Rule::number, 10, 11),
            Token::new(Rule::number, 12, 13),
            Token::new(Rule::number, 14, 15),
        ];

        assert_eq!(parser.queue(), &tokens);
        assert_eq!(parser.compile(),
                   vec![0x0, 0xa, 0xb, 0xc, 0x1, 0x2, 0x3, 0x4]);
    }
}
<|endoftext|>