Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OrderSet #46

Merged
merged 12 commits into from
Nov 25, 2017
38 changes: 4 additions & 34 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@
//!
//! [`OrderMap`]: struct.OrderMap.html

#[macro_use]
mod macros;
#[cfg(feature = "serde-1")]
mod serde;
mod util;
mod equivalent;
mod mutable_keys;

pub mod set;

use std::hash::Hash;
use std::hash::BuildHasher;
use std::hash::Hasher;
Expand All @@ -28,6 +31,7 @@ use std::marker::PhantomData;
use util::{third, ptrdistance, enumerate};
pub use equivalent::Equivalent;
pub use mutable_keys::MutableKeys;
pub use set::OrderSet;

fn hash_elem_using<B: BuildHasher, K: ?Sized + Hash>(build: &B, k: &K) -> HashValue {
let mut h = build.build_hasher();
Expand Down Expand Up @@ -1163,40 +1167,6 @@ use std::slice::Iter as SliceIter;
use std::slice::IterMut as SliceIterMut;
use std::vec::IntoIter as VecIntoIter;

// generate all the Iterator methods by just forwarding to the underlying
// self.iter and mapping its element.
macro_rules! iterator_methods {
// $map_elt is the mapping function from the underlying iterator's element
// same mapping function for both options and iterators
($map_elt:expr) => {
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map($map_elt)
}

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

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

fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.iter.nth(n).map($map_elt)
}

fn last(mut self) -> Option<Self::Item> {
self.next_back()
}

fn collect<C>(self) -> C
where C: FromIterator<Self::Item>
{
self.iter.map($map_elt).collect()
}
}
}

pub struct Keys<'a, K: 'a, V: 'a> {
iter: SliceIter<'a, Bucket<K, V>>,
}
Expand Down
74 changes: 74 additions & 0 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,77 @@ macro_rules! ordermap {
}
};
}

#[macro_export]
/// Create an `OrderSet` from a list of values
///
/// ## Example
///
/// ```
/// #[macro_use] extern crate ordermap;
/// # fn main() {
///
/// let set = orderset!{
/// "a",
/// "b",
/// };
/// assert!(set.contains("a"));
/// assert!(set.contains("b"));
/// assert!(!set.contains("c"));
///
/// // "a" is the first value
/// assert_eq!(set.iter().next(), Some(&"a"));
/// # }
/// ```
macro_rules! orderset {
(@single $($x:tt)*) => (());
(@count $($rest:expr),*) => (<[()]>::len(&[$(orderset!(@single $rest)),*]));

($($value:expr,)+) => { orderset!($($value),+) };
($($value:expr),*) => {
{
let _cap = orderset!(@count $($value),*);
let mut _set = $crate::OrderSet::with_capacity(_cap);
$(
_set.insert($value);
)*
_set
}
};
}

// generate all the Iterator methods by just forwarding to the underlying
// self.iter and mapping its element.
macro_rules! iterator_methods {
// $map_elt is the mapping function from the underlying iterator's element
// same mapping function for both options and iterators
($map_elt:expr) => {
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map($map_elt)
}

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

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

fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.iter.nth(n).map($map_elt)
}

fn last(mut self) -> Option<Self::Item> {
self.next_back()
}

fn collect<C>(self) -> C
where C: FromIterator<Self::Item>
{
// NB: forwarding this directly to standard iterators will
// allow it to leverage unstable traits like `TrustedLen`.
self.iter.map($map_elt).collect()
}
}
}
62 changes: 59 additions & 3 deletions src/serde.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@

extern crate serde;

use self::serde::ser::{Serialize, Serializer, SerializeMap};
use self::serde::de::{Deserialize, Deserializer, MapAccess, Visitor};
use self::serde::ser::{Serialize, Serializer, SerializeMap, SerializeSeq};
use self::serde::de::{Deserialize, Deserializer, MapAccess, SeqAccess, Visitor};

use std::fmt::{self, Formatter};
use std::hash::{BuildHasher, Hash};
Expand Down Expand Up @@ -43,7 +43,7 @@ impl<'de, K, V, S> Visitor<'de> for OrderMapVisitor<K, V, S>
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where A: MapAccess<'de>
{
let mut values = OrderMap::with_capacity_and_hasher(map.size_hint().unwrap_or(0), Default::default());
let mut values = OrderMap::with_capacity_and_hasher(map.size_hint().unwrap_or(0), S::default());

while let Some((key, value)) = try!(map.next_entry()) {
values.insert(key, value);
Expand All @@ -65,3 +65,59 @@ impl<'de, K, V, S> Deserialize<'de> for OrderMap<K, V, S>
deserializer.deserialize_map(OrderMapVisitor(PhantomData))
}
}


use OrderSet;

/// Requires crate feature `"serde-1"`
impl<T, S> Serialize for OrderSet<T, S>
where T: Serialize + Hash + Eq,
S: BuildHasher
{
fn serialize<Se>(&self, serializer: Se) -> Result<Se::Ok, Se::Error>
where Se: Serializer
{
let mut set_serializer = try!(serializer.serialize_seq(Some(self.len())));
for value in self {
try!(set_serializer.serialize_element(value));
}
set_serializer.end()
}
}

struct OrderSetVisitor<T, S>(PhantomData<(T, S)>);

impl<'de, T, S> Visitor<'de> for OrderSetVisitor<T, S>
where T: Deserialize<'de> + Eq + Hash,
S: Default + BuildHasher
{
type Value = OrderSet<T, S>;

fn expecting(&self, formatter: &mut Formatter) -> fmt::Result {
write!(formatter, "a set")
}

fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where A: SeqAccess<'de>
{
let mut values = OrderSet::with_capacity_and_hasher(seq.size_hint().unwrap_or(0), S::default());

while let Some(value) = try!(seq.next_element()) {
values.insert(value);
}

Ok(values)
}
}

/// Requires crate feature `"serde-1"`
impl<'de, T, S> Deserialize<'de> for OrderSet<T, S>
where T: Deserialize<'de> + Eq + Hash,
S: Default + BuildHasher
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>
{
deserializer.deserialize_seq(OrderSetVisitor(PhantomData))
}
}
Loading