use std::borrow::Borrow;
use std::fmt::{self, Display, Formatter};
use std::iter::{Extend, FromIterator};
use std::ops::Deref;
use std::slice::Iter;
use std::str::FromStr;
use serde::de::{Deserialize, Deserializer};
use serde::ser::{Serialize, Serializer};
use error::Error;
use sealed::Sealed;
use value::{Key, Stringify};
#[derive(Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Path(Vec<Key>);
impl Path {
pub fn new() -> Self {
Default::default()
}
pub fn with_capacity(capacity: usize) -> Self {
Path(Vec::with_capacity(capacity))
}
pub fn capacity(&self) -> usize {
self.0.capacity()
}
pub fn char_count(&self) -> usize {
let keys = &self.0;
let count = keys.len();
if count > 0 {
keys.iter()
.map(|key| key.len())
.fold(count - 1, |prev, next| prev + next)
} else {
count
}
}
pub fn pop(&mut self) -> Option<Key> {
self.0.pop()
}
pub fn push(&mut self, key: Key) {
self.0.push(key);
}
pub fn reserve(&mut self, additional: usize) {
self.0.reserve(additional);
}
pub fn reserve_exact(&mut self, additional: usize) {
self.0.reserve_exact(additional);
}
pub fn shrink_to_fit(&mut self) {
self.0.shrink_to_fit();
}
}
impl AsRef<[Key]> for Path {
fn as_ref(&self) -> &[Key] {
self
}
}
impl Borrow<[Key]> for Path {
fn borrow(&self) -> &[Key] {
self
}
}
impl Deref for Path {
type Target = [Key];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Display for Path {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
f.write_str(&self.stringify())
}
}
impl Extend<Key> for Path {
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = Key>,
{
self.0.extend(iter);
}
}
impl<'a> Extend<&'a Key> for Path {
fn extend<I>(&mut self, iter: I)
where
I: IntoIterator<Item = &'a Key>,
{
self.extend(iter.into_iter().cloned());
}
}
impl From<Path> for String {
fn from(path: Path) -> Self {
path.stringify()
}
}
impl From<Path> for Vec<u8> {
fn from(path: Path) -> Self {
path.to_bytes()
}
}
impl FromIterator<Key> for Path {
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = Key>,
{
Path(Vec::from_iter(iter))
}
}
impl FromStr for Path {
type Err = Error;
fn from_str(value: &str) -> Result<Self, Self::Err> {
value.split('.').map(Key::from_str).collect()
}
}
impl IntoIterator for Path {
type Item = Key;
type IntoIter = <Vec<Key> as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<'a> IntoIterator for &'a Path {
type Item = &'a Key;
type IntoIter = Iter<'a, Key>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl PartialEq<str> for Path {
fn eq(&self, rhs: &str) -> bool {
let mut parts = rhs.split('.');
for part in self.iter().map(|key| Some(&**key)) {
if part != parts.next() {
return false;
}
}
parts.next().is_none()
}
}
impl<'a> PartialEq<&'a str> for Path {
fn eq(&self, rhs: &&str) -> bool {
self == *rhs
}
}
impl PartialEq<String> for Path {
fn eq(&self, rhs: &String) -> bool {
self == &*rhs
}
}
impl<'de> Deserialize<'de> for Path {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
use serde::de::{Error, Visitor};
struct PathVisitor;
impl<'de> Visitor<'de> for PathVisitor {
type Value = Path;
fn expecting(&self, f: &mut Formatter) -> fmt::Result {
f.write_str(r#"a string of json api member names, separated by a ".""#)
}
fn visit_str<E: Error>(self, value: &str) -> Result<Self::Value, E> {
value.parse().map_err(Error::custom)
}
}
deserializer.deserialize_str(PathVisitor)
}
}
impl Serialize for Path {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&self.stringify())
}
}
impl Sealed for Path {}
impl Stringify for Path {
fn to_bytes(&self) -> Vec<u8> {
let mut bytes = match self.char_count() {
0 => return Default::default(),
len => Vec::with_capacity(len),
};
for key in self {
if !bytes.is_empty() {
bytes.push(b'.');
}
bytes.append(&mut key.to_bytes());
}
bytes
}
}
pub trait Segment<T> {
fn join(&self, other: T) -> Path;
}
impl Segment<Key> for Key {
fn join(&self, other: Key) -> Path {
let mut path = Path::with_capacity(2);
path.push(self.clone());
path.push(other);
path
}
}
impl<'a> Segment<&'a Key> for Key {
fn join(&self, other: &Key) -> Path {
self.join(other.clone())
}
}
impl<'a, T> Segment<T> for Key
where
T: IntoIterator<Item = &'a Key>,
{
fn join(&self, other: T) -> Path {
let iter = other.into_iter();
let mut path = match iter.size_hint() {
(_, Some(size)) => Path::with_capacity(size + 1),
_ => Path::new(),
};
path.push(self.clone());
path.extend(iter);
path
}
}
impl Segment<Key> for Path {
fn join(&self, other: Key) -> Path {
let mut path = Path::with_capacity(self.len() + 1);
path.extend(self);
path.push(other);
path
}
}
impl<'a> Segment<&'a Key> for Path {
fn join(&self, other: &Key) -> Path {
self.join(other.clone())
}
}
impl<'a, T> Segment<T> for Path
where
T: IntoIterator<Item = &'a Key>,
{
fn join(&self, other: T) -> Path {
let iter = other.into_iter();
let mut path = match iter.size_hint() {
(_, Some(size)) => Path::with_capacity(self.len() + size),
_ => Path::new(),
};
path.extend(self);
path.extend(iter);
path
}
}