use std::array;
use std::borrow::{Borrow, BorrowMut};
use std::iter;
use std::ops::{Deref, DerefMut};
use std::{mem, slice};
use crate::count_repetition;
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum ElementSelector {
Branch(bool),
Block(usize),
}
impl ElementSelector {
#[inline]
pub fn as_path(&self) -> &ElementPath {
ElementPath::from_slice(slice::from_ref(self))
}
#[inline]
pub fn as_mut_path(&mut self) -> &mut ElementPath {
ElementPath::from_mut_slice(slice::from_mut(self))
}
pub fn unwrap_branch(self) -> bool {
match self {
ElementSelector::Branch(cond) => cond,
ElementSelector::Block(_) => panic!("Not a Branch Selector"),
}
}
pub fn unwrap_block(self) -> usize {
match self {
ElementSelector::Block(idx) => idx,
ElementSelector::Branch(_) => panic!("Not a Block Selector"),
}
}
pub fn unwrap_branch_mut(&mut self) -> &mut bool {
match self {
ElementSelector::Branch(cond) => cond,
ElementSelector::Block(_) => panic!("Not a Branch Selector"),
}
}
pub fn unwrap_block_mut(&mut self) -> &mut usize {
match self {
ElementSelector::Block(idx) => idx,
ElementSelector::Branch(_) => panic!("Not a Block Selector"),
}
}
}
impl From<bool> for ElementSelector {
#[inline]
fn from(cond: bool) -> Self {
Self::Branch(cond)
}
}
impl From<usize> for ElementSelector {
#[inline]
fn from(index: usize) -> Self {
Self::Block(index)
}
}
impl Borrow<ElementPath> for ElementSelector {
#[inline]
fn borrow(&self) -> &ElementPath {
self.as_path()
}
}
impl BorrowMut<ElementPath> for ElementSelector {
#[inline]
fn borrow_mut(&mut self) -> &mut ElementPath {
self.as_mut_path()
}
}
impl ElementIndex for ElementSelector {
type PathSelectors = iter::Once<Self>;
#[inline]
fn path_selectors(self) -> Self::PathSelectors {
iter::once(self)
}
}
#[derive(Debug, Default, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[repr(transparent)]
pub struct ElementPathBuf {
path: Vec<ElementSelector>,
}
impl ElementPathBuf {
#[inline]
pub fn new() -> Self {
Default::default()
}
pub fn from_path(path: &ElementPath) -> Self {
Self {
path: path.as_slice().to_vec(),
}
}
#[inline]
pub fn as_path(&self) -> &ElementPath {
ElementPath::from_slice(&self.path)
}
#[inline]
pub fn as_mut_path(&mut self) -> &mut ElementPath {
ElementPath::from_mut_slice(&mut self.path)
}
#[inline]
pub fn push<S>(&mut self, selector: S)
where
S: Into<ElementSelector>,
{
self.path.push(selector.into());
}
#[inline]
pub fn append<P>(&mut self, path: P)
where
P: ElementIndex,
{
self.path.extend(path.path_selectors())
}
#[inline]
pub fn pop(&mut self) -> Option<ElementSelector> {
self.path.pop()
}
}
impl Deref for ElementPathBuf {
type Target = ElementPath;
#[inline]
fn deref(&self) -> &Self::Target {
self.as_path()
}
}
impl DerefMut for ElementPathBuf {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
self.as_mut_path()
}
}
impl Borrow<ElementPath> for ElementPathBuf {
#[inline]
fn borrow(&self) -> &ElementPath {
self.as_path()
}
}
impl BorrowMut<ElementPath> for ElementPathBuf {
#[inline]
fn borrow_mut(&mut self) -> &mut ElementPath {
self.as_mut_path()
}
}
impl AsRef<ElementPath> for ElementPathBuf {
#[inline]
fn as_ref(&self) -> &ElementPath {
self.as_path()
}
}
impl AsMut<ElementPath> for ElementPathBuf {
#[inline]
fn as_mut(&mut self) -> &mut ElementPath {
self.as_mut_path()
}
}
impl AsRef<[ElementSelector]> for ElementPathBuf {
#[inline]
fn as_ref(&self) -> &[ElementSelector] {
self.as_slice()
}
}
impl AsMut<[ElementSelector]> for ElementPathBuf {
#[inline]
fn as_mut(&mut self) -> &mut [ElementSelector] {
self.as_mut_slice()
}
}
impl IntoIterator for ElementPathBuf {
type IntoIter = std::vec::IntoIter<ElementSelector>;
type Item = ElementSelector;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.path.into_iter()
}
}
impl<'p> IntoIterator for &'p ElementPathBuf {
type IntoIter = slice::Iter<'p, ElementSelector>;
type Item = &'p ElementSelector;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'p> IntoIterator for &'p mut ElementPathBuf {
type IntoIter = slice::IterMut<'p, ElementSelector>;
type Item = &'p mut ElementSelector;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl PartialEq<ElementPath> for ElementPathBuf {
#[inline]
fn eq(&self, other: &ElementPath) -> bool {
self.as_path() == other
}
}
impl PartialEq<&ElementPath> for ElementPathBuf {
#[inline]
fn eq(&self, other: &&ElementPath) -> bool {
self.as_path() == *other
}
}
impl PartialEq<&mut ElementPath> for ElementPathBuf {
#[inline]
fn eq(&self, other: &&mut ElementPath) -> bool {
self.as_path() == *other
}
}
impl<'p> ElementIndex for ElementPathBuf {
type PathSelectors = std::vec::IntoIter<ElementSelector>;
#[inline]
fn path_selectors(self) -> Self::PathSelectors {
self.into_iter()
}
}
impl<'p> ElementIndex for &'p ElementPathBuf {
type PathSelectors = iter::Copied<slice::Iter<'p, ElementSelector>>;
#[inline]
fn path_selectors(self) -> Self::PathSelectors {
self.iter().copied()
}
}
impl<'p> ElementIndex for &'p mut ElementPathBuf {
type PathSelectors = iter::Copied<slice::Iter<'p, ElementSelector>>;
#[inline]
fn path_selectors(self) -> Self::PathSelectors {
self.iter().copied()
}
}
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[repr(transparent)]
pub struct ElementPath {
path: [ElementSelector],
}
impl ElementPath {
pub const EMPTY: &ElementPath = ElementPath::from_slice(&[]);
#[inline]
pub const fn from_slice<'p>(slice: &'p [ElementSelector]) -> &'p Self {
unsafe { mem::transmute(slice) }
}
#[inline]
pub fn from_mut_slice<'p>(slice: &'p mut [ElementSelector]) -> &'p mut Self {
unsafe { mem::transmute(slice) }
}
#[inline]
pub const fn len(&self) -> usize {
self.path.len()
}
#[inline]
pub fn to_buf(&self) -> ElementPathBuf {
ElementPathBuf::from_path(self)
}
#[inline]
pub const fn as_slice(&self) -> &[ElementSelector] {
&self.path
}
#[inline]
pub fn as_mut_slice(&mut self) -> &mut [ElementSelector] {
&mut self.path
}
#[inline]
pub fn iter(&self) -> slice::Iter<ElementSelector> {
self.as_slice().iter()
}
#[inline]
pub fn iter_mut(&mut self) -> slice::IterMut<ElementSelector> {
self.as_mut_slice().iter_mut()
}
pub const fn parent(&self) -> Option<&ElementPath> {
match self.path.split_last() {
Some((_, head)) => Some(ElementPath::from_slice(head)),
None => None,
}
}
#[inline]
pub const fn last(&self) -> Option<ElementSelector> {
match self.path.last() {
Some(last) => Some(*last),
None => None,
}
}
#[inline]
pub fn last_mut(&mut self) -> Option<&mut ElementSelector> {
self.path.last_mut()
}
}
impl AsRef<[ElementSelector]> for ElementPath {
#[inline]
fn as_ref(&self) -> &[ElementSelector] {
self.as_slice()
}
}
impl AsMut<[ElementSelector]> for ElementPath {
#[inline]
fn as_mut(&mut self) -> &mut [ElementSelector] {
self.as_mut_slice()
}
}
impl ToOwned for ElementPath {
type Owned = ElementPathBuf;
#[inline]
fn to_owned(&self) -> Self::Owned {
self.to_buf()
}
}
impl<'p> IntoIterator for &'p ElementPath {
type IntoIter = slice::Iter<'p, ElementSelector>;
type Item = &'p ElementSelector;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'p> IntoIterator for &'p mut ElementPath {
type IntoIter = slice::IterMut<'p, ElementSelector>;
type Item = &'p mut ElementSelector;
#[inline]
fn into_iter(self) -> Self::IntoIter {
self.iter_mut()
}
}
impl<'p> ElementIndex for &'p ElementPath {
type PathSelectors = iter::Copied<slice::Iter<'p, ElementSelector>>;
#[inline]
fn path_selectors(self) -> Self::PathSelectors {
self.iter().copied()
}
}
impl<'p> ElementIndex for &'p mut ElementPath {
type PathSelectors = iter::Copied<slice::Iter<'p, ElementSelector>>;
#[inline]
fn path_selectors(self) -> Self::PathSelectors {
self.iter().copied()
}
}
impl PartialEq<ElementPathBuf> for ElementPath {
#[inline]
fn eq(&self, other: &ElementPathBuf) -> bool {
self == other.as_path()
}
}
impl PartialEq<ElementPathBuf> for &ElementPath {
#[inline]
fn eq(&self, other: &ElementPathBuf) -> bool {
*self == other.as_path()
}
}
impl PartialEq<ElementPathBuf> for &mut ElementPath {
#[inline]
fn eq(&self, other: &ElementPathBuf) -> bool {
*self == other.as_path()
}
}
pub trait ElementIndex {
type PathSelectors: Iterator<Item = ElementSelector>
+ DoubleEndedIterator
+ ExactSizeIterator
+ iter::FusedIterator;
fn path_selectors(self) -> Self::PathSelectors;
}
impl ElementIndex for bool {
type PathSelectors = iter::Once<ElementSelector>;
#[inline]
fn path_selectors(self) -> Self::PathSelectors {
ElementSelector::from(self).path_selectors()
}
}
impl ElementIndex for usize {
type PathSelectors = iter::Once<ElementSelector>;
#[inline]
fn path_selectors(self) -> Self::PathSelectors {
ElementSelector::from(self).path_selectors()
}
}
macro_rules! tuple_element_index {
($($t:ident),* $(,)?) => {
impl<$($t),*> ElementIndex for ($($t,)*)
where $($t: Into<ElementSelector>,)*
{
type PathSelectors = array::IntoIter<ElementSelector, {count_repetition!($($t,)*)}>;
fn path_selectors(self) -> Self::PathSelectors {
#[allow(non_snake_case)]
let ($($t,)*) = self;
[$($t.into(),)*].into_iter()
}
}
};
}
tuple_element_index!();
tuple_element_index!(A);
tuple_element_index!(A, B);
tuple_element_index!(A, B, C);
tuple_element_index!(A, B, C, D);
tuple_element_index!(A, B, C, D, E);
tuple_element_index!(A, B, C, D, E, F);
tuple_element_index!(A, B, C, D, E, F, G);
tuple_element_index!(A, B, C, D, E, F, G, H);
tuple_element_index!(A, B, C, D, E, F, G, H, I);
tuple_element_index!(A, B, C, D, E, F, G, H, I, J);