use serde_json::Value;
use std::collections::BTreeMap;
use std::fmt::Debug;
use std::sync::Arc;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum RuntimeRefResolverError {
#[error("runtime-ref invalid: {0}")]
Invalid(String),
#[error("runtime-ref internal error: {0}")]
Internal(String),
}
pub trait RuntimeRefResolver: Debug + Send + Sync {
fn resolve(&self, runtime_ref: &str) -> Result<Option<Value>, RuntimeRefResolverError>;
}
#[derive(Clone, Debug)]
pub struct RuntimeRefsInjection {
pub refs: Arc<BTreeMap<String, String>>,
pub resolver: Arc<dyn RuntimeRefResolver>,
}
#[cfg(test)]
mod tests {
use super::*;
#[derive(Debug)]
struct FixedResolver {
uri: String,
value: Value,
}
impl RuntimeRefResolver for FixedResolver {
fn resolve(&self, runtime_ref: &str) -> Result<Option<Value>, RuntimeRefResolverError> {
if runtime_ref == self.uri {
Ok(Some(self.value.clone()))
} else {
Ok(None)
}
}
}
#[test]
fn resolver_returns_value_for_bound_uri() {
let resolver = FixedResolver {
uri: "runtime://local/discovered/alb_dns".into(),
value: Value::String("alb.example.com".into()),
};
let value = resolver
.resolve("runtime://local/discovered/alb_dns")
.unwrap();
assert_eq!(value, Some(Value::String("alb.example.com".into())));
}
#[test]
fn resolver_returns_none_for_unbound_uri() {
let resolver = FixedResolver {
uri: "runtime://local/discovered/alb_dns".into(),
value: Value::String("alb.example.com".into()),
};
assert_eq!(
resolver
.resolve("runtime://local/discovered/other")
.unwrap(),
None,
);
}
}