use std::{fmt::Display, ops::Deref};
use crate::{
query::{
parser::{Parser, KEY_WRAP},
Error, QueryResult,
},
Any, Dapt, Path,
};
use super::Expression;
#[derive(Debug, Clone)]
pub struct PathExpression {
path: Path,
}
impl From<Path> for PathExpression {
fn from(path: Path) -> Self {
PathExpression { path }
}
}
impl PathExpression {
pub fn from_parser(parser: &mut Parser) -> QueryResult<Self> {
parser.consume_token(KEY_WRAP)?;
let key = match parser.token() {
Some(tok) => tok,
None => return Err(Error::unexpected_eof(parser.consumed())),
};
let path = Path::try_from(key.replace("\\\"", "\"").as_str())
.map_err(|e| Error::with_history(&e.to_string(), parser.consumed()))?;
match parser.token() {
Some(KEY_WRAP) => Ok(PathExpression { path }),
Some(tok) => Err(Error::with_history(
&format!("expected {KEY_WRAP} but got {tok}"),
parser.consumed(),
)),
None => Err(Error::unexpected_eof(parser.consumed())),
}
}
pub fn new(path: Path) -> Self {
PathExpression { path }
}
}
impl Deref for PathExpression {
type Target = Path;
fn deref(&self) -> &Self::Target {
&self.path
}
}
impl Expression for PathExpression {
fn evaluate<'a, 'b: 'a>(&'a self, d: &'a Dapt) -> Option<Any<'a>> {
d.any_path(self).ok()
}
}
impl Display for PathExpression {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "\"{}\"", format!("{}", self.path).replace("\"", "\\\""))
}
}