<commit_before>// Copyright 2016 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.

//! A stack-allocated vector, allowing storage of N elements on the stack.

use std::marker::Unsize;
use std::iter::Extend;
use std::ptr::{self, drop_in_place, Shared};
use std::ops::{Deref, DerefMut, Range};
use std::hash::{Hash, Hasher};
use std::slice;
use std::fmt;
use std::mem;
use std::collections::range::RangeArgument;
use std::collections::Bound::{Excluded, Included, Unbounded};
use std::mem::ManuallyDrop;

pub unsafe trait Array {
    type Element;
    type PartialStorage: Unsize<[ManuallyDrop<Self::Element>]>;
    const LEN: usize;
}

unsafe impl<T> Array for [T; 1] {
    type Element = T;
    type PartialStorage = [ManuallyDrop<T>; 1];
    const LEN: usize = 1;
}

unsafe impl<T> Array for [T; 8] {
    type Element = T;
    type PartialStorage = [ManuallyDrop<T>; 8];
    const LEN: usize = 8;
}

unsafe impl<T> Array for [T; 32] {
    type Element = T;
    type PartialStorage = [ManuallyDrop<T>; 32];
    const LEN: usize = 32;
}

pub struct ArrayVec {
    count: usize,
    values: A::PartialStorage
}

impl Hash for ArrayVec
    where A: Array,
          A::Element: Hash {
    fn hash<H>(&self, state: &mut H) where H: Hasher {
        (&self[..]).hash(state);
    }
}

impl Clone for ArrayVec
    where A: Array,
          A::Element: Clone {
    fn clone(&self) -> Self {
        let mut v = ArrayVec::new();
        v.extend(self.iter().cloned());
        v
    }
}

impl ArrayVec {
    pub fn new() -> Self {
        ArrayVec {
            count: 0,
            values: unsafe { ::std::mem::uninitialized() },
        }
    }

    pub fn len(&self) -> usize {
        self.count
    }

    pub unsafe fn set_len(&mut self, len: usize) {
        self.count = len;
    }

    /// Panics when the stack vector is full.
    pub fn push(&mut self, el: A::Element) {
        let arr = &mut self.values as &mut [ManuallyDrop<_>];
        arr[self.count] = ManuallyDrop::new(el);
        self.count += 1;
    }

    pub fn pop(&mut self) -> Option {
        if self.count > 0 {
            let arr = &mut self.values as &mut [ManuallyDrop<_>];
            self.count -= 1;
            unsafe {
                let value = ptr::read(&*arr[self.count]);
                Some(value)
            }
        } else {
            None
        }
    }

    pub fn drain<R>(&mut self, range: R) -> Drain
        where R: RangeArgument<usize>
    {
        // Memory safety
        //
        // When the Drain is first created, it shortens the length of
        // the source vector to make sure no uninitialized or moved-from elements
        // are accessible at all if the Drain's destructor never gets to run.
        //
        // Drain will ptr::read out the values to remove.
        // When finished, remaining tail of the vec is copied back to cover
        // the hole, and the vector length is restored to the new length.
        //
        let len = self.len();
        let start = match range.start() {
            Included(&n) => n,
            Excluded(&n) => n + 1,
            Unbounded    => 0,
        };
        let end = match range.end() {
            Included(&n) => n + 1,
            Excluded(&n) => n,
            Unbounded    => len,
        };
        assert!(start <= end);
        assert!(end <= len);

        unsafe {
            // set self.vec length's to start, to be safe in case Drain is leaked
            self.set_len(start);
            // Use the borrow in the IterMut to indicate borrowing behavior of the
            // whole Drain iterator (like &mut T).
            let range_slice = {
                let arr = &mut self.values as &mut [ManuallyDrop<_>];
                slice::from_raw_parts_mut(arr.as_mut_ptr().offset(start as isize),
                                          end - start)
            };
            Drain {
                tail_start: end,
                tail_len: len - end,
                iter: range_slice.iter(),
                array_vec: Shared::from(self),
            }
        }
    }
}

impl Default for ArrayVec
    where A: Array {
    fn default() -> Self {
        ArrayVec::new()
    }
}

impl fmt::Debug for ArrayVec
    where A: Array,
          A::Element: fmt::Debug {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self[..].fmt(f)
    }
}

impl Deref for ArrayVec {
    type Target = [A::Element];
    fn deref(&self) -> &Self::Target {
        unsafe {
            slice::from_raw_parts(&self.values as *const _ as *const A::Element, self.count)
        }
    }
}

impl DerefMut for ArrayVec {
    fn deref_mut(&mut self) -> &mut [A::Element] {
        unsafe {
            slice::from_raw_parts_mut(&mut self.values as *mut _ as *mut A::Element, self.count)
        }
    }
}

impl Drop for ArrayVec {
    fn drop(&mut self) {
        unsafe {
            drop_in_place(&mut self[..])
        }
    }
}

impl Extend for ArrayVec {
    fn extend(&mut self, iter: I) where I: IntoIterator<Item=A::Element> {
        for el in iter {
            self.push(el);
        }
    }
}

pub struct Iter {
    indices: Range<usize>,
    store: A::PartialStorage,
}

impl Drop for Iter {
    fn drop(&mut self) {
        for _ in self {}
    }
}

impl Iterator for Iter {
    type Item = A::Element;

    fn next(&mut self) -> Option {
        let arr = &self.store as &[ManuallyDrop<_>];
        unsafe {
            self.indices.next().map(|i| ptr::read(&*arr[i]))
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.indices.size_hint()
    }
}

pub struct Drain<'a, A: Array>
        where A::Element: 'a
{
    tail_start: usize,
    tail_len: usize,
    iter: slice::Iter<'a, ManuallyDrop>,
    array_vec: Shared<ArrayVec>,
}

impl<'a, A: Array> Iterator for Drain<'a, A> {
    type Item = A::Element;

