use std::{any::TypeId, collections::HashMap};
#[derive(Clone, Debug, Default, Eq, PartialEq)]
#[non_exhaustive]
pub enum CloudConfiguration {
#[default]
AzurePublic,
AzureGovernment,
AzureChina,
Custom(CustomConfiguration),
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
#[non_exhaustive]
pub struct CustomConfiguration {
pub authority_host: String,
pub audiences: Audiences,
}
impl From<CustomConfiguration> for CloudConfiguration {
fn from(config: CustomConfiguration) -> Self {
Self::Custom(config)
}
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct Audiences(HashMap<TypeId, String>);
impl Audiences {
pub fn new() -> Self {
Self(HashMap::new())
}
pub fn get<T: 'static>(&self) -> Option<&str> {
self.0.get(&TypeId::of::<T>()).map(|s| s.as_str())
}
pub fn insert<T: 'static>(&mut self, audience: String) {
self.0.insert(TypeId::of::<T>(), audience);
}
pub fn with<T: 'static>(mut self, audience: String) -> Self {
self.0.insert(TypeId::of::<T>(), audience);
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn custom() {
struct A;
struct B;
struct C;
let cloud = CustomConfiguration {
authority_host: "https://login.mycloud.local".to_string(),
audiences: Audiences::new()
.with::<A>("A".to_string())
.with::<B>("B".to_string()),
}
.into();
let CloudConfiguration::Custom(mut custom) = cloud else {
unreachable!();
};
assert_eq!(custom.authority_host, "https://login.mycloud.local");
assert_eq!(custom.audiences.get::<A>(), Some("A"));
assert_eq!(custom.audiences.get::<B>(), Some("B"));
assert_eq!(custom.audiences.get::<C>(), None);
custom.audiences.insert::<C>("C".to_string());
assert_eq!(custom.audiences.get::<C>(), Some("C"));
}
#[test]
fn default() {
assert_eq!(
CloudConfiguration::AzurePublic,
CloudConfiguration::default()
);
}
}