StrokeLinejoin is the first property that I ported. First I had to
write a little bunch of machinery to allow CSS properties to be kept
in Rust-space instead of the main C structure that holds them
(upcoming blog post about that). But for now, I just want to show how
this boiled down to a macro after refactoring.

First cut at the code

The stroke-linejoin property can have the values miter, round,
bevel, or inherit. Here is an enum definition for those values,
and the conventional machinery which librsvg uses to parse property values:

It's called make_ident_property because it makes a property
definition from simple string identifiers. It has the name of the
property (StrokeLinejoin), a default value, and a few repeating
elements, one for each possible value.

macro_rules!make_ident_property{($name: ident,// ^^^^^^^^^^^^ will match an identifier and put it in $namedefault: $default: ident,// ^^^^^^^^^^^^^^^ will match an identifier and put it in $default// ^^^^^^^^ arbitrary text$($str_prop: expr=>$variant: ident,)+^^arbitrarytext// ^^ start of repetition ^^ end of repetition, repeats one or more times)=>{...};}

For example, saying "$foo: ident" in a macro's pattern means that the
compiler will expect an identifier, and bind it to $foo within the
macro's definition.

Similarly, an expr means that the compiler will
look for an expression — in this case, we want one of the string
values.

In a macro pattern, anything that is not a binding is just arbitrary
text which must appear in the macro's invocation. This is how we can
create a little syntax of our own within the macro: the "default:"
part, and the "=>" inside each string/symbol pair.

Finally, macro patterns allow repetition. Anything within $(...)
indicates repetition. Here, $(...)+ indicates that the
compiler must match one or more of the repeating elements.

I pasted the duplicated code, and substituted the actual symbol names
for the macro's bindings: