use std::collections::HashSet;
use std::hash::Hash;
use std::borrow::Borrow;
use std::fmt::Debug;
use serde::{Serialize, Deserialize, ser::{Serializer, SerializeSeq}, de::{Deserializer, Visitor, SeqAccess}};
use crate::util::*;
#[derive(Debug, Clone, Suitability)]
pub struct Set<T: Debug> {
pub set: HashSet<T>,
pub if_none: bool
}
impl<T: Debug + Hash + Eq> Set<T> {
pub fn with_capacity(capacity: usize) -> Self {
Self {
set: HashSet::with_capacity(capacity),
if_none: false
}
}
pub fn contains<Q>(&self, value: Option<&Q>) -> bool where T: Borrow<Q>, Q: Debug + Hash + Eq + ?Sized {
debug!(Set::contains, self, value);
match value {
Some(x) => self.set.contains(x),
None => self.if_none
}
}
pub fn insert(&mut self, value: Option<T>) -> bool {
match value {
Some(value) => self.set.insert(value),
None => {let ret = !self.if_none; self.if_none = true; ret}
}
}
pub fn extend<I: IntoIterator<Item = Option<T>>>(&mut self, iter: I) {
for x in iter {
self.insert(x);
}
}
pub fn remove<Q>(&mut self, value: Option<&Q>) -> bool where T: Borrow<Q>, Q: Debug + Hash + Eq + ?Sized {
match value {
Some(value) => self.set.remove(value),
None => {let ret = self.if_none; self.if_none = false; ret}
}
}
}
impl<T: Debug> Default for Set<T> {
fn default() -> Self {
Self {
set: Default::default(),
if_none: Default::default()
}
}
}
impl<T: Debug + Hash + Eq> PartialEq for Set<T> {
fn eq(&self, other: &Self) -> bool {
self.set == other.set && self.if_none == other.if_none
}
}
impl<T: Debug + Hash + Eq> Eq for Set<T> {}
impl<T: Debug + Eq + Hash, const N: usize> From<[Option<T>; N]> for Set<T> {
fn from(value: [Option<T>; N]) -> Self {
let mut ret = Self::default();
for x in value {
ret.insert(x);
}
ret
}
}
impl<T: Debug + Eq + Hash, const N: usize> From<[T; N]> for Set<T> {
fn from(value: [T; N]) -> Self {
let mut ret = Self::default();
for x in value {
ret.insert(Some(x));
}
ret
}
}
impl<T: Debug + Eq + Hash> FromIterator<T> for Set<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self{
let mut ret = Self::default();
for x in iter {
ret.insert(Some(x));
}
ret
}
}
impl<T: Debug + Eq + Hash> FromIterator<Option<T>> for Set<T> {
fn from_iter<I: IntoIterator<Item = Option<T>>>(iter: I) -> Self{
let mut ret = Self::default();
for x in iter {
ret.insert(x);
}
ret
}
}
impl<T: Debug + Hash + Eq> From<HashSet<Option<T>>> for Set<T> {
fn from(value: HashSet<Option<T>>) -> Self {
let mut ret = Self::default();
for x in value {
match x {
Some(x) => {ret.set.insert(x);},
None => ret.if_none = true
}
}
ret
}
}
impl<T: Debug + Hash + Eq> From<Set<T>> for HashSet<Option<T>> {
fn from(value: Set<T>) -> Self {
let mut ret = Self::default();
for x in value.set {
ret.insert(Some(x));
}
if value.if_none {ret.insert(None);}
ret
}
}
impl<T: Debug + Serialize> Serialize for Set<T> {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
#[allow(clippy::arithmetic_side_effects, reason = "Can't happen.")]
let mut seq = serializer.serialize_seq(Some(self.set.len() + (self.if_none as usize)))?;
if self.if_none {seq.serialize_element(&None::<T>)?;}
for element in &self.set {
seq.serialize_element(element)?;
}
seq.end()
}
}
impl<'de, T: Debug + Deserialize<'de> + Eq + Hash> Deserialize<'de> for Set<T> {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
deserializer.deserialize_seq(SetDeserializer::<T>(Default::default()))
}
}
#[derive(Debug, Default)]
struct SetDeserializer<T>(std::marker::PhantomData<T>);
impl<'de, T: Debug + Deserialize<'de> + Eq + Hash> Visitor<'de> for SetDeserializer<T> {
type Value = Set<T>;
fn expecting(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(fmt, "A sequence of type {}", std::any::type_name::<Option<T>>())
}
fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
let mut ret = Set::with_capacity(seq.size_hint().unwrap_or_default());
while let Some(x) = seq.next_element()? {
ret.insert(x);
}
Ok(ret)
}
}