table 0.4.0

A specialized map for storing values of varying types.
Documentation
// Copyright (C) 2018  Project Tsukurou!
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

//! Structs and utilities offered by the List API.

use std::ops;

use value::Value;
use util::convert::{TryAsRef, TryAsMut};

mod iter;
pub use self::iter::{Iter, IterMut, IntoIter};

/// An ordered sequence of value elements.
#[derive(Debug, Clone, PartialEq)]
pub struct List<'a> {
    vec: Vec<Value<'a>>,
}

impl<'a> List<'a> {
    
    /// Constructs an empty list.
    ///
    /// # Examples
    ///
    /// ```
    /// use table::List;
    ///
    /// let list = List::new();
    /// assert!(list.is_empty());
    /// ```
    pub fn new() -> List<'a> {
        List {
            vec: Vec::new(),
        }
    }

    /// Constructs a list from an existing `Vec` of values.
    ///
    /// # Examples
    ///
    /// ```
    /// use table::{List, Value};
    ///
    /// let vec = vec![
    ///     Value::I64(8),
    ///     Value::Null,
    ///     Value::Bool(false)
    /// ];
    /// let list = List::with_vec(vec);
    /// assert_eq!(list.get(0), Some(&8));
    /// ```
    pub fn with_vec(vec: Vec<Value<'a>>) -> List<'a> {
        List {
            vec,
        }
    }
    
    /// Returns the number of elements in the list. Any indices in the range
    /// `0..list.len()` are guaranteed to be valid.
    ///
    /// # Examples
    ///
    /// ```
    /// use table::List;
    ///
    /// let mut list = List::new();
    /// assert_eq!(list.len(), 0);
    ///
    /// list.push("foo");
    /// assert_eq!(list.len(), 1);
    /// ```
    pub fn len(&self) -> usize {
        self.vec.len()
    }

    /// Returns `true` if and only if there are no elements in the list,
    /// meaning it is equivalent to `list.len() == 0`.
    /// 
    /// # Examples
    ///
    /// ```
    /// use table::List;
    ///
    /// let mut list = List::new();
    /// assert!(list.is_empty());
    ///
    /// list.push("bar");
    /// assert!(!list.is_empty());
    /// ```
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    /// Removes all elements in the list, resetting its length to zero.
    ///
    /// # Examples
    ///
    /// ```
    /// use table::List;
    ///
    /// let mut list = List::new();
    /// list.push(33);
    /// list.clear();
    /// assert!(list.is_empty());
    /// ```
    pub fn clear(&mut self) {
        self.vec.clear()
    }

    /// Attempts to retrieve a value and take reference to the inner value.
    /// Calling this method with the `T=Value` type parameter will not
    /// perform the conversion, instead returning a reference to the
    /// wrapping `Value` object.
    ///
    /// # Examples
    ///
    /// ```
    /// use table::{List, Value};
    ///
    /// let mut list = List::new();
    /// assert_eq!(list.get::<Value>(0), None);
    /// 
    /// list.push("spam");
    /// assert_eq!(list.get(0), Some("spam"))
    /// ```
    pub fn get<T>(&self, index: usize) -> Option<&T>
    where
        T: ?Sized,
        Value<'a>: TryAsRef<T>,
    {
        self.vec.get(index)
            .and_then(TryAsRef::try_as_ref)
    }

    /// Attempts to retrive a value and mutably reference the inner value.
    /// Calling this method with the `T=Value` type parameter will not perform
    /// the conversion, instead returning a reference to the wrapping `Value`
    /// object.
    ///
    /// # Examples
    ///
    /// ```
    /// use table::List;
    ///
    /// let mut list = List::new();
    /// list.push(33);
    /// *list.get_mut(0).unwrap() = 35;
    ///
    /// assert_eq!(list.get(0), Some(&35));
    /// ```
    pub fn get_mut<T>(&mut self, index: usize) -> Option<&mut T>
    where
        T: ?Sized,
        Value<'a>: TryAsMut<T>,
    {
        self.vec.get_mut(index)
            .and_then(TryAsMut::try_as_mut)
    }

    /// Inserts a value at the given index, moving all the elements after it
    /// forward one space.
    ///
    /// # Examples
    ///
    /// ```
    /// use table::List;
    ///
    /// let mut list = List::new();
    /// list.push(92);
    /// list.insert(0, "nay");
    /// assert_eq!(list.get(0), Some("nay"));
    /// ```
    pub fn insert<T>(&mut self, index: usize, value: T)
    where
        Value<'a>: From<T>,    
    {
        self.vec.insert(index, value.into());
    }

    /// Removes a value at the given index, moving all the elements after it
    /// backward one space.
    ///
    /// # Panics
    ///
    /// Panics if the given index is out of range.
    ///
    /// # Examples
    ///
    /// ```
    /// use table::{List, Value};
    ///
    /// let mut list = List::new();
    /// list.push(93);
    /// list.push(84);
    /// assert_eq!(list.remove(0), Value::I64(93));
    /// assert_eq!(list.get(0), Some(&84));
    /// ```
    pub fn remove(&mut self, index: usize) -> Value<'a> {
        self.vec.remove(index)
    }

    /// Appends a value to the end of the list.
    ///
    /// # Examples
    ///
    /// ```
    /// use table::List;
    ///
    /// let mut list = List::new();
    /// list.push("ok");
    /// assert_eq!(list.get(0), Some("ok"))
    /// ```
    pub fn push<T>(&mut self, value: T)
    where
        Value<'a>: From<T>,
    {
        self.vec.push(value.into())
    }

    /// Takes the value from the end of the list and returns it, or returns
    /// `None` if the list is empty.
    ///
    /// # Examples
    ///
    /// ```
    /// use table::{List, Value};
    ///
    /// let mut list = List::new();
    /// list.push(99);
    /// assert_eq!(list.pop(), Some(Value::I64(99)));
    /// assert_eq!(list.pop(), None);
    /// ```
    pub fn pop(&mut self) -> Option<Value<'a>> {
        self.vec.pop()
    }

    /// Returns a borrowing iterator over the elements in the list.
    ///
    /// # Examples
    ///
    /// ```
    /// use table::{List, Value};
    ///
    /// let mut list = List::new();
    /// list.push("a");
    /// list.push(6);
    ///
    /// let mut iter = list.iter();
    /// assert_eq!(iter.next(), Some(&Value::from("a")));
    /// assert_eq!(iter.next(), Some(&Value::I64(6)));
    /// assert_eq!(iter.next(), None);
    /// ```
    pub fn iter<'b>(&'b self) -> Iter<'a, 'b> {
        self.into_iter()
    }

    /// Returns a mutably borrowing iterator over the elements in the list.
    ///
    /// # Examples
    ///
    /// ```
    /// use table::{List, Value};
    ///
    /// let mut list = List::new();
    /// list.push("a");
    /// list.push(8);
    ///
    /// for (i, elem) in list.iter_mut().enumerate() {
    ///     *elem = Value::from(i);
    /// }
    ///
    /// assert_eq!(list.get(0), Some(&0));
    /// assert_eq!(list.get(1), Some(&1));
    /// ```
    pub fn iter_mut<'b>(&'b mut self) -> IterMut<'a, 'b> {
        self.into_iter()
    }
}

impl<'a> ops::Index<usize> for List<'a> {
    type Output = Value<'a>;

    fn index(&self, index: usize) -> &Self::Output {
        self.get(index).unwrap()
    }
}

impl<'a> ops::IndexMut<usize> for List<'a> {
    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
        self.get_mut(index).unwrap()
    }
}

impl<'a> ops::Deref for List<'a> {
    type Target = [Value<'a>];

    fn deref(&self) -> &[Value<'a>] {
        self.vec.deref()
    }
}