‹ back home

Status update, May 2022

2022-05-27 #open-source

vdirsyncer rewrite

I’ve been working on some foundational code for the vdirsyncer rewrite.

I have some basic traits that all storages will implement, and have a working filesystem storage, which reads a vdir. The filesystem storage itself also helps validate that the API is sound enough before starting to write the other storage implementations.

I considered exposing async APIs, but this turned out to not be a great idea. Async functions in trait are not something fully stabilised. I gave it a shot using async-trait, and kind of worked. An obvious fault was that the generated documentation (e.g.: with cargo doc) for the methods was painful to read. For example, this simple function:

pub trait Storage: Sized {
    async fn discover_collections(&self) -> Result<Self::Discovery>;

Would render like this in documentation:

pub trait Storage: Sized {
    fn discover_collections<'life0, 'async_trait>(
        &'life0 self
    ) -> Pin<Box<dyn Future<Output = Result<Self::Discovery>> + Send + 'async_trait>>
        'life0: 'async_trait,
        Self: 'async_trait;

Maybe there’s a workaround to patch this somehow during documentation generation. I honestly didn’t look; dealing with this kind of details on unstable features is not something in which I want to invest time for this project.

While standing back to analyse the situation and usability it became very clear that shipping an async library would not be ideal. All users using the API would need to deal with the complexity of async, and this would likely become a deal breaker when using the library from other languages (which is an important goal of this project).

I’ll be addressing the WebCal storage next. This one has the quirk of always having a single collection, so I’ll need to think a few details around it. It’s probably the simplest one, but I also have good use for it right now, and will help validate that the current storage API has no obvious pitfalls when networking (with async out of the way, I highly doubt it).

Almost everything so far is pretty draft and being iterated upon rather quickly, but I do expect to have some presentable code soon, though nowhere near an alpha or alike.


The latest release of darkman (1.3.1) has proved itself quite solid. It ironed out the last issues that were coming up with the Portal implementation, and now plenty of applications pick up the current dark/light mode properly. This includes GTK applications, Firefox, Telegram, and a few miscellaneous others.

The good old “run this script” escape hatch still exists for everything else.

I’ve also consolidated its documentation into a man page, which is now also easily accessible online.

A bit thanks goes to all the contributors who’ve reported bugs in various different scenarios and setups.


I’ve been consolidating a lot of Password Management into KeePassXC. It works pretty nicely, but needed a small patch to work cleanly in sandboxed contexts (e.g.: with Firejail or alike).

I’ll likely try and tweak a few other rough edges I came across (especially in the browser integration side), or at least try and report them clearly. But my experience has been pretty positive. It’s nice to be embracing a fully functional open source password manager.

Regrettably, I do see some deal breakers in using KeePassXC for teams or vaults that need to be shared and actively mutated by multiple users. However, I do think it’s pretty good for personal usage.

— § —