Day 4: KDLing up with some feeds

Yesterday I mused on whether I want to store feed URLs in a database or config file. On reading this, my partner mentioned they are a fan of how the RSS reader Newsboat works: just have a single file that lists feed URLs (with optional comments).

I think this is a good system, but I don’t think copying it directly is the right call. Audio files are considerably larger than text, so you will likely want some sort of rotating storage system. For example, maybe you only want to keep the last 5 episodes, or only 100 MiB total. This would be awkward to add to a URL-only config file.

To get the best of both worlds, I’ll use a KDL config file. KDL is close to as simple as a URL list for common configs, but is extensible to more complex setups in the future. Here’s what I’m imagining the config would look like:

defaults {
    keep all
}

feed "https://a.example.com"
feed "https://b.example.com"

feed "https://daily-news.example.com" {
    keep last=3
}

// More out-there ideas:

feed "https://d.example.com" {
    // Seprate keep policies for machines with different
    // amounts of storage
    on hostname=desktop {
        keep last=10
    }

    on hostname=laptop {
        keep last=3
    }
}

// Multi-location syncing, overridable per feed
location tangara {
    drive name="Tangara"
}

feed "https://e.example.com" {
    sync tangara
}

I’ve sketched out the Rust structs that I will use for the config, and the code to load the file as before. I don’t yet have the logic to actually parse the KDL file, that comes next.

fn main() -> Result {
    // ...
    let config_dir = project_dirs.config_dir();
    let config_path = config_dir.join("config.kdl");
    let config = load_config(config_path);
    // ...
}

struct Config {
    defaults: Defaults,
    feeds: Vec<Feed>
}

struct Defaults {
    keep: Keep
}

struct Feed {
    url: Url,
    keep: Option<Keep>
}

enum Keep {
    All,
    Last(u128)
}

fn load_config(path: &Path) -> Result<Config> {
    todo!("actually load the kdl config");
}