use std::collections::BTreeSet;
use std::ops::{Deref, DerefMut};
use serde::{Deserialize, Serialize};
use crate::Value;
use crate::sql::{SqlFormat, ToSql};
#[derive(Clone, Debug, Default, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(transparent)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
pub struct Set(pub(crate) BTreeSet<Value>);
impl Set {
pub fn new() -> Self {
Self(BTreeSet::new())
}
pub fn into_inner(self) -> BTreeSet<Value> {
self.0
}
}
impl From<Vec<Value>> for Set {
fn from(vec: Vec<Value>) -> Self {
Self(vec.into_iter().collect())
}
}
impl From<BTreeSet<Value>> for Set {
fn from(set: BTreeSet<Value>) -> Self {
Self(set)
}
}
impl From<Set> for Vec<Value> {
fn from(set: Set) -> Self {
set.0.into_iter().collect()
}
}
impl IntoIterator for Set {
type Item = Value;
type IntoIter = std::collections::btree_set::IntoIter<Value>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<'a> IntoIterator for &'a Set {
type Item = &'a Value;
type IntoIter = std::collections::btree_set::Iter<'a, Value>;
fn into_iter(self) -> Self::IntoIter {
self.0.iter()
}
}
impl Deref for Set {
type Target = BTreeSet<Value>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for Set {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl ToSql for Set {
fn fmt_sql(&self, f: &mut String, fmt: SqlFormat) {
if self.is_empty() {
f.push_str("{,}");
return;
}
f.push('{');
let len = self.len();
for (i, v) in self.iter().enumerate() {
v.fmt_sql(f, fmt);
if len == 1 {
f.push(',');
} else if i < len - 1 {
f.push_str(", ");
}
}
f.push('}');
}
}