rustling in the open source maplibre community
starting in september i spent a few months learning rust. i had a few inchoate reasons:
- i’ve always wanted to learn systems programming…i wanted to be exposed to deeper programming concepts. i do appreciate web development and working on web and business logic on the front and backend, but i’m also interested in coding that’s closer to computer science, or at least working with the ideas of computer science. and to better understand things at a lower level. rip off the hood of abstraction
- people talk about it a lot on hacker news and in the blockchain space, i know you know. but also
- linux is supporting rust. cool! so i guess it’s it’s here to stay
so then i learned it https://github.com/kimpham54/rust-book-homework-kim. i was pretty motivated because i was trying to get into the january polkadot blockchain academy in buenos aires, and got through most of the rust book. unfotunately i didn’t get a chance to take the rust exam… so now what? well i really enjoyed learning it, so might as well put those amateur skills to use.
to me, contributing to open-source is a beautiful and brutal mechanism for self-reflection for both personal professional growth. the transparency, the feedback, the meritocratic initiative, it’s a chance to discover your intrinsic/extrinsic motivations and to know who you are, who you should be, and who you want to be as a worker. i don’t know of a better way to know what you truly know/don’t know about coding. you have to apply your skills in front of a surveying audience and do it without any obvious incentive. teaching comes close to this naked vulnerability feeling, but even then it masks a bit of the truth. it’s humbling, empowering. ok i’m waxing poetic a bit here, but i’m sentimental because in the past my most rewarding and idealized professional experiences were when I got to work in open source. I do miss being part of that more in libraryland world - much love forever goes to Islandora.
so i looked for some open source rust projects, and found one that hits close to my passion for maps - maplibre-rs. i reached out to max, who’s heading development on maplibre-rs. i’ve lurked in the community for a bit and let him know i was interested in a beginner task. so finally when one came up i volunteered.
i was working on parsing some style specs over the christmas break. took a break, then came back to it in february, which means i forgot everything. but it’s also cool because i look at my code and go whoa, how did i know how to do this?
henceforth i shall keep notes, and you’re welcome to peruse them too (cw: may not make sense)!
maplibre-rs style parser
i’m only concerned with the style module in maplibre-rs. here’s how the project is organized
maplibre-rs/maplibre/src/style
├── layer.rs
├── mod.rs
├── original
│ ├── layer.rs
│ ├── source.rs
│ └── style.rs
├── source.rs
├── style.rs
└── tests
├── map-styles
│ ├── test-cl4whef.json
│ ├── test-cl4whev.json
│ ├── test-cl4wxue.json
│ ├── test-dark-v10.json
│ ├── test-light-v10.json
│ ├── test-navigation-guidan.json
│ ├── test-navigation-guidance.json
│ ├── test-outdoors-v11.json
│ ├── test-satellite-st.json
│ ├── test-satellite-v9.json
│ └── test-streets-v11.json
├── test-data
│ ├── cl4.json
│ └── sample1.json
├── testresult-20220211.json
└── testresult-20220211b.json
5 directories, 70 files
maplibre-rs has the maplibre module which contains styles. here we’re trying to parse an input style in json and deserialize it into a rust object.
- source.rs, style.rs, layer.rs - parsers
- original directory: original style files
- tests directory: test data, test results from parser rust tests
- mod.rs - module layout
serialize
rust object -> json
deserialize
json -> rust object
i’m using the serde library to do this. we made some rust parsers, right now styles, sources, and layers. style includes the layer and source parsers. in the style parser we have a Style and Metadata rust structs. in the source we have a VectorSource struct, in layer we have some funky BackgroundPaint, FillPaint, LinePaint structs part of the enum LayerPaint, and a StyleLayer struct. i think the re-organization will grow organically, and eventually should mirror the style spec: https://maplibre.org/maplibre-gl-js-docs/style-spec/.
wrote some parts of the parser, wrote some tests that input test data max gave me of style exports, good way to flag any attributes/parts of the style spec that weren’t accounted for and iterate on writing the parser that way.
to run tests, in style.rs
cargo test --package maplibre --lib -- style::style::tests
can also add --nocapture or --show-output for verbose flags
cargo test --package maplibre --lib -- style::style::tests::load_sample_data_two --show-output
cargo test --package maplibre --lib -- style::style::tests::load_sample_data_two --show-output > ./maplibre/src/style/tests/testresult-yyymmdd.json
i created a pub extra trait
#[serde(flatten)]
pub extra: Map<String, Value>
which uses serde_json::Value parsing any json data using serde_json::from_str function. you don’t have to be explicit, in this case. it grabs everything and dumps it in an object. it’ll be good to pick these apart later and properly deserialize them later, if needed or if they are useful or require some additional computation.
serde has a Map struct which I used https://docs.rs/serde_json/latest/serde_json/struct.Map.html, but maybe we can just use HashMap.
resources
- i think i learned how to make tests here https://youtu.be/A38SoLTB1Y4