[librsvg] viewbox.rs: Implement FromStr for RsvgViewBox based on the parsers
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg] viewbox.rs: Implement FromStr for RsvgViewBox based on the parsers
- Date: Wed, 22 Feb 2017 03:39:16 +0000 (UTC)
commit 9a927252b2a4d7e81aa12b3201d5757deb571560
Author: Federico Mena Quintero <federico gnome org>
Date: Tue Feb 21 21:19:59 2017 -0600
viewbox.rs: Implement FromStr for RsvgViewBox based on the parsers
parsers.rs: Don't validate the viewBox's width and height here; do it upstream
rust/src/parsers.rs | 26 +++++++++-----
rust/src/viewbox.rs | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 115 insertions(+), 10 deletions(-)
---
diff --git a/rust/src/parsers.rs b/rust/src/parsers.rs
index 364eacc..f8a5681 100644
--- a/rust/src/parsers.rs
+++ b/rust/src/parsers.rs
@@ -61,15 +61,15 @@ named! (pub comma,
// Where w and h must be nonnegative.
named! (pub view_box<(f64, f64, f64, f64)>,
- verify! (ws! (do_parse! (x: double >>
- opt! (comma) >>
- y: double >>
- opt! (comma) >>
- w: double >>
- opt! (comma) >>
- h: double >>
- (x, y, w, h))),
- |(x, y, w, h)| w >= 0.0 && h >= 0.0));
+ ws! (do_parse! (x: double >>
+ opt! (comma) >>
+ y: double >>
+ opt! (comma) >>
+ w: double >>
+ opt! (comma) >>
+ h: double >>
+ eof! () >>
+ (x, y, w, h))));
#[cfg(test)]
mod tests {
@@ -93,5 +93,13 @@ mod tests {
#[test]
fn parses_view_box () {
assert_eq! (view_box (b"1 2 3 4"), IResult::Done (&b""[..], (1.0, 2.0, 3.0, 4.0)));
+ assert_eq! (view_box (b"1,2,3 4"), IResult::Done (&b""[..], (1.0, 2.0, 3.0, 4.0)));
+
+ let result = view_box (b"1 2 3 4 5");
+
+ match result {
+ IResult::Error (_) => { },
+ _ => { panic! ("{:?}", result); }
+ }
}
}
diff --git a/rust/src/viewbox.rs b/rust/src/viewbox.rs
index 1799d22..e878bdb 100644
--- a/rust/src/viewbox.rs
+++ b/rust/src/viewbox.rs
@@ -1,8 +1,15 @@
extern crate cairo;
+use std::fmt;
+use std::str::FromStr;
+
+use nom::{IResult};
+
+use parsers;
+
/* Keep this in sync with rsvg-private.h:RsvgViewBox */
#[repr(C)]
-#[derive(Debug, Copy, Clone)]
+#[derive(Debug, Copy, Clone, PartialEq)]
pub struct RsvgViewBox {
pub rect: cairo::Rectangle,
pub active: bool
@@ -19,3 +26,93 @@ impl RsvgViewBox {
}
}
}
+
+impl Default for RsvgViewBox {
+ fn default () -> RsvgViewBox {
+ RsvgViewBox::new_inactive ()
+ }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub enum ParseViewBoxError {
+ NegativeWidthOrHeight, // In "x y w h", w and h must be nonnegative
+ Error // General parsing error
+}
+
+impl fmt::Display for ParseViewBoxError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ ParseViewBoxError::NegativeWidthOrHeight => {
+ "width and height must not be negative".fmt (f)
+ },
+
+ ParseViewBoxError::Error => {
+ "string does not match 'x [,] y [,] w [,] h'".fmt (f)
+ }
+ }
+ }
+}
+
+impl FromStr for RsvgViewBox {
+ type Err = ParseViewBoxError;
+
+ fn from_str (s: &str) -> Result<RsvgViewBox, ParseViewBoxError> {
+ let result = parsers::view_box (s.as_bytes ()).to_full_result ();
+
+ match result {
+ Ok ((x, y, w, h)) => {
+ if w >= 0.0 && h >= 0.0 {
+ Ok (RsvgViewBox { rect: cairo::Rectangle { x: x,
+ y: y,
+ width: w,
+ height: h },
+ active: true })
+ } else {
+ Err (ParseViewBoxError::NegativeWidthOrHeight)
+ }
+ },
+
+ Err (_) => {
+ Err (ParseViewBoxError::Error)
+ }
+ }
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use std::str::FromStr;
+
+ #[test]
+ fn parses_valid_viewboxes () {
+ assert_eq! (RsvgViewBox::from_str ("1 2 3 4"),
+ Ok (RsvgViewBox { rect: cairo::Rectangle { x: 1.0,
+ y: 2.0,
+ width: 3.0,
+ height: 4.0 },
+ active: true }));
+
+ assert_eq! (RsvgViewBox::from_str ("-1.5 -2.5e1,34,56e2"),
+ Ok (RsvgViewBox { rect: cairo::Rectangle { x: -1.5,
+ y: -25.0,
+ width: 34.0,
+ height: 5600.0 },
+ active: true }));
+ }
+
+ #[test]
+ fn parsing_invalid_viewboxes_yields_error () {
+ assert_eq! (RsvgViewBox::from_str (""),
+ Err (ParseViewBoxError::Error));
+
+ assert_eq! (RsvgViewBox::from_str ("1,2,-3,-4"),
+ Err (ParseViewBoxError::NegativeWidthOrHeight));
+
+ assert_eq! (RsvgViewBox::from_str ("qwerasdfzxcv"),
+ Err (ParseViewBoxError::Error));
+
+ assert_eq! (RsvgViewBox::from_str ("1 2 3 4 5"),
+ Err (ParseViewBoxError::Error));
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]