Skip to main content

forge_workspace/store/
speaking_models.rs

1//! What this machine has installed for the speaking role, keyed by variant.
2
3use redb::{ReadableTable, TableDefinition};
4
5use crate::tts::SpeakingInstall;
6
7use super::Db;
8
9/// One row per installed variant, keyed by the variant's name.
10const INSTALLED: TableDefinition<&str, &[u8]> = TableDefinition::new("speaking_installed");
11
12/// Every speaking install, oldest first.
13pub fn installed(db: &Db) -> anyhow::Result<Vec<SpeakingInstall>> {
14    let txn = db.database().begin_read()?;
15    let table = match txn.open_table(INSTALLED) {
16        Ok(table) => table,
17        // A store that never installed a speaking model has no table, which
18        // is not an error: the boot reads cleanly either way.
19        Err(redb::TableError::TableDoesNotExist(_)) => return Ok(Vec::new()),
20        Err(error) => return Err(error.into()),
21    };
22    let mut rows = Vec::new();
23    for entry in table.iter()? {
24        let (_, value) = entry?;
25        rows.push(serde_json::from_slice(value.value())?);
26    }
27    rows.sort_by(|a: &SpeakingInstall, b: &SpeakingInstall| a.at.cmp(&b.at));
28    Ok(rows)
29}
30
31/// Record one installed variant, replacing any row for the same variant.
32pub fn record_installed(db: &Db, install: &SpeakingInstall) -> anyhow::Result<()> {
33    let txn = db.database().begin_write()?;
34    {
35        let mut table = txn.open_table(INSTALLED)?;
36        table.insert(install.variant.as_str(), serde_json::to_vec(install)?.as_slice())?;
37    }
38    txn.commit()?;
39    Ok(())
40}