[librsvg: 17/18] Get rid of ParseError; only use ValueErrorKind



commit 2c4ebf3b669a9145fabeecd5c1e228ebbf5cde52
Author: Federico Mena Quintero <federico gnome org>
Date:   Fri Dec 6 20:35:12 2019 -0600

    Get rid of ParseError; only use ValueErrorKind

 rsvg_internals/src/angle.rs                      | 14 ++++------
 rsvg_internals/src/aspect_ratio.rs               | 11 ++++----
 rsvg_internals/src/color.rs                      |  7 ++---
 rsvg_internals/src/cond.rs                       | 14 ++++------
 rsvg_internals/src/coord_units.rs                |  6 ++--
 rsvg_internals/src/error.rs                      | 35 +++++++++++++-----------
 rsvg_internals/src/filter.rs                     | 10 +++----
 rsvg_internals/src/filters/blend.rs              |  6 +---
 rsvg_internals/src/filters/color_matrix.rs       | 33 ++++++++++------------
 rsvg_internals/src/filters/component_transfer.rs |  9 ++----
 rsvg_internals/src/filters/convolve_matrix.rs    | 29 ++++++--------------
 rsvg_internals/src/filters/displacement_map.rs   |  7 ++---
 rsvg_internals/src/filters/image.rs              |  4 +--
 rsvg_internals/src/filters/input.rs              |  6 +---
 rsvg_internals/src/filters/mod.rs                | 10 +++----
 rsvg_internals/src/filters/morphology.rs         |  7 ++---
 rsvg_internals/src/filters/turbulence.rs         | 12 ++------
 rsvg_internals/src/font_props.rs                 | 16 ++++-------
 rsvg_internals/src/gradient.rs                   |  4 +--
 rsvg_internals/src/image.rs                      |  4 +--
 rsvg_internals/src/iri.rs                        | 10 +++++--
 rsvg_internals/src/length.rs                     | 10 +++----
 rsvg_internals/src/marker.rs                     |  6 ++--
 rsvg_internals/src/number_list.rs                |  6 ++--
 rsvg_internals/src/parsers.rs                    | 15 +---------
 rsvg_internals/src/property_defs.rs              | 16 +++++------
 rsvg_internals/src/property_macros.rs            |  4 +--
 rsvg_internals/src/style.rs                      |  6 ++--
 rsvg_internals/src/transform.rs                  |  6 ++--
 rsvg_internals/src/unit_interval.rs              |  4 +--
 rsvg_internals/src/viewbox.rs                    | 12 ++++----
 31 files changed, 136 insertions(+), 203 deletions(-)
---
diff --git a/rsvg_internals/src/angle.rs b/rsvg_internals/src/angle.rs
index d91db743..7343b628 100644
--- a/rsvg_internals/src/angle.rs
+++ b/rsvg_internals/src/angle.rs
@@ -3,7 +3,7 @@ use std::f64::consts::*;
 use cssparser::{Parser, Token};
 
 use crate::error::ValueErrorKind;
-use crate::parsers::{finite_f32, Parse, ParseError};
+use crate::parsers::{finite_f32, Parse};
 
 #[derive(Debug, Copy, Clone, PartialEq)]
 pub struct Angle(f64);
@@ -62,9 +62,7 @@ impl Angle {
 impl Parse for Angle {
     fn parse(parser: &mut Parser<'_, '_>) -> Result<Angle, ValueErrorKind> {
         let angle = {
-            let token = parser
-                .next()
-                .map_err(|_| ParseError::new("expected angle"))?;
+            let token = parser.next()?;
 
             match *token {
                 Token::Number { value, .. } => {
@@ -82,20 +80,20 @@ impl Parse for Angle {
                         "grad" => Angle::from_degrees(value * 360.0 / 400.0),
                         "rad" => Angle::new(value),
                         _ => {
-                            return Err(ValueErrorKind::Parse(ParseError::new(
+                            return Err(ValueErrorKind::parse_error(
                                 "expected 'deg' | 'grad' | 'rad'",
-                            )));
+                            ));
                         }
                     }
                 }
 
-                _ => return Err(ValueErrorKind::Parse(ParseError::new("expected angle"))),
+                _ => return Err(ValueErrorKind::parse_error("expected angle")),
             }
         };
 
         parser
             .expect_exhausted()
-            .map_err(|_| ValueErrorKind::Parse(ParseError::new("expected angle")))?;
+            .map_err(|_| ValueErrorKind::parse_error("expected angle"))?;
 
         Ok(angle)
     }
diff --git a/rsvg_internals/src/aspect_ratio.rs b/rsvg_internals/src/aspect_ratio.rs
index 43a4851f..a42362d0 100644
--- a/rsvg_internals/src/aspect_ratio.rs
+++ b/rsvg_internals/src/aspect_ratio.rs
@@ -27,7 +27,6 @@ use cairo;
 use crate::error::ValueErrorKind;
 use crate::float_eq_cairo::ApproxEqCairo;
 use crate::parsers::Parse;
-use crate::parsers::ParseError;
 use crate::viewbox::ViewBox;
 use cssparser::{CowRcStr, Parser};
 
@@ -206,7 +205,7 @@ fn parse_align_xy(ident: &CowRcStr) -> Result<Option<(X, Y)>, ValueErrorKind> {
         "xMidYMax" => Ok(Some((X(Mid), Y(Max)))),
         "xMaxYMax" => Ok(Some((X(Max), Y(Max)))),
 
-        _ => Err(ValueErrorKind::Parse(ParseError::new("invalid alignment"))),
+        _ => Err(ValueErrorKind::parse_error("invalid alignment")),
     }
 }
 
@@ -214,7 +213,7 @@ fn parse_fit_mode(s: &str) -> Result<FitMode, ValueErrorKind> {
     match s {
         "meet" => Ok(FitMode::Meet),
         "slice" => Ok(FitMode::Slice),
-        _ => Err(ValueErrorKind::Parse(ParseError::new("invalid fit mode"))),
+        _ => Err(ValueErrorKind::parse_error("invalid fit mode")),
     }
 }
 
@@ -226,21 +225,21 @@ impl Parse for AspectRatio {
 
         let align_xy = parser.try_parse(|p| {
             p.expect_ident()
-                .map_err(|_| ValueErrorKind::Parse(ParseError::new("expected identifier")))
+                .map_err(|_| ValueErrorKind::parse_error("expected identifier"))
                 .and_then(|ident| parse_align_xy(ident))
         })?;
 
         let fit = parser
             .try_parse(|p| {
                 p.expect_ident()
-                    .map_err(|_| ValueErrorKind::Parse(ParseError::new("expected identifier")))
+                    .map_err(|_| ValueErrorKind::parse_error("expected identifier"))
                     .and_then(|ident| parse_fit_mode(ident))
             })
             .unwrap_or_default();
 
         parser
             .expect_exhausted()
-            .map_err(|_| ValueErrorKind::Parse(ParseError::new("extra data in AspectRatio")))?;
+            .map_err(|_| ValueErrorKind::parse_error("extra data in AspectRatio"))?;
 
         let align = align_xy.map(|(x, y)| Align { x, y, fit });
 
diff --git a/rsvg_internals/src/color.rs b/rsvg_internals/src/color.rs
index 75780792..da7fbbb0 100644
--- a/rsvg_internals/src/color.rs
+++ b/rsvg_internals/src/color.rs
@@ -3,7 +3,6 @@ use libc;
 
 use crate::error::*;
 use crate::parsers::Parse;
-use crate::parsers::ParseError;
 use crate::util::utf8_cstr;
 
 pub use cssparser::Color;
@@ -11,7 +10,7 @@ pub use cssparser::Color;
 impl Parse for cssparser::Color {
     fn parse(parser: &mut Parser<'_, '_>) -> Result<cssparser::Color, ValueErrorKind> {
         cssparser::Color::parse(parser)
-            .map_err(|_| ValueErrorKind::Parse(ParseError::new("invalid syntax for color")))
+            .map_err(|_| ValueErrorKind::parse_error("invalid syntax for color"))
     }
 }
 
@@ -22,9 +21,7 @@ impl Parse for cssparser::RGBA {
             Ok(cssparser::Color::CurrentColor) => Err(ValueErrorKind::Value(
                 "currentColor is not allowed here".to_string(),
             )),
-            _ => Err(ValueErrorKind::Parse(ParseError::new(
-                "invalid syntax for color",
-            ))),
+            _ => Err(ValueErrorKind::parse_error("invalid syntax for color")),
         }
     }
 }
diff --git a/rsvg_internals/src/cond.rs b/rsvg_internals/src/cond.rs
index 8bbf1cb8..76875856 100644
--- a/rsvg_internals/src/cond.rs
+++ b/rsvg_internals/src/cond.rs
@@ -7,7 +7,6 @@ use language_tags::LanguageTag;
 use locale_config::{LanguageRange, Locale};
 
 use crate::error::*;
-use crate::parsers::ParseError;
 
 // No extensions at the moment.
 static IMPLEMENTED_EXTENSIONS: &[&str] = &[];
@@ -100,10 +99,9 @@ impl SystemLanguage {
                     }
                 }
 
-                Err(e) => Err(ValueErrorKind::Parse(ParseError::new(&format!(
-                    "invalid language tag: \"{}\"",
-                    e
-                )))),
+                Err(e) => Err(ValueErrorKind::parse_error(&format!(
+                    "invalid language tag: \"{}\"", e)
+                )),
             },
         )
     }
@@ -121,14 +119,14 @@ fn locale_accepts_language_tag(
         let str_locale_range = locale_range.as_ref();
 
         let locale_tag = LanguageTag::from_str(str_locale_range).map_err(|e| {
-            ValueErrorKind::Parse(ParseError::new(&format!(
+            ValueErrorKind::parse_error(&format!(
                 "invalid language tag \"{}\" in locale: {}",
                 str_locale_range, e
-            )))
+            ))
         })?;
 
         if !locale_tag.is_language_range() {
-            return Err(ValueErrorKind::Value(format!(
+            return Err(ValueErrorKind::value_error(&format!(
                 "language tag \"{}\" is not a language range",
                 locale_tag
             )));
diff --git a/rsvg_internals/src/coord_units.rs b/rsvg_internals/src/coord_units.rs
index b550ceb3..fd4a3655 100644
--- a/rsvg_internals/src/coord_units.rs
+++ b/rsvg_internals/src/coord_units.rs
@@ -1,7 +1,7 @@
 use cssparser::{CowRcStr, Parser, Token};
 
 use crate::error::ValueErrorKind;
-use crate::parsers::{Parse, ParseError};
+use crate::parsers::Parse;
 
 /// Defines the units to be used for things that can consider a
 /// coordinate system in terms of the current transformation, or in
@@ -28,9 +28,7 @@ impl Parse for CoordUnits {
                 ),
             })
             .map_err(|_| {
-                ValueErrorKind::Parse(ParseError::new(
-                    "expected 'userSpaceOnUse' or 'objectBoundingBox'",
-                ))
+                ValueErrorKind::parse_error("expected 'userSpaceOnUse' or 'objectBoundingBox'")
             })
     }
 }
diff --git a/rsvg_internals/src/error.rs b/rsvg_internals/src/error.rs
index 5a76758d..ae55c6b8 100644
--- a/rsvg_internals/src/error.rs
+++ b/rsvg_internals/src/error.rs
@@ -8,7 +8,6 @@ use markup5ever::QualName;
 
 use crate::allowed_url::Fragment;
 use crate::node::RsvgNode;
-use crate::parsers::ParseError;
 
 /// A simple error which refers to an attribute's value
 #[derive(Debug, Clone, PartialEq)]
@@ -17,21 +16,31 @@ pub enum ValueErrorKind {
     UnknownProperty,
 
     /// The value could not be parsed
-    Parse(ParseError),
+    Parse(String),
 
     // The value could be parsed, but is invalid
     Value(String),
 }
 
+impl ValueErrorKind {
+    pub fn parse_error(s: &str) -> ValueErrorKind {
+        ValueErrorKind::Parse(s.to_string())
+    }
+
+    pub fn value_error(s: &str) -> ValueErrorKind {
+        ValueErrorKind::Value(s.to_string())
+    }
+}
+
 impl fmt::Display for ValueErrorKind {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match *self {
             ValueErrorKind::UnknownProperty => write!(f, "unknown property name"),
 
-            ValueErrorKind::Parse(ref n) => write!(
+            ValueErrorKind::Parse(ref s) => write!(
                 f,
                 "parse error: {}",
-                n.display
+                s
             ),
 
             ValueErrorKind::Value(ref s) => write!(
@@ -55,10 +64,10 @@ impl NodeError {
         NodeError { attr, err: error }
     }
 
-    pub fn parse_error(attr: QualName, error: ParseError) -> NodeError {
+    pub fn parse_error(attr: QualName, error: &str) -> NodeError {
         NodeError {
             attr,
-            err: ValueErrorKind::Parse(error),
+            err: ValueErrorKind::Parse(error.to_string()),
         }
     }
 
@@ -86,12 +95,6 @@ impl fmt::Display for NodeError {
     }
 }
 
-impl From<ParseError> for ValueErrorKind {
-    fn from(pe: ParseError) -> ValueErrorKind {
-        ValueErrorKind::Parse(pe)
-    }
-}
-
 impl<'a> From<BasicParseError<'a>> for ValueErrorKind {
     fn from(e: BasicParseError<'_>) -> ValueErrorKind {
         let BasicParseError { kind, location: _ } =  e;
@@ -104,7 +107,7 @@ impl<'a> From<BasicParseError<'a>> for ValueErrorKind {
             BasicParseErrorKind::QualifiedRuleInvalid => "invalid qualified rule",
         };
 
-        ValueErrorKind::Parse(ParseError::new(msg))
+        ValueErrorKind::parse_error(msg)
     }
 }
 
@@ -212,12 +215,12 @@ pub enum HrefError {
 impl From<HrefError> for ValueErrorKind {
     fn from(e: HrefError) -> ValueErrorKind {
         match e {
-            HrefError::ParseError => ValueErrorKind::Parse(ParseError::new("url parse error")),
+            HrefError::ParseError => ValueErrorKind::parse_error("url parse error"),
             HrefError::FragmentForbidden => {
-                ValueErrorKind::Value("fragment identifier not allowed".to_string())
+                ValueErrorKind::value_error("fragment identifier not allowed")
             }
             HrefError::FragmentRequired => {
-                ValueErrorKind::Value("fragment identifier required".to_string())
+                ValueErrorKind::value_error("fragment identifier required")
             }
         }
     }
diff --git a/rsvg_internals/src/filter.rs b/rsvg_internals/src/filter.rs
index a1494fe4..a1779740 100644
--- a/rsvg_internals/src/filter.rs
+++ b/rsvg_internals/src/filter.rs
@@ -7,7 +7,7 @@ use crate::drawing_ctx::DrawingCtx;
 use crate::error::ValueErrorKind;
 use crate::length::*;
 use crate::node::{NodeResult, NodeTrait, RsvgNode};
-use crate::parsers::{Parse, ParseError, ParseValue};
+use crate::parsers::{Parse, ParseValue};
 use crate::properties::ComputedValues;
 use crate::property_bag::PropertyBag;
 
@@ -131,9 +131,9 @@ impl NodeTrait for Filter {
 
             match length.unit {
                 LengthUnit::Px | LengthUnit::Percent => Ok(length),
-                _ => Err(ValueErrorKind::Parse(ParseError::new(
+                _ => Err(ValueErrorKind::parse_error(
                     "unit identifiers are not allowed with filterUnits set to objectBoundingBox",
-                ))),
+                )),
             }
         };
 
@@ -144,9 +144,9 @@ impl NodeTrait for Filter {
 
             match length.unit {
                 LengthUnit::Px | LengthUnit::Percent => Ok(length),
-                _ => Err(ValueErrorKind::Parse(ParseError::new(
+                _ => Err(ValueErrorKind::parse_error(
                     "unit identifiers are not allowed with filterUnits set to objectBoundingBox",
-                ))),
+                )),
             }
         };
 
diff --git a/rsvg_internals/src/filters/blend.rs b/rsvg_internals/src/filters/blend.rs
index e3925a33..b7eefb8a 100755
--- a/rsvg_internals/src/filters/blend.rs
+++ b/rsvg_internals/src/filters/blend.rs
@@ -4,7 +4,6 @@ use markup5ever::{expanded_name, local_name, namespace_url, ns, QualName};
 use crate::drawing_ctx::DrawingCtx;
 use crate::error::NodeError;
 use crate::node::{NodeResult, NodeTrait, RsvgNode};
-use crate::parsers::ParseError;
 use crate::property_bag::PropertyBag;
 use crate::surface_utils::shared_surface::SharedImageSurface;
 
@@ -151,10 +150,7 @@ impl Mode {
             "saturation" => Ok(Mode::HslSaturation),
             "color" => Ok(Mode::HslColor),
             "luminosity" => Ok(Mode::HslLuminosity),
-            _ => Err(NodeError::parse_error(
-                attr,
-                ParseError::new("invalid value"),
-            )),
+            _ => Err(NodeError::parse_error(attr, "invalid value")),
         }
     }
 }
diff --git a/rsvg_internals/src/filters/color_matrix.rs b/rsvg_internals/src/filters/color_matrix.rs
index 59375f8a..4a8492e6 100644
--- a/rsvg_internals/src/filters/color_matrix.rs
+++ b/rsvg_internals/src/filters/color_matrix.rs
@@ -6,7 +6,7 @@ use crate::drawing_ctx::DrawingCtx;
 use crate::error::{AttributeResultExt, NodeError};
 use crate::node::{NodeResult, NodeTrait, RsvgNode};
 use crate::number_list::{NumberList, NumberListError, NumberListLength};
-use crate::parsers::{self, ParseError};
+use crate::parsers;
 use crate::property_bag::PropertyBag;
 use crate::surface_utils::{
     iterators::Pixels, shared_surface::SharedImageSurface, ImageSurfaceDataExt, Pixel,
@@ -78,21 +78,19 @@ impl NodeTrait for FeColorMatrix {
                 let new_matrix = match operation_type {
                     OperationType::LuminanceToAlpha => unreachable!(),
                     OperationType::Matrix => {
-                        let NumberList(v) = NumberList::parse_str(
-                            value,
-                            NumberListLength::Exact(20),
-                        )
-                        .map_err(|err| {
-                            NodeError::parse_error(
-                                attr,
-                                match err {
-                                    NumberListError::IncorrectNumberOfElements => {
-                                        ParseError::new("incorrect number of elements: expected 20")
-                                    }
-                                    NumberListError::Parse(err) => err,
+                        let NumberList(v) =
+                            NumberList::parse_str(value, NumberListLength::Exact(20)).map_err(
+                                |err| {
+                                    let err_str = match err {
+                                        NumberListError::IncorrectNumberOfElements => {
+                                            "incorrect number of elements: expected 20"
+                                        }
+                                        NumberListError::Parse(ref err) => &err,
+                                    };
+
+                                    NodeError::parse_error(attr, err_str)
                                 },
-                            )
-                        })?;
+                            )?;
                         let matrix = Matrix4x5::from_row_slice(&v);
                         let mut matrix = matrix.fixed_resize(0.0);
                         matrix[(4, 4)] = 1.0;
@@ -233,10 +231,7 @@ impl OperationType {
             "saturate" => Ok(OperationType::Saturate),
             "hueRotate" => Ok(OperationType::HueRotate),
             "luminanceToAlpha" => Ok(OperationType::LuminanceToAlpha),
-            _ => Err(NodeError::parse_error(
-                attr,
-                ParseError::new("invalid value"),
-            )),
+            _ => Err(NodeError::parse_error(attr, "invalid value")),
         }
     }
 }
diff --git a/rsvg_internals/src/filters/component_transfer.rs 
b/rsvg_internals/src/filters/component_transfer.rs
index a7ab2ba7..16cfae2f 100644
--- a/rsvg_internals/src/filters/component_transfer.rs
+++ b/rsvg_internals/src/filters/component_transfer.rs
@@ -7,7 +7,7 @@ use crate::drawing_ctx::DrawingCtx;
 use crate::error::{AttributeResultExt, NodeError};
 use crate::node::{NodeResult, NodeTrait, NodeType, RsvgNode};
 use crate::number_list::{NumberList, NumberListError, NumberListLength};
-use crate::parsers::{self, ParseError};
+use crate::parsers;
 use crate::property_bag::PropertyBag;
 use crate::surface_utils::{
     iterators::Pixels,
@@ -71,10 +71,7 @@ impl FunctionType {
             "discrete" => Ok(FunctionType::Discrete),
             "linear" => Ok(FunctionType::Linear),
             "gamma" => Ok(FunctionType::Gamma),
-            _ => Err(NodeError::parse_error(
-                attr,
-                ParseError::new("invalid value"),
-            )),
+            _ => Err(NodeError::parse_error(attr, "invalid value")),
         }
     }
 }
@@ -221,7 +218,7 @@ macro_rules! func_x {
                                 NumberList::parse_str(value, NumberListLength::Unbounded).map_err(
                                     |err| {
                                         if let NumberListError::Parse(err) = err {
-                                            NodeError::parse_error(attr, err)
+                                            NodeError::parse_error(attr, &err)
                                         } else {
                                             panic!("unexpected number list error");
                                         }
diff --git a/rsvg_internals/src/filters/convolve_matrix.rs b/rsvg_internals/src/filters/convolve_matrix.rs
index 320ece76..7e549dd4 100644
--- a/rsvg_internals/src/filters/convolve_matrix.rs
+++ b/rsvg_internals/src/filters/convolve_matrix.rs
@@ -6,15 +6,13 @@ use crate::drawing_ctx::DrawingCtx;
 use crate::error::{AttributeResultExt, NodeError};
 use crate::node::{NodeResult, NodeTrait, RsvgNode};
 use crate::number_list::{NumberList, NumberListError, NumberListLength};
-use crate::parsers::{self, ParseError};
+use crate::parsers;
 use crate::property_bag::PropertyBag;
 use crate::rect::IRect;
 use crate::surface_utils::{
     iterators::{PixelRectangle, Pixels},
     shared_surface::SharedImageSurface,
-    EdgeMode,
-    ImageSurfaceDataExt,
-    Pixel,
+    EdgeMode, ImageSurfaceDataExt, Pixel,
 };
 use crate::util::clamp;
 
@@ -110,10 +108,7 @@ impl NodeTrait for FeConvolveMatrix {
                         "false" => false,
                         "true" => true,
                         _ => {
-                            return Err(NodeError::parse_error(
-                                attr,
-                                ParseError::new("expected false or true"),
-                            ));
+                            return Err(NodeError::parse_error(attr, "expected false or true"));
                         }
                     }
                 }
@@ -175,14 +170,11 @@ impl NodeTrait for FeConvolveMatrix {
                 // #352: Parse as an unbounded list rather than exact length to prevent aborts due
                 //       to huge allocation attempts by underlying Vec::with_capacity().
                 let NumberList(v) = NumberList::parse_str(value, NumberListLength::Unbounded)
-                    .map_err(|err| {
-                        NodeError::parse_error(
-                            attr.clone(),
-                            match err {
-                                NumberListError::IncorrectNumberOfElements => unreachable!(),
-                                NumberListError::Parse(err) => err,
-                            },
-                        )
+                    .map_err(|err| match err {
+                        NumberListError::IncorrectNumberOfElements => unreachable!(),
+                        NumberListError::Parse(ref err) => {
+                            NodeError::parse_error(attr.clone(), &err)
+                        }
                     })?;
 
                 if v.len() != number_of_elements {
@@ -370,10 +362,7 @@ impl EdgeMode {
             "duplicate" => Ok(EdgeMode::Duplicate),
             "wrap" => Ok(EdgeMode::Wrap),
             "none" => Ok(EdgeMode::None),
-            _ => Err(NodeError::parse_error(
-                attr,
-                ParseError::new("invalid value"),
-            )),
+            _ => Err(NodeError::parse_error(attr, "invalid value")),
         }
     }
 }
diff --git a/rsvg_internals/src/filters/displacement_map.rs b/rsvg_internals/src/filters/displacement_map.rs
index 6d2e1f86..0e6893ec 100644
--- a/rsvg_internals/src/filters/displacement_map.rs
+++ b/rsvg_internals/src/filters/displacement_map.rs
@@ -4,7 +4,7 @@ use markup5ever::{expanded_name, local_name, namespace_url, ns, QualName};
 use crate::drawing_ctx::DrawingCtx;
 use crate::error::{AttributeResultExt, NodeError};
 use crate::node::{NodeResult, NodeTrait, RsvgNode};
-use crate::parsers::{self, ParseError};
+use crate::parsers;
 use crate::property_bag::PropertyBag;
 use crate::surface_utils::{iterators::Pixels, shared_surface::SharedImageSurface};
 
@@ -150,10 +150,7 @@ impl ColorChannel {
             "G" => Ok(ColorChannel::G),
             "B" => Ok(ColorChannel::B),
             "A" => Ok(ColorChannel::A),
-            _ => Err(NodeError::parse_error(
-                attr,
-                ParseError::new("invalid value"),
-            )),
+            _ => Err(NodeError::parse_error(attr, "invalid value")),
         }
     }
 }
diff --git a/rsvg_internals/src/filters/image.rs b/rsvg_internals/src/filters/image.rs
index c4b14131..c3e13f67 100644
--- a/rsvg_internals/src/filters/image.rs
+++ b/rsvg_internals/src/filters/image.rs
@@ -7,7 +7,7 @@ use crate::drawing_ctx::DrawingCtx;
 use crate::error::{NodeError, RenderingError};
 use crate::float_eq_cairo::ApproxEqCairo;
 use crate::node::{CascadedValues, NodeResult, NodeTrait, RsvgNode};
-use crate::parsers::{ParseError, ParseValue};
+use crate::parsers::ParseValue;
 use crate::property_bag::PropertyBag;
 use crate::rect::IRect;
 use crate::surface_utils::shared_surface::{SharedImageSurface, SurfaceType};
@@ -170,7 +170,7 @@ impl NodeTrait for FeImage {
                 // "path" is used by some older Adobe Illustrator versions
                 expanded_name!(xlink "href") | expanded_name!(svg "path") => {
                     let href = Href::parse(value).map_err(|_| {
-                        NodeError::parse_error(attr, ParseError::new("could not parse href"))
+                        NodeError::parse_error(attr, "could not parse href")
                     })?;
 
                     self.href = Some(href);
diff --git a/rsvg_internals/src/filters/input.rs b/rsvg_internals/src/filters/input.rs
index 70c24a06..48f76bdf 100644
--- a/rsvg_internals/src/filters/input.rs
+++ b/rsvg_internals/src/filters/input.rs
@@ -1,7 +1,6 @@
 use markup5ever::QualName;
 
 use crate::error::NodeError;
-use crate::parsers::ParseError;
 
 /// An enumeration of possible inputs for a filter primitive.
 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
@@ -25,10 +24,7 @@ impl Input {
             "FillPaint" => Ok(Input::FillPaint),
             "StrokePaint" => Ok(Input::StrokePaint),
             s if !s.is_empty() => Ok(Input::FilterOutput(s.to_string())),
-            _ => Err(NodeError::parse_error(
-                attr,
-                ParseError::new("invalid value"),
-            )),
+            _ => Err(NodeError::parse_error(attr, "invalid value")),
         }
     }
 }
diff --git a/rsvg_internals/src/filters/mod.rs b/rsvg_internals/src/filters/mod.rs
index 11ab0c7c..a117bb3f 100644
--- a/rsvg_internals/src/filters/mod.rs
+++ b/rsvg_internals/src/filters/mod.rs
@@ -11,7 +11,7 @@ use crate::error::{RenderingError, ValueErrorKind};
 use crate::filter::Filter;
 use crate::length::*;
 use crate::node::{CascadedValues, NodeResult, NodeTrait, NodeType, RsvgNode};
-use crate::parsers::{ParseError, ParseValue};
+use crate::parsers::ParseValue;
 use crate::properties::ComputedValues;
 use crate::property_bag::PropertyBag;
 use crate::property_defs::ColorInterpolationFilters;
@@ -131,9 +131,9 @@ impl NodeTrait for Primitive {
 
             match length.unit {
                 LengthUnit::Px | LengthUnit::Percent => Ok(length),
-                _ => Err(ValueErrorKind::Parse(ParseError::new(
+                _ => Err(ValueErrorKind::parse_error(
                     "unit identifiers are not allowed with primitiveUnits set to objectBoundingBox",
-                ))),
+                )),
             }
         };
 
@@ -144,9 +144,9 @@ impl NodeTrait for Primitive {
 
             match length.unit {
                 LengthUnit::Px | LengthUnit::Percent => Ok(length),
-                _ => Err(ValueErrorKind::Parse(ParseError::new(
+                _ => Err(ValueErrorKind::parse_error(
                     "unit identifiers are not allowed with primitiveUnits set to objectBoundingBox",
-                ))),
+                )),
             }
         };
 
diff --git a/rsvg_internals/src/filters/morphology.rs b/rsvg_internals/src/filters/morphology.rs
index c986e908..5bfbb593 100644
--- a/rsvg_internals/src/filters/morphology.rs
+++ b/rsvg_internals/src/filters/morphology.rs
@@ -6,7 +6,7 @@ use markup5ever::{expanded_name, local_name, namespace_url, ns, QualName};
 use crate::drawing_ctx::DrawingCtx;
 use crate::error::{AttributeResultExt, NodeError};
 use crate::node::{NodeResult, NodeTrait, RsvgNode};
-use crate::parsers::{self, ParseError};
+use crate::parsers;
 use crate::property_bag::PropertyBag;
 use crate::rect::IRect;
 use crate::surface_utils::{
@@ -165,10 +165,7 @@ impl Operator {
         match s {
             "erode" => Ok(Operator::Erode),
             "dilate" => Ok(Operator::Dilate),
-            _ => Err(NodeError::parse_error(
-                attr,
-                ParseError::new("invalid value"),
-            )),
+            _ => Err(NodeError::parse_error(attr, "invalid value")),
         }
     }
 }
diff --git a/rsvg_internals/src/filters/turbulence.rs b/rsvg_internals/src/filters/turbulence.rs
index 874c57bc..84720045 100644
--- a/rsvg_internals/src/filters/turbulence.rs
+++ b/rsvg_internals/src/filters/turbulence.rs
@@ -4,7 +4,7 @@ use markup5ever::{expanded_name, local_name, namespace_url, ns, QualName};
 use crate::drawing_ctx::DrawingCtx;
 use crate::error::{AttributeResultExt, NodeError};
 use crate::node::{CascadedValues, NodeResult, NodeTrait, RsvgNode};
-use crate::parsers::{self, ParseError};
+use crate::parsers;
 use crate::property_bag::PropertyBag;
 use crate::property_defs::ColorInterpolationFilters;
 use crate::surface_utils::{
@@ -431,10 +431,7 @@ impl StitchTiles {
         match s {
             "stitch" => Ok(StitchTiles::Stitch),
             "noStitch" => Ok(StitchTiles::NoStitch),
-            _ => Err(NodeError::parse_error(
-                attr,
-                ParseError::new("invalid value"),
-            )),
+            _ => Err(NodeError::parse_error(attr, "invalid value")),
         }
     }
 }
@@ -444,10 +441,7 @@ impl NoiseType {
         match s {
             "fractalNoise" => Ok(NoiseType::FractalNoise),
             "turbulence" => Ok(NoiseType::Turbulence),
-            _ => Err(NodeError::parse_error(
-                attr,
-                ParseError::new("invalid value"),
-            )),
+            _ => Err(NodeError::parse_error(attr, "invalid value")),
         }
     }
 }
diff --git a/rsvg_internals/src/font_props.rs b/rsvg_internals/src/font_props.rs
index c810f5cc..e84747f9 100644
--- a/rsvg_internals/src/font_props.rs
+++ b/rsvg_internals/src/font_props.rs
@@ -3,7 +3,7 @@ use cssparser::{BasicParseError, Parser, Token};
 use crate::drawing_ctx::ViewParams;
 use crate::error::*;
 use crate::length::*;
-use crate::parsers::{Parse, ParseError};
+use crate::parsers::Parse;
 use crate::properties::ComputedValues;
 
 // https://www.w3.org/TR/2008/REC-CSS2-20080411/fonts.html#propdef-font-size
@@ -69,9 +69,7 @@ impl Parse for FontSizeSpec {
 
                 {
                     let token = parser.next().map_err(|_| {
-                        crate::error::ValueErrorKind::Parse(crate::parsers::ParseError::new(
-                            "expected token",
-                        ))
+                        crate::error::ValueErrorKind::parse_error("expected token")
                     })?;
 
                     if let Token::Ident(ref cow) = token {
@@ -149,9 +147,9 @@ impl Parse for FontWeightSpec {
         {
             Ok(r)
         } else {
-            Err(ValueErrorKind::Parse(ParseError::new(
+            Err(ValueErrorKind::parse_error(
                 "invalid font-weight specification",
-            )))
+            ))
         }
     }
 }
@@ -198,9 +196,7 @@ impl Parse for LetterSpacingSpec {
 
                 {
                     let token = parser.next().map_err(|_| {
-                        crate::error::ValueErrorKind::Parse(crate::parsers::ParseError::new(
-                            "expected token",
-                        ))
+                        crate::error::ValueErrorKind::parse_error("expected token")
                     })?;
 
                     if let Token::Ident(ref cow) = token {
@@ -224,7 +220,7 @@ pub struct SingleFontFamily(pub String);
 impl Parse for SingleFontFamily {
     fn parse(parser: &mut Parser<'_, '_>) -> Result<SingleFontFamily, ValueErrorKind> {
         parse_single_font_family(parser)
-            .map_err(|_| ValueErrorKind::from(ParseError::new("expected font family")))
+            .map_err(|_| ValueErrorKind::parse_error("expected font family"))
     }
 }
 
diff --git a/rsvg_internals/src/gradient.rs b/rsvg_internals/src/gradient.rs
index d4021baa..638d1b3a 100644
--- a/rsvg_internals/src/gradient.rs
+++ b/rsvg_internals/src/gradient.rs
@@ -11,7 +11,7 @@ use crate::error::*;
 use crate::length::*;
 use crate::node::{CascadedValues, NodeResult, NodeTrait, NodeType, RsvgNode};
 use crate::paint_server::{AsPaintSource, PaintSource};
-use crate::parsers::{Parse, ParseError, ParseValue};
+use crate::parsers::{Parse, ParseValue};
 use crate::properties::ComputedValues;
 use crate::property_bag::PropertyBag;
 use crate::property_defs::StopColor;
@@ -59,7 +59,7 @@ impl Parse for SpreadMethod {
                 ),
             })
             .map_err(|_| {
-                ValueErrorKind::Parse(ParseError::new("expected 'pad' | 'reflect' | 'repeat'"))
+                ValueErrorKind::parse_error("expected 'pad' | 'reflect' | 'repeat'")
             })
     }
 }
diff --git a/rsvg_internals/src/image.rs b/rsvg_internals/src/image.rs
index 59d1914d..873b75e5 100644
--- a/rsvg_internals/src/image.rs
+++ b/rsvg_internals/src/image.rs
@@ -10,7 +10,7 @@ use crate::error::{NodeError, RenderingError};
 use crate::float_eq_cairo::ApproxEqCairo;
 use crate::length::*;
 use crate::node::*;
-use crate::parsers::{ParseError, ParseValue};
+use crate::parsers::ParseValue;
 use crate::property_bag::PropertyBag;
 use crate::rect::RectangleExt;
 use crate::viewbox::ViewBox;
@@ -42,7 +42,7 @@ impl NodeTrait for Image {
                 // "path" is used by some older Adobe Illustrator versions
                 expanded_name!(xlink "href") | expanded_name!(svg "path") => {
                     let href = Href::parse(value).map_err(|_| {
-                        NodeError::parse_error(attr, ParseError::new("could not parse href"))
+                        NodeError::parse_error(attr, "could not parse href")
                     })?;
 
                     self.href = Some(href);
diff --git a/rsvg_internals/src/iri.rs b/rsvg_internals/src/iri.rs
index b1c1ae3b..c830812c 100644
--- a/rsvg_internals/src/iri.rs
+++ b/rsvg_internals/src/iri.rs
@@ -3,7 +3,6 @@ use cssparser::Parser;
 use crate::allowed_url::{Fragment, Href};
 use crate::error::ValueErrorKind;
 use crate::parsers::Parse;
-use crate::parsers::ParseError;
 
 /// Used where style properties take a funciri or "none"
 ///
@@ -44,8 +43,13 @@ impl Parse for IRI {
             let url = parser.expect_url()?;
             parser.expect_exhausted()?;
 
-            match Href::parse(&url).map_err(|_| ParseError::new("could not parse href"))? {
-                Href::PlainUrl(_) => Err(ParseError::new("href requires a fragment identifier"))?,
+            let href = Href::parse(&url)
+                .map_err(|_| ValueErrorKind::parse_error("could not parse href"))?;
+
+            match href {
+                Href::PlainUrl(_) => Err(ValueErrorKind::parse_error(
+                    "href requires a fragment identifier",
+                ))?,
                 Href::WithFragment(f) => Ok(IRI::Resource(f)),
             }
         }
diff --git a/rsvg_internals/src/length.rs b/rsvg_internals/src/length.rs
index f0bcfd4c..dc39da72 100644
--- a/rsvg_internals/src/length.rs
+++ b/rsvg_internals/src/length.rs
@@ -48,7 +48,7 @@ use std::marker::PhantomData;
 use crate::drawing_ctx::ViewParams;
 use crate::error::*;
 use crate::parsers::Parse;
-use crate::parsers::{finite_f32, ParseError};
+use crate::parsers::finite_f32;
 use crate::properties::ComputedValues;
 
 /// Units for length values.
@@ -228,19 +228,19 @@ const MM_PER_INCH: f64 = 25.4;
 const PICA_PER_INCH: f64 = 6.0;
 
 fn make_err() -> ValueErrorKind {
-    ValueErrorKind::Parse(ParseError::new(
+    ValueErrorKind::parse_error(
         "expected length: number(\"em\" | \"ex\" | \"px\" | \"in\" | \"cm\" | \"mm\" | \"pt\" | \
          \"pc\" | \"%\")?",
-    ))
+    )
 }
 
 impl<N: Normalize> Parse for Length<N> {
     fn parse(parser: &mut Parser<'_, '_>) -> Result<Length<N>, ValueErrorKind> {
         let length = {
             let token = parser.next().map_err(|_| {
-                ValueErrorKind::Parse(ParseError::new(
+                ValueErrorKind::parse_error(
                     "expected number and optional symbol, or number and percentage",
-                ))
+                )
             })?;
 
             match *token {
diff --git a/rsvg_internals/src/marker.rs b/rsvg_internals/src/marker.rs
index 4a0651de..4edbf600 100644
--- a/rsvg_internals/src/marker.rs
+++ b/rsvg_internals/src/marker.rs
@@ -14,7 +14,7 @@ use crate::float_eq_cairo::ApproxEqCairo;
 use crate::iri::IRI;
 use crate::length::*;
 use crate::node::*;
-use crate::parsers::{Parse, ParseError, ParseValue};
+use crate::parsers::{Parse, ParseValue};
 use crate::path_builder::*;
 use crate::properties::{ComputedValues, SpecifiedValue, SpecifiedValues};
 use crate::property_bag::PropertyBag;
@@ -50,9 +50,7 @@ impl Parse for MarkerUnits {
                 ),
             })
             .map_err(|_| {
-                ValueErrorKind::Parse(ParseError::new(
-                    "expected \"userSpaceOnUse\" or \"strokeWidth\"",
-                ))
+                ValueErrorKind::parse_error("expected \"userSpaceOnUse\" or \"strokeWidth\"")
             })
     }
 }
diff --git a/rsvg_internals/src/number_list.rs b/rsvg_internals/src/number_list.rs
index e8f9cec6..7bd00d33 100644
--- a/rsvg_internals/src/number_list.rs
+++ b/rsvg_internals/src/number_list.rs
@@ -1,6 +1,6 @@
 use cssparser::{Parser, ParserInput};
 
-use crate::parsers::{CssParserExt, ParseError};
+use crate::parsers::CssParserExt;
 
 #[derive(Eq, PartialEq)]
 pub enum NumberListLength {
@@ -11,7 +11,7 @@ pub enum NumberListLength {
 #[derive(Debug, PartialEq)]
 pub enum NumberListError {
     IncorrectNumberOfElements,
-    Parse(ParseError),
+    Parse(String),
 }
 
 #[derive(Debug, PartialEq)]
@@ -38,7 +38,7 @@ impl NumberList {
             }
 
             v.push(f64::from(parser.expect_finite_number().map_err(|_| {
-                NumberListError::Parse(ParseError::new("expected number"))
+                NumberListError::Parse("expected number".to_string())
             })?));
 
             if let NumberListLength::Exact(l) = length {
diff --git a/rsvg_internals/src/parsers.rs b/rsvg_internals/src/parsers.rs
index d0053a7e..3f90f03c 100644
--- a/rsvg_internals/src/parsers.rs
+++ b/rsvg_internals/src/parsers.rs
@@ -5,19 +5,6 @@ use std::str;
 
 use crate::error::{NodeError, ValueErrorKind};
 
-#[derive(Debug, Clone, PartialEq)]
-pub struct ParseError {
-    pub display: String,
-}
-
-impl ParseError {
-    pub fn new<T: AsRef<str>>(msg: T) -> ParseError {
-        ParseError {
-            display: msg.as_ref().to_string(),
-        }
-    }
-}
-
 /// Trait to parse values using `cssparser::Parser`.
 pub trait Parse: Sized {
     /// Parses a value out of the `parser`.
@@ -104,7 +91,7 @@ impl<T: Parse> ParseValue<T> for QualName {
 impl Parse for f64 {
     fn parse(parser: &mut Parser<'_, '_>) -> Result<f64, ValueErrorKind> {
         Ok(f64::from(parser.expect_finite_number().map_err(|_| {
-            ValueErrorKind::Parse(ParseError::new("expected number"))
+            ValueErrorKind::Parse(String::from("expected number"))
         })?))
     }
 }
diff --git a/rsvg_internals/src/property_defs.rs b/rsvg_internals/src/property_defs.rs
index e5a0cc0e..da940861 100644
--- a/rsvg_internals/src/property_defs.rs
+++ b/rsvg_internals/src/property_defs.rs
@@ -6,7 +6,7 @@ use crate::dasharray::Dasharray;
 use crate::iri::IRI;
 use crate::length::*;
 use crate::paint_server::PaintServer;
-use crate::parsers::{Parse, ParseError};
+use crate::parsers::Parse;
 use crate::properties::ComputedValues;
 use crate::property_macros::Property;
 use crate::unit_interval::UnitInterval;
@@ -46,9 +46,9 @@ make_property!(
                 let parser_state = parser.state();
 
                 {
-                    let token = parser.next().map_err(|_| crate::error::ValueErrorKind::Parse(
-                        crate::parsers::ParseError::new("expected token"),
-                    ))?;
+                    let token = parser.next().map_err(|_| {
+                        crate::error::ValueErrorKind::parse_error("expected token")
+                    })?;
 
                     if let Token::Ident(ref cow) = token {
                         match cow.as_ref() {
@@ -561,15 +561,15 @@ make_property!(
                 }
 
                 while !parser.is_exhausted() {
-                    let cow = parser.expect_ident().map_err(|_| crate::error::ValueErrorKind::Parse(
-                        crate::parsers::ParseError::new("expected identifier"),
-                    ))?;
+                    let cow = parser.expect_ident().map_err(|_| {
+                        crate::error::ValueErrorKind::parse_error("expected identifier")
+                    })?;
 
                     match cow.as_ref() {
                         "overline" => overline = true,
                         "underline" => underline = true,
                         "line-through" => strike = true,
-                        _ => return Err(ValueErrorKind::Parse(ParseError::new("invalid syntax"))),
+                        _ => return Err(ValueErrorKind::parse_error("invalid syntax")),
                     }
                 }
 
diff --git a/rsvg_internals/src/property_macros.rs b/rsvg_internals/src/property_macros.rs
index a499cafb..914af23b 100644
--- a/rsvg_internals/src/property_macros.rs
+++ b/rsvg_internals/src/property_macros.rs
@@ -60,9 +60,7 @@ macro_rules! make_property {
                             ),
                     })
                     .map_err(|_| {
-                        crate::error::ValueErrorKind::Parse(crate::parsers::ParseError::new(
-                            "unexpected value",
-                        ))
+                        crate::error::ValueErrorKind::parse_error("unexpected value")
                     })
             }
         }
diff --git a/rsvg_internals/src/style.rs b/rsvg_internals/src/style.rs
index ca6b3736..991456c6 100644
--- a/rsvg_internals/src/style.rs
+++ b/rsvg_internals/src/style.rs
@@ -3,7 +3,7 @@ use markup5ever::{expanded_name, local_name, namespace_url, ns};
 
 use crate::error::*;
 use crate::node::{NodeResult, NodeTrait, RsvgNode};
-use crate::parsers::{Parse, ParseError, ParseValue};
+use crate::parsers::{Parse, ParseValue};
 use crate::property_bag::PropertyBag;
 
 /// Represents the syntax used in the <style> node.
@@ -23,9 +23,7 @@ impl Parse for StyleType {
             .expect_ident_matching("text/css")
             .and_then(|_| Ok(StyleType::TextCss))
             .map_err(|_| {
-                ValueErrorKind::Parse(ParseError::new(
-                    "only the \"text/css\" style type is supported",
-                ))
+                ValueErrorKind::parse_error("only the \"text/css\" style type is supported")
             })
     }
 }
diff --git a/rsvg_internals/src/transform.rs b/rsvg_internals/src/transform.rs
index 0d3351d7..06782231 100644
--- a/rsvg_internals/src/transform.rs
+++ b/rsvg_internals/src/transform.rs
@@ -5,7 +5,7 @@ use std::f64::consts::*;
 use cssparser::{ParseError as CssParseError, Parser, Token};
 
 use crate::error::*;
-use crate::parsers::{finite_f32, CssParserExt, Parse, ParseError};
+use crate::parsers::{finite_f32, CssParserExt, Parse};
 
 impl Parse for cairo::Matrix {
     fn parse(parser: &mut Parser<'_, '_>) -> Result<cairo::Matrix, ValueErrorKind> {
@@ -40,9 +40,7 @@ fn parse_transform_list(parser: &mut Parser<'_, '_>) -> Result<cairo::Matrix, Va
 }
 
 fn make_expected_function_error() -> ValueErrorKind {
-    ValueErrorKind::from(ParseError::new(
-        "expected matrix|translate|scale|rotate|skewX|skewY",
-    ))
+    ValueErrorKind::parse_error("expected matrix|translate|scale|rotate|skewX|skewY")
 }
 
 fn parse_transform_command(parser: &mut Parser<'_, '_>) -> Result<cairo::Matrix, ValueErrorKind> {
diff --git a/rsvg_internals/src/unit_interval.rs b/rsvg_internals/src/unit_interval.rs
index 897866ff..154d2609 100644
--- a/rsvg_internals/src/unit_interval.rs
+++ b/rsvg_internals/src/unit_interval.rs
@@ -1,7 +1,7 @@
 use cssparser::Parser;
 
 use crate::error::*;
-use crate::parsers::{CssParserExt, Parse, ParseError};
+use crate::parsers::{CssParserExt, Parse};
 use crate::util;
 
 #[derive(Debug, Default, Copy, Clone, PartialEq, PartialOrd)]
@@ -18,7 +18,7 @@ impl Parse for UnitInterval {
         let x = f64::from(
             parser
                 .expect_finite_number()
-                .map_err(|_| ValueErrorKind::Parse(ParseError::new("expected number")))?,
+                .map_err(|_| ValueErrorKind::parse_error("expected number"))?,
         );
 
         Ok(UnitInterval::clamp(x))
diff --git a/rsvg_internals/src/viewbox.rs b/rsvg_internals/src/viewbox.rs
index 1f48c97d..ac18d4d9 100644
--- a/rsvg_internals/src/viewbox.rs
+++ b/rsvg_internals/src/viewbox.rs
@@ -2,7 +2,7 @@ use cssparser::Parser;
 
 use crate::error::*;
 use crate::number_list::{NumberList, NumberListLength};
-use crate::parsers::{Parse, ParseError};
+use crate::parsers::Parse;
 
 #[derive(Debug, Copy, Clone, PartialEq)]
 pub struct ViewBox {
@@ -38,17 +38,17 @@ impl Parse for ViewBox {
     //
     // Where w and h must be nonnegative.
     fn parse(parser: &mut Parser<'_, '_>) -> Result<ViewBox, ValueErrorKind> {
-        let NumberList(v) = NumberList::parse(parser, NumberListLength::Exact(4))
-            .map_err(|_| ParseError::new("string does not match 'x [,] y [,] w [,] h'"))?;
+        let NumberList(v) =
+            NumberList::parse(parser, NumberListLength::Exact(4)).map_err(|_| {
+                ValueErrorKind::parse_error("string does not match 'x [,] y [,] w [,] h'")
+            })?;
 
         let (x, y, width, height) = (v[0], v[1], v[2], v[3]);
 
         if width >= 0.0 && height >= 0.0 {
             Ok(ViewBox::new(x, y, width, height))
         } else {
-            Err(ValueErrorKind::Value(
-                "width and height must not be negative".to_string(),
-            ))
+            Err(ValueErrorKind::value_error("width and height must not be negative"))
         }
     }
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]