#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ConfigScope {
GlobalOnly,
PerHost,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum IntegrationHosting {
Managed,
HostBound(&'static [&'static str]),
}
#[derive(Debug, Clone, Copy)]
pub struct BlockedSetting {
pub key: &'static str,
pub remediation: &'static str,
}
pub trait Hostable {
const PROVIDER: &'static str;
const HOSTING: IntegrationHosting;
const CONFIG_SCOPE: ConfigScope;
const RESOURCE_KIND: &'static str;
const OUTPUTS: &'static [&'static str];
const BLOCKED_SETTINGS: &'static [BlockedSetting] = &[];
const VALIDATED: () = validate_hostable_pair(Self::HOSTING, Self::CONFIG_SCOPE);
}
#[allow(clippy::panic)]
const fn validate_hostable_pair(hosting: IntegrationHosting, scope: ConfigScope) {
match (hosting, scope) {
(IntegrationHosting::Managed, ConfigScope::GlobalOnly) => (),
(IntegrationHosting::Managed, ConfigScope::PerHost) => {
panic!("Managed integrations must use ConfigScope::GlobalOnly")
}
_ => (),
}
}
pub fn host_bound_supports(hosting: IntegrationHosting, host: &str) -> bool {
match hosting {
IntegrationHosting::Managed => true,
IntegrationHosting::HostBound(hosts) => hosts.contains(&host),
}
}
pub fn host_bound_hosts(hosting: IntegrationHosting) -> &'static [&'static str] {
match hosting {
IntegrationHosting::Managed => &[],
IntegrationHosting::HostBound(hosts) => hosts,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn host_bound_supports_declared_hosts_only() {
let hosting = IntegrationHosting::HostBound(&["local", "render"]);
assert!(host_bound_supports(hosting, "local"));
assert!(host_bound_supports(hosting, "render"));
assert!(!host_bound_supports(hosting, "vercel"));
}
#[test]
fn managed_supports_every_active_host_check() {
let hosting = IntegrationHosting::Managed;
for host in ["local", "render", "vercel"] {
assert!(host_bound_supports(hosting, host));
}
}
}