[librsvg] parsers::Parse - new trait; we'll use this instead of std::FromStr
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] parsers::Parse - new trait; we'll use this instead of std::FromStr
- Date: Tue, 5 Sep 2017 02:35:34 +0000 (UTC)
commit 5510e4c3f9c9c84bac4a05f6d93a09c9b4862544
Author: Federico Mena Quintero <federico gnome org>
Date: Mon Sep 4 21:09:38 2017 -0500
parsers::Parse - new trait; we'll use this instead of std::FromStr
This has a Data associated type, which is passed to parse(&str, data) -> Result<>
We'll use that Data to pass RsvgLength's auxiliary data for parsing.
Hopefully this way we can have a unified way to parse attribute values
from strings, without having exceptions just because:
a) RsvgLength needs to know the direction upon parsing/construction;
b) We can't impl FromStr for cairo::Matrix because they both come
from extern traits.
rust/src/aspect_ratio.rs | 77 ++++++++++++++++++++++-----------------------
rust/src/gradient.rs | 4 +-
rust/src/marker.rs | 48 +++++++++++++++--------------
rust/src/paint_server.rs | 31 +++++++++---------
rust/src/parsers.rs | 7 ++++
rust/src/pattern.rs | 17 +++++-----
rust/src/property_bag.rs | 21 ++++++------
rust/src/structure.rs | 8 ++--
rust/src/viewbox.rs | 23 ++++++-------
9 files changed, 121 insertions(+), 115 deletions(-)
---
diff --git a/rust/src/aspect_ratio.rs b/rust/src/aspect_ratio.rs
index ebda583..63482ba 100644
--- a/rust/src/aspect_ratio.rs
+++ b/rust/src/aspect_ratio.rs
@@ -18,8 +18,7 @@
use ::libc;
use ::glib::translate::*;
-use std::str::FromStr;
-
+use parsers::Parse;
use parsers::ParseError;
use error::*;
@@ -258,10 +257,11 @@ fn make_err () -> AttributeError {
AttributeError::Parse (ParseError::new ("expected \"[defer] <align> [meet | slice]\""))
}
-impl FromStr for AspectRatio {
+impl Parse for AspectRatio {
+ type Data = ();
type Err = AttributeError;
- fn from_str(s: &str) -> Result<AspectRatio, AttributeError> {
+ fn parse(s: &str, _: ()) -> Result<AspectRatio, AttributeError> {
let mut defer = false;
let mut align: Align = Default::default ();
let mut fit_mode = FitMode::Meet;
@@ -333,7 +333,7 @@ impl FromStr for AspectRatio {
#[no_mangle]
pub extern fn rsvg_aspect_ratio_parse (c_str: *const libc::c_char) -> u32 {
let my_str = unsafe { &String::from_glib_none (c_str) };
- let parsed = AspectRatio::from_str (my_str);
+ let parsed = AspectRatio::parse (my_str, ());
match parsed {
Ok (aspect_ratio) => { aspect_ratio.to_u32 () },
@@ -365,61 +365,60 @@ pub extern fn rsvg_aspect_ratio_compute (aspect: u32,
#[cfg(test)]
mod tests {
use super::*;
- use std::str::FromStr;
#[test]
fn parsing_invalid_strings_yields_error () {
- assert! (AspectRatio::from_str ("").is_err ());
+ assert! (AspectRatio::parse ("", ()).is_err ());
- assert! (AspectRatio::from_str ("defer").is_err ());
+ assert! (AspectRatio::parse ("defer", ()).is_err ());
- assert! (AspectRatio::from_str ("defer foo").is_err ());
+ assert! (AspectRatio::parse ("defer foo", ()).is_err ());
- assert! (AspectRatio::from_str ("defer xmidymid").is_err ());
+ assert! (AspectRatio::parse ("defer xmidymid", ()).is_err ());
- assert! (AspectRatio::from_str ("defer xMidYMid foo").is_err ());
+ assert! (AspectRatio::parse ("defer xMidYMid foo", ()).is_err ());
- assert! (AspectRatio::from_str ("xmidymid").is_err ());
+ assert! (AspectRatio::parse ("xmidymid", ()).is_err ());
- assert! (AspectRatio::from_str ("xMidYMid foo").is_err ());
+ assert! (AspectRatio::parse ("xMidYMid foo", ()).is_err ());
- assert! (AspectRatio::from_str ("defer xMidYMid meet foo").is_err ());
+ assert! (AspectRatio::parse ("defer xMidYMid meet foo", ()).is_err ());
}
#[test]
fn parses_valid_strings () {
- assert_eq! (AspectRatio::from_str ("defer none"),
+ assert_eq! (AspectRatio::parse ("defer none", ()),
Ok (AspectRatio { defer: true,
align: Align::None }));
- assert_eq! (AspectRatio::from_str ("xMidYMid"),
+ assert_eq! (AspectRatio::parse ("xMidYMid", ()),
Ok (AspectRatio { defer: false,
align: Align::Aligned { align: AlignMode::XmidYmid,
fit: FitMode::Meet } }));
- assert_eq! (AspectRatio::from_str ("defer xMidYMid"),
+ assert_eq! (AspectRatio::parse ("defer xMidYMid", ()),
Ok (AspectRatio { defer: true,
align: Align::Aligned { align: AlignMode::XmidYmid,
fit: FitMode::Meet } }));
- assert_eq! (AspectRatio::from_str ("defer xMinYMax"),
+ assert_eq! (AspectRatio::parse ("defer xMinYMax", ()),
Ok (AspectRatio { defer: true,
align: Align::Aligned { align: AlignMode::XminYmax,
fit: FitMode::Meet } }));
- assert_eq! (AspectRatio::from_str ("defer xMaxYMid meet"),
+ assert_eq! (AspectRatio::parse ("defer xMaxYMid meet", ()),
Ok (AspectRatio { defer: true,
align: Align::Aligned { align: AlignMode::XmaxYmid,
fit: FitMode::Meet } }));
- assert_eq! (AspectRatio::from_str ("defer xMinYMax slice"),
+ assert_eq! (AspectRatio::parse ("defer xMinYMax slice", ()),
Ok (AspectRatio { defer: true,
align: Align::Aligned { align: AlignMode::XminYmax,
fit: FitMode::Slice } }));
}
fn test_roundtrip (s: &str) {
- let a = AspectRatio::from_str (s).unwrap ();
+ let a = AspectRatio::parse (s, ()).unwrap ();
assert_eq! (AspectRatio::from_u32 (a.to_u32 ()), a);
}
@@ -434,31 +433,31 @@ mod tests {
#[test]
fn aligns () {
- assert_eq! (AspectRatio::from_str ("xMinYMin meet").unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (0.0, 0.0, 0.1, 1.0));
- assert_eq! (AspectRatio::from_str ("xMinYMin slice").unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (0.0, 0.0, 10.0, 100.0));
+ assert_eq! (AspectRatio::parse ("xMinYMin meet", ()).unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (0.0, 0.0, 0.1, 1.0));
+ assert_eq! (AspectRatio::parse ("xMinYMin slice", ()).unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (0.0, 0.0, 10.0, 100.0));
- assert_eq! (AspectRatio::from_str ("xMinYMid meet").unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (0.0, 0.0, 0.1, 1.0));
- assert_eq! (AspectRatio::from_str ("xMinYMid slice").unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (0.0, -49.5, 10.0, 100.0));
+ assert_eq! (AspectRatio::parse ("xMinYMid meet", ()).unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (0.0, 0.0, 0.1, 1.0));
+ assert_eq! (AspectRatio::parse ("xMinYMid slice", ()).unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (0.0, -49.5, 10.0, 100.0));
- assert_eq! (AspectRatio::from_str ("xMinYMax meet").unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (0.0, 0.0, 0.1, 1.0));
- assert_eq! (AspectRatio::from_str ("xMinYMax slice").unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (0.0, -99.0, 10.0, 100.0));
+ assert_eq! (AspectRatio::parse ("xMinYMax meet", ()).unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (0.0, 0.0, 0.1, 1.0));
+ assert_eq! (AspectRatio::parse ("xMinYMax slice", ()).unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (0.0, -99.0, 10.0, 100.0));
- assert_eq! (AspectRatio::from_str ("xMidYMin meet").unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (4.95, 0.0, 0.1, 1.0));
- assert_eq! (AspectRatio::from_str ("xMidYMin slice").unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (0.0, 0.0, 10.0, 100.0));
+ assert_eq! (AspectRatio::parse ("xMidYMin meet", ()).unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (4.95, 0.0, 0.1, 1.0));
+ assert_eq! (AspectRatio::parse ("xMidYMin slice", ()).unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (0.0, 0.0, 10.0, 100.0));
- assert_eq! (AspectRatio::from_str ("xMidYMid meet").unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (4.95, 0.0, 0.1, 1.0));
- assert_eq! (AspectRatio::from_str ("xMidYMid slice").unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (0.0, -49.5, 10.0, 100.0));
+ assert_eq! (AspectRatio::parse ("xMidYMid meet", ()).unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (4.95, 0.0, 0.1, 1.0));
+ assert_eq! (AspectRatio::parse ("xMidYMid slice", ()).unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (0.0, -49.5, 10.0, 100.0));
- assert_eq! (AspectRatio::from_str ("xMidYMax meet").unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (4.95, 0.0, 0.1, 1.0));
- assert_eq! (AspectRatio::from_str ("xMidYMax slice").unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (0.0, -99.0, 10.0, 100.0));
+ assert_eq! (AspectRatio::parse ("xMidYMax meet", ()).unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (4.95, 0.0, 0.1, 1.0));
+ assert_eq! (AspectRatio::parse ("xMidYMax slice", ()).unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (0.0, -99.0, 10.0, 100.0));
- assert_eq! (AspectRatio::from_str ("xMaxYMin meet").unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (9.9, 0.0, 0.1, 1.0));
- assert_eq! (AspectRatio::from_str ("xMaxYMin slice").unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (0.0, 0.0, 10.0, 100.0));
+ assert_eq! (AspectRatio::parse ("xMaxYMin meet", ()).unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (9.9, 0.0, 0.1, 1.0));
+ assert_eq! (AspectRatio::parse ("xMaxYMin slice", ()).unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (0.0, 0.0, 10.0, 100.0));
- assert_eq! (AspectRatio::from_str ("xMaxYMid meet").unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (9.9, 0.0, 0.1, 1.0));
- assert_eq! (AspectRatio::from_str ("xMaxYMid slice").unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (0.0, -49.5, 10.0, 100.0));
+ assert_eq! (AspectRatio::parse ("xMaxYMid meet", ()).unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (9.9, 0.0, 0.1, 1.0));
+ assert_eq! (AspectRatio::parse ("xMaxYMid slice", ()).unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (0.0, -49.5, 10.0, 100.0));
- assert_eq! (AspectRatio::from_str ("xMaxYMax meet").unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (9.9, 0.0, 0.1, 1.0));
- assert_eq! (AspectRatio::from_str ("xMaxYMax slice").unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (0.0, -99.0, 10.0, 100.0));
+ assert_eq! (AspectRatio::parse ("xMaxYMax meet", ()).unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (9.9, 0.0, 0.1, 1.0));
+ assert_eq! (AspectRatio::parse ("xMaxYMax slice", ()).unwrap().compute (1.0, 10.0, 0.0, 0.0, 10.0,
1.0), (0.0, -99.0, 10.0, 100.0));
}
}
diff --git a/rust/src/gradient.rs b/rust/src/gradient.rs
index aac0ea2..ac2b2bf 100644
--- a/rust/src/gradient.rs
+++ b/rust/src/gradient.rs
@@ -556,9 +556,9 @@ impl NodeTrait for NodeGradient {
// Attributes common to linear and radial gradients
- g.common.units = property_bag::parse_or_none (pbag, "gradientUnits")?;
+ g.common.units = property_bag::parse_or_none (pbag, "gradientUnits", ())?;
g.common.affine = property_bag::transform_or_none (pbag, "gradientTransform")?;
- g.common.spread = property_bag::parse_or_none (pbag, "spreadMethod")?;
+ g.common.spread = property_bag::parse_or_none (pbag, "spreadMethod", ())?;
g.common.fallback = property_bag::lookup (pbag, "xlink:href");
// Attributes specific to each gradient type. The defaults mandated by the spec
diff --git a/rust/src/marker.rs b/rust/src/marker.rs
index 596bdbd..927455c 100644
--- a/rust/src/marker.rs
+++ b/rust/src/marker.rs
@@ -4,7 +4,6 @@ use ::libc;
use std::cell::Cell;
use std::f64::consts::*;
-use std::str::FromStr;
use cairo::MatrixTrait;
@@ -17,6 +16,7 @@ use length::*;
use node::*;
use path_builder::*;
use parsers;
+use parsers::Parse;
use parsers::ParseError;
use property_bag;
use property_bag::*;
@@ -37,10 +37,11 @@ impl Default for MarkerUnits {
}
}
-impl FromStr for MarkerUnits {
+impl Parse for MarkerUnits {
+ type Data = ();
type Err = AttributeError;
- fn from_str (s: &str) -> Result <MarkerUnits, AttributeError> {
+ fn parse (s: &str, _: ()) -> Result <MarkerUnits, AttributeError> {
match s {
"userSpaceOnUse" => Ok (MarkerUnits::UserSpaceOnUse),
"strokeWidth" => Ok (MarkerUnits::StrokeWidth),
@@ -63,10 +64,11 @@ impl Default for MarkerOrient {
}
}
-impl FromStr for MarkerOrient {
+impl Parse for MarkerOrient {
+ type Data = ();
type Err = AttributeError;
- fn from_str (s: &str) -> Result <MarkerOrient, AttributeError> {
+ fn parse (s: &str, _: ()) -> Result <MarkerOrient, AttributeError> {
match s {
"auto" => Ok (MarkerOrient::Auto),
_ => parsers::angle_degrees (s)
@@ -190,7 +192,7 @@ impl NodeMarker {
impl NodeTrait for NodeMarker {
fn set_atts (&self, _: &RsvgNode, _: *const RsvgHandle, pbag: *const RsvgPropertyBag) -> NodeResult {
- self.units.set (property_bag::parse_or_default (pbag, "markerUnits")?);
+ self.units.set (property_bag::parse_or_default (pbag, "markerUnits", ())?);
self.ref_x.set (property_bag::length_or_default (pbag, "refX", LengthDir::Horizontal)?);
self.ref_y.set (property_bag::length_or_default (pbag, "refY", LengthDir::Vertical)?);
@@ -207,10 +209,10 @@ impl NodeTrait for NodeMarker {
.check_nonnegative ()
.map_err (|e| NodeError::attribute_error ("markerHeight", e))?);
- self.orient.set (property_bag::parse_or_default (pbag, "orient")?);
- self.aspect.set (property_bag::parse_or_default (pbag, "preserveAspectRatio")?);
- self.vbox.set (property_bag::parse_or_none (pbag, "viewBox")?);
- self.aspect.set (property_bag::parse_or_default (pbag, "preserveAspectRatio")?);
+ self.orient.set (property_bag::parse_or_default (pbag, "orient", ())?);
+ self.aspect.set (property_bag::parse_or_default (pbag, "preserveAspectRatio", ())?);
+ self.vbox.set (property_bag::parse_or_none (pbag, "viewBox", ())?);
+ self.aspect.set (property_bag::parse_or_default (pbag, "preserveAspectRatio", ())?);
Ok (())
}
@@ -769,32 +771,32 @@ mod parser_tests {
#[test]
fn parsing_invalid_marker_units_yields_error () {
- assert! (is_parse_error (&MarkerUnits::from_str ("").map_err (|e| AttributeError::from (e))));
- assert! (is_parse_error (&MarkerUnits::from_str ("foo").map_err (|e| AttributeError::from (e))));
+ assert! (is_parse_error (&MarkerUnits::parse ("", ()).map_err (|e| AttributeError::from (e))));
+ assert! (is_parse_error (&MarkerUnits::parse ("foo", ()).map_err (|e| AttributeError::from (e))));
}
#[test]
fn parses_marker_units () {
- assert_eq! (MarkerUnits::from_str ("userSpaceOnUse"), Ok (MarkerUnits::UserSpaceOnUse));
- assert_eq! (MarkerUnits::from_str ("strokeWidth"), Ok (MarkerUnits::StrokeWidth));
+ assert_eq! (MarkerUnits::parse ("userSpaceOnUse", ()), Ok (MarkerUnits::UserSpaceOnUse));
+ assert_eq! (MarkerUnits::parse ("strokeWidth", ()), Ok (MarkerUnits::StrokeWidth));
}
#[test]
fn parsing_invalid_marker_orient_yields_error () {
- assert! (is_parse_error (&MarkerOrient::from_str ("").map_err (|e| AttributeError::from (e))));
- assert! (is_parse_error (&MarkerOrient::from_str ("blah").map_err (|e| AttributeError::from (e))));
- assert! (is_parse_error (&MarkerOrient::from_str ("45blah").map_err (|e| AttributeError::from (e))));
+ assert! (is_parse_error (&MarkerOrient::parse ("", ()).map_err (|e| AttributeError::from (e))));
+ assert! (is_parse_error (&MarkerOrient::parse ("blah", ()).map_err (|e| AttributeError::from (e))));
+ assert! (is_parse_error (&MarkerOrient::parse ("45blah", ()).map_err (|e| AttributeError::from
(e))));
}
#[test]
fn parses_marker_orient () {
- assert_eq! (MarkerOrient::from_str ("auto"), Ok (MarkerOrient::Auto));
+ assert_eq! (MarkerOrient::parse ("auto", ()), Ok (MarkerOrient::Auto));
- assert_eq! (MarkerOrient::from_str ("0"), Ok (MarkerOrient::Degrees (0.0)));
- assert_eq! (MarkerOrient::from_str ("180"), Ok (MarkerOrient::Degrees (180.0)));
- assert_eq! (MarkerOrient::from_str ("180deg"), Ok (MarkerOrient::Degrees (180.0)));
- assert_eq! (MarkerOrient::from_str ("-400grad"), Ok (MarkerOrient::Degrees (-360.0)));
- assert_eq! (MarkerOrient::from_str ("1rad"), Ok (MarkerOrient::Degrees (180.0 / PI)));
+ assert_eq! (MarkerOrient::parse ("0", ()), Ok (MarkerOrient::Degrees (0.0)));
+ assert_eq! (MarkerOrient::parse ("180", ()), Ok (MarkerOrient::Degrees (180.0)));
+ assert_eq! (MarkerOrient::parse ("180deg", ()), Ok (MarkerOrient::Degrees (180.0)));
+ assert_eq! (MarkerOrient::parse ("-400grad", ()), Ok (MarkerOrient::Degrees (-360.0)));
+ assert_eq! (MarkerOrient::parse ("1rad", ()), Ok (MarkerOrient::Degrees (180.0 / PI)));
}
}
diff --git a/rust/src/paint_server.rs b/rust/src/paint_server.rs
index e5f0342..3e5af59 100644
--- a/rust/src/paint_server.rs
+++ b/rust/src/paint_server.rs
@@ -1,8 +1,7 @@
use ::cairo;
-use std::str::FromStr;
-
use error::*;
+use parsers::Parse;
use parsers::ParseError;
/// Defines the units to be used for scaling paint servers, per the [svg specification].
@@ -14,10 +13,11 @@ pub enum PaintServerUnits {
ObjectBoundingBox
}
-impl FromStr for PaintServerUnits {
+impl Parse for PaintServerUnits {
+ type Data = ();
type Err = AttributeError;
- fn from_str (s: &str) -> Result<PaintServerUnits, AttributeError> {
+ fn parse (s: &str, _: ()) -> Result<PaintServerUnits, AttributeError> {
match s {
"userSpaceOnUse" => Ok (PaintServerUnits::UserSpaceOnUse),
"objectBoundingBox" => Ok (PaintServerUnits::ObjectBoundingBox),
@@ -32,14 +32,14 @@ impl Default for PaintServerUnits {
}
}
-// We define this as a newtype so we can impl FromStr on it
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct PaintServerSpread (pub cairo::enums::Extend);
-impl FromStr for PaintServerSpread {
+impl Parse for PaintServerSpread {
+ type Data = ();
type Err = AttributeError;
- fn from_str (s: &str) -> Result <PaintServerSpread, AttributeError> {
+ fn parse (s: &str, _: ()) -> Result <PaintServerSpread, AttributeError> {
match s {
"pad" => Ok (PaintServerSpread (cairo::enums::Extend::Pad)),
"reflect" => Ok (PaintServerSpread (cairo::enums::Extend::Reflect)),
@@ -58,31 +58,30 @@ impl Default for PaintServerSpread {
#[cfg(test)]
mod tests {
use super::*;
- use std::str::FromStr;
#[test]
fn parsing_invalid_strings_yields_error () {
- assert! (PaintServerUnits::from_str ("").is_err ());
- assert! (PaintServerUnits::from_str ("foo").is_err ());
+ assert! (PaintServerUnits::parse ("", ()).is_err ());
+ assert! (PaintServerUnits::parse ("foo", ()).is_err ());
}
#[test]
fn parses_paint_server_units () {
- assert_eq! (PaintServerUnits::from_str ("userSpaceOnUse"), Ok (PaintServerUnits::UserSpaceOnUse));
- assert_eq! (PaintServerUnits::from_str ("objectBoundingBox"), Ok
(PaintServerUnits::ObjectBoundingBox));
+ assert_eq! (PaintServerUnits::parse ("userSpaceOnUse", ()), Ok (PaintServerUnits::UserSpaceOnUse));
+ assert_eq! (PaintServerUnits::parse ("objectBoundingBox", ()), Ok
(PaintServerUnits::ObjectBoundingBox));
}
#[test]
fn parses_spread_method () {
- assert_eq! (PaintServerSpread::from_str ("pad"),
+ assert_eq! (PaintServerSpread::parse ("pad", ()),
Ok (PaintServerSpread (cairo::enums::Extend::Pad)));
- assert_eq! (PaintServerSpread::from_str ("reflect"),
+ assert_eq! (PaintServerSpread::parse ("reflect", ()),
Ok (PaintServerSpread (cairo::enums::Extend::Reflect)));
- assert_eq! (PaintServerSpread::from_str ("repeat"),
+ assert_eq! (PaintServerSpread::parse ("repeat", ()),
Ok (PaintServerSpread (cairo::enums::Extend::Repeat)));
- assert! (PaintServerSpread::from_str ("foobar").is_err ());
+ assert! (PaintServerSpread::parse ("foobar", ()).is_err ());
}
}
diff --git a/rust/src/parsers.rs b/rust/src/parsers.rs
index 70d2449..4130a50 100644
--- a/rust/src/parsers.rs
+++ b/rust/src/parsers.rs
@@ -26,6 +26,13 @@ impl<'a> From<BasicParseError<'a>> for ParseError {
}
}
+pub trait Parse: Sized {
+ type Data;
+ type Err;
+
+ fn parse (s: &str, data: Self::Data) -> Result<Self, Self::Err>;
+}
+
// angle:
// https://www.w3.org/TR/SVG/types.html#DataTypeAngle
//
diff --git a/rust/src/pattern.rs b/rust/src/pattern.rs
index 901cb73..a3b31e8 100644
--- a/rust/src/pattern.rs
+++ b/rust/src/pattern.rs
@@ -5,7 +5,6 @@ use ::libc;
use std::cell::RefCell;
use std::rc::*;
-use std::str::FromStr;
use cairo::MatrixTrait;
use cairo::Pattern as CairoPattern;
@@ -19,6 +18,7 @@ use handle::RsvgHandle;
use length::*;
use node::*;
use paint_server::*;
+use parsers::Parse;
use property_bag;
use property_bag::*;
use util::*;
@@ -83,11 +83,12 @@ impl Default for PatternContentUnits {
}
}
-impl FromStr for PatternContentUnits {
+impl Parse for PatternContentUnits {
+ type Data = ();
type Err = AttributeError;
- fn from_str (s: &str) -> Result<PatternContentUnits, AttributeError> {
- Ok (PatternContentUnits::from (PaintServerUnits::from_str (s)?))
+ fn parse (s: &str, _: ()) -> Result<PatternContentUnits, AttributeError> {
+ Ok (PatternContentUnits::from (PaintServerUnits::parse (s, ())?))
}
}
@@ -198,11 +199,11 @@ impl NodeTrait for NodePattern {
p.node = Some (Rc::downgrade (node));
- p.units = property_bag::parse_or_none (pbag, "patternUnits")?;
- p.content_units = property_bag::parse_or_none (pbag, "patternContentUnits")?;
- p.vbox = property_bag::parse_or_none (pbag, "viewBox")?.map (Some).or (None);
+ p.units = property_bag::parse_or_none (pbag, "patternUnits", ())?;
+ p.content_units = property_bag::parse_or_none (pbag, "patternContentUnits", ())?;
+ p.vbox = property_bag::parse_or_none (pbag, "viewBox", ())?.map (Some).or (None);
- p.preserve_aspect_ratio = property_bag::parse_or_none (pbag, "preserveAspectRatio")?;
+ p.preserve_aspect_ratio = property_bag::parse_or_none (pbag, "preserveAspectRatio", ())?;
p.affine = property_bag::transform_or_none (pbag, "patternTransform")?;
diff --git a/rust/src/property_bag.rs b/rust/src/property_bag.rs
index 90b516f..271be08 100644
--- a/rust/src/property_bag.rs
+++ b/rust/src/property_bag.rs
@@ -2,11 +2,10 @@ use ::cairo;
use ::glib::translate::*;
use ::libc;
-use std::str::FromStr;
-
use error::*;
use length::*;
use transform::*;
+use parsers::Parse;
pub enum RsvgPropertyBag {}
@@ -66,14 +65,14 @@ pub fn length_or_value (pbag: *const RsvgPropertyBag, key: &'static str, length_
}
}
-pub fn parse_or_none<T> (pbag: *const RsvgPropertyBag, key: &'static str) -> Result <Option<T>, NodeError>
- where T: FromStr<Err = AttributeError>
+pub fn parse_or_none<T> (pbag: *const RsvgPropertyBag, key: &'static str, data: <T as Parse>::Data) ->
Result <Option<T>, NodeError>
+ where T: Parse<Err = AttributeError>
{
let value = lookup (pbag, key);
match value {
Some (v) => {
- T::from_str (&v).map (|v| Some (v))
+ T::parse (&v, data).map (|v| Some (v))
.map_err (|e| NodeError::attribute_error (key, e))
},
@@ -81,16 +80,16 @@ pub fn parse_or_none<T> (pbag: *const RsvgPropertyBag, key: &'static str) -> Res
}
}
-pub fn parse_or_default<T> (pbag: *const RsvgPropertyBag, key: &'static str) -> Result <T, NodeError>
- where T: Default + FromStr<Err = AttributeError> + Copy
+pub fn parse_or_default<T> (pbag: *const RsvgPropertyBag, key: &'static str, data: <T as Parse>::Data) ->
Result <T, NodeError>
+ where T: Default + Parse<Err = AttributeError> + Copy
{
- parse_or_value (pbag, key, T::default ())
+ parse_or_value (pbag, key, data, T::default ())
}
-pub fn parse_or_value<T> (pbag: *const RsvgPropertyBag, key: &'static str, value: T) -> Result <T, NodeError>
- where T: Default + FromStr<Err = AttributeError> + Copy
+pub fn parse_or_value<T> (pbag: *const RsvgPropertyBag, key: &'static str, data: <T as Parse>::Data, value:
T) -> Result <T, NodeError>
+ where T: Default + Parse<Err = AttributeError> + Copy
{
- let r = parse_or_none::<T> (pbag, key);
+ let r = parse_or_none::<T> (pbag, key, data);
match r {
Ok (Some (v)) => Ok (v),
diff --git a/rust/src/structure.rs b/rust/src/structure.rs
index 6f3bbbb..e660b19 100644
--- a/rust/src/structure.rs
+++ b/rust/src/structure.rs
@@ -135,7 +135,7 @@ impl NodeSvg {
impl NodeTrait for NodeSvg {
fn set_atts (&self, node: &RsvgNode, _: *const RsvgHandle, pbag: *const RsvgPropertyBag) -> NodeResult {
- self.preserve_aspect_ratio.set (property_bag::parse_or_default (pbag, "preserveAspectRatio")?);
+ self.preserve_aspect_ratio.set (property_bag::parse_or_default (pbag, "preserveAspectRatio", ())?);
// x & y attributes have no effect on outermost svg
// http://www.w3.org/TR/SVG/struct.html#SVGElement
@@ -152,7 +152,7 @@ impl NodeTrait for NodeSvg {
.and_then (|l| l.check_nonnegative ()
.map_err (|e| NodeError::attribute_error ("height", e)))?);
- self.vbox.set (property_bag::parse_or_none (pbag, "viewBox")?);
+ self.vbox.set (property_bag::parse_or_none (pbag, "viewBox", ())?);
// The "style" sub-element is not loaded yet here, so we need
// to store other attributes to be applied later.
@@ -419,8 +419,8 @@ impl NodeSymbol {
impl NodeTrait for NodeSymbol {
fn set_atts (&self, _: &RsvgNode, _: *const RsvgHandle, pbag: *const RsvgPropertyBag) -> NodeResult {
- self.preserve_aspect_ratio.set (property_bag::parse_or_default (pbag, "preserveAspectRatio")?);
- self.vbox.set (property_bag::parse_or_none (pbag, "viewBox")?);
+ self.preserve_aspect_ratio.set (property_bag::parse_or_default (pbag, "preserveAspectRatio", ())?);
+ self.vbox.set (property_bag::parse_or_none (pbag, "viewBox", ())?);
Ok (())
}
diff --git a/rust/src/viewbox.rs b/rust/src/viewbox.rs
index 9abe7a2..1e882f7 100644
--- a/rust/src/viewbox.rs
+++ b/rust/src/viewbox.rs
@@ -2,10 +2,9 @@ use ::cairo;
use ::glib_sys;
use ::glib;
-use std::str::FromStr;
-
use error::*;
use parsers;
+use parsers::Parse;
use parsers::{ListLength, ParseError};
use self::glib::translate::*;
@@ -40,7 +39,8 @@ impl From<Option<ViewBox>> for RsvgViewBox {
}
}
-impl FromStr for ViewBox {
+impl Parse for ViewBox {
+ type Data = ();
type Err = AttributeError;
// Parse a viewBox attribute
@@ -51,7 +51,7 @@ impl FromStr for ViewBox {
// x, y, w, h
//
// Where w and h must be nonnegative.
- fn from_str (s: &str) -> Result<ViewBox, AttributeError> {
+ fn parse (s: &str, _: ()) -> Result<ViewBox, AttributeError> {
let v = parsers::number_list (s, ListLength::Exact (4))
.map_err (|_| ParseError::new ("string does not match 'x [,] y [,] w [,] h'"))?;
@@ -71,17 +71,16 @@ impl FromStr for ViewBox {
#[cfg(test)]
mod tests {
use super::*;
- use std::str::FromStr;
#[test]
fn parses_valid_viewboxes () {
- assert_eq! (ViewBox::from_str (" 1 2 3 4"),
+ assert_eq! (ViewBox::parse (" 1 2 3 4", ()),
Ok (ViewBox (cairo::Rectangle { x: 1.0,
y: 2.0,
width: 3.0,
height: 4.0 })));
- assert_eq! (ViewBox::from_str (" -1.5 -2.5e1,34,56e2 "),
+ assert_eq! (ViewBox::parse (" -1.5 -2.5e1,34,56e2 ", ()),
Ok (ViewBox (cairo::Rectangle { x: -1.5,
y: -25.0,
width: 34.0,
@@ -90,14 +89,14 @@ mod tests {
#[test]
fn parsing_invalid_viewboxes_yields_error () {
- assert! (is_parse_error (&ViewBox::from_str ("")));
+ assert! (is_parse_error (&ViewBox::parse ("", ())));
- assert! (is_value_error (&ViewBox::from_str (" 1,2,-3,-4 ")));
+ assert! (is_value_error (&ViewBox::parse (" 1,2,-3,-4 ", ())));
- assert! (is_parse_error (&ViewBox::from_str ("qwerasdfzxcv")));
+ assert! (is_parse_error (&ViewBox::parse ("qwerasdfzxcv", ())));
- assert! (is_parse_error (&ViewBox::from_str (" 1 2 3 4 5")));
+ assert! (is_parse_error (&ViewBox::parse (" 1 2 3 4 5", ())));
- assert! (is_parse_error (&ViewBox::from_str (" 1 2 foo 3 4")));
+ assert! (is_parse_error (&ViewBox::parse (" 1 2 foo 3 4", ())));
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]