george-norton / headphones-toolbox

A UI for configuring Ploopy Headphones
GNU General Public License v3.0
24 stars 4 forks source link

Type system! #9

Closed Igigog closed 8 months ago

Igigog commented 10 months ago

This one is a lot of boilerplate. While trying to move graph generation to Rust (failed), I just so happened to reinforce the type-level abstractions. Didn't want to just trash it, so I decided to clean it up and let you decide whether we want it or not. I'll be happy either way.

There is a lot of very rust-y type level magic in this PR. I know this project is your first Rust, so I want you to really understand it first before merging. Here's what this PR basically does:

  1. Creates a distinct type for every filter type. You can see all of them in FilterConfig enum. These types are basically their structure type (either FreqQualFilter, FreqQualGainFilter or CustomIIRFilter) plus a marker.
  2. Each type has their own FilterType on the type system level. Pattern matching is outdated - we're encoding it directly on a type now with trait LowLevelFilter. Trait Discriminant then transforms FilterType into u8 as before. Check function read_filter - looks cool.
  3. Each structure type implements StructuralPayload, which basically just says how we encode them into bytes. We get StructuralPayload for filter types of respective structure types for free.
  4. I added some nice little things like Into<FilterConfig> for *Filter.

The why is interesting here. Type-level magic makes impossible for things to do not what you want. Like, if you refactor stuff and forget to implement a trait for a type or something - compiler will scream at you until you're done. And then it will probably work first try.

Disadvantage is, it is a bit hard to understand. It is also a bit hard to fully comprehend. Good thing is compiler will scream at you regardless, but feels kinda cheap anyway.

In short, you decide whether you'll want to work with this code. What we already have is fine, I just didn't want to trash what I wrote for the other thing.