Who here's familiar with Rust? And it's automatic code generation facilities?

I want some advice.

@balrogboogie @federicomena Thanks!

To set some context I'm implementing my own browser engine (I'm happy to discuss why, but I don't think it's relevant here) and the trickiest bit so far has been parsing CSS properties.

So I created a program which reads in an internal domain specific language and outputs piles of match statements and type declarations as text files.

I find that program extremely helpful in coping with even a relative few CSS properties, but I don't like maintaining it.

@alcinnz @balrogboogie oooooh, boy, I have Opinions(tm) on this specific problem.

1. What sort of advice are you looking for?

2. If it makes you feel better, librsvg is though the fourth or fifth refactoring of parsing CSS properties. It uses Rust macros, mostly.

3. ... and Servo is on its Nth, and it's still not finished. It generates tons of Rust code from Mako/Python templates. It feels to me like they wanted Rust proc-macros, but they weren't ready when they wrote that code.

@federicomena @balrogboogie Procedural macros? I'll look that up. Hopefully that gives you an idea of the sort of advice I want.

And yes, it does make me feel better knowing I'm far from the only one struggling with this.

@alcinnz @balrogboogie yeah, crate-ifying your code generator and calling it from sounds like the most direct thing here. Where is your code hosted?

@balrogboogie @federicomena So does Rust have anything nicer to help me implement this? Or even integrate it into the Cargo build system?

I can provide links to show what I'm trying to accomplish.

@alcinnz you can use a build script with cargo. In fact, they have an example of code generation right in the cargo docs:

You can make your code generation library a crate, include it as a `[build-dependency]`, then use it in your `` file to generate code at build time


@alcinnz @balrogboogie I'd love to look at your code. is where most of this happens in librsvg - it could certainly be compressed with some codegen and such. Grep for make_property! there.

@alcinnz @balrogboogie first thought: instead of println!("code here"), use the quote crate and do something like

let token_stream = quote! { code here };

Then print it to a file with


That way you avoid all the fragile indentation and stuff inside println.

@alcinnz @balrogboogie any reason not to use the cssparser crate? Or do you want to do everything from scratch?

@alcinnz @balrogboogie I have an example of a code generator with the quote crate here:

Probably start with - that has the toplevel code, which interpolates sub-pieces into it. Grep for "quote!" in that file.

@federicomena @balrogboogie Thanks, you've given me plenty to look into!

And no, I'm not planning on implementing everything myself (WebRender will be very handy for one thing). With the cssparser crate I basically just failed to look into it, not that I'm finding the parsing (other than the CSS properties) to be too difficult. I'll look into that too.

But it was a conscious decision that I wanted to handle parsing CSS properties outside of CSS parsing/selection/cascade.

@alcinnz @balrogboogie Cool! Feel free to ask if you have questions about those pieces.

(cssparser is not a full parser; it's more of a CSS tokenizer, and you must build the actual parsing code from it. It leaves all the data structures up to you. It has traits to parse e.g. selectors and at-rules, but expects you to provide the corresponding data structures. *Very* happy to talk about this if you want; one of the next steps in librsvg is supporting that.)

@federicomena @alcinnz @balrogboogie the best part about quote!() is that your editor/IDE treats it as a usual macro and you still get all the autocompletion/highlighting/whatever features

Sign in to participate in the conversation

For people who care about, support, or build Free, Libre, and Open Source Software (FLOSS).