[librsvg] parse_or_*() - Take an extra argument, a validation function
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] parse_or_*() - Take an extra argument, a validation function
- Date: Tue, 5 Sep 2017 15:05:22 +0000 (UTC)
commit 5c9b8bb3114047da98b11b29541def1fcba1e706
Author: Federico Mena Quintero <federico gnome org>
Date: Tue Sep 5 08:32:49 2017 -0500
parse_or_*() - Take an extra argument, a validation function
We'll use this to contain the extraction/parsing/validation of an
attribute into a single function call, instead of making the caller
implement the validation separately.
rust/src/gradient.rs | 25 +++++++++++++------------
rust/src/marker.rs | 20 +++++++++++---------
rust/src/pattern.rs | 18 +++++++++---------
rust/src/property_bag.rs | 35 ++++++++++++++++++++++++++---------
rust/src/shapes.rs | 34 +++++++++++++++++-----------------
rust/src/stop.rs | 2 +-
rust/src/structure.rs | 32 ++++++++++++++++++++------------
7 files changed, 97 insertions(+), 69 deletions(-)
---
diff --git a/rust/src/gradient.rs b/rust/src/gradient.rs
index 3150fc7..e1cc313 100644
--- a/rust/src/gradient.rs
+++ b/rust/src/gradient.rs
@@ -10,6 +10,7 @@ use cairo::MatrixTrait;
use bbox::*;
use drawing_ctx;
use drawing_ctx::RsvgDrawingCtx;
+use error::*;
use handle::RsvgHandle;
use length::*;
use node::*;
@@ -557,9 +558,9 @@ impl NodeTrait for NodeGradient {
// Attributes common to linear and radial gradients
- g.common.units = property_bag::parse_or_none (pbag, "gradientUnits", ())?;
- g.common.affine = property_bag::parse_or_none (pbag, "gradientTransform", ())?;
- g.common.spread = property_bag::parse_or_none (pbag, "spreadMethod", ())?;
+ g.common.units = property_bag::parse_or_none (pbag, "gradientUnits", (), None)?;
+ g.common.affine = property_bag::parse_or_none (pbag, "gradientTransform", (), None)?;
+ g.common.spread = property_bag::parse_or_none (pbag, "spreadMethod", (), None)?;
g.common.fallback = property_bag::lookup (pbag, "xlink:href");
// Attributes specific to each gradient type. The defaults mandated by the spec
@@ -568,20 +569,20 @@ impl NodeTrait for NodeGradient {
match node.get_type () {
NodeType::LinearGradient => {
g.variant = GradientVariant::Linear {
- x1: property_bag::parse_or_none (pbag, "x1", LengthDir::Horizontal)?,
- y1: property_bag::parse_or_none (pbag, "y1", LengthDir::Vertical)?,
- x2: property_bag::parse_or_none (pbag, "x2", LengthDir::Horizontal)?,
- y2: property_bag::parse_or_none (pbag, "y2", LengthDir::Vertical)?
+ x1: property_bag::parse_or_none (pbag, "x1", LengthDir::Horizontal, None)?,
+ y1: property_bag::parse_or_none (pbag, "y1", LengthDir::Vertical, None)?,
+ x2: property_bag::parse_or_none (pbag, "x2", LengthDir::Horizontal, None)?,
+ y2: property_bag::parse_or_none (pbag, "y2", LengthDir::Vertical, None)?
};
},
NodeType::RadialGradient => {
g.variant = GradientVariant::Radial {
- cx: property_bag::parse_or_none (pbag, "cx", LengthDir::Horizontal)?,
- cy: property_bag::parse_or_none (pbag, "cy", LengthDir::Vertical)?,
- r: property_bag::parse_or_none (pbag, "r", LengthDir::Both)?,
- fx: property_bag::parse_or_none (pbag, "fx", LengthDir::Horizontal)?,
- fy: property_bag::parse_or_none (pbag, "fy", LengthDir::Vertical)?
+ cx: property_bag::parse_or_none (pbag, "cx", LengthDir::Horizontal, None)?,
+ cy: property_bag::parse_or_none (pbag, "cy", LengthDir::Vertical, None)?,
+ r: property_bag::parse_or_none (pbag, "r", LengthDir::Both, None)?,
+ fx: property_bag::parse_or_none (pbag, "fx", LengthDir::Horizontal, None)?,
+ fy: property_bag::parse_or_none (pbag, "fy", LengthDir::Vertical, None)?
};
},
diff --git a/rust/src/marker.rs b/rust/src/marker.rs
index f4c0164..3c82461 100644
--- a/rust/src/marker.rs
+++ b/rust/src/marker.rs
@@ -192,27 +192,29 @@ 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", (), None)?);
- self.ref_x.set (property_bag::parse_or_default (pbag, "refX", LengthDir::Horizontal)?);
- self.ref_y.set (property_bag::parse_or_default (pbag, "refY", LengthDir::Vertical)?);
+ self.ref_x.set (property_bag::parse_or_default (pbag, "refX", LengthDir::Horizontal, None)?);
+ self.ref_y.set (property_bag::parse_or_default (pbag, "refY", LengthDir::Vertical, None)?);
self.width.set (property_bag::parse_or_value (pbag, "markerWidth",
LengthDir::Horizontal,
- NodeMarker::get_default_size (LengthDir::Horizontal))?
+ NodeMarker::get_default_size (LengthDir::Horizontal),
+ None)?
.check_nonnegative ()
.map_err (|e| NodeError::attribute_error ("markerWidth", e))?);
self.height.set (property_bag::parse_or_value (pbag, "markerHeight",
LengthDir::Vertical,
- NodeMarker::get_default_size (LengthDir::Vertical))?
+ NodeMarker::get_default_size (LengthDir::Vertical),
+ None)?
.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", (), None)?);
+ self.aspect.set (property_bag::parse_or_default (pbag, "preserveAspectRatio", (), None)?);
+ self.vbox.set (property_bag::parse_or_none (pbag, "viewBox", (), None)?);
+ self.aspect.set (property_bag::parse_or_default (pbag, "preserveAspectRatio", (), None)?);
Ok (())
}
diff --git a/rust/src/pattern.rs b/rust/src/pattern.rs
index fdf7dce..c601edf 100644
--- a/rust/src/pattern.rs
+++ b/rust/src/pattern.rs
@@ -199,20 +199,20 @@ 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", (), None)?;
+ p.content_units = property_bag::parse_or_none (pbag, "patternContentUnits", (), None)?;
+ p.vbox = property_bag::parse_or_none (pbag, "viewBox", (), None)?.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", (), None)?;
- p.affine = property_bag::parse_or_none (pbag, "patternTransform", ())?;
+ p.affine = property_bag::parse_or_none (pbag, "patternTransform", (), None)?;
p.fallback = property_bag::lookup (pbag, "xlink:href");
- p.x = property_bag::parse_or_none (pbag, "x", LengthDir::Horizontal)?;
- p.y = property_bag::parse_or_none (pbag, "y", LengthDir::Vertical)?;
- p.width = property_bag::parse_or_none (pbag, "width", LengthDir::Horizontal)?;
- p.height = property_bag::parse_or_none (pbag, "height", LengthDir::Vertical)?;
+ p.x = property_bag::parse_or_none (pbag, "x", LengthDir::Horizontal, None)?;
+ p.y = property_bag::parse_or_none (pbag, "y", LengthDir::Vertical, None)?;
+ p.width = property_bag::parse_or_none (pbag, "width", LengthDir::Horizontal, None)?;
+ p.height = property_bag::parse_or_none (pbag, "height", LengthDir::Vertical, None)?;
Ok (())
}
diff --git a/rust/src/property_bag.rs b/rust/src/property_bag.rs
index 90d06f7..0d32b3b 100644
--- a/rust/src/property_bag.rs
+++ b/rust/src/property_bag.rs
@@ -32,31 +32,48 @@ pub fn free (pbag: *mut RsvgPropertyBag) {
}
}
-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>
+pub fn parse_or_none<T> (pbag: *const RsvgPropertyBag,
+ key: &'static str,
+ data: <T as Parse>::Data,
+ validate: Option<fn(T) -> Result<T, AttributeError>>) -> Result <Option<T>,
NodeError>
+ where T: Parse<Err = AttributeError> + Copy
{
let value = lookup (pbag, key);
match value {
Some (v) => {
- T::parse (&v, data).map (|v| Some (v))
+ T::parse (&v, data)
+ .and_then (|v|
+ if let Some(validate) = validate {
+ validate(v)
+ .map(|v| Some(v))
+ } else {
+ Ok(Some(v))
+ })
.map_err (|e| NodeError::attribute_error (key, e))
},
- None => Ok (None)
+ None => Ok(None)
}
}
-pub fn parse_or_default<T> (pbag: *const RsvgPropertyBag, key: &'static str, data: <T as Parse>::Data) ->
Result <T, NodeError>
+pub fn parse_or_default<T> (pbag: *const RsvgPropertyBag,
+ key: &'static str,
+ data: <T as Parse>::Data,
+ validate: Option<fn(T) -> Result<T, AttributeError>>) -> Result <T, NodeError>
where T: Default + Parse<Err = AttributeError> + Copy
{
- parse_or_value (pbag, key, data, T::default ())
+ parse_or_value (pbag, key, data, T::default (), validate)
}
-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
+pub fn parse_or_value<T> (pbag: *const RsvgPropertyBag,
+ key: &'static str,
+ data: <T as Parse>::Data,
+ value: T,
+ validate: Option<fn(T) -> Result<T, AttributeError>>) -> Result <T, NodeError>
+ where T: Parse<Err = AttributeError> + Copy
{
- let r = parse_or_none::<T> (pbag, key, data);
+ let r = parse_or_none (pbag, key, data, validate);
match r {
Ok (Some (v)) => Ok (v),
diff --git a/rust/src/shapes.rs b/rust/src/shapes.rs
index 360e886..6705d75 100644
--- a/rust/src/shapes.rs
+++ b/rust/src/shapes.rs
@@ -201,10 +201,10 @@ impl NodeLine {
impl NodeTrait for NodeLine {
fn set_atts (&self, _: &RsvgNode, _: *const RsvgHandle, pbag: *const RsvgPropertyBag) -> NodeResult {
- self.x1.set (property_bag::parse_or_default (pbag, "x1", LengthDir::Horizontal)?);
- self.y1.set (property_bag::parse_or_default (pbag, "y1", LengthDir::Vertical)?);
- self.x2.set (property_bag::parse_or_default (pbag, "x2", LengthDir::Horizontal)?);
- self.y2.set (property_bag::parse_or_default (pbag, "y2", LengthDir::Vertical)?);
+ self.x1.set (property_bag::parse_or_default (pbag, "x1", LengthDir::Horizontal, None)?);
+ self.y1.set (property_bag::parse_or_default (pbag, "y1", LengthDir::Vertical, None)?);
+ self.x2.set (property_bag::parse_or_default (pbag, "x2", LengthDir::Horizontal, None)?);
+ self.y2.set (property_bag::parse_or_default (pbag, "y2", LengthDir::Vertical, None)?);
Ok (())
}
@@ -258,13 +258,13 @@ impl NodeRect {
impl NodeTrait for NodeRect {
fn set_atts (&self, _: &RsvgNode, _: *const RsvgHandle, pbag: *const RsvgPropertyBag) -> NodeResult {
- self.x.set (property_bag::parse_or_default (pbag, "x", LengthDir::Horizontal)?);
- self.y.set (property_bag::parse_or_default (pbag, "y", LengthDir::Vertical)?);
- self.w.set (property_bag::parse_or_default (pbag, "width", LengthDir::Horizontal)?);
- self.h.set (property_bag::parse_or_default (pbag, "height", LengthDir::Vertical)?);
+ self.x.set (property_bag::parse_or_default (pbag, "x", LengthDir::Horizontal, None)?);
+ self.y.set (property_bag::parse_or_default (pbag, "y", LengthDir::Vertical, None)?);
+ self.w.set (property_bag::parse_or_default (pbag, "width", LengthDir::Horizontal, None)?);
+ self.h.set (property_bag::parse_or_default (pbag, "height", LengthDir::Vertical, None)?);
- self.rx.set (property_bag::parse_or_none (pbag, "rx", LengthDir::Horizontal)?);
- self.ry.set (property_bag::parse_or_none (pbag, "ry", LengthDir::Vertical)?);
+ self.rx.set (property_bag::parse_or_none (pbag, "rx", LengthDir::Horizontal, None)?);
+ self.ry.set (property_bag::parse_or_none (pbag, "ry", LengthDir::Vertical, None)?);
Ok (())
}
@@ -433,10 +433,10 @@ impl NodeCircle {
impl NodeTrait for NodeCircle {
fn set_atts (&self, _: &RsvgNode, _: *const RsvgHandle, pbag: *const RsvgPropertyBag) -> NodeResult {
- self.cx.set (property_bag::parse_or_default (pbag, "cx", LengthDir::Horizontal)?);
- self.cy.set (property_bag::parse_or_default (pbag, "cy", LengthDir::Vertical)?);
+ self.cx.set (property_bag::parse_or_default (pbag, "cx", LengthDir::Horizontal, None)?);
+ self.cy.set (property_bag::parse_or_default (pbag, "cy", LengthDir::Vertical, None)?);
- self.r.set (property_bag::parse_or_default (pbag, "r", LengthDir::Both)
+ self.r.set (property_bag::parse_or_default (pbag, "r", LengthDir::Both, None)
.and_then (|l: RsvgLength| l.check_nonnegative ()
.map_err (|e| NodeError::attribute_error ("r", e)))?);
@@ -478,14 +478,14 @@ impl NodeEllipse {
impl NodeTrait for NodeEllipse {
fn set_atts (&self, _: &RsvgNode, _: *const RsvgHandle, pbag: *const RsvgPropertyBag) -> NodeResult {
- self.cx.set (property_bag::parse_or_default (pbag, "cx", LengthDir::Horizontal)?);
- self.cy.set (property_bag::parse_or_default (pbag, "cy", LengthDir::Vertical)?);
+ self.cx.set (property_bag::parse_or_default (pbag, "cx", LengthDir::Horizontal, None)?);
+ self.cy.set (property_bag::parse_or_default (pbag, "cy", LengthDir::Vertical, None)?);
- self.rx.set (property_bag::parse_or_default (pbag, "rx", LengthDir::Horizontal)
+ self.rx.set (property_bag::parse_or_default (pbag, "rx", LengthDir::Horizontal, None)
.and_then (|l: RsvgLength| l.check_nonnegative ()
.map_err (|e| NodeError::attribute_error ("rx", e)))?);
- self.ry.set (property_bag::parse_or_default (pbag, "ry", LengthDir::Vertical)
+ self.ry.set (property_bag::parse_or_default (pbag, "ry", LengthDir::Vertical, None)
.and_then (|l: RsvgLength| l.check_nonnegative ()
.map_err (|e| NodeError::attribute_error ("ry", e)))?);
diff --git a/rust/src/stop.rs b/rust/src/stop.rs
index 780b8ea..fd51511 100644
--- a/rust/src/stop.rs
+++ b/rust/src/stop.rs
@@ -40,7 +40,7 @@ impl NodeStop {
impl NodeTrait for NodeStop {
fn set_atts (&self, node: &RsvgNode, handle: *const RsvgHandle, pbag: *const RsvgPropertyBag) ->
NodeResult {
- let offset_length: RsvgLength = property_bag::parse_or_default (pbag, "offset", LengthDir::Both)?;
+ let offset_length: RsvgLength = property_bag::parse_or_default (pbag, "offset", LengthDir::Both,
None)?;
match offset_length.unit {
LengthUnit::Default |
LengthUnit::Percent => {
diff --git a/rust/src/structure.rs b/rust/src/structure.rs
index fea1e41..c9edbb3 100644
--- a/rust/src/structure.rs
+++ b/rust/src/structure.rs
@@ -136,24 +136,32 @@ 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", (),
None)?);
// x & y attributes have no effect on outermost svg
// http://www.w3.org/TR/SVG/struct.html#SVGElement
if node.get_parent ().is_some () {
- self.x.set (property_bag::parse_or_default (pbag, "x", LengthDir::Horizontal)?);
- self.y.set (property_bag::parse_or_default (pbag, "y", LengthDir::Vertical)?);
+ self.x.set (property_bag::parse_or_default (pbag, "x", LengthDir::Horizontal, None)?);
+ self.y.set (property_bag::parse_or_default (pbag, "y", LengthDir::Vertical, None)?);
}
- self.w.set (property_bag::parse_or_value (pbag, "width", LengthDir::Horizontal, RsvgLength::parse
("100%", LengthDir::Horizontal).unwrap ())
+ self.w.set (property_bag::parse_or_value (pbag,
+ "width",
+ LengthDir::Horizontal,
+ RsvgLength::parse ("100%", LengthDir::Horizontal).unwrap
(),
+ None)
.and_then (|l| l.check_nonnegative ()
.map_err (|e| NodeError::attribute_error ("width", e)))?);
- self.h.set (property_bag::parse_or_value (pbag, "height", LengthDir::Vertical, RsvgLength::parse
("100%", LengthDir::Vertical).unwrap ())
+ self.h.set (property_bag::parse_or_value (pbag,
+ "height",
+ LengthDir::Vertical,
+ RsvgLength::parse ("100%", LengthDir::Vertical).unwrap (),
+ None)
.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", (), None)?);
// The "style" sub-element is not loaded yet here, so we need
// to store other attributes to be applied later.
@@ -265,10 +273,10 @@ impl NodeTrait for NodeUse {
fn set_atts (&self, _: &RsvgNode, _: *const RsvgHandle, pbag: *const RsvgPropertyBag) -> NodeResult {
*self.link.borrow_mut () = property_bag::lookup (pbag, "xlink:href");
- self.x.set (property_bag::parse_or_default (pbag, "x", LengthDir::Horizontal)?);
- self.y.set (property_bag::parse_or_default (pbag, "y", LengthDir::Vertical)?);
+ self.x.set (property_bag::parse_or_default (pbag, "x", LengthDir::Horizontal, None)?);
+ self.y.set (property_bag::parse_or_default (pbag, "y", LengthDir::Vertical, None)?);
- let opt_w: Option<RsvgLength> = property_bag::parse_or_none (pbag, "width", LengthDir::Horizontal)?;
+ let opt_w: Option<RsvgLength> = property_bag::parse_or_none (pbag, "width", LengthDir::Horizontal,
None)?;
self.w.set (match opt_w {
Some (w) => {
Some (w.check_nonnegative ().map_err (|e| NodeError::attribute_error ("width", e))?)
@@ -279,7 +287,7 @@ impl NodeTrait for NodeUse {
}
});
- let opt_h: Option<RsvgLength> = property_bag::parse_or_none (pbag, "height", LengthDir::Vertical)?;
+ let opt_h: Option<RsvgLength> = property_bag::parse_or_none (pbag, "height", LengthDir::Vertical,
None)?;
let h = match opt_h {
Some (h) => {
Some (h.check_nonnegative ().map_err (|e| NodeError::attribute_error ("height", e))?)
@@ -420,8 +428,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", (),
None)?);
+ self.vbox.set (property_bag::parse_or_none (pbag, "viewBox", (), None)?);
Ok (())
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]