    #[inline]
    fn next(&mut self) -> Option {
        self.iter.next().map(|elt| unsafe { ptr::read(&**elt) })
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

impl<'a, A: Array> Drop for Drain<'a, A> {
    fn drop(&mut self) {
        // exhaust self first
        while let Some(_) = self.next() {}

        if self.tail_len > 0 {
            unsafe {
                let source_array_vec = self.array_vec.as_mut();
                // memmove back untouched tail, update to new length
                let start = source_array_vec.len();
                let tail = self.tail_start;
                {
                    let arr = &mut source_array_vec.values as &mut [ManuallyDrop<_>];
                    let src = arr.as_ptr().offset(tail as isize);
                    let dst = arr.as_mut_ptr().offset(start as isize);
                    ptr::copy(src, dst, self.tail_len);
                };
                source_array_vec.set_len(start + self.tail_len);
            }
        }
    }
}

impl IntoIterator for ArrayVec {
    type Item = A::Element;
    type IntoIter = Iter;
    fn into_iter(self) -> Self::IntoIter {
        let store = unsafe {
            ptr::read(&self.values)
        };
        let indices = 0..self.count;
        mem::forget(self);
        Iter {
            indices,
            store,
        }
    }
}

impl<'a, A: Array> IntoIterator for &'a ArrayVec {
    type Item = &'a A::Element;
    type IntoIter = slice::Iter<'a, A::Element>;
    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}

impl<'a, A: Array> IntoIterator for &'a mut ArrayVec {
    type Item = &'a mut A::Element;
    type IntoIter = slice::IterMut<'a, A::Element>;
    fn into_iter(self) -> Self::IntoIter {
        self.iter_mut()
    }
}
<commit_msg>fix errors in rustc_data_structures<commit_after>// Copyright 2016 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.

//! A stack-allocated vector, allowing storage of N elements on the stack.

use std::marker::Unsize;
use std::iter::Extend;
use std::ptr::{self, drop_in_place, Shared};
use std::ops::{Deref, DerefMut, Range};
use std::hash::{Hash, Hasher};
use std::slice;
use std::fmt;
use std::mem;
use std::collections::range::RangeArgument;
use std::collections::Bound::{Excluded, Included, Unbounded};
use std::mem::ManuallyDrop;

pub unsafe trait Array {
    type Element;
    type PartialStorage: Unsize<[ManuallyDrop<Self::Element>]>;
    const LEN: usize;
}

unsafe impl<T> Array for [T; 1] {
    type Element = T;
    type PartialStorage = [ManuallyDrop<T>; 1];
    const LEN: usize = 1;
}

unsafe impl<T> Array for [T; 8] {
    type Element = T;
    type PartialStorage = [ManuallyDrop<T>; 8];
    const LEN: usize = 8;
}

unsafe impl<T> Array for [T; 32] {
    type Element = T;
    type PartialStorage = [ManuallyDrop<T>; 32];
    const LEN: usize = 32;
}

pub struct ArrayVec {
    count: usize,
    values: A::PartialStorage
}

impl Hash for ArrayVec
    where A: Array,
          A::Element: Hash {
    fn hash<H>(&self, state: &mut H) where H: Hasher {
        (&self[..]).hash(state);
    }
}

impl Clone for ArrayVec
    where A: Array,
          A::Element: Clone {
    fn clone(&self) -> Self {
        let mut v = ArrayVec::new();
        v.extend(self.iter().cloned());
        v
    }
}

impl ArrayVec {
    pub fn new() -> Self {
        ArrayVec {
            count: 0,
            values: unsafe { ::std::mem::uninitialized() },
        }
    }

    pub fn len(&self) -> usize {
        self.count
    }

    pub unsafe fn set_len(&mut self, len: usize) {
        self.count = len;
    }

    /// Panics when the stack vector is full.
    pub fn push(&mut self, el: A::Element) {
        let arr = &mut self.values as &mut [ManuallyDrop<_>];
        arr[self.count] = ManuallyDrop::new(el);
        self.count += 1;
    }

    pub fn pop(&mut self) -> Option {
        if self.count > 0 {
            let arr = &mut self.values as &mut [ManuallyDrop<_>];
            self.count -= 1;
            unsafe {
                let value = ptr::read(&*arr[self.count]);
                Some(value)
            }
        } else {
            None
        }
    }

    pub fn drain<R>(&mut self, range: R) -> Drain
        where R: RangeArgument<usize>
    {
        // Memory safety
        //
        // When the Drain is first created, it shortens the length of
        // the source vector to make sure no uninitialized or moved-from elements
        // are accessible at all if the Drain's destructor never gets to run.
        //
        // Drain will ptr::read out the values to remove.
        // When finished, remaining tail of the vec is copied back to cover
        // the hole, and the vector length is restored to the new length.
        //
        let len = self.len();
        let start = match range.start() {
            Included(&n) => n,
            Excluded(&n) => n + 1,
            Unbounded    => 0,
        };
        let end = match range.end() {
            Included(&n) => n + 1,
            Excluded(&n) => n,
            Unbounded    => len,
        };
        assert!(start <= end);
        assert!(end <= len);

        unsafe {
            // set self.vec length's to start, to be safe in case Drain is leaked
            self.set_len(start);
            // Use the borrow in the IterMut to indicate borrowing behavior of the
            // whole Drain iterator (like &mut T).
            let range_slice = {
                let arr = &mut self.values as &mut [ManuallyDrop<_>];
                slice::from_raw_parts_mut(arr.as_mut_ptr().offset(start as isize),
                                          end - start)
            };
            Drain {
                tail_start: end,
                tail_len: len - end,
                iter: range_slice.iter(),
                array_vec: Shared::from(self),
            }
        }
    }
}

impl Default for ArrayVec
    where A: Array {
    fn default() -> Self {
        ArrayVec::new()
    }
}

impl fmt::Debug for ArrayVec
    where A: Array,
          A::Element: fmt::Debug {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        self[..].fmt(f)
    }
}

impl Deref for ArrayVec {
    type Target = [A::Element];
    fn deref(&self) -> &Self::Target {
        unsafe {
            slice::from_raw_parts(&self.values as *const _ as *const A::Element, self.count)
        }
    }
}

impl DerefMut for ArrayVec {
    fn deref_mut(&mut self) -> &mut [A::Element] {
        unsafe {
            slice::from_raw_parts_mut(&mut self.values as *mut _ as *mut A::Element, self.count)
        }
    }
}

impl Drop for ArrayVec {
    fn drop(&mut self) {
        unsafe {
            drop_in_place(&mut self[..])
        }
    }
}

impl Extend for ArrayVec {
    fn extend(&mut self, iter: I) where I: IntoIterator<Item=A::Element> {
        for el in iter {
            self.push(el);
        }
    }
}

pub struct Iter {
    indices: Range<usize>,
    store: A::PartialStorage,
}

impl Drop for Iter {
    fn drop(&mut self) {
        for _ in self {}
    }
}

impl Iterator for Iter {
    type Item = A::Element;

    fn next(&mut self) -> Option {
        let arr = &self.store as &[ManuallyDrop<_>];
        unsafe {
            self.indices.next().map(|i| ptr::read(&*arr[i]))
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.indices.size_hint()
    }
}

pub struct Drain<'a, A: Array>
        where A::Element: 'a
{
    tail_start: usize,
    tail_len: usize,
    iter: slice::Iter<'a, ManuallyDrop>,
    array_vec: Shared<ArrayVec>,
}

impl<'a, A: Array> Iterator for Drain<'a, A> {
    type Item = A::Element;

