mirror of
https://github.com/servo/servo.git
synced 2025-06-11 10:00:18 +00:00
* Add XPath parser/evaluator Signed-off-by: Ville Lindholm <ville@lindholm.dev> * Correctly annotate XPathEvaluator IDL Signed-off-by: Ville Lindholm <ville@lindholm.dev> * [PR review]: have bindings pass in `can_gc` Signed-off-by: Ville Lindholm <ville@lindholm.dev> * [PR review]: add docstrings Signed-off-by: Ville Lindholm <ville@lindholm.dev> * [PR review]: implement PartialEq for Value for readability Signed-off-by: Ville Lindholm <ville@lindholm.dev> * [PR review]: add docstrings for CoreFunctions Signed-off-by: Ville Lindholm <ville@lindholm.dev> * [PR review]: simplify node test code Signed-off-by: Ville Lindholm <ville@lindholm.dev> * [PR review]: add unit tests for string handling xpath functions Signed-off-by: Ville Lindholm <ville@lindholm.dev> * put xpath features behind dom.xpath.enabled pref Signed-off-by: Ville Lindholm <ville@lindholm.dev> * [PR review] remove rstest and insta dev-deps Signed-off-by: Ville Lindholm <ville@lindholm.dev> * update wpt test expectations Signed-off-by: Ville Lindholm <ville@lindholm.dev> * [PR review]: tweak metadata files Signed-off-by: Ville Lindholm <ville@lindholm.dev> * update wpt test expectations AGAIN Signed-off-by: Ville Lindholm <ville@lindholm.dev> --------- Signed-off-by: Ville Lindholm <ville@lindholm.dev>
73 lines
2.1 KiB
Rust
73 lines
2.1 KiB
Rust
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
|
|
use context::EvaluationCtx;
|
|
use eval::Evaluatable;
|
|
pub use eval_value::{NodesetHelpers, Value};
|
|
use parser::OwnedParserError;
|
|
pub use parser::{parse as parse_impl, Expr};
|
|
|
|
use super::dom::node::Node;
|
|
|
|
mod context;
|
|
mod eval;
|
|
mod eval_function;
|
|
mod eval_value;
|
|
mod parser;
|
|
|
|
/// The failure modes of executing an XPath.
|
|
#[derive(Debug, PartialEq)]
|
|
pub enum Error {
|
|
/// The XPath was syntactically invalid
|
|
Parsing { source: OwnedParserError },
|
|
/// The XPath could not be executed
|
|
Evaluating { source: eval::Error },
|
|
}
|
|
|
|
impl std::fmt::Display for Error {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
match self {
|
|
Error::Parsing { source } => write!(f, "Unable to parse XPath: {}", source),
|
|
Error::Evaluating { source } => write!(f, "Unable to evaluate XPath: {}", source),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl std::error::Error for Error {
|
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
|
match self {
|
|
Error::Parsing { source } => Some(source),
|
|
Error::Evaluating { source } => Some(source),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Parse an XPath expression from a string
|
|
pub fn parse(xpath: &str) -> Result<Expr, Error> {
|
|
match parse_impl(xpath) {
|
|
Ok(expr) => {
|
|
debug!("Parsed XPath: {:?}", expr);
|
|
Ok(expr)
|
|
},
|
|
Err(e) => {
|
|
debug!("Unable to parse XPath: {}", e);
|
|
Err(Error::Parsing { source: e })
|
|
},
|
|
}
|
|
}
|
|
|
|
/// Evaluate an already-parsed XPath expression
|
|
pub fn evaluate_parsed_xpath(expr: &Expr, context_node: &Node) -> Result<Value, Error> {
|
|
let context = EvaluationCtx::new(context_node);
|
|
match expr.evaluate(&context) {
|
|
Ok(v) => {
|
|
debug!("Evaluated XPath: {:?}", v);
|
|
Ok(v)
|
|
},
|
|
Err(e) => {
|
|
debug!("Unable to evaluate XPath: {}", e);
|
|
Err(Error::Evaluating { source: e })
|
|
},
|
|
}
|
|
}
|