bgenc.net/output/posts/rust-typesystem-tricks.gmi

38 lines
2.7 KiB
Plaintext

# A little type system trick in Rust
2022-03-15 00:00
> This post is day 1 of me taking part in the
> #100DaysToOffload challenge.
=> https://100daystooffload.com/ #100DaysToOffload
While working on a small project recently, I ended up writing this type in Rust.
```rust
type ImageData = Arc<Mutex<Option<ImageBuffer<Rgba<u8>, Vec<u8>>>>>;
```
Even though I wrote it myself, it actually took me a bit after writing it to figure out what this type was doing so I wanted to write about it.
Let me start from outside-in, the first type we have is `Arc`. `Arc` stands for "atomic reference counting". Reference counting is a method to handle ownership of the data, or in other words to figure out when the data needs to be freed. Garbage collected languages do this transparently in the background, but in Rust we explicitly need to state that we want it. Atomic means this is done using atomic operations, so it is thread safe. In my case, I needed this because this data was going to be shared between multiple threads, and I didn't know exactly when I would be "done" with the data.
=> https://en.wikipedia.org/wiki/Reference_counting Reference counting
=> https://en.wikipedia.org/wiki/Linearizability#Primitive_atomic_instructions atomic operations
The next type is `Mutex`, which means mutual exclusion or locking. Locks are used to restrict access to data to a single thread at a time. That means whatever type is inside of this is not thread safe, so I'm using the lock to protect it. Which is true!
=> https://en.wikipedia.org/wiki/Lock_(computer_science) mutual exclusion
The type after that is `Option`. This basically means "nullable", there may or may not be a thing inside this. The interesting thing here is that this is a sum type, so Rust helps remind us that this is nullable without introducing a nullability concept to the language. It's just part of the type system!
=> https://en.wikipedia.org/wiki/Tagged_union sum type
Then we have `ImageBuffer`, a type from the popular image crate. Not much to talk about with this, that's the data I wanted to store.
=> https://docs.rs/image/latest/image/index.html image crate
The next thing that *is* interesting is the `Rgba<u8>` and `Vec<u8>` inside the image buffer. What that means (and I'm speculating here because I'm lazy/too busy to check), is that `Rgba` is just a basic wrapper type (or a "newtype"). It makes the compiler enforce the type of the image data that's stored in this image buffer, so the user doesn't mix up different data types. Similar for `Vec<u8>`, (I think) it means that the data inside this buffer is stored in a vector.
Finally, `u8` is probably self descriptive, the pixels and the vector are made out of 8-bit unsigned integers.