    #[inline]
    fn next(&mut self) -> Option {
        self.iter.next().map(|elt| unsafe { ptr::read(&**elt) })
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

impl<'a, A: Array> Drop for Drain<'a, A> {
    fn drop(&mut self) {
        // exhaust self first
        while let Some(_) = self.next() {}

        if self.tail_len > 0 {
            unsafe {
                let source_array_vec: &mut ArrayVec = self.array_vec.as_mut();
                // memmove back untouched tail, update to new length
                let start = source_array_vec.len();
                let tail = self.tail_start;
                {
                    let arr = &mut source_array_vec.values as &mut [ManuallyDrop<_>];
                    let src = arr.as_ptr().offset(tail as isize);
                    let dst = arr.as_mut_ptr().offset(start as isize);
                    ptr::copy(src, dst, self.tail_len);
                };
                source_array_vec.set_len(start + self.tail_len);
            }
        }
    }
}

impl IntoIterator for ArrayVec {
    type Item = A::Element;
    type IntoIter = Iter;
    fn into_iter(self) -> Self::IntoIter {
        let store = unsafe {
            ptr::read(&self.values)
        };
        let indices = 0..self.count;
        mem::forget(self);
        Iter {
            indices,
            store,
        }
    }
}

impl<'a, A: Array> IntoIterator for &'a ArrayVec {
    type Item = &'a A::Element;
    type IntoIter = slice::Iter<'a, A::Element>;
    fn into_iter(self) -> Self::IntoIter {
        self.iter()
    }
}

impl<'a, A: Array> IntoIterator for &'a mut ArrayVec {
    type Item = &'a mut A::Element;
    type IntoIter = slice::IterMut<'a, A::Element>;
    fn into_iter(self) -> Self::IntoIter {
        self.iter_mut()
    }
}
<|endoftext|>


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

/// Calculates the offset of the specified field from the start of the struct.
/// This macro supports arbitrary amount of subscripts and recursive member-accesses.
///
/// *Note*: This macro may not make much sense when used on structs that are not `#[repr(C, packed)]`
///
/// ## Examples
/// ```
/// #[macro_use]
/// extern crate memoffset;
///
/// #[repr(C, packed)]
/// struct Foo {
///     a: u32,
///     b: u64,
///     c: [u8; 5]
/// }
///
/// fn main() {
///     assert_eq!(offset_of!(Foo, a), 0);
///     assert_eq!(offset_of!(Foo, b), 4);
/// }
/// ```
#[macro_export]
#[cfg(memoffset_maybe_uninit)]
macro_rules! offset_of {
    ($parent:tt, $field:tt) => (unsafe {
        // Create an instance of the container and calculate the offset to its field.
        // Here we're using an uninitialized instance of $parent.
        // Since we're not using its field, there's no UB caused by reading uninitialized memoty.
        // There *IS*, though, UB caused by creating references to uninitialized data,
        // which is illegal since the compiler is allowed to assume that a reference
        // points to valid data.
        // AFAIK we cannot avoid UB completely.
        let val = $crate::mem::MaybeUninit::<$parent>::uninit();
        let &$parent { $field: ref f, .. } = &*val.as_ptr();
        (f as *const _ as *const u8 as usize) - (val.as_ptr() as *const u8 as usize)
    });
}

#[macro_export]
#[cfg(not(memoffset_maybe_uninit))]
macro_rules! offset_of {
    ($parent:ty, $field:tt) => {{
        // This is UB since we're dealing with dangling references.
        // We're never dereferencing it, but it's UB nonetheless.
        // AFAIK we cannot avoid UB completely.
        let non_null = $crate::ptr::NonNull::<$parent>::dangling();
        let base_ptr = unsafe { non_null.as_ref() };
        #[allow(unused_unsafe)]
        let field_ptr = unsafe { &base_ptr.$field };
        let offset = (field_ptr as *const _ as usize) - (base_ptr as *const _ as usize);
        offset
    }};
}

#[cfg(test)]
mod tests {
    #[repr(C, packed)]
    struct Foo {
        a: u32,
        b: [u8; 4],
        c: i64,
    }

    #[test]
    fn offset_simple() {
        assert_eq!(offset_of!(Foo, a), 0);
        assert_eq!(offset_of!(Foo, b), 4);
        assert_eq!(offset_of!(Foo, c), 8);
    }

    #[test]
    fn tuple_struct() {
        #[repr(C, packed)]
        struct Tup(i32, i32);

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

/// Calculates the offset of the specified field from the start of the struct.
/// This macro supports arbitrary amount of subscripts and recursive member-accesses.
///
/// *Note*: This macro may not make much sense when used on structs that are not `#[repr(C, packed)]`
///
/// ## Examples
/// ```
/// #[macro_use]
/// extern crate memoffset;
///
/// #[repr(C, packed)]
/// struct Foo {
///     a: u32,
///     b: u64,
///     c: [u8; 5]
/// }
///
/// fn main() {
///     assert_eq!(offset_of!(Foo, a), 0);
///     assert_eq!(offset_of!(Foo, b), 4);
/// }
/// ```
#[macro_export]
#[cfg(memoffset_maybe_uninit)]
macro_rules! offset_of {
    ($parent:tt, $field:tt) => {{
        // Make sure the field actually exists. This line ensures that a
        // compile-time error is generated if $field is accessed through a
        // Deref impl.
        let $parent { $field: _, .. };

        // Create an instance of the container and calculate the offset to its field.
        // Here we're using an uninitialized instance of $parent.
        // Since we're not using its field, there's no UB caused by reading uninitialized memory.
        // There *IS*, though, UB caused by creating references to uninitialized data,
        // which is illegal since the compiler is allowed to assume that a reference
        // points to valid data.
        // However, currently we just cannot avoid UB completely.
        let val = $crate::mem::MaybeUninit::<$parent>::uninit();
        let base_ptr = val.as_ptr();
        #[allow(unused_unsafe)] // for when the macro is used in an unsafe block
        let field_ptr = unsafe { &(*base_ptr).$field as *const _ };
        let offset = (field_ptr as usize) - (base_ptr as usize);
        offset
    }};
}

#[macro_export]
#[cfg(not(memoffset_maybe_uninit))]
macro_rules! offset_of {
    ($parent:tt, $field:tt) => {{
        // Make sure the field actually exists. This line ensures that a
        // compile-time error is generated if $field is accessed through a
        // Deref impl.
        let $parent { $field: _, .. };

        // This is UB since we're dealing with dangling references.
        // We're never dereferencing it, but it's UB nonetheless.
        // See above for a better version that only works with newer Rust.
        let non_null = $crate::ptr::NonNull::<$parent>::dangling();
        #[allow(unused_unsafe)]
        let base_ptr = unsafe { non_null.as_ref() as *const _ };
        #[allow(unused_unsafe)]
        let field_ptr = unsafe { &(*base_ptr).$field as *const _ };
        let offset = (field_ptr as usize) - (base_ptr as usize);
        offset
    }};
}

#[cfg(test)]
mod tests {
    #[repr(C, packed)]
    struct Foo {
        a: u32,
        b: [u8; 4],
        c: i64,
    }

    #[test]
    fn offset_simple() {
        assert_eq!(offset_of!(Foo, a), 0);
        assert_eq!(offset_of!(Foo, b), 4);
        assert_eq!(offset_of!(Foo, c), 8);
    }

    #[test]
    fn tuple_struct() {
        #[repr(C, packed)]
        struct Tup(i32, i32);

        assert_eq!(offset_of!(Tup, 0), 0);
    }
}
<|endoftext|>


<commit_before>use serde;
use serde_json as json;
use line::Line;

#[derive(Deserialize, Debug, PartialEq)]
pub enum OperationType {
    Copy_,
    Skip,
    Invalidate,
    Update,
    Insert,
}

#[derive(Deserialize, Debug, PartialEq)]
pub struct Operation {
    #[serde(rename="op")]
    #[serde(deserialize_with="deserialize_operation_type")]
    pub operation_type: OperationType,
    #[serde(rename="n")]
    pub nb_lines: u64,
    pub lines: Option<Vec<Line>>,
}

fn deserialize_operation_type<'de, D>(de: D) -> Result<OperationType, D::Error>
    where D: serde::Deserializer<'de>
{
    let value: json::Value = try!(serde::Deserialize::deserialize(de));
    match value {
        json::Value::String(ref s) if &*s == "copy" => Ok(OperationType::Copy_),
        json::Value::String(ref s) if &*s == "skip" => Ok(OperationType::Skip),
        json::Value::String(ref s) if &*s == "invalidate" => Ok(OperationType::Invalidate),
        json::Value::String(ref s) if &*s == "update" => Ok(OperationType::Update),
        json::Value::String(ref s) if &*s == "ins" => Ok(OperationType::Insert),
        _ => Err(serde::de::Error::custom("Unexpected value for operation type")),
    }
}

impl Operation {
    pub fn apply(&self, old_lines: &[Line], old_line_index: u64, new_lines: &mut Vec<Line>) -> u64 {
        match self.operation_type {
            OperationType::Copy_ => {
                let new_index = old_line_index + self.nb_lines;
                for i in old_line_index..new_index {
                    new_lines.push(old_lines[i as usize].clone());
                }
                new_index
            }
            OperationType::Skip => old_line_index + self.nb_lines,
            OperationType::Invalidate => {
                let new_index = old_line_index + self.nb_lines;
                for _ in 0..self.nb_lines {
                    new_lines.push(Line::invalid());
                }
                new_index
            }
            OperationType::Update => {
                let new_index = old_line_index + self.nb_lines;
                let lines = self.lines.clone().unwrap();
                for i in old_line_index..new_index {
                    let mut line = old_lines[i as usize].clone();
                    line.cursor = lines[i as usize].cursor.clone();
                    line.styles = lines[i as usize].styles.clone();
                    new_lines.push(line);
                }
                new_index
            }
            OperationType::Insert => {
                let lines = self.lines.clone().unwrap();
                new_lines.extend(lines.iter().cloned());
                old_line_index + self.nb_lines
            }
        }
    }
}

#[test]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn deserialize_operation_from_value() {
    use serde_json;

    let value = json!({"n": 12, "op": "ins"});
    let operation = Operation {
        operation_type: OperationType::Insert,
        nb_lines: 12,
        lines: None,
    };
    let deserialized: Result<Operation, _> = serde_json::from_value(value);
    assert_eq!(deserialized.unwrap(), operation);

    let value = json!({"lines":[{"cursor":[0],"styles":[],"text":"foo"},{"styles":[],"text":""}],"n":60,"op":"invalidate"});
    let operation = Operation {
        operation_type: OperationType::Invalidate,
        nb_lines: 60,
        lines: Some(vec![
            Line { cursor: Some(vec![0]), styles: Some(vec![]), text: Some("foo".to_owned()) },
            Line { cursor: None, styles: Some(vec![]), text: Some("".to_owned()) }]),
    };
    let deserialized: Result<Operation, _> = serde_json::from_value(value);
    assert_eq!(deserialized.unwrap(), operation);
}

#[test]
fn deserialize_operation() {
    use serde_json;

    let s = r#"{"n": 12, "op": "ins"}"#;
    let operation = Operation {
        operation_type: OperationType::Insert,
        nb_lines: 12,
        lines: None,
    };
    let deserialized: Result<Operation, _> = serde_json::from_str(s);
    assert_eq!(deserialized.unwrap(), operation);

    let s = r#"{"lines":[{"cursor":[0],"styles":[],"text":"foo"},{"styles":[],"text":""}],"n":60,"op":"invalidate"}"#;
    let operation = Operation {
        operation_type: OperationType::Invalidate,
        nb_lines: 60,
        lines: Some(vec![
            Line { cursor: Some(vec![0]), styles: Some(vec![]), text: Some("foo".to_owned()) },
            Line { cursor: None, styles: Some(vec![]), text: Some("".to_owned()) }]),
    };
    let deserialized: Result<Operation, _> = serde_json::from_str(s);
    assert_eq!(deserialized.unwrap(), operation);
}
<commit_msg>operations fix & cleanup<commit_after>use serde;
use serde_json as json;
use line::Line;

#[derive(Deserialize, Debug, PartialEq)]
pub enum OperationType {
    Copy_,
    Skip,
    Invalidate,
    Update,
    Insert,
}

#[derive(Deserialize, Debug, PartialEq)]
pub struct Operation {
    #[serde(rename="op")]
    #[serde(deserialize_with="deserialize_operation_type")]
    pub operation_type: OperationType,
    #[serde(rename="n")]
    pub nb_lines: u64,
    pub lines: Option<Vec<Line>>,
}

fn deserialize_operation_type<'de, D>(de: D) -> Result<OperationType, D::Error>
    where D: serde::Deserializer<'de>
{
    let value: json::Value = try!(serde::Deserialize::deserialize(de));
    match value {
        json::Value::String(ref s) if &*s == "copy" => Ok(OperationType::Copy_),
        json::Value::String(ref s) if &*s == "skip" => Ok(OperationType::Skip),
        json::Value::String(ref s) if &*s == "invalidate" => Ok(OperationType::Invalidate),
        json::Value::String(ref s) if &*s == "update" => Ok(OperationType::Update),
        json::Value::String(ref s) if &*s == "ins" => Ok(OperationType::Insert),
        _ => Err(serde::de::Error::custom("Unexpected value for operation type")),
    }
}

impl Operation {
    pub fn apply(&self, old_lines: &[Line], old_ix: u64, new_lines: &mut Vec<Line>) -> u64 {
        match self.operation_type {
            OperationType::Copy_ => {
                let new_ix = old_ix + self.nb_lines;
                debug!("copying line {} to {}", old_ix, new_ix);

                for i in old_ix..new_ix {
                    new_lines.push(old_lines[i as usize].clone());
                }
                new_ix
            }
            OperationType::Skip => {
                debug!("skipping {} lines", self.nb_lines);
                old_ix + self.nb_lines
            }
            OperationType::Invalidate => {
                let new_ix = old_ix + self.nb_lines;
                debug!("invalidating lines {} to {}", old_ix, new_ix);

                for _ in 0..self.nb_lines {
                    new_lines.push(Line::invalid());
                }
                new_ix
            }
            OperationType::Update => {
                let new_ix = old_ix + self.nb_lines;
                debug!("updating lines {} to {}", old_ix, new_ix);
                let lines = self.lines.clone().unwrap();
                for i in old_ix..new_ix {
                    let mut line = old_lines[i as usize].clone();
                    line.cursor = lines[i as usize].cursor.clone();
                    line.styles = lines[i as usize].styles.clone();
                    new_lines.push(line);
                }
                new_ix
            }
            OperationType::Insert => {
                let lines = self.lines.clone().unwrap();
                new_lines.extend(lines.iter().cloned());
                old_ix
            }
        }
    }
}

#[test]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn deserialize_operation_from_value() {
    use serde_json;

    let value = json!({"n": 12, "op": "ins"});
    let operation = Operation {
        operation_type: OperationType::Insert,
        nb_lines: 12,
        lines: None,
    };
    let deserialized: Result<Operation, _> = serde_json::from_value(value);
    assert_eq!(deserialized.unwrap(), operation);

    let value = json!({"lines":[{"cursor":[0],"styles":[],"text":"foo"},{"styles":[],"text":""}],"n":60,"op":"invalidate"});
    let operation = Operation {
        operation_type: OperationType::Invalidate,
        nb_lines: 60,
        lines: Some(vec![
            Line { cursor: Some(vec![0]), styles: Some(vec![]), text: Some("foo".to_owned()) },
            Line { cursor: None, styles: Some(vec![]), text: Some("".to_owned()) }]),
    };
    let deserialized: Result<Operation, _> = serde_json::from_value(value);
    assert_eq!(deserialized.unwrap(), operation);
}

#[test]
fn deserialize_operation() {
    use serde_json;

    let s = r#"{"n": 12, "op": "ins"}"#;
    let operation = Operation {
        operation_type: OperationType::Insert,
        nb_lines: 12,
        lines: None,
    };
    let deserialized: Result<Operation, _> = serde_json::from_str(s);
    assert_eq!(deserialized.unwrap(), operation);

    let s = r#"{"lines":[{"cursor":[0],"styles":[],"text":"foo"},{"styles":[],"text":""}],"n":60,"op":"invalidate"}"#;
    let operation = Operation {
        operation_type: OperationType::Invalidate,
        nb_lines: 60,
        lines: Some(vec![
            Line { cursor: Some(vec![0]), styles: Some(vec![]), text: Some("foo".to_owned()) },
            Line { cursor: None, styles: Some(vec![]), text: Some("".to_owned()) }]),
    };
    let deserialized: Result<Operation, _> = serde_json::from_str(s);
    assert_eq!(deserialized.unwrap(), operation);
}
<|endoftext|>


<commit_before>// Copyright 2017 TiKV Project Authors. Licensed under Apache-2.0.

use std::mem;

use super::super::Result;
use super::path_expr::{PathExpression, PathLeg};
use super::Json;

/// `ModifyType` is for modify a JSON.
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum ModifyType {
    /// `Insert` is for inserting a new element into a JSON.
    Insert,
    /// `Replace` is for replacing a old element from a JSON.
    Replace,
    /// `Set` = `Insert` | `Replace`
    Set,
}

impl Json {
    // Modifies a Json object by insert, replace or set.
    // All path expressions cannot contain * or ** wildcard.
    // If any error occurs, the input won't be changed.
    pub fn modify(
        &mut self,
        path_expr_list: &[PathExpression],
        mut values: Vec<Json>,
        mt: ModifyType,
    ) -> Result<()> {
        if path_expr_list.len() != values.len() {
            return Err(box_err!("Incorrect parameter count"));
        }
        for expr in path_expr_list {
            if expr.contains_any_asterisk() {
                return Err(box_err!("Invalid path expression"));
            }
        }
        for (expr, value) in path_expr_list.iter().zip(values.drain(..)) {
            self.set_json(&expr.legs, value, mt);
        }
        Ok(())
    }

    // `set_json` is used in Json::modify().
    fn set_json(&mut self, path_legs: &[PathLeg], value: Json, mt: ModifyType) {
        if path_legs.is_empty() {
            match mt {
                ModifyType::Replace | ModifyType::Set => {
                    *self = value;
                }
                _ => {}
            }
            return;
        }

        let (current_leg, sub_path_legs) = (&path_legs[0], &path_legs[1..]);

        if let PathLeg::Index(i) = *current_leg {
            let base_data = mem::replace(self, Json::None);
            let index = i as usize;
            // If `base_data` is not an array, we should autowrap it to be an array.
            // Then if the length of result array equals to 1, it's unwraped.
            let (mut array, wrapped) = match base_data {
                Json::Array(array) => (array, false),
                _ => (vec![base_data], true),
            };
            if array.len() > index {
                array[index].set_json(sub_path_legs, value, mt);
            } else if sub_path_legs.is_empty() && mt != ModifyType::Replace {
                // e.g. json_insert('[1, 2, 3]', '$[3]', "x") => '[1, 2, 3, "x"]'
                array.push(value);
            }
            if (array.len() == 1) && wrapped {
                *self = array.pop().unwrap();
            } else {
                *self = Json::Array(array);
            }
            return;
        }

        if let PathLeg::Key(ref key) = *current_leg {
            if let Json::Object(ref mut map) = *self {
                if map.contains_key(key) {
                    // e.g. json_replace('{"a": 1}', '$.a', 2) => '{"a": 2}'
                    let v = map.get_mut(key).unwrap();
                    v.set_json(sub_path_legs, value, mt);
                } else if sub_path_legs.is_empty() && mt != ModifyType::Replace {
                    // e.g. json_insert('{"a": 1}', '$.b', 2) => '{"a": 1, "b": 2}'
                    map.insert(key.clone(), value);
                }
            }
        }
    }
}

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

    #[test]
    fn test_json_modify() {
        let mut test_cases = vec![
            (r#"null"#, "$", r#"{}"#, ModifyType::Set, r#"{}"#, true),
            (r#"{}"#, "$.a", r#"3"#, ModifyType::Set, r#"{"a": 3}"#, true),
            (
                r#"{"a": 3}"#,
                "$.a",
                r#"[]"#,
                ModifyType::Replace,
                r#"{"a": []}"#,
                true,
            ),
            (
                r#"{"a": []}"#,
                "$.a[0]",
                r#"3"#,
                ModifyType::Set,
                r#"{"a": [3]}"#,
                true,
            ),
            (
                r#"{"a": [3]}"#,
                "$.a[1]",
                r#"4"#,
                ModifyType::Insert,
                r#"{"a": [3, 4]}"#,
                true,
            ),
            (
                r#"{"a": [3]}"#,
                "$[0]",
                r#"4"#,
                ModifyType::Set,
                r#"4"#,
                true,
            ),
            (
                r#"{"a": [3]}"#,
                "$[1]",
                r#"4"#,
                ModifyType::Set,
                r#"[{"a": [3]}, 4]"#,
                true,
            ),
            // Nothing changed because the path is empty and we want to insert.
            (r#"{}"#, "$", r#"1"#, ModifyType::Insert, r#"{}"#, true),
            // Nothing changed because the path without last leg doesn't exist.
            (
                r#"{"a": [3, 4]}"#,
                "$.b[1]",
                r#"3"#,
                ModifyType::Set,
                r#"{"a": [3, 4]}"#,
                true,
            ),
            // Nothing changed because the path without last leg doesn't exist.
            (
                r#"{"a": [3, 4]}"#,
                "$.a[2].b",
                r#"3"#,
                ModifyType::Set,
                r#"{"a": [3, 4]}"#,
                true,
            ),
            // Nothing changed because we want to insert but the full path exists.
            (
                r#"{"a": [3, 4]}"#,
                "$.a[0]",
                r#"30"#,
                ModifyType::Insert,
                r#"{"a": [3, 4]}"#,
                true,
            ),
            // Nothing changed because we want to replace but the full path doesn't exist.
            (
                r#"{"a": [3, 4]}"#,
                "$.a[2]",
                r#"30"#,
                ModifyType::Replace,
                r#"{"a": [3, 4]}"#,
                true,
            ),
            // Bad path expression.
            (r#"null"#, "$.*", r#"{}"#, ModifyType::Set, r#"null"#, false),
            (
                r#"null"#,
                "$[*]",
                r#"{}"#,
                ModifyType::Set,
                r#"null"#,
                false,
            ),
            (
                r#"null"#,
                "$**.a",
                r#"{}"#,
                ModifyType::Set,
                r#"null"#,
                false,
            ),
            (
                r#"null"#,
                "$**[3]",
                r#"{}"#,
                ModifyType::Set,
                r#"null"#,
                false,
            ),
        ];
        for (i, (json, path, value, mt, expected, success)) in test_cases.drain(..).enumerate() {
            let j: Result<Json> = json.parse();
            assert!(j.is_ok(), "#{} expect json parse ok but got {:?}", i, j);
            let p = parse_json_path_expr(path);
            assert!(p.is_ok(), "#{} expect path parse ok but got {:?}", i, p);
            let v = value.parse();
            assert!(v.is_ok(), "#{} expect value parse ok but got {:?}", i, v);
            let e: Result<Json> = expected.parse();
            assert!(
                e.is_ok(),
                "#{} expect expected value parse ok but got {:?}",
                i,
                e
            );
            let (mut j, p, v, e) = (j.unwrap(), p.unwrap(), v.unwrap(), e.unwrap());
            let r = j.modify(vec![p].as_slice(), vec![v], mt);
            if success {
                assert!(r.is_ok(), "#{} expect modify ok but got {:?}", i, r);
            } else {
                assert!(r.is_err(), "#{} expect modify error but got {:?}", i, r);
            }
            assert_eq!(e, j, "#{} expect modified json {:?} == {:?}", i, j, e);
        }
    }
}
<commit_msg>improve: json modify error (#5967)<commit_after>// Copyright 2017 TiKV Project Authors. Licensed under Apache-2.0.

use std::mem;

use super::super::Result;
use super::path_expr::{PathExpression, PathLeg};
use super::Json;

/// `ModifyType` is for modify a JSON.
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum ModifyType {
    /// `Insert` is for inserting a new element into a JSON.
    Insert,
    /// `Replace` is for replacing a old element from a JSON.
    Replace,
    /// `Set` = `Insert` | `Replace`
    Set,
}

impl Json {
    // Modifies a Json object by insert, replace or set.
    // All path expressions cannot contain * or ** wildcard.
    // If any error occurs, the input won't be changed.
    pub fn modify(
        &mut self,
        path_expr_list: &[PathExpression],
        mut values: Vec<Json>,
        mt: ModifyType,
    ) -> Result<()> {
        if path_expr_list.len() != values.len() {
            return Err(box_err!(
                "Incorrect number of parameters: expected: {:?}, found {:?}",
                values.len(),
                path_expr_list.len()
            ));
        }
        for expr in path_expr_list {
            if expr.contains_any_asterisk() {
                return Err(box_err!(
                    "Invalid path expression: expected no asterisk, found {:?}",
                    expr
                ));
            }
        }
        for (expr, value) in path_expr_list.iter().zip(values.drain(..)) {
            self.set_json(&expr.legs, value, mt);
        }
        Ok(())
    }

    // `set_json` is used in Json::modify().
    fn set_json(&mut self, path_legs: &[PathLeg], value: Json, mt: ModifyType) {
        if path_legs.is_empty() {
            match mt {
                ModifyType::Replace | ModifyType::Set => {
                    *self = value;
                }
                _ => {}
            }
            return;
        }

        let (current_leg, sub_path_legs) = (&path_legs[0], &path_legs[1..]);

        if let PathLeg::Index(i) = *current_leg {
            let base_data = mem::replace(self, Json::None);
            let index = i as usize;
            // If `base_data` is not an array, we should autowrap it to be an array.
            // Then if the length of result array equals to 1, it's unwraped.
            let (mut array, wrapped) = match base_data {
                Json::Array(array) => (array, false),
                _ => (vec![base_data], true),
            };
            if array.len() > index {
                array[index].set_json(sub_path_legs, value, mt);
            } else if sub_path_legs.is_empty() && mt != ModifyType::Replace {
                // e.g. json_insert('[1, 2, 3]', '$[3]', "x") => '[1, 2, 3, "x"]'
                array.push(value);
            }
            if (array.len() == 1) && wrapped {
                *self = array.pop().unwrap();
            } else {
                *self = Json::Array(array);
            }
            return;
        }

        if let PathLeg::Key(ref key) = *current_leg {
            if let Json::Object(ref mut map) = *self {
                if map.contains_key(key) {
                    // e.g. json_replace('{"a": 1}', '$.a', 2) => '{"a": 2}'
                    let v = map.get_mut(key).unwrap();
                    v.set_json(sub_path_legs, value, mt);
                } else if sub_path_legs.is_empty() && mt != ModifyType::Replace {
                    // e.g. json_insert('{"a": 1}', '$.b', 2) => '{"a": 1, "b": 2}'
                    map.insert(key.clone(), value);
                }
            }
        }
    }
}

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

    #[test]
    fn test_json_modify() {
        let mut test_cases = vec![
            (r#"null"#, "$", r#"{}"#, ModifyType::Set, r#"{}"#, true),
            (r#"{}"#, "$.a", r#"3"#, ModifyType::Set, r#"{"a": 3}"#, true),
            (
                r#"{"a": 3}"#,
                "$.a",
                r#"[]"#,
                ModifyType::Replace,
                r#"{"a": []}"#,
                true,
            ),
            (
                r#"{"a": []}"#,
                "$.a[0]",
                r#"3"#,
                ModifyType::Set,
                r#"{"a": [3]}"#,
                true,
            ),
            (
                r#"{"a": [3]}"#,
                "$.a[1]",
                r#"4"#,
                ModifyType::Insert,
                r#"{"a": [3, 4]}"#,
                true,
            ),
            (
                r#"{"a": [3]}"#,
                "$[0]",
                r#"4"#,
                ModifyType::Set,
                r#"4"#,
                true,
            ),
            (
                r#"{"a": [3]}"#,
                "$[1]",
                r#"4"#,
                ModifyType::Set,
                r#"[{"a": [3]}, 4]"#,
                true,
            ),
            // Nothing changed because the path is empty and we want to insert.
            (r#"{}"#, "$", r#"1"#, ModifyType::Insert, r#"{}"#, true),
            // Nothing changed because the path without last leg doesn't exist.
            (
                r#"{"a": [3, 4]}"#,
                "$.b[1]",
                r#"3"#,
                ModifyType::Set,
                r#"{"a": [3, 4]}"#,
                true,
            ),
            // Nothing changed because the path without last leg doesn't exist.
            (
                r#"{"a": [3, 4]}"#,
                "$.a[2].b",
                r#"3"#,
                ModifyType::Set,
                r#"{"a": [3, 4]}"#,
                true,
            ),
            // Nothing changed because we want to insert but the full path exists.
            (
                r#"{"a": [3, 4]}"#,
                "$.a[0]",
                r#"30"#,
                ModifyType::Insert,
                r#"{"a": [3, 4]}"#,
                true,
            ),
            // Nothing changed because we want to replace but the full path doesn't exist.
            (
                r#"{"a": [3, 4]}"#,
                "$.a[2]",
                r#"30"#,
                ModifyType::Replace,
                r#"{"a": [3, 4]}"#,
                true,
            ),
            // Bad path expression.
            (r#"null"#, "$.*", r#"{}"#, ModifyType::Set, r#"null"#, false),
            (
                r#"null"#,
                "$[*]",
                r#"{}"#,
                ModifyType::Set,
                r#"null"#,
                false,
            ),
            (
                r#"null"#,
                "$**.a",
                r#"{}"#,
                ModifyType::Set,
                r#"null"#,
                false,
            ),
            (
                r#"null"#,
                "$**[3]",
                r#"{}"#,
                ModifyType::Set,
                r#"null"#,
                false,
            ),
        ];
        for (i, (json, path, value, mt, expected, success)) in test_cases.drain(..).enumerate() {
            let j: Result<Json> = json.parse();
            assert!(j.is_ok(), "#{} expect json parse ok but got {:?}", i, j);
            let p = parse_json_path_expr(path);
            assert!(p.is_ok(), "#{} expect path parse ok but got {:?}", i, p);
            let v = value.parse();
            assert!(v.is_ok(), "#{} expect value parse ok but got {:?}", i, v);
            let e: Result<Json> = expected.parse();
            assert!(
                e.is_ok(),
                "#{} expect expected value parse ok but got {:?}",
                i,
                e
            );
            let (mut j, p, v, e) = (j.unwrap(), p.unwrap(), v.unwrap(), e.unwrap());
            let r = j.modify(vec![p].as_slice(), vec![v], mt);
            if success {
                assert!(r.is_ok(), "#{} expect modify ok but got {:?}", i, r);
            } else {
                assert!(r.is_err(), "#{} expect modify error but got {:?}", i, r);
            }
            assert_eq!(e, j, "#{} expect modified json {:?} == {:?}", i, j, e);
        }
    }
}
<|endoftext|>


<commit_before>use dotenv::dotenv;
use teloxide::prelude::*;
use tokio;

mod bot;
mod db;
mod web;

#[actix_rt::main]
async fn main() {
    dotenv();
    run().await;
}

async fn run() {
    teloxide::enable_logging!();

    let bot_instance = Bot::from_env();

    tokio::select! {
        _ = bot::run(bot_instance) => {},
        _ = web::run() => {}
    }
}
<commit_msg>clean up rust server main function<commit_after>use anyhow::Result;
use dotenv::dotenv;
use teloxide::prelude::*;
use tokio;

mod bot;
mod db;
mod web;

#[actix_rt::main]
async fn main() -> Result<()> {
    dotenv()?;
    run().await?;

    Ok(())
}

async fn run() -> Result<()> {
    teloxide::enable_logging!();

    let bot_instance = Bot::from_env();

    tokio::select! {
        r = bot::run(bot_instance) => r,
        r = web::run() => r
    }
}
<|endoftext|>


<commit_before>// Note, in actual code use this instead https://doc.rust-lang.org/std/collections/struct.LinkedList.html
// Also refer to https://rust-unofficial.github.io/too-many-lists/

pub struct LinkedList<T> {
    head: Option<Box<Node<T>>>,
    size: usize,
}

pub struct Node<T> {
    data: T,
    next: Option<Box<Node<T>>>,
}

impl<T> LinkedList<T> {
    pub fn new() -> Self {
        LinkedList {
            head: None,
            size: 0,
        }
    }

    /// Adds a new node containing the specified value at the start of the LinkedList
    pub fn push(&mut self, e: T) {
        let node = Node {
            data: e,
            next: self.head.take(),
        };
        self.head = Some(Box::new(node));
        self.size += 1;
    }

    /// Removes the node at the beginning of the LinkedList
    pub fn pop(&mut self) -> Option<T> {
        self.head.take().map(|node| {
            self.head = node.next;
            self.size -= 1;
            node.data
        })
    }
}

impl<T> Drop for LinkedList<T> {
    fn drop(&mut self) {
        let mut cur_link = self.head.take();
        while let Some(mut boxed_node) = cur_link {
            cur_link = boxed_node.next.take();
        }
        self.size = 0;
    }
}

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

    #[test]
    fn an_empty_list_has_size_zero() {
        let list: LinkedList<u32> = LinkedList::new();
        assert_eq!(list.size, 0);
    }

    #[test]
    fn adding_an_element_increases_size() {
        let mut list = LinkedList::new();
        list.push(10);
        assert_eq!(list.size, 1);
    }

    #[test]
    fn adding_and_removing_elements() {
        let mut list = LinkedList::new();
        list.push(22);
        list.push(11);
        let value = list.pop();
        assert_eq!(list.size, 1);
        assert_eq!(value.unwrap(), 11);

        list.push(33);
        list.push(44);
        assert_eq!(list.size, 3);

        let value = list.pop();
        assert_eq!(list.size, 2);
        assert_eq!(value.unwrap(), 44);
    }
}
<commit_msg>add peek fn<commit_after>// Note, in actual code use this instead https://doc.rust-lang.org/std/collections/struct.LinkedList.html
// Also refer to https://rust-unofficial.github.io/too-many-lists/

pub struct LinkedList<T> {
    head: Option<Box<Node<T>>>,
    size: usize,
}

pub struct Node<T> {
    data: T,
    next: Option<Box<Node<T>>>,
}

impl<T> LinkedList<T> {
    pub fn new() -> Self {
        LinkedList {
            head: None,
            size: 0,
        }
    }

    /// Adds a new node containing the specified value at the start of the LinkedList
    pub fn push(&mut self, e: T) {
        let node = Node {
            data: e,
            next: self.head.take(),
        };
        self.head = Some(Box::new(node));
        self.size += 1;
    }

    /// Removes the node at the beginning of the LinkedList
    pub fn pop(&mut self) -> Option<T> {
        self.head.take().map(|node| {
            self.head = node.next;
            self.size -= 1;
            node.data
        })
    }

    pub fn peek(&self) -> Option<&T> {
        self.head.as_ref().map(|node| {
            &node.data
        })
    }

    pub fn peek_mut(&mut self) -> Option<&mut T> {
        self.head.as_mut().map(|node| {
            &mut node.data
        })
    }
}

impl<T> Drop for LinkedList<T> {
    fn drop(&mut self) {
        let mut cur_link = self.head.take();
        while let Some(mut boxed_node) = cur_link {
            cur_link = boxed_node.next.take();
        }
        self.size = 0;
    }
}

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

    #[test]
    fn an_empty_list_has_size_zero() {
        let list: LinkedList<u32> = LinkedList::new();
        assert_eq!(list.size, 0);
    }

    #[test]
    fn adding_an_element_increases_size() {
        let mut list = LinkedList::new();
        list.push(10);
        assert_eq!(list.size, 1);
    }

    #[test]
    fn adding_and_removing_elements() {
        let mut list = LinkedList::new();
        list.push(22);
        list.push(11);
        let value = list.pop();
        assert_eq!(list.size, 1);
        assert_eq!(value.unwrap(), 11);

        list.push(33);
        list.push(44);
        assert_eq!(list.size, 3);

        let value = list.pop();
        assert_eq!(list.size, 2);
        assert_eq!(value.unwrap(), 44);
    }

    #[test]
    fn peek() {
        let mut list = LinkedList::new();
        assert_eq!(list.peek(), None);
        assert_eq!(list.peek_mut(), None);
        list.push(1); list.push(2); list.push(3);

        assert_eq!(list.peek(), Some(&3));
        assert_eq!(list.peek_mut(), Some(&mut 3));

        list.peek_mut().map(|value| {
            *value = 42
        });

        assert_eq!(list.peek(), Some(&42));
        assert_eq!(list.pop(), Some(42));
    }
}
<|endoftext|>


<commit_before>//! De-/serialization helpers for other ruma crates

use js_int::Int;
use serde::{
    de::{Error, IntoDeserializer},
    Deserialize,
};
use std::convert::{TryFrom, TryInto};

pub mod can_be_empty;
mod canonical_json;
mod cow;
pub mod duration;
pub mod empty;
pub mod json_string;
pub mod single_element_seq;
pub mod test;
pub mod time;
pub mod urlencoded;

pub use can_be_empty::{is_empty, CanBeEmpty};
pub use canonical_json::{
    to_canonical_value, to_string as to_canonical_json_string, try_from_json_map,
    value::{CanonicalJsonValue, Object as CanonicalJsonObject},
    Error as CanonicalJsonError,
};
pub use cow::deserialize_cow_str;
pub use empty::vec_as_map_of_empty;

/// Check whether a value is equal to its default value.
pub fn is_default<T: Default + PartialEq>(val: &T) -> bool {
    val == &T::default()
}

/// Simply returns `true`.
///
/// Useful for `#[serde(default = ...)]`.
pub fn default_true() -> bool {
    true
}

/// Simplfy dereferences the given bool.
///
/// Useful for `#[serde(skip_serializing_if = ...)]`
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn is_true(b: &bool) -> bool {
    *b
}

/// Serde deserialization decorator to map empty Strings to None,
/// and forward non-empty Strings to the Deserialize implementation for T.
/// Useful for the typical
/// "A room with an X event with an absent, null, or empty Y field
/// should be treated the same as a room with no such event."
/// formulation in the spec.
///
/// To be used like this:
/// `#[serde(deserialize_with = "empty_string_as_none")]`
/// Relevant serde issue: https://github.com/serde-rs/serde/issues/1425
pub fn empty_string_as_none<'de, D, T>(de: D) -> Result<Option<T>, D::Error>
where
    D: serde::Deserializer<'de>,
    T: serde::Deserialize<'de>,
{
    let opt = Option::<String>::deserialize(de)?;
    match opt.as_deref() {
        None | Some("") => Ok(None),
        // If T = String, like in m.room.name, the second deserialize is actually superfluous.
        // TODO: optimize that somehow?
        Some(s) => T::deserialize(s.into_deserializer()).map(Some),
    }
}

// Helper type for deserialize_int_or_string_to_int
#[derive(Deserialize)]
#[serde(untagged)]
enum IntOrString<'a> {
    Num(Int),
    Str(&'a str),
}

impl TryFrom<IntOrString<'_>> for Int {
    type Error = js_int::ParseIntError;

    fn try_from(input: IntOrString) -> Result<Self, Self::Error> {
        match input {
            IntOrString::Num(n) => Ok(n),
            IntOrString::Str(string) => string.parse(),
        }
    }
}

/// Take either an integer number or a string and deserialize to an integer number.
///
/// To be used like this:
/// `#[serde(deserialize_with = "int_or_string_to_int")]`
pub fn int_or_string_to_int<'de, D>(de: D) -> Result<Int, D::Error>
where
    D: serde::Deserializer<'de>,
{
    IntOrString::deserialize(de)?.try_into().map_err(D::Error::custom)
}
<commit_msg>Add function to deserialize BTreeMap with values of numbers and strings to integers<commit_after>//! De-/serialization helpers for other ruma crates

use js_int::Int;
use serde::{
    de::{Error, IntoDeserializer},
    Deserialize,
};
use std::{
    collections::BTreeMap,
    convert::{TryFrom, TryInto},
};

pub mod can_be_empty;
mod canonical_json;
mod cow;
pub mod duration;
pub mod empty;
pub mod json_string;
pub mod single_element_seq;
pub mod test;
pub mod time;
pub mod urlencoded;

pub use can_be_empty::{is_empty, CanBeEmpty};
pub use canonical_json::{
    to_canonical_value, to_string as to_canonical_json_string, try_from_json_map,
    value::{CanonicalJsonValue, Object as CanonicalJsonObject},
    Error as CanonicalJsonError,
};
pub use cow::deserialize_cow_str;
pub use empty::vec_as_map_of_empty;

/// Check whether a value is equal to its default value.
pub fn is_default<T: Default + PartialEq>(val: &T) -> bool {
    val == &T::default()
}

/// Simply returns `true`.
///
/// Useful for `#[serde(default = ...)]`.
pub fn default_true() -> bool {
    true
}

/// Simplfy dereferences the given bool.
///
/// Useful for `#[serde(skip_serializing_if = ...)]`
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn is_true(b: &bool) -> bool {
    *b
}

/// Serde deserialization decorator to map empty Strings to None,
/// and forward non-empty Strings to the Deserialize implementation for T.
/// Useful for the typical
/// "A room with an X event with an absent, null, or empty Y field
/// should be treated the same as a room with no such event."
/// formulation in the spec.
///
/// To be used like this:
/// `#[serde(deserialize_with = "empty_string_as_none")]`
/// Relevant serde issue: https://github.com/serde-rs/serde/issues/1425
pub fn empty_string_as_none<'de, D, T>(de: D) -> Result<Option<T>, D::Error>
where
    D: serde::Deserializer<'de>,
    T: serde::Deserialize<'de>,
{
    let opt = Option::<String>::deserialize(de)?;
    match opt.as_deref() {
        None | Some("") => Ok(None),
        // If T = String, like in m.room.name, the second deserialize is actually superfluous.
        // TODO: optimize that somehow?
        Some(s) => T::deserialize(s.into_deserializer()).map(Some),
    }
}

// Helper type for deserialize_int_or_string_to_int
#[derive(Deserialize)]
#[serde(untagged)]
enum IntOrString<'a> {
    Num(Int),
    Str(&'a str),
}

impl TryFrom<IntOrString<'_>> for Int {
    type Error = js_int::ParseIntError;

    fn try_from(input: IntOrString) -> Result<Self, Self::Error> {
        match input {
            IntOrString::Num(n) => Ok(n),
            IntOrString::Str(string) => string.parse(),
        }
    }
}

/// Take either an integer number or a string and deserialize to an integer number.
///
/// To be used like this:
/// `#[serde(deserialize_with = "int_or_string_to_int")]`
pub fn int_or_string_to_int<'de, D>(de: D) -> Result<Int, D::Error>
where
    D: serde::Deserializer<'de>,
{
    IntOrString::deserialize(de)?.try_into().map_err(D::Error::custom)
}

/// Take a BTreeMap with values of either an integer number or a string and deserialize
/// those to integer numbers.
///
/// To be used like this:
/// `#[serde(deserialize_with = "btreemap_int_or_string_to_int_values")]`
pub fn btreemap_int_or_string_to_int_values<'de, D, T>(de: D) -> Result<BTreeMap<T, Int>, D::Error>
where
    D: serde::Deserializer<'de>,
    T: serde::Deserialize<'de> + Ord,
{
    BTreeMap::<T, IntOrString>::deserialize(de)?
        .into_iter()
        .map(|(k, v)| v.try_into().map(|n| (k, n)).map_err(D::Error::custom))
        .collect()
}
<|endoftext|>


<commit_before>//! De-/serialization helpers for other ruma crates

pub mod can_be_empty;
mod canonical_json;
mod cow;
pub mod duration;
pub mod empty;
pub mod json_string;
mod raw;
pub mod single_element_seq;
mod strings;
pub mod test;
pub mod time;
pub mod urlencoded;

pub use can_be_empty::{is_empty, CanBeEmpty};
pub use canonical_json::{
    to_canonical_value, to_string as to_canonical_json_string, try_from_json_map,
    value::{CanonicalJsonValue, Object as CanonicalJsonObject},
    Error as CanonicalJsonError,
};
pub use cow::deserialize_cow_str;
pub use empty::vec_as_map_of_empty;
pub use raw::Raw;
pub use strings::{
    btreemap_int_or_string_to_int_values, empty_string_as_none, int_or_string_to_int,
};

/// Check whether a value is equal to its default value.
pub fn is_default<T: Default + PartialEq>(val: &T) -> bool {
    val == &T::default()
}

/// Simply returns `true`.
///
/// Useful for `#[serde(default = ...)]`.
pub fn default_true() -> bool {
    true
}

/// Simply dereferences the given bool.
///
/// Useful for `#[serde(skip_serializing_if = ...)]`
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn is_true(b: &bool) -> bool {
    *b
}

/// A type that can be sent to another party that understands the matrix protocol. If any of the
/// fields of `Self` don't implement serde's `Deserialize`, you can derive this trait to generate a
/// corresponding 'Incoming' type that supports deserialization. This is useful for things like
/// ruma_events' `EventResult` type. For more details, see the [derive macro's documentation][doc].
///
/// [doc]: derive.Outgoing.html
// TODO: Better explain how this trait relates to serde's traits
pub trait Outgoing {
    /// The 'Incoming' variant of `Self`.
    type Incoming;
}

// -- Everything below is macro-related --

pub use ruma_serde_macros::*;

/// This module is used to support the generated code from ruma-serde-macros.
/// It is not considered part of ruma-serde's public API.
#[doc(hidden)]
pub mod exports {
    pub use serde;
}
<commit_msg>serde: Small code style change<commit_after>//! De-/serialization helpers for other ruma crates

pub mod can_be_empty;
mod canonical_json;
mod cow;
pub mod duration;
pub mod empty;
pub mod json_string;
mod raw;
pub mod single_element_seq;
mod strings;
pub mod test;
pub mod time;
pub mod urlencoded;

pub use can_be_empty::{is_empty, CanBeEmpty};
pub use canonical_json::{
    to_canonical_value, to_string as to_canonical_json_string, try_from_json_map,
    value::{CanonicalJsonValue, Object as CanonicalJsonObject},
    Error as CanonicalJsonError,
};
pub use cow::deserialize_cow_str;
pub use empty::vec_as_map_of_empty;
pub use raw::Raw;
pub use strings::{
    btreemap_int_or_string_to_int_values, empty_string_as_none, int_or_string_to_int,
};

/// Check whether a value is equal to its default value.
pub fn is_default<T: Default + PartialEq>(val: &T) -> bool {
    *val == T::default()
}

/// Simply returns `true`.
///
/// Useful for `#[serde(default = ...)]`.
pub fn default_true() -> bool {
    true
}

/// Simply dereferences the given bool.
///
/// Useful for `#[serde(skip_serializing_if = ...)]`
#[allow(clippy::trivially_copy_pass_by_ref)]
pub fn is_true(b: &bool) -> bool {
    *b
}

/// A type that can be sent to another party that understands the matrix protocol. If any of the
/// fields of `Self` don't implement serde's `Deserialize`, you can derive this trait to generate a
/// corresponding 'Incoming' type that supports deserialization. This is useful for things like
/// ruma_events' `EventResult` type. For more details, see the [derive macro's documentation][doc].
///
/// [doc]: derive.Outgoing.html
// TODO: Better explain how this trait relates to serde's traits
pub trait Outgoing {
    /// The 'Incoming' variant of `Self`.
    type Incoming;
}

// -- Everything below is macro-related --

pub use ruma_serde_macros::*;

/// This module is used to support the generated code from ruma-serde-macros.
/// It is not considered part of ruma-serde's public API.
#[doc(hidden)]
pub mod exports {
    pub use serde;
}
<|endoftext|>


<commit_before>use value::Value;

fn compiler_schema() -> Vec<(&'static str, Vec<&'static str>, Vec<&'static str>)> {
    // the schema is arranged as (table name, unique key fields, other fields)

    vec![
    // all state lives in a view of some kind
    // `kind` is one of:
    // "table" - a view which can depend on the past
    // "join" - take the product of multiple views and filter the results
    // "union" - take the union of multiple views
    // "aggregate" - group one view by the contents of another and run reducing functions on the groups
    // "primitive" - a built-in function, represented as a view with one or more non-Data fields
    ("view", vec!["view"], vec!["kind"]),

    // views have fields
    // some fields have constraints on how they can be queried
    // `kind` is one of:
    // "output" - a normal field
    // "scalar input" - a field that must be constrained to a single scalar value
    // "vector input" - a field that must be constrained to a single vector value (in an aggregate)
    ("field", vec!["view", "field"], vec!["kind"]),
    // fields are displayed in order
    // `priority` is an f64. higher priority fields are displayed first. ties are broken by field id
    ("field display order", vec!["view", "field"], vec!["priority"]),

    // source ids have two purposes
    // a) uniquely generated ids to disambiguate multiple uses of the same view
    // (eg when joining a view with itself)
    // b) fixed ids to identify views which are used for some specific purpose
    // (these are "insert" and "remove" in tables and "inner" and "outer" in aggregates)
    ("source", vec!["view", "source"], vec!["source view"]),

    // every view also has an implicit "constant" source
    // anywhere source-field is expected, you can instead use "constant"-id
    // `value` may be any valid eve value
    ("constant", vec!["constant"], vec!["value"]),

    // constraints belong to a join view
    // the left and right fields are compared using the operation
    // `operation` is one of "==", "/=", "<", "<=", ">", ">="
    ("constraint", vec!["constraint"], vec!["view"]),
    ("constraint left", vec!["constraint"], vec!["left source", "left field"]),
    ("constraint right", vec!["constraint"], vec!["right source", "right field"]),
    ("constraint operation", vec!["constraint"], vec!["operation"]),

    // aggregates group an "inner" source by the rows of an "outer" source
    // the grouping is determined by binding inner fields to outer fields or constants
    ("aggregate grouping", vec!["aggregate", "inner field"], vec!["group source", "group field"]),
    // before aggregation the groups are sorted
    // `priority` is an f64. higher priority fields are compared first. ties are broken by field id
    // `direction` is one of "ascending" or "descending"
    // fields which have no entry default to 0, "ascending"
    ("aggregate sorting", vec!["aggregate", "inner field"], vec!["priority", "direction"]),
    // groups may optionally be limited by an inner field or constant
    ("aggregate limit from", vec!["aggregate"], vec!["from source", "from field"]),
    ("aggregate limit to", vec!["aggregate"], vec!["to source", "to field"]),
    // the groups may be reduced by binding against reducer sources
    // constants and grouped inner fields may both be used as ScalarInput arguments
    // ungrouped inner fields which are not bound to outer fields may be used as VectorInput arguments
    ("aggregate argument", vec!["aggregate", "reducer source", "reducer field"], vec!["argument source", "argument field"]),

    // views produce output by binding fields from sources
    // each table or join field must be bound exactly once
    // each aggregate field must be bound exactly once and can only bind constants, inner fields or reducer outputs
    // each union field must be bound exactly once per source
    // (the unique key is different for union than for other kinds, so I don't give a key at all)
    ("select", vec![], vec!["view", "view field", "source", "source field"]),

    // things can have human readable names
    // `name` is a string
    ("display name", vec!["id"], vec!["name"]),
    ]
}<commit_msg>Revert change to display order. Make fields ids unique instead.<commit_after>use value::Value;

fn compiler_schema() -> Vec<(&'static str, Vec<&'static str>, Vec<&'static str>)> {
    // the schema is arranged as (table name, unique key fields, other fields)

    vec![
    // all state lives in a view of some kind
    // `kind` is one of:
    // "table" - a view which can depend on the past
    // "join" - take the product of multiple views and filter the results
    // "union" - take the union of multiple views
    // "aggregate" - group one view by the contents of another and run reducing functions on the groups
    // "primitive" - a built-in function, represented as a view with one or more non-Data fields
    ("view", vec!["view"], vec!["kind"]),

    // views have fields
    // some fields have constraints on how they can be queried
    // `kind` is one of:
    // "output" - a normal field
    // "scalar input" - a field that must be constrained to a single scalar value
    // "vector input" - a field that must be constrained to a single vector value (in an aggregate)
    ("field", vec!["field"], vec!["view", "kind"]),

    // source ids have two purposes
    // a) uniquely generated ids to disambiguate multiple uses of the same view
    // (eg when joining a view with itself)
    // b) fixed ids to identify views which are used for some specific purpose
    // (these are "insert" and "remove" in tables and "inner" and "outer" in aggregates)
    ("source", vec!["view", "source"], vec!["source view"]),

    // every view also has an implicit "constant" source
    // anywhere source-field is expected, you can instead use "constant"-id
    // `value` may be any valid eve value
    ("constant", vec!["constant"], vec!["value"]),

    // constraints belong to a join view
    // the left and right fields are compared using the operation
    // `operation` is one of "==", "/=", "<", "<=", ">", ">="
    ("constraint", vec!["constraint"], vec!["view"]),
    ("constraint left", vec!["constraint"], vec!["left source", "left field"]),
    ("constraint right", vec!["constraint"], vec!["right source", "right field"]),
    ("constraint operation", vec!["constraint"], vec!["operation"]),

    // aggregates group an "inner" source by the rows of an "outer" source
    // the grouping is determined by binding inner fields to outer fields or constants
    ("aggregate grouping", vec!["aggregate", "inner field"], vec!["group source", "group field"]),
    // before aggregation the groups are sorted
    // `priority` is an f64. higher priority fields are compared first. ties are broken by field id
    // `direction` is one of "ascending" or "descending"
    // fields which have no entry default to 0, "ascending"
    ("aggregate sorting", vec!["aggregate", "inner field"], vec!["priority", "direction"]),
    // groups may optionally be limited by an inner field or constant
    ("aggregate limit from", vec!["aggregate"], vec!["from source", "from field"]),
    ("aggregate limit to", vec!["aggregate"], vec!["to source", "to field"]),
    // the groups may be reduced by binding against reducer sources
    // constants and grouped inner fields may both be used as ScalarInput arguments
    // ungrouped inner fields which are not bound to outer fields may be used as VectorInput arguments
    ("aggregate argument", vec!["aggregate", "reducer source", "reducer field"], vec!["argument source", "argument field"]),

    // views produce output by binding fields from sources
    // each table or join field must be bound exactly once
    // each aggregate field must be bound exactly once and can only bind constants, inner fields or reducer outputs
    // each union field must be bound exactly once per source
    // (the unique key is different for union than for other kinds, so I don't give a key at all)
    ("select", vec![], vec!["view", "view field", "source", "source field"]),

    // things can have human readable names
    // `name` is a string
    ("display name", vec!["id"], vec!["name"]),
    // things can be displayed in ordered lists
    // `priority` is an f64. higher priority thigs are displayed first. ties are broken by id
    ("display order", vec!["field"], vec!["priority"]),
    ]
}<|endoftext|>