Last active
July 24, 2024 21:44
-
-
Save lann/eafad8496b720d68b8fbff72dddb0cdf to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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