Maybe a bit long, can probably be cut down.
The project began and completed in less than a month. Around 2-3 weeks of time. Something that wouldn't have been possible in C, and certainly not at this level of quality. The vast majority of time was spent implementing features, rather than fixing bugs. Issues in the UI could be fixed in a couple minutes, so QA had quick turnaround (although compile times caused us to have to wait).
There was a smaller C attempt prior to this that integrated directly into GNOME Settings, but a month later it was far from complete, riddled with bugs requiring runtime sanitizers to find, and nearly-unmaintainable. System libraries are often unergonomic to use, and prone to misuse. Many things had to be implemented from scratch. Code handling DBus was atrocious. Many basic data structures completely absent.
We then decided to scrap it for a more ambitious firmware manager project written in Rust, and by the third day of development, it was already significantly better than the C implementation. I was surprised at how easy it was to write GTK widgets in Rust, and then give a C application a pointer to its container widget.
slotmapfor storing firmware devices as entities, and then storing data associated with that entity in secondary map component storages. Examples of components would be the GTK widgets related to the entity, data shared between fwupd and system76 firmware, as well as fwupd-specific and system76-specific data. The UI frontend holds exclusive access to the slotmap and its secondary maps.
There's a background thread that carries out all of the tasks on behalf of the UI in the main thread. Widgets send events through channels to the background thread, along with the entity key referring to the device being handled. The background thread then sends responses through a glib channel, with that entity key associated with the response. The UI can then map the entity key to the proper widgets and update the UI accordingly.