Holllo LogoHolllo

Developing my first Rust crate: an OPML parser

This was originally posted on Tildes as a comment on ~comp's weekly "What have you been working on?" topic.

I published my first crate on crates.io! :3 For another project I'm (slowly) working on I want to add support for importing feeds via OPML and since there was no OPML parser crate yet, I made one. Now normally, I don't really like touching XML parsing because my experience with it has always been awful, but this time it turned out to be really easy.

With the strong_xml crate, all you have to do is define a struct that describes the XML, then add some macros, and bam it's done. For example, the OPML spec says:

<opml> is an XML element, with a single required attribute, version; a <head> element and a <body> element, both of which are required.

So, let's make a struct with exactly that:

pub struct OPML {
  pub version: String,
  pub head: Head,
  pub body: Body,
}

Then we just sprinkle some macros on top:

#[derive(XmlWrite, XmlRead, PartialEq, Debug)]
#[xml(tag = "opml")]
pub struct OPML {
  #[xml(attr = "version")]
  pub version: String,
  #[xml(child = "head")]
  pub head: Head,
  #[xml(child = "body")]
  pub body: Body,
}

And done. Now we can just call OPML::from_str() and it will parse, like so:

OPML::from_str(r#"<opml version="2.0"><head/><body/></opml>"#);

And if we leave out the version attribute, the head or the body, strong_xml will error out telling us it's missing required things. Amazing!

Continue through the rest of the spec, and soon enough I had a complete OPML parser.

Discuss this post