hadean-std 0.2.0

Hadean stdlib. Requires Hadean Rust.
//! A vector that is "pinned" in memory, i.e. it is never reallocated. Thus it must be given a capacity on instantiation that will not change for its duration. `push` and other functions that increase the length fail if capacity is reached, and thus return a `Result`.

use std::{ops,fmt};

/// A vector that is "pinned" in memory, i.e. it is never reallocated. Thus it must be given a capacity on instantiation that will not change for its duration. `push` and other functions that increase the length fail if capacity is reached, and thus return a `Result`.
pub struct PinnedVec<T>(Vec<T>);
impl<T> PinnedVec<T> {
	/// Constructs a new, empty `PinnedVec<T>` with the specified capacity.
	/// The vector will be able to hold exactly `capacity` elements. Inserting elements beyond `capacity` will return an error `Result`.
	pub fn with_capacity(capacity: usize) -> PinnedVec<T> {
		PinnedVec(Vec::with_capacity(capacity))
	}
	/// Returns the number of elements in the vector.
	pub fn len(&self) -> usize {
		self.0.len()
	}
	/// Returns the number of elements the vector can hold.
	pub fn capacity(&self) -> usize {
		self.0.capacity()
	}
	/// Appends an element to the back of a collection. If it would result in exceeding `capacity`, this returns an error `Result`.
	pub fn push(&mut self, value: T) -> Result<(),PinnedVecError<T>> {
		if self.0.len() == self.0.capacity() {
			Err(PinnedVecError(value))
		} else {
			self.0.push(value);
			Ok(())
		}
	}
	/// Sets the length of a vector.
	/// This will explicitly set the size of the vector, without actually modifying its buffers, so the resulting vector may contain unitialized data
	/// Unlike the Vec::set_len, this will panic if len > capacity
	pub unsafe fn set_len(&mut self, len: usize) {
		if len > self.0.capacity() {
			panic!("Setting vector length too long")
		}
		self.0.set_len(len)
	}
}
impl<T> PinnedVec<T> where T: Clone {
	/// Appends all elements in a slice to the `PinnedVec`.
	/// Iterates over the slice `other`, clones each element, and then appends it to this `PinnedVec`. The `other` vector is traversed in-order.
	/// Note that this function is same as `extend` except that it is specialized to work with slices instead. If and when Rust gets specialization this function will likely be deprecated (but still available).
	pub fn extend_from_slice(&mut self, other: &[T]) -> Result<(),()> {
		if self.0.len() + other.len() > self.0.capacity() {
			Err(())
		} else {
			self.0.extend_from_slice(other);
			Ok(())
		}
	}
}
impl<T> Clone for PinnedVec<T> where T: Clone {
	fn clone(&self) -> Self {
		let mut pv = PinnedVec(Vec::with_capacity(self.capacity()));
		pv.0.clone_from(&self.0);
		pv
	}
}
impl<T> ops::Deref for PinnedVec<T> {
	type Target = [T];
	fn deref(&self) -> &[T] {
		&*self.0
	}
}
impl<T> ops::DerefMut for PinnedVec<T> {
	fn deref_mut(&mut self) -> &mut [T] {
		&mut *self.0
	}
}
impl<T> AsRef<PinnedVec<T>> for PinnedVec<T> {
	fn as_ref(&self) -> &PinnedVec<T> {
		self
	}
}
impl<T> AsMut<PinnedVec<T>> for PinnedVec<T> {
	fn as_mut(&mut self) -> &mut PinnedVec<T> {
		self
	}
}
impl<T> AsRef<[T]> for PinnedVec<T> {
	fn as_ref(&self) -> &[T] {
		self
	}
}
impl<T> AsMut<[T]> for PinnedVec<T> {
	fn as_mut(&mut self) -> &mut [T] {
		self
	}
}

/// Returned when an attempted insertion into a `PinnedVec` would exceed `capacity`.
pub struct PinnedVecError<T>(T);
impl<T> fmt::Debug for PinnedVecError<T> {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		write!(f, "PinnedVecError")
	}
}

/*

https://doc.rust-lang.org/std/vec/struct.Vec.html
https://github.com/rust-lang/rust/blob/master/src/libcollections/vec.rs

http://bluss.github.io/arrayvec/doc/arrayvec/struct.ArrayVec.html

*/