use std::{collections::{hash_map::RandomState}, hash::BuildHasher, hash::Hash, borrow::Borrow};
use crate::ScopeMap;
#[derive(Clone)]
pub struct ScopeSet<T, S: BuildHasher = RandomState> {
map: ScopeMap<T, (), S>
}
impl<T, S: Default + BuildHasher> Default for ScopeSet<T, S> {
#[inline]
fn default() -> Self {
Self {
map: Default::default()
}
}
}
impl<T> ScopeSet<T, RandomState> {
#[inline]
pub fn new() -> Self {
Default::default()
}
#[inline]
pub fn with_capacity(capacity: usize) -> Self {
Self {
map: ScopeMap::with_capacity(capacity)
}
}
}
impl<T, S: BuildHasher> ScopeSet<T, S> {
#[inline]
pub fn with_hasher(hash_builder: S) -> Self {
Self {
map: ScopeMap::with_hasher(hash_builder)
}
}
#[inline]
pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self {
Self {
map: ScopeMap::with_capacity_and_hasher(capacity, hash_builder)
}
}
}
impl<T, S: BuildHasher> ScopeSet<T, S> {
#[inline]
pub fn is_empty(&self) -> bool {
self.map.is_empty()
}
#[inline]
pub fn capacity(&self) -> usize {
self.map.capacity()
}
#[inline]
pub fn len(&self) -> usize {
self.map.len()
}
#[inline]
pub fn depth(&self) -> usize {
self.map.depth()
}
#[inline]
pub fn push_layer(&mut self) {
self.map.push_layer()
}
#[inline]
pub fn pop_layer(&mut self) -> bool {
self.map.pop_layer()
}
}
impl<T: Eq + Hash, S: BuildHasher> ScopeSet<T, S> {
#[inline]
pub fn clear_all(&mut self) {
self.map.clear_all()
}
#[inline]
pub fn clear_top(&mut self) {
self.map.clear_top()
}
#[inline]
pub fn define(&mut self, key: T) {
self.map.define(key, ());
}
#[inline]
pub fn define_parent(&mut self, key: T, min_depth: usize) {
self.map.define_parent(key, (), min_depth);
}
#[inline]
pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> bool
where
T: Borrow<Q>,
Q: Eq + Hash,
{
self.map.remove(key).is_some()
}
#[inline]
pub fn contains<Q: ?Sized>(&self, key: &Q) -> bool
where
T: Borrow<Q>,
Q: Eq + Hash,
{
self.map.contains_key(key)
}
#[inline]
pub fn contains_at_top<Q: ?Sized>(&self, key: &Q) -> bool
where
T: Borrow<Q>,
Q: Eq + Hash,
{
self.map.contains_key_at_top(key)
}
#[inline]
pub fn depth_of<Q: ?Sized>(&self, key: &Q) -> Option<usize>
where
T: Borrow<Q>,
Q: Eq + Hash,
{
self.map.depth_of(key)
}
#[inline]
pub fn depth_of_parent<Q: ?Sized>(&self, key: &Q, min_depth: usize) -> Option<usize>
where
T: Borrow<Q>,
Q: Eq + Hash,
{
self.map.get_parent_depth(key, min_depth).map(|(_, d)| d)
}
#[inline]
pub fn height_of<Q: ?Sized>(&self, key: &Q) -> Option<usize>
where
T: Borrow<Q>,
Q: Eq + Hash,
{
self.map.height_of(key)
}
#[inline]
pub fn height_of_parent<Q: ?Sized>(&self, key: &Q, min_depth: usize) -> Option<usize>
where
T: Borrow<Q>,
Q: Eq + Hash,
{
self.map.get_parent_height(key, min_depth).map(|(_, h)| h)
}
#[inline]
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.map.keys()
}
#[inline]
pub fn iter_top(&self) -> impl Iterator<Item = &T> {
self.map.keys_top()
}
}
#[cfg(test)]
mod test {
use super::*;
use std::collections::HashSet;
#[test]
fn set_init() {
let set: ScopeSet<String> = ScopeSet::new();
assert_eq!(0, set.len());
assert_eq!(1, set.depth());
assert!(set.is_empty());
}
#[test]
fn set_default() {
let set: ScopeSet<String> = Default::default();
assert_eq!(0, set.len());
assert_eq!(1, set.depth());
assert!(set.is_empty());
}
#[test]
fn set_capacity() {
let set: ScopeSet<String> = ScopeSet::with_capacity(32);
assert_eq!(32, set.capacity());
}
#[test]
fn set_define() {
let mut set = ScopeSet::new();
set.define("foo");
assert_eq!(1, set.len());
}
#[test]
fn set_define_parent() {
let mut set = ScopeSet::new();
set.push_layer();
set.define_parent("foo", 1);
assert_eq!(Some(1), set.depth_of("foo"));
assert!(set.contains("foo"));
}
#[test]
fn set_delete() {
let mut set = ScopeSet::new();
set.define("foo");
set.remove("foo");
assert!(!set.contains("foo"));
}
#[test]
fn set_pop_to_delete() {
let mut set = ScopeSet::new();
set.push_layer();
set.define("foo");
assert!(set.contains("foo"));
set.pop_layer();
assert!(!set.contains("foo"));
}
#[test]
fn set_layer_count() {
let mut set: ScopeSet<String> = Default::default();
set.push_layer();
assert_eq!(2, set.depth());
set.pop_layer();
assert_eq!(1, set.depth());
}
#[test]
fn set_try_pop_first_layer() {
let mut set: ScopeSet<String> = Default::default();
assert_eq!(false, set.pop_layer());
assert_eq!(1, set.depth());
}
#[test]
fn set_contains() {
let mut set = ScopeSet::new();
set.define("foo");
assert!(set.contains("foo"));
}
#[test]
fn set_contains_none() {
let mut set = ScopeSet::new();
set.define("foo");
assert!(!set.contains("bar"));
}
#[test]
fn set_contains_multi_layer() {
let mut set = ScopeSet::new();
set.define("foo");
set.push_layer();
set.define("bar");
assert!(set.contains("foo"));
assert!(set.contains("bar"));
}
#[test]
fn set_depth_of() {
let mut set = ScopeSet::new();
set.define("foo");
set.push_layer();
set.define("bar");
assert_eq!(Some(1), set.depth_of("foo"));
assert_eq!(Some(0), set.depth_of("bar"));
assert_eq!(None, set.depth_of("baz"));
}
#[test]
fn set_depth_of_parent() {
let mut set = ScopeSet::new();
set.define("foo");
set.push_layer();
set.push_layer();
set.define("foo");
assert_eq!(Some(0), set.depth_of_parent("foo", 0));
assert_eq!(Some(2), set.depth_of_parent("foo", 1));
assert_eq!(Some(2), set.depth_of_parent("foo", 2));
}
#[test]
fn set_height_of() {
let mut set = ScopeSet::new();
set.define("foo");
set.push_layer();
set.define("bar");
assert_eq!(Some(0), set.height_of("foo"));
assert_eq!(Some(1), set.height_of("bar"));
assert_eq!(None, set.height_of("baz"));
}
#[test]
fn set_height_of_parent() {
let mut set = ScopeSet::new();
set.define("foo");
set.push_layer();
set.push_layer();
set.define("foo");
assert_eq!(Some(2), set.height_of_parent("foo", 0));
assert_eq!(Some(0), set.height_of_parent("foo", 1));
assert_eq!(Some(0), set.height_of_parent("foo", 2));
}
#[test]
fn set_iter() {
let mut set = ScopeSet::new();
set.define("foo");
set.push_layer();
set.define("bar");
set.push_layer();
set.define("baz");
let expected_keys: HashSet<&str> = ["foo", "bar", "baz"].iter().cloned().collect();
let actual_keys: HashSet<&str> = set.iter().cloned().collect();
assert_eq!(expected_keys, actual_keys);
}
#[test]
fn set_iter_top() {
let mut set = ScopeSet::new();
set.define("foo");
set.push_layer();
set.define("bar");
set.push_layer();
set.define("baz");
set.define("qux");
let expected_keys: HashSet<&str> = ["baz", "qux"].iter().cloned().collect();
let actual_keys: HashSet<&str> = set.iter_top().cloned().collect();
assert_eq!(expected_keys, actual_keys);
}
}