use core::fmt;
use std::borrow::Borrow;
use std::collections::BTreeMap;
use std::num::NonZeroUsize;
#[cfg(feature = "serde")]
use serde::Deserialize;
#[cfg(feature = "serde")]
use serde::Serialize;
use crate::FromNonEmptyIterator;
use crate::IntoIteratorExt;
use crate::IntoNonEmptyIterator;
use crate::NonEmptyIterator;
use crate::Singleton;
#[macro_export]
macro_rules! nebtm {
($hk:expr => $hv:expr, $( $xk:expr => $xv:expr ),* $(,)?) => {{
let mut map = $crate::NEBTreeMap::new($hk, $hv);
$( map.insert($xk, $xv); )*
map
}};
($hk:expr => $hv:expr) => {
$crate::NEBTreeMap::new($hk, $hv)
}
}
#[allow(clippy::unsafe_derive_deserialize)]
#[cfg_attr(
feature = "serde",
derive(Deserialize, Serialize),
serde(bound(
serialize = "K: Ord + Clone + Serialize, V: Clone + Serialize",
deserialize = "K: Ord + Clone + Deserialize<'de>, V: Deserialize<'de>"
)),
serde(into = "BTreeMap<K, V>", try_from = "BTreeMap<K, V>")
)]
#[derive(Clone)]
pub struct NEBTreeMap<K, V> {
inner: BTreeMap<K, V>,
}
impl<K, V> NEBTreeMap<K, V>
where
K: Ord,
{
#[must_use]
pub fn new(k: K, v: V) -> NEBTreeMap<K, V> {
let mut inner = BTreeMap::new();
inner.insert(k, v);
NEBTreeMap { inner }
}
}
impl<K, V> NEBTreeMap<K, V> {
#[must_use]
pub fn try_from_map(map: BTreeMap<K, V>) -> Option<Self> {
if map.is_empty() {
None
} else {
Some(Self { inner: map })
}
}
pub fn iter(&self) -> std::collections::btree_map::Iter<'_, K, V> {
self.inner.iter()
}
pub fn iter_mut(&mut self) -> std::collections::btree_map::IterMut<'_, K, V> {
self.inner.iter_mut()
}
pub fn nonempty_iter(&self) -> Iter<'_, K, V> {
Iter {
iter: self.inner.iter(),
}
}
pub fn nonempty_iter_mut(&mut self) -> IterMut<'_, K, V> {
IterMut {
iter: self.inner.iter_mut(),
}
}
pub fn keys(&self) -> Keys<'_, K, V> {
Keys {
inner: self.inner.keys(),
}
}
#[must_use]
pub fn len(&self) -> NonZeroUsize {
unsafe { NonZeroUsize::new_unchecked(self.inner.len()) }
}
pub fn values(&self) -> Values<'_, K, V> {
Values {
inner: self.inner.values(),
}
}
}
impl<K, V> NEBTreeMap<K, V>
where
K: Ord,
{
#[must_use]
pub fn contains_key<Q>(&self, k: &Q) -> bool
where
K: Borrow<Q>,
Q: Ord + ?Sized,
{
self.inner.contains_key(k)
}
#[must_use]
pub fn get<Q>(&self, k: &Q) -> Option<&V>
where
K: Borrow<Q>,
Q: Ord + ?Sized,
{
self.inner.get(k)
}
#[must_use]
pub fn get_key_value<Q>(&self, k: &Q) -> Option<(&K, &V)>
where
K: Borrow<Q>,
Q: Ord + ?Sized,
{
self.inner.get_key_value(k)
}
#[must_use]
pub fn get_mut<Q>(&mut self, k: &Q) -> Option<&mut V>
where
K: Borrow<Q>,
Q: Ord + ?Sized,
{
self.inner.get_mut(k)
}
pub fn insert(&mut self, k: K, v: V) -> Option<V> {
self.inner.insert(k, v)
}
}
impl<K, V> AsRef<BTreeMap<K, V>> for NEBTreeMap<K, V> {
fn as_ref(&self) -> &BTreeMap<K, V> {
&self.inner
}
}
impl<K, V> AsMut<BTreeMap<K, V>> for NEBTreeMap<K, V> {
fn as_mut(&mut self) -> &mut BTreeMap<K, V> {
&mut self.inner
}
}
impl<K, V> PartialEq for NEBTreeMap<K, V>
where
K: Ord,
V: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
self.inner.eq(&other.inner)
}
}
impl<K, V> Eq for NEBTreeMap<K, V>
where
K: Ord,
V: Eq,
{
}
impl<K, V> From<NEBTreeMap<K, V>> for BTreeMap<K, V>
where
K: Ord,
{
fn from(m: NEBTreeMap<K, V>) -> Self {
m.inner
}
}
impl<K, V> TryFrom<BTreeMap<K, V>> for NEBTreeMap<K, V>
where
K: Ord,
{
type Error = crate::Error;
fn try_from(map: BTreeMap<K, V>) -> Result<Self, Self::Error> {
map.try_into_nonempty_iter()
.map(NonEmptyIterator::collect)
.ok_or(crate::Error::Empty)
}
}
impl<K, V> IntoNonEmptyIterator for NEBTreeMap<K, V> {
type IntoNEIter = IntoIter<K, V>;
fn into_nonempty_iter(self) -> Self::IntoNEIter {
IntoIter {
iter: self.inner.into_iter(),
}
}
}
impl<'a, K, V> IntoNonEmptyIterator for &'a NEBTreeMap<K, V> {
type IntoNEIter = Iter<'a, K, V>;
fn into_nonempty_iter(self) -> Self::IntoNEIter {
self.nonempty_iter()
}
}
impl<K, V> IntoIterator for NEBTreeMap<K, V> {
type Item = (K, V);
type IntoIter = std::collections::btree_map::IntoIter<K, V>;
fn into_iter(self) -> Self::IntoIter {
self.inner.into_iter()
}
}
impl<'a, K, V> IntoIterator for &'a NEBTreeMap<K, V> {
type Item = (&'a K, &'a V);
type IntoIter = std::collections::btree_map::Iter<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a, K, V> IntoIterator for &'a mut NEBTreeMap<K, V> {
type Item = (&'a K, &'a mut V);
type IntoIter = std::collections::btree_map::IterMut<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl<K, V> FromNonEmptyIterator<(K, V)> for NEBTreeMap<K, V>
where
K: Ord,
{
fn from_nonempty_iter<I>(iter: I) -> Self
where
I: IntoNonEmptyIterator<Item = (K, V)>,
{
NEBTreeMap {
inner: iter.into_nonempty_iter().into_iter().collect(),
}
}
}
#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
pub struct Iter<'a, K: 'a, V: 'a> {
iter: std::collections::btree_map::Iter<'a, K, V>,
}
impl<K, V> NonEmptyIterator for Iter<'_, K, V> {}
impl<'a, K, V> IntoIterator for Iter<'a, K, V> {
type Item = (&'a K, &'a V);
type IntoIter = std::collections::btree_map::Iter<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.iter
}
}
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for Iter<'_, K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.iter.fmt(f)
}
}
#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
pub struct IterMut<'a, K: 'a, V: 'a> {
iter: std::collections::btree_map::IterMut<'a, K, V>,
}
impl<K, V> NonEmptyIterator for IterMut<'_, K, V> {}
impl<'a, K, V> IntoIterator for IterMut<'a, K, V> {
type Item = (&'a K, &'a mut V);
type IntoIter = std::collections::btree_map::IterMut<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.iter
}
}
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IterMut<'_, K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.iter.fmt(f)
}
}
pub struct IntoIter<K, V> {
iter: std::collections::btree_map::IntoIter<K, V>,
}
impl<K, V> NonEmptyIterator for IntoIter<K, V> {}
impl<K, V> IntoIterator for IntoIter<K, V> {
type Item = (K, V);
type IntoIter = std::collections::btree_map::IntoIter<K, V>;
fn into_iter(self) -> Self::IntoIter {
self.iter
}
}
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IntoIter<K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.iter.fmt(f)
}
}
#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
pub struct Keys<'a, K: 'a, V: 'a> {
inner: std::collections::btree_map::Keys<'a, K, V>,
}
impl<K, V> NonEmptyIterator for Keys<'_, K, V> {}
impl<'a, K, V> IntoIterator for Keys<'a, K, V> {
type Item = &'a K;
type IntoIter = std::collections::btree_map::Keys<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.inner
}
}
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for Keys<'_, K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.inner.fmt(f)
}
}
#[must_use = "non-empty iterators are lazy and do nothing unless consumed"]
pub struct Values<'a, K: 'a, V: 'a> {
inner: std::collections::btree_map::Values<'a, K, V>,
}
impl<K, V> NonEmptyIterator for Values<'_, K, V> {}
impl<'a, K, V> IntoIterator for Values<'a, K, V> {
type Item = &'a V;
type IntoIter = std::collections::btree_map::Values<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
self.inner
}
}
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for Values<'_, K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.inner.fmt(f)
}
}
impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for NEBTreeMap<K, V> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.inner.fmt(f)
}
}
impl<K, V> Singleton for NEBTreeMap<K, V>
where
K: Ord,
{
type Item = (K, V);
fn singleton((k, v): Self::Item) -> Self {
NEBTreeMap::new(k, v)
}
}
impl<K, V> Extend<(K, V)> for NEBTreeMap<K, V>
where
K: Ord,
{
fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
self.inner.extend(iter);
}
}
#[cfg(test)]
mod test {
use maplit::hashmap;
use std::num::NonZeroUsize;
struct Foo {
user: String,
}
#[test]
fn debug_impl() {
let expected = format!("{:?}", hashmap! {0 => 10});
let actual = format!("{:?}", nebtm! {0 => 10});
assert_eq!(expected, actual);
}
#[test]
fn macro_usage() {
let a = Foo {
user: "a".to_string(),
};
let b = Foo {
user: "b".to_string(),
};
let map = nebtm![1 => a, 2 => b];
assert_eq!("a", map.get(&1).unwrap().user);
assert_eq!("b", map.get(&2).unwrap().user);
}
#[test]
fn macro_length() {
let map = nebtm![1 => 'a', 2 => 'b', 1 => 'c'];
assert_eq!(unsafe { NonZeroUsize::new_unchecked(2) }, map.len());
assert_eq!('c', *map.get(&1).unwrap());
assert_eq!('b', *map.get(&2).unwrap());
}
#[test]
fn iter_mut() {
let mut v = nebtm! {"a" => 0, "b" => 1, "c" => 2};
v.iter_mut().for_each(|(_k, v)| {
*v += 1;
});
assert_eq!(nebtm! {"a" => 1, "b" => 2, "c" => 3}, v);
for (_k, v) in &mut v {
*v -= 1;
}
assert_eq!(nebtm! {"a" => 0, "b" => 1, "c" => 2}, v);
}
}
#[cfg(feature = "serde")]
#[cfg(test)]
mod serde_tests {
use crate::NEBTreeMap;
use std::collections::BTreeMap;
#[test]
fn json() {
let map0 = nebtm![1 => 'a', 2 => 'b', 1 => 'c'];
let j = serde_json::to_string(&map0).unwrap();
let map1 = serde_json::from_str(&j).unwrap();
assert_eq!(map0, map1);
let empty: BTreeMap<usize, char> = BTreeMap::new();
let j = serde_json::to_string(&empty).unwrap();
let bad = serde_json::from_str::<NEBTreeMap<usize, char>>(&j);
assert!(bad.is_err());
}
}