use ion_rs::Symbol;
use ion_rs::{Element, SExp, Sequence};
use std::fmt;
use std::fmt::{Debug, Formatter};
#[derive(Clone, PartialEq, PartialOrd, Eq, Hash)]
pub enum IonPathElement {
Index(usize),
Field(String),
}
impl fmt::Debug for IonPathElement {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self {
IonPathElement::Index(index) => {
write!(f, "{}", Element::from(*index as i64))
}
IonPathElement::Field(name) => {
write!(f, "{}", Element::from(Symbol::from(name.as_str())))
}
}
}
}
impl fmt::Display for IonPathElement {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
Debug::fmt(&self, f)
}
}
#[derive(Default, Clone, PartialEq, PartialOrd, Eq, Hash)]
pub struct IonPath {
ion_path_elements: Vec<IonPathElement>,
}
impl IonPath {
pub fn push(&mut self, parent: IonPathElement) {
self.ion_path_elements.push(parent);
}
pub fn pop(&mut self) -> Option<IonPathElement> {
self.ion_path_elements.pop()
}
pub(crate) fn new(ion_path_elements: Vec<IonPathElement>) -> Self {
Self { ion_path_elements }
}
}
impl From<IonPath> for Element {
fn from(value: IonPath) -> Element {
let mut ion_path_elements = vec![];
for parent in &value.ion_path_elements {
let element = match parent {
IonPathElement::Index(index) => Element::from(*index as i64),
IonPathElement::Field(name) => Element::from(Symbol::from(name.as_str())),
};
ion_path_elements.push(element);
}
SExp::from(Sequence::new(ion_path_elements)).into()
}
}
impl fmt::Debug for IonPath {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let ion_path_sexp: Element = self.to_owned().into();
write!(f, "{ion_path_sexp}")
}
}
impl fmt::Display for IonPath {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
Debug::fmt(&self, f)
}
}