[librsvg: 8/43] Convert SingleFontFamily / FontFamily to CssParseError



commit 4fab2a5c0454fc656028ee43e2d425dd75883245
Author: Federico Mena Quintero <federico gnome org>
Date:   Thu Dec 19 20:17:02 2019 -0600

    Convert SingleFontFamily / FontFamily to CssParseError
    
    As a bonus, this now detects the empty string as an invalid
    SingleFontFamilty.

 rsvg_internals/src/font_props.rs      | 65 ++++++++++++++++++-----------------
 rsvg_internals/src/properties.rs      |  2 +-
 rsvg_internals/src/property_defs.rs   |  2 +-
 rsvg_internals/src/property_macros.rs |  2 +-
 4 files changed, 37 insertions(+), 34 deletions(-)
---
diff --git a/rsvg_internals/src/font_props.rs b/rsvg_internals/src/font_props.rs
index 2115471f..bf2d7a7b 100644
--- a/rsvg_internals/src/font_props.rs
+++ b/rsvg_internals/src/font_props.rs
@@ -1,6 +1,6 @@
 //! CSS font properties.
 
-use cssparser::{BasicParseError, Parser};
+use cssparser::Parser;
 
 use crate::drawing_ctx::ViewParams;
 use crate::error::*;
@@ -184,30 +184,33 @@ impl ParseToParseError for LetterSpacingSpec {
 #[derive(Debug, Clone, PartialEq)]
 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::parse_error("expected font family"))
-    }
-}
+impl ParseToParseError for SingleFontFamily {
+    fn parse_to_parse_error<'i>(
+        parser: &mut Parser<'i, '_>,
+    ) -> Result<SingleFontFamily, CssParseError<'i>> {
+        let loc = parser.current_source_location();
+
+        if let Ok(cow) = parser.try_parse(|p| p.expect_string_cloned()) {
+            if cow == "" {
+                return Err(loc.new_custom_error(ValueErrorKind::value_error(
+                    "empty string is not a valid font family name",
+                )));
+            }
 
-fn parse_single_font_family<'i>(
-    parser: &'i mut Parser<'_, '_>,
-) -> Result<SingleFontFamily, BasicParseError<'i>> {
-    if let Ok(cow) = parser.try_parse(|p| p.expect_string_cloned()) {
-        return Ok(SingleFontFamily((*cow).to_owned()));
-    }
+            return Ok(SingleFontFamily((*cow).to_owned()));
+        }
 
-    let first_ident = parser.expect_ident()?.clone();
+        let first_ident = parser.expect_ident()?.clone();
 
-    let mut value = first_ident.as_ref().to_owned();
+        let mut value = first_ident.as_ref().to_owned();
 
-    while let Ok(cow) = parser.try_parse(|p| p.expect_ident_cloned()) {
-        value.push(' ');
-        value.push_str(&cow);
-    }
+        while let Ok(cow) = parser.try_parse(|p| p.expect_ident_cloned()) {
+            value.push(' ');
+            value.push_str(&cow);
+        }
 
-    Ok(SingleFontFamily(value))
+        Ok(SingleFontFamily(value))
+    }
 }
 
 #[cfg(test)]
@@ -261,14 +264,16 @@ mod tests {
     #[test]
     fn computes_letter_spacing() {
         assert_eq!(
-            <LetterSpacingSpec as ParseToParseError>::parse_str_to_parse_error("normal").map(|s| 
s.compute()),
+            <LetterSpacingSpec as ParseToParseError>::parse_str_to_parse_error("normal")
+                .map(|s| s.compute()),
             Ok(LetterSpacingSpec::Value(Length::<Horizontal>::new(
                 0.0,
                 LengthUnit::Px,
             )))
         );
         assert_eq!(
-            <LetterSpacingSpec as ParseToParseError>::parse_str_to_parse_error("10em").map(|s| s.compute()),
+            <LetterSpacingSpec as ParseToParseError>::parse_str_to_parse_error("10em")
+                .map(|s| s.compute()),
             Ok(LetterSpacingSpec::Value(Length::<Horizontal>::new(
                 10.0,
                 LengthUnit::Em,
@@ -284,32 +289,30 @@ mod tests {
     #[test]
     fn parses_font_family() {
         assert_eq!(
-            <SingleFontFamily as Parse>::parse_str("'Hello world'"),
+            <SingleFontFamily as ParseToParseError>::parse_str_to_parse_error("'Hello world'"),
             Ok(SingleFontFamily("Hello world".to_owned()))
         );
 
         assert_eq!(
-            <SingleFontFamily as Parse>::parse_str("\"Hello world\""),
+            <SingleFontFamily as ParseToParseError>::parse_str_to_parse_error("\"Hello world\""),
             Ok(SingleFontFamily("Hello world".to_owned()))
         );
 
         assert_eq!(
-            <SingleFontFamily as Parse>::parse_str("  Hello  world  "),
+            <SingleFontFamily as ParseToParseError>::parse_str_to_parse_error("  Hello  world  "),
             Ok(SingleFontFamily("Hello world".to_owned()))
         );
 
         assert_eq!(
-            <SingleFontFamily as Parse>::parse_str("Plonk"),
+            <SingleFontFamily as ParseToParseError>::parse_str_to_parse_error("Plonk"),
             Ok(SingleFontFamily("Plonk".to_owned()))
         );
     }
 
     #[test]
     fn detects_invalid_font_family() {
-        assert!(<SingleFontFamily as Parse>::parse_str("").is_err());
-
-        // assert!(<SingleFontFamily as Parse>::parse_str("''").is_err());
-
-        assert!(<SingleFontFamily as Parse>::parse_str("42").is_err());
+        assert!(<SingleFontFamily as ParseToParseError>::parse_str_to_parse_error("").is_err());
+        assert!(<SingleFontFamily as ParseToParseError>::parse_str_to_parse_error("''").is_err());
+        assert!(<SingleFontFamily as ParseToParseError>::parse_str_to_parse_error("42").is_err());
     }
 }
diff --git a/rsvg_internals/src/properties.rs b/rsvg_internals/src/properties.rs
index 085a5ac1..e98b5e62 100644
--- a/rsvg_internals/src/properties.rs
+++ b/rsvg_internals/src/properties.rs
@@ -273,7 +273,7 @@ pub fn parse_property<'i>(prop_name: &QualName, input: &mut Parser<'i, '_>, acce
             Ok(ParsedProperty::FloodOpacity(parse_input(input)?)),
 
         expanded_name!(svg "font-family") =>
-            Ok(ParsedProperty::FontFamily(parse_input(input)?)),
+            Ok(ParsedProperty::FontFamily(parse_input_to_parse_error(input)?)),
 
         expanded_name!(svg "font-size") =>
             Ok(ParsedProperty::FontSize(parse_input_to_parse_error(input)?)),
diff --git a/rsvg_internals/src/property_defs.rs b/rsvg_internals/src/property_defs.rs
index 871ee83d..522bf6ca 100644
--- a/rsvg_internals/src/property_defs.rs
+++ b/rsvg_internals/src/property_defs.rs
@@ -223,7 +223,7 @@ make_property!(
     FontFamily,
     default: SingleFontFamily("Times New Roman".to_string()),
     inherits_automatically: true,
-    newtype_parse: SingleFontFamily,
+    newtype_parse_to_parse_error: SingleFontFamily,
 );
 
 // https://www.w3.org/TR/SVG/text.html#FontSizeProperty
diff --git a/rsvg_internals/src/property_macros.rs b/rsvg_internals/src/property_macros.rs
index dcbd9626..a24d1a2a 100644
--- a/rsvg_internals/src/property_macros.rs
+++ b/rsvg_internals/src/property_macros.rs
@@ -194,7 +194,7 @@ macro_rules! impl_property {
 mod tests {
     use super::*;
 
-    use crate::parsers::{Parse, ParseToParseError};
+    use crate::parsers::ParseToParseError;
     use cssparser::RGBA;
 
     #[test]


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