use super::zero_one_or_many::ZeroOneOrMany;
use serde::de::{self, Deserializer, MapAccess, SeqAccess, Visitor};
use serde::ser::{SerializeSeq, Serializer};
use serde::{Deserialize, Serialize};
use std::fmt;
use std::iter::FromIterator;
use std::marker::PhantomData;
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct OneOrMany<T>(ZeroOneOrMany<T>);
#[derive(Debug)]
pub struct EmptyListError;
impl fmt::Display for EmptyListError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "OneOrMany cannot be empty")
}
}
impl std::error::Error for EmptyListError {}
impl<T> OneOrMany<T> {
#[inline]
pub fn one(item: T) -> Self {
OneOrMany(ZeroOneOrMany::One(item))
}
#[inline]
pub fn many(items: Vec<T>) -> Result<Self, EmptyListError> {
if items.is_empty() {
Err(EmptyListError)
} else {
Ok(OneOrMany(ZeroOneOrMany::Many(items)))
}
}
#[inline]
pub fn from_hashmap<K, V>(
map: ::hashbrown::HashMap<K, V>,
) -> Result<OneOrMany<(K, V)>, EmptyListError> {
let items: Vec<(K, V)> = map.into_iter().collect();
if items.is_empty() {
Err(EmptyListError)
} else {
Ok(OneOrMany(ZeroOneOrMany::Many(items)))
}
}
#[inline]
pub fn from_array_tuple<K, V, F>(f: F) -> Result<OneOrMany<(K, V)>, EmptyListError>
where
F: FnOnce() -> ::hashbrown::HashMap<K, V>,
{
Self::from_hashmap(f())
}
#[inline]
pub fn merge<I>(items: I) -> Result<Self, EmptyListError>
where
I: IntoIterator<Item = OneOrMany<T>>,
T: Clone + 'static,
{
let vec: Vec<T> = items
.into_iter()
.flat_map(|oom| oom.0.into_iter())
.collect();
Self::many(vec)
}
#[inline]
pub fn merge_refs<'a, I>(items: I) -> Result<OneOrMany<&'a T>, EmptyListError>
where
I: IntoIterator<Item = &'a OneOrMany<T>>,
{
let vec: Vec<&T> = items.into_iter().flat_map(|oom| oom.iter()).collect();
OneOrMany::many(vec)
}
#[inline]
pub fn len(&self) -> usize {
self.0.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
false
}
#[inline]
pub fn first(&self) -> &T {
match &self.0 {
ZeroOneOrMany::None => unreachable!("OneOrMany cannot be None"),
ZeroOneOrMany::One(item) => item,
ZeroOneOrMany::Many(v) => &v[0],
}
}
#[inline]
pub fn rest(&self) -> Vec<&T> {
self.0.rest()
}
#[inline]
pub fn rest_iter(&self) -> impl Iterator<Item = &T> {
self.0.rest_iter()
}
#[inline]
pub fn with_pushed(self, item: T) -> Self {
OneOrMany(self.0.with_pushed(item))
}
#[inline]
pub fn with_inserted(self, idx: usize, item: T) -> Self {
OneOrMany(self.0.with_inserted(idx, item))
}
#[inline]
pub fn map<U, F: FnMut(T) -> U>(self, f: F) -> OneOrMany<U> {
OneOrMany(self.0.map(f))
}
#[inline]
pub fn try_map<U, E, F: FnMut(T) -> Result<U, E>>(self, f: F) -> Result<OneOrMany<U>, E> {
self.0.try_map(f).map(OneOrMany)
}
#[inline]
pub fn iter(&self) -> impl Iterator<Item = &T> {
self.0.iter()
}
}
impl<T: Clone + 'static> IntoIterator for OneOrMany<T> {
type Item = T;
type IntoIter = Box<dyn Iterator<Item = T>>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
Box::new(self.0.into_iter())
}
}
impl<'a, T> IntoIterator for &'a OneOrMany<T> {
type Item = &'a T;
type IntoIter = Box<dyn Iterator<Item = &'a T> + 'a>;
#[inline]
fn into_iter(self) -> Self::IntoIter {
Box::new(self.iter())
}
}
impl<T: Serialize> Serialize for OneOrMany<T> {
fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
match &self.0 {
ZeroOneOrMany::None => unreachable!("OneOrMany cannot be None"),
ZeroOneOrMany::One(item) => {
let mut seq = ser.serialize_seq(Some(1))?;
seq.serialize_element(item)?;
seq.end()
}
ZeroOneOrMany::Many(v) => {
let mut seq = ser.serialize_seq(Some(v.len()))?;
for item in v {
seq.serialize_element(item)?;
}
seq.end()
}
}
}
}
impl<'de, T: Deserialize<'de>> Deserialize<'de> for OneOrMany<T> {
fn deserialize<D: Deserializer<'de>>(de: D) -> Result<Self, D::Error> {
struct V<T>(PhantomData<T>);
impl<'de, T: Deserialize<'de>> Visitor<'de> for V<T> {
type Value = OneOrMany<T>;
fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("a non-empty sequence or single value")
}
#[inline]
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut vec = Vec::new();
while let Some(elem) = seq.next_element()? {
vec.push(elem);
}
if vec.is_empty() {
Err(de::Error::invalid_length(0, &"at least one element"))
} else {
Ok(OneOrMany(ZeroOneOrMany::many(vec)))
}
}
#[inline]
fn visit_map<M>(self, map: M) -> Result<Self::Value, M::Error>
where
M: MapAccess<'de>,
{
let v = Deserialize::deserialize(de::value::MapAccessDeserializer::new(map))?;
Ok(OneOrMany(ZeroOneOrMany::One(v)))
}
}
de.deserialize_any(V(PhantomData))
}
}
impl<T> From<T> for OneOrMany<T> {
#[inline]
fn from(value: T) -> Self {
OneOrMany(ZeroOneOrMany::One(value))
}
}
impl<T> TryFrom<Vec<T>> for OneOrMany<T> {
type Error = EmptyListError;
#[inline]
fn try_from(vec: Vec<T>) -> Result<Self, Self::Error> {
OneOrMany::many(vec)
}
}
impl<T> From<OneOrMany<T>> for Vec<T> {
#[inline]
fn from(value: OneOrMany<T>) -> Self {
value.0.into()
}
}
impl<T> FromIterator<T> for OneOrMany<T> {
#[inline]
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut iter = iter.into_iter();
match iter.next() {
None => panic!("OneOrMany requires at least one element"),
Some(first) => {
let rest: Vec<T> = iter.collect();
if rest.is_empty() {
OneOrMany::one(first)
} else {
let mut vec = Vec::with_capacity(1 + rest.len());
vec.push(first);
vec.extend(rest);
OneOrMany(ZeroOneOrMany::Many(vec))
}
}
}
}
}