#![allow(dead_code)]
use aws_smithy_runtime_api::box_error::BoxError;
use aws_smithy_runtime_api::client::interceptors::context::BeforeSerializationInterceptorContextMut;
use aws_smithy_runtime_api::client::interceptors::Intercept;
use aws_smithy_runtime_api::client::runtime_components::RuntimeComponents;
use aws_smithy_types::config_bag::ConfigBag;
use std::fmt;
use std::marker::PhantomData;
fn trim_resource_id(resource_id: &mut Option<String>) {
const PREFIXES: &[&str] = &["/hostedzone/", "hostedzone/", "/change/", "change/", "/delegationset/", "delegationset/"];
for prefix in PREFIXES {
if let Some(id) = resource_id.as_deref().unwrap_or_default().strip_prefix(prefix) {
*resource_id = Some(id.to_string());
return;
}
}
}
pub(crate) struct Route53ResourceIdInterceptor<G, T>
where
G: for<'a> Fn(&'a mut T) -> &'a mut Option<String>,
{
get_mut_resource_id: G,
_phantom: PhantomData<T>,
}
impl<G, T> fmt::Debug for Route53ResourceIdInterceptor<G, T>
where
G: for<'a> Fn(&'a mut T) -> &'a mut Option<String>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Route53ResourceIdInterceptor").finish()
}
}
impl<G, T> Route53ResourceIdInterceptor<G, T>
where
G: for<'a> Fn(&'a mut T) -> &'a mut Option<String>,
{
pub(crate) fn new(get_mut_resource_id: G) -> Self {
Self {
get_mut_resource_id,
_phantom: Default::default(),
}
}
}
impl<G, T> Intercept for Route53ResourceIdInterceptor<G, T>
where
G: for<'a> Fn(&'a mut T) -> &'a mut Option<String> + Send + Sync,
T: fmt::Debug + Send + Sync + 'static,
{
fn name(&self) -> &'static str {
"Route53ResourceIdInterceptor"
}
fn modify_before_serialization(
&self,
context: &mut BeforeSerializationInterceptorContextMut<'_>,
_runtime_components: &RuntimeComponents,
_cfg: &mut ConfigBag,
) -> Result<(), BoxError> {
let input: &mut T = context.input_mut().downcast_mut().expect("correct type");
let field = (self.get_mut_resource_id)(input);
trim_resource_id(field);
Ok(())
}
}
#[cfg(test)]
mod test {
use super::trim_resource_id;
#[test]
fn does_not_change_regular_zones() {
struct OperationInput {
resource: Option<String>,
}
let mut operation = OperationInput {
resource: Some("Z0441723226OZ66S5ZCNZ".to_string()),
};
trim_resource_id(&mut operation.resource);
assert_eq!(&operation.resource.unwrap_or_default(), "Z0441723226OZ66S5ZCNZ");
}
#[test]
fn sanitizes_prefixed_zone() {
struct OperationInput {
change_id: Option<String>,
}
let mut operation = OperationInput {
change_id: Some("/change/Z0441723226OZ66S5ZCNZ".to_string()),
};
trim_resource_id(&mut operation.change_id);
assert_eq!(&operation.change_id.unwrap_or_default(), "Z0441723226OZ66S5ZCNZ");
}
#[test]
fn allow_no_leading_slash() {
struct OperationInput {
hosted_zone: Option<String>,
}
let mut operation = OperationInput {
hosted_zone: Some("hostedzone/Z0441723226OZ66S5ZCNZ".to_string()),
};
trim_resource_id(&mut operation.hosted_zone);
assert_eq!(&operation.hosted_zone.unwrap_or_default(), "Z0441723226OZ66S5ZCNZ");
}
}