220 results for "":
The many rewrites of the itch.io desktop app
I started working on the itch.io desktop app over 4 years ago.
It has arguably been my main project ever since, along with companion projects like butler, capsule and many smaller libraries.
I’m fuzzy on the initial history, but I remember the codebase went through a lot of changes. As early as 2014, the whole codebase was ported from vanilla JavaScript to TypeScript. In 2016, I released a timeline of all the changes. In 2018, I released a postmortem for v25 (which I then deleted).
Migrating from warp to axum
Falling out of love with warp
Back when I wrote this codebase, warp was the best / only alternative for something relatively high-level on top of hyper.
I was never super fond of warp’s model — it’s a fine crate, just not for me.
The way routing works is essentially building a type that gets larger and larger. One route might look like:
let bye = warp::path("bye")
.and(warp::path::param())
.map(|name: String| format!("Good bye, {}!", name));
Finding the default network interface through WMI
Let’s set aside our sup project for a while.
Don’t get me wrong - it’s a perfectly fine project, and, were we simply rewriting “ping” for Windows in Rust, we could (almost) stop there.
We’re currently using the operating system’s facility to speak ICMP, which is great for a bunch of reasons: we can be sure that whatever flaws there are in the implementation, all “native” Windows programs suffer from it as well.
Frustrated? It's not you, it's Rust
Learning Rust is… an experience. An emotional journey. I’ve rarely been more frustrated than in my first few months of trying to learn Rust.
What makes it worse is that it doesn’t matter how much prior experience you have, in Java, C#, C or C++ or otherwise - it’ll still be unnerving.
In fact, more experience probably makes it worse! The habits have settled in deeper, and there’s a certain expectation that, by now, you should be able to get that done in a shorter amount of time.
Day 6 (Advent of Code 2020)
The end of Advent of Code 2020 is fast approaching, and we’re nowhere near done. Time to do Day 6!
The problem statement here is a little contrived, as uh, as the days that came before it, but that won’t stop us.
Basically, the input looks like this:
abc
a
b
c
ab
ac
a
a
a
a
b
Each line represents one person, and “groups of persons” are separated by blank lines.
sam, homebrew-mingw, etc.
I want to write blog posts, but right now I have too much to do.
So instead, here are bullet points:
I wrote an ooc tool named sam, which helps you keep your git repos up-to-date, and helps to remind you what to push when switching workstations. It’s pretty neat, and portable.
A while ago, I started working on homebrew for Windows, or rather, for MinGW+MSYS. Provided you have msysgit and Ruby in your PATH, it’ll let you brew install most packages. I’ve tested a few dozen, send in your pull requests anytime.
Abstracting away correctness
I’ve been banging the same drum for years: APIs must be carefully designed.
This statement doesn’t resonate the same way with everyone. In order to really understand what I mean by “careful API design”, one has to have experienced both ends of the spectrum.
But there is a silver lining - once you have experienced “good design”, it’s really hard to go back to the other kind. Even after acknowledging that “good design” inevitably comes at a cost, whether it’s cognitive load, compile times, making hiring more challenging, etc.
Truly headless draw.io exports
I love diagrams. I love them so much!
In fact, I have fairly poor visualization skills, so making a diagram is extremely helpful to me: I’ll have some vague idea of how different things are connected, and then I’ll make a diagram, and suddenly there’s a tangible thing I can look at and talk about.
Of course the diagram only represents a fraction of what I had in mind in the first place, but that’s okay: the point is to be able to talk about some aspect of a concept, and so I have to make choices about what to include in the diagram. And maybe make several diagrams.
Improving error handling - panics vs. proper errors
Before we move on to parsing more of our raw packets, I want to take some time to improve our error handling strategy.
Currently, the ersatz codebase contains a mix of Result<T, E>, and some
methods that panic, like unwrap() and expect().
We also have a custom Error enum that lets us return rawsock errors, IO errors,
or Win32 errors:
pub enum Error {
Rawsock(rawsock::Error),
IO(std::io::Error),
Win32(u32),
}
Rust generics vs Java generics
In my previous article, I said I needed to stop thinking of Rust generics as Java generics, because in Rust, generic types are erased.
Someone gently pointed out that they are also erased in Java, the difference was elsewhere. And so, let’s learn the difference together.
Java generics
I learned Java first (a long, long time ago), and their approach to generics made sense to me at the time.