[librsvg: 25/51] Introduce a ParseError type
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 25/51] Introduce a ParseError type
- Date: Thu, 19 Dec 2019 01:50:07 +0000 (UTC)
commit b72421e1e488fde07043e4a7fb53e704b11b1c7a
Author: Federico Mena Quintero <federico gnome org>
Date: Tue Dec 17 14:54:58 2019 -0600
Introduce a ParseError type
This is a type alias:
type ParseError<'i> = cssparser::ParseError<'i, ValueErrorKind>;
to represent short-lived errors.
We also impl AttributeResultExt for results with that error type, to
turn them into a long-lived NodeError.
rsvg_internals/src/css.rs | 5 ++-
rsvg_internals/src/error.rs | 85 ++++++++++++++++++++++++++++++++++-----------
2 files changed, 66 insertions(+), 24 deletions(-)
---
diff --git a/rsvg_internals/src/css.rs b/rsvg_internals/src/css.rs
index 0fe1503a..f2f2619e 100644
--- a/rsvg_internals/src/css.rs
+++ b/rsvg_internals/src/css.rs
@@ -265,7 +265,7 @@ impl<'i> AtRuleParser<'i> for RuleParser {
&mut self,
name: CowRcStr<'i>,
input: &mut Parser<'i, 't>,
- ) -> Result<AtRuleType<Self::PreludeNoBlock, Self::PreludeBlock>, ParseError<'i, Self::Error>>
+ ) -> Result<AtRuleType<Self::PreludeNoBlock, Self::PreludeBlock>, cssparser::ParseError<'i, Self::Error>>
{
match_ignore_ascii_case! { &name,
"import" => {
@@ -588,8 +588,7 @@ impl<'a> PartialOrd for Match<'a> {
impl<'a> PartialEq for Match<'a> {
fn eq(&self, other: &Self) -> bool {
- self.origin == other.origin
- && self.specificity == other.specificity
+ self.origin == other.origin && self.specificity == other.specificity
}
}
diff --git a/rsvg_internals/src/error.rs b/rsvg_internals/src/error.rs
index 5e558e5e..2ca560e7 100644
--- a/rsvg_internals/src/error.rs
+++ b/rsvg_internals/src/error.rs
@@ -4,13 +4,24 @@ use std::error::{self, Error};
use std::fmt;
use cairo;
-use cssparser::{BasicParseError, BasicParseErrorKind};
+use cssparser::{self, BasicParseError, BasicParseErrorKind, ParseErrorKind, ToCss};
use glib;
use markup5ever::QualName;
use crate::allowed_url::Fragment;
use crate::node::RsvgNode;
+/// A short-lived error.
+///
+/// The lifetime of the error is the same as the `cssparser::ParserInput` that
+/// was used to create a `cssparser::Parser`. That is, it is the lifetime of
+/// the string data that is being parsed.
+///
+/// The code flow will sometimes require preserving this error as a long-lived struct;
+/// see the `impl<'i, O> AttributeResultExt<O> for Result<O, ParseError<'i>>` for that
+/// purpose.
+pub type ParseError<'i> = cssparser::ParseError<'i, ValueErrorKind>;
+
/// A simple error which refers to an attribute's value
#[derive(Debug, Clone, PartialEq)]
pub enum ValueErrorKind {
@@ -39,17 +50,9 @@ impl fmt::Display for ValueErrorKind {
match *self {
ValueErrorKind::UnknownProperty => write!(f, "unknown property name"),
- ValueErrorKind::Parse(ref s) => write!(
- f,
- "parse error: {}",
- s
- ),
-
- ValueErrorKind::Value(ref s) => write!(
- f,
- "invalid value: {}",
- s
- ),
+ ValueErrorKind::Parse(ref s) => write!(f, "parse error: {}", s),
+
+ ValueErrorKind::Value(ref s) => write!(f, "invalid value: {}", s),
}
}
}
@@ -79,7 +82,7 @@ impl fmt::Display for NodeError {
impl<'a> From<BasicParseError<'a>> for ValueErrorKind {
fn from(e: BasicParseError<'_>) -> ValueErrorKind {
- let BasicParseError { kind, location: _ } = e;
+ let BasicParseError { kind, location: _ } = e;
let msg = match kind {
BasicParseErrorKind::UnexpectedToken(_) => "unexpected token",
@@ -129,17 +132,19 @@ pub enum AcquireError {
impl fmt::Display for AcquireError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
- AcquireError::LinkNotFound(ref frag) =>
- write!(f, "link not found: {}", frag),
+ AcquireError::LinkNotFound(ref frag) => write!(f, "link not found: {}", frag),
- AcquireError::InvalidLinkType(ref frag) =>
- write!(f, "link {} is to object of invalid type", frag),
+ AcquireError::InvalidLinkType(ref frag) => {
+ write!(f, "link {} is to object of invalid type", frag)
+ }
- AcquireError::CircularReference(ref node) =>
- write!(f, "circular reference in node {}", node),
+ AcquireError::CircularReference(ref node) => {
+ write!(f, "circular reference in node {}", node)
+ }
- AcquireError::MaxReferencesExceeded =>
- write!(f, "maximum number of references exceeded"),
+ AcquireError::MaxReferencesExceeded => {
+ write!(f, "maximum number of references exceeded")
+ }
}
}
}
@@ -176,6 +181,44 @@ impl<O, E: Into<ValueErrorKind>> AttributeResultExt<O> for Result<O, E> {
}
}
+/// Turns a short-lived `ParseError` into a long-lived `NodeError`
+impl<'i, O> AttributeResultExt<O> for Result<O, ParseError<'i>> {
+ fn attribute(self, attr: QualName) -> Result<O, NodeError> {
+ self.map_err(|e| {
+ // FIXME: eventually, here we'll want to preserve the location information
+
+ let ParseError {
+ kind,
+ location: _location,
+ } = e;
+
+ match kind {
+ ParseErrorKind::Basic(BasicParseErrorKind::UnexpectedToken(tok)) => {
+ let mut s = String::from("unexpected token '");
+ tok.to_css(&mut s).unwrap(); // FIXME: what do we do with a fmt::Error?
+ s.push_str("'");
+
+ NodeError {
+ attr,
+ err: ValueErrorKind::Parse(s),
+ }
+ },
+
+ ParseErrorKind::Basic(BasicParseErrorKind::EndOfInput) => NodeError {
+ attr,
+ err: ValueErrorKind::parse_error("unexpected end of input"),
+ },
+
+ ParseErrorKind::Basic(_) => unreachable!(
+ "attribute parsers should not return errors for CSS rules"
+ ),
+
+ ParseErrorKind::Custom(err) => NodeError { attr, err },
+ }
+ })
+ }
+}
+
/// Errors returned when creating an `Href` out of a string
#[derive(Debug, Clone, PartialEq)]
pub enum HrefError {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]