pub extern crate value_bag;
use std::borrow::Cow;
use std::fmt;
use std::slice;
use value_bag::OwnedValueBag;
use value_bag::ValueBag;
use crate::Error;
use crate::str::OwnedStr;
use crate::str::RefStr;
pub trait Visitor {
fn visit(&mut self, key: Key, value: Value) -> Result<(), Error>;
}
pub type Value<'a> = ValueBag<'a>;
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Key<'a>(RefStr<'a>);
impl Key<'static> {
pub const fn new(k: &'static str) -> Key<'static> {
Key(RefStr::Static(k))
}
}
impl fmt::Display for Key<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}
impl<'a> Key<'a> {
pub const fn new_ref(k: &'a str) -> Key<'a> {
Key(RefStr::Borrowed(k))
}
pub fn to_owned(&self) -> KeyOwned {
KeyOwned(self.0.into_owned())
}
pub fn to_cow(&self) -> Cow<'static, str> {
self.0.into_cow_static()
}
pub fn as_str(&self) -> &str {
self.0.get()
}
}
pub type ValueOwned = OwnedValueBag;
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct KeyOwned(OwnedStr);
impl KeyOwned {
pub fn by_ref(&self) -> Key<'_> {
Key(self.0.by_ref())
}
}
impl fmt::Display for KeyOwned {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.0, f)
}
}
pub struct KeyValues<'a>(KeyValuesState<'a>);
enum KeyValuesState<'a> {
Borrowed(&'a [(Key<'a>, Value<'a>)]),
Owned(&'a [(KeyOwned, ValueOwned)]),
}
impl<'a> KeyValues<'a> {
pub fn len(&self) -> usize {
match self.0 {
KeyValuesState::Borrowed(p) => p.len(),
KeyValuesState::Owned(p) => p.len(),
}
}
pub fn is_empty(&self) -> bool {
match self.0 {
KeyValuesState::Borrowed(p) => p.is_empty(),
KeyValuesState::Owned(p) => p.is_empty(),
}
}
pub fn iter(&self) -> KeyValuesIter<'a> {
match &self.0 {
KeyValuesState::Borrowed(p) => KeyValuesIter(KeyValuesIterState::Borrowed(p.iter())),
KeyValuesState::Owned(p) => KeyValuesIter(KeyValuesIterState::Owned(p.iter())),
}
}
pub fn get(&self, key: &str) -> Option<Value<'a>> {
match &self.0 {
KeyValuesState::Borrowed(p) => p.iter().find_map(|(k, v)| {
if k.0.get() != key {
None
} else {
Some(v.clone())
}
}),
KeyValuesState::Owned(p) => p.iter().find_map(|(k, v)| {
if k.0.get() != key {
None
} else {
Some(v.by_ref())
}
}),
}
}
pub fn visit(&self, visitor: &mut dyn Visitor) -> Result<(), Error> {
for (k, v) in self.iter() {
visitor.visit(k, v)?;
}
Ok(())
}
}
impl fmt::Debug for KeyValues<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.iter()).finish()
}
}
impl Clone for KeyValues<'_> {
fn clone(&self) -> Self {
match &self.0 {
KeyValuesState::Borrowed(p) => KeyValues(KeyValuesState::Borrowed(p)),
KeyValuesState::Owned(p) => KeyValues(KeyValuesState::Owned(p)),
}
}
}
impl Default for KeyValues<'_> {
fn default() -> Self {
KeyValues(KeyValuesState::Borrowed(&[]))
}
}
impl<'a> IntoIterator for KeyValues<'a> {
type Item = (Key<'a>, Value<'a>);
type IntoIter = KeyValuesIter<'a>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a> From<&'a [(Key<'a>, Value<'a>)]> for KeyValues<'a> {
fn from(kvs: &'a [(Key<'a>, Value<'a>)]) -> Self {
Self(KeyValuesState::Borrowed(kvs))
}
}
impl<'a> From<&'a [(KeyOwned, ValueOwned)]> for KeyValues<'a> {
fn from(kvs: &'a [(KeyOwned, ValueOwned)]) -> Self {
Self(KeyValuesState::Owned(kvs))
}
}
pub struct KeyValuesIter<'a>(KeyValuesIterState<'a>);
enum KeyValuesIterState<'a> {
Borrowed(slice::Iter<'a, (Key<'a>, Value<'a>)>),
Owned(slice::Iter<'a, (KeyOwned, ValueOwned)>),
}
impl<'a> Iterator for KeyValuesIter<'a> {
type Item = (Key<'a>, Value<'a>);
fn next(&mut self) -> Option<Self::Item> {
match &mut self.0 {
KeyValuesIterState::Borrowed(iter) => iter.next().map(|(k, v)| (k.clone(), v.clone())),
KeyValuesIterState::Owned(iter) => iter.next().map(|(k, v)| (k.by_ref(), v.by_ref())),
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
match &self.0 {
KeyValuesIterState::Borrowed(iter) => iter.size_hint(),
KeyValuesIterState::Owned(iter) => iter.size_hint(),
}
}
}