Href::WithFragment - consolidate the FragmentId and UriWithFragmentId variants into one

parent b164436d
......@@ -36,11 +36,14 @@ impl Defs {
pub fn lookup(&mut self, handle: *const RsvgHandle, reference: &Href) -> Option<&Rc<Node>> {
match reference {
Href::PlainUri(_) => None,
Href::FragmentId(ref fragment) => self.nodes.get(fragment),
Href::UriWithFragmentId(ref href, ref fragment) => {
match self.get_extern_handle(handle, href) {
Ok(extern_handle) => handle::get_defs(extern_handle).nodes.get(fragment),
Err(()) => None,
Href::WithFragment(ref opt_href, ref fragment) => {
if let Some(ref href) = *opt_href {
match self.get_extern_handle(handle, href) {
Ok(extern_handle) => handle::get_defs(extern_handle).nodes.get(fragment),
Err(()) => None,
}
} else {
self.nodes.get(fragment)
}
}
}
......@@ -65,17 +68,18 @@ impl Defs {
}
}
/// Represents a possibly non-canonical URI with an optional fragment identifier
/// Parsed result of an href from an SVG or CSS file
///
/// Sometimes in SVG element references (e.g. the `href` in the `<feImage>` element) we
/// must decide between referencing an external file, or using a plain fragment identifier
/// like `href="#foo"` as a reference to an SVG element in the same file as the one being
/// processes. This enum makes that distinction.
/// processed. This enum makes that distinction.
#[derive(Debug, PartialEq)]
pub enum Href {
PlainUri(String),
FragmentId(String),
UriWithFragmentId(String, String),
/// Optional URI, mandatory fragment id
WithFragment(Option<String>, String),
}
/// Errors returned when creating an `Href` out of a string
......@@ -112,11 +116,11 @@ impl Href {
match (uri, fragment) {
(None, Some(f)) if f.len() == 0 => Err(HrefError::ParseError),
(None, Some(f)) => Ok(Href::FragmentId(f.to_string())),
(None, Some(f)) => Ok(Href::WithFragment(None, f.to_string())),
(Some(u), _) if u.len() == 0 => Err(HrefError::ParseError),
(Some(u), None) => Ok(Href::PlainUri(u.to_string())),
(Some(_u), Some(f)) if f.len() == 0 => Err(HrefError::ParseError),
(Some(u), Some(f)) => Ok(Href::UriWithFragmentId(u.to_string(), f.to_string())),
(Some(u), Some(f)) => Ok(Href::WithFragment(Some(u.to_string()), f.to_string())),
(_, _) => Err(HrefError::ParseError),
}
}
......@@ -126,7 +130,7 @@ impl Href {
match Href::parse(href)? {
r @ PlainUri(_) => Ok(r),
FragmentId(_) | UriWithFragmentId(_, _) => Err(HrefError::FragmentForbidden),
WithFragment(_, _) => Err(HrefError::FragmentForbidden),
}
}
......@@ -135,8 +139,7 @@ impl Href {
match Href::parse(href)? {
PlainUri(_) => Err(HrefError::FragmentRequired),
r @ FragmentId(_) => Ok(r),
r @ UriWithFragmentId(_, _) => Ok(r),
r @ WithFragment(_, _) => Ok(r),
}
}
}
......@@ -186,11 +189,11 @@ mod tests {
);
assert_eq!(
Href::parse("#fragment").unwrap(),
Href::FragmentId("fragment".to_string())
Href::WithFragment(None, "fragment".to_string())
);
assert_eq!(
Href::parse("uri#fragment").unwrap(),
Href::UriWithFragmentId("uri".to_string(), "fragment".to_string())
Href::WithFragment(Some("uri".to_string()), "fragment".to_string())
);
}
......@@ -223,12 +226,12 @@ mod tests {
fn with_fragment() {
assert_eq!(
Href::with_fragment("#foo").unwrap(),
Href::FragmentId("foo".to_string())
Href::WithFragment(None, "foo".to_string())
);
assert_eq!(
Href::with_fragment("uri#foo").unwrap(),
Href::UriWithFragmentId("uri".to_string(), "foo".to_string())
Href::WithFragment(Some("uri".to_string()), "foo".to_string())
);
assert_eq!(Href::with_fragment("uri"), Err(HrefError::FragmentRequired));
......
......@@ -52,8 +52,8 @@ impl Image {
href: &Href,
) -> Result<ImageSurface, FilterError> {
let url = match *href {
Href::FragmentId(ref f) => format!("#{}", f),
Href::UriWithFragmentId(ref u, ref f) => format!("{}#{}", u, f),
Href::WithFragment(None, ref f) => format!("#{}", f),
Href::WithFragment(Some(ref u), ref f) => format!("{}#{}", u, f),
_ => unreachable!(),
};
......@@ -230,7 +230,7 @@ impl Filter for Image {
Href::PlainUri(_) => {
self.render_external_image(ctx, draw_ctx, bounds_builder, &href)?
}
_ => self.render_node(ctx, draw_ctx, bounds, &href)?,
Href::WithFragment(_, _) => self.render_node(ctx, draw_ctx, bounds, &href)?,
};
Ok(FilterResult {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment