use aws_smithy_types::config_bag::{Storable, StoreReplace};
use std::sync::Arc;
pub trait HeaderOmitSettings: Send + Sync + std::fmt::Debug {
fn should_omit_default_content_type(&self) -> bool {
false
}
fn should_omit_default_content_length(&self) -> bool {
false
}
}
#[derive(Debug, Clone)]
pub struct SharedHeaderOmitSettings {
inner: Arc<dyn HeaderOmitSettings>,
}
impl SharedHeaderOmitSettings {
pub fn new<T>(settings: T) -> Self
where
T: HeaderOmitSettings + 'static,
{
Self {
inner: Arc::new(settings),
}
}
pub fn from_arc(inner: Arc<dyn HeaderOmitSettings>) -> Self {
Self { inner }
}
}
impl std::ops::Deref for SharedHeaderOmitSettings {
type Target = dyn HeaderOmitSettings;
fn deref(&self) -> &Self::Target {
&*self.inner
}
}
impl Storable for SharedHeaderOmitSettings {
type Storer = StoreReplace<Self>;
}
#[cfg(test)]
mod tests {
use super::*;
use aws_smithy_types::config_bag::{ConfigBag, Layer};
#[derive(Debug, Default)]
struct OmitBoth;
impl HeaderOmitSettings for OmitBoth {
fn should_omit_default_content_type(&self) -> bool {
true
}
fn should_omit_default_content_length(&self) -> bool {
true
}
}
#[derive(Debug, Default)]
struct OmitNone;
impl HeaderOmitSettings for OmitNone {}
#[test]
fn default_trait_methods_return_false() {
let settings = OmitNone;
assert!(!settings.should_omit_default_content_type());
assert!(!settings.should_omit_default_content_length());
}
#[test]
fn shared_delegates_to_inner_via_deref() {
let shared = SharedHeaderOmitSettings::new(OmitBoth);
assert!(shared.should_omit_default_content_type());
assert!(shared.should_omit_default_content_length());
}
#[test]
fn shared_round_trips_through_config_bag() {
let mut layer = Layer::new("test");
layer.store_put(SharedHeaderOmitSettings::new(OmitBoth));
let cfg = ConfigBag::of_layers(vec![layer]);
let loaded = cfg
.load::<SharedHeaderOmitSettings>()
.expect("settings stored in ConfigBag");
assert!(loaded.should_omit_default_content_type());
assert!(loaded.should_omit_default_content_length());
}
#[test]
fn shared_absent_from_config_bag_means_no_omits() {
let cfg = ConfigBag::base();
assert!(cfg.load::<SharedHeaderOmitSettings>().is_none());
}
#[test]
fn from_arc_avoids_realloc_when_caller_already_holds_arc() {
let original: Arc<dyn HeaderOmitSettings> = Arc::new(OmitBoth);
let strong = Arc::strong_count(&original);
let shared = SharedHeaderOmitSettings::from_arc(Arc::clone(&original));
assert_eq!(Arc::strong_count(&original), strong + 1);
assert!(shared.should_omit_default_content_type());
}
}