Skip to content

Instantly share code, notes, and snippets.

@lann
Last active July 24, 2024 21:44
Show Gist options
  • Save lann/eafad8496b720d68b8fbff72dddb0cdf to your computer and use it in GitHub Desktop.
Save lann/eafad8496b720d68b8fbff72dddb0cdf to your computer and use it in GitHub Desktop.
use serde::Deserialize;
use crate::Factor;
pub trait RuntimeConfigSource<T: Factor> {
fn get_runtime_config(&mut self) -> anyhow::Result<Option<T::RuntimeConfig>>;
}
pub trait RuntimeConfigFinalizer {
fn finalize(&mut self) -> anyhow::Result<()>;
}
trait NoRuntimeConfig {}
impl NoRuntimeConfig for () {}
impl<T: Factor> RuntimeConfigSource<T> for T
where
T::RuntimeConfig: NoRuntimeConfig,
{
fn get_runtime_config(&mut self) -> anyhow::Result<Option<()>> {
Ok(None)
}
}
// All "standard" Spin factors would implement this
pub trait DeserializeRuntimeConfig<'de>: Deserialize<'de> {
const KEY: &'static str;
}
#[cfg(test)]
mod example {
use std::collections::HashMap;
use anyhow::{bail, Context};
use super::*;
struct TomlRuntimeConfig {
table: toml::Table,
keys_factors: HashMap<&'static str, Vec<&'static str>>,
}
impl<'de, T: Factor> RuntimeConfigSource<T> for TomlRuntimeConfig
where
T::RuntimeConfig: DeserializeRuntimeConfig<'de>,
{
fn get_runtime_config(&mut self) -> anyhow::Result<Option<T>> {
let key = T::RuntimeConfig::KEY;
let factor_name = std::any::type_name::<T>();
self.keys_factors.entry(key).or_default().push(factor_name);
let Some(value) = self.table.get(key) else {
return Ok(None);
};
Ok(Some(value.clone().try_into().with_context(|| {
format!("failed to deserialize runtime config for {factor_name}")
})?))
}
}
impl RuntimeConfigFinalizer for TomlRuntimeConfig {
fn finalize(&mut self) -> anyhow::Result<()> {
for key in self.table.keys() {
match self.keys_factors.get(key) {
Some(factors) if factors.len() == 1 => {}
Some(factors) => bail!(
"multiple factors requested runtime config key {key:?}: {}",
factors.join(", ")
),
None => bail!("unused runtime config with key {key:?}"),
}
}
Ok(())
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment