use crate::{
custom_serde::{deserialize_headers, deserialize_nullish, http_method, serialize_multi_value_headers},
encodings::Body,
};
#[cfg(feature = "builders")]
use bon::Builder;
use http::{HeaderMap, Method};
use query_map::QueryMap;
use serde::{Deserialize, Serialize};
#[cfg(feature = "catch-all-fields")]
use serde_json::Value;
#[non_exhaustive]
#[cfg_attr(feature = "builders", derive(Builder))]
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct VpcLatticeRequestV2 {
#[serde(default = "default_version")]
pub version: String,
#[serde(default)]
#[serde(skip_serializing_if = "Option::is_none")]
pub path: Option<String>,
#[serde(deserialize_with = "http_method::deserialize_optional")]
#[serde(serialize_with = "http_method::serialize_optional")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub method: Option<Method>,
#[serde(default, deserialize_with = "deserialize_headers")]
#[serde(serialize_with = "serialize_multi_value_headers")]
pub headers: HeaderMap,
#[serde(default)]
pub query_string_parameters: QueryMap,
#[serde(default)]
pub body: Option<Body>,
#[serde(default, deserialize_with = "deserialize_nullish")]
pub is_base64_encoded: bool,
pub request_context: VpcLatticeRequestV2Context,
#[cfg(feature = "catch-all-fields")]
#[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
#[serde(flatten)]
#[cfg_attr(feature = "builders", builder(default))]
pub other: serde_json::Map<String, Value>,
}
#[non_exhaustive]
#[cfg_attr(feature = "builders", derive(Builder))]
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct VpcLatticeRequestV2Context {
pub service_network_arn: String,
pub service_arn: String,
pub target_group_arn: String,
#[serde(default)]
pub identity: Option<VpcLatticeRequestV2Identity>,
pub region: String,
pub time_epoch: String,
#[cfg(feature = "catch-all-fields")]
#[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
#[serde(flatten)]
#[cfg_attr(feature = "builders", builder(default))]
pub other: serde_json::Map<String, Value>,
}
#[non_exhaustive]
#[cfg_attr(feature = "builders", derive(Builder))]
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct VpcLatticeRequestV2Identity {
#[serde(default)]
pub source_vpc_arn: Option<String>,
#[serde(rename = "type")]
#[serde(default)]
pub identity_type: Option<String>,
#[serde(default)]
pub principal: Option<String>,
#[serde(rename = "principalOrgID")]
#[serde(default)]
pub principal_org_id: Option<String>,
#[serde(default)]
pub session_name: Option<String>,
#[serde(rename = "x509IssuerOu")]
#[serde(default)]
pub x509_issuer_ou: Option<String>,
#[serde(rename = "x509SanDns")]
#[serde(default)]
pub x509_san_dns: Option<String>,
#[serde(rename = "x509SanNameCn")]
#[serde(default)]
pub x509_san_name_cn: Option<String>,
#[serde(rename = "x509SanUri")]
#[serde(default)]
pub x509_san_uri: Option<String>,
#[serde(rename = "x509SubjectCn")]
#[serde(default)]
pub x509_subject_cn: Option<String>,
#[cfg(feature = "catch-all-fields")]
#[cfg_attr(docsrs, doc(cfg(feature = "catch-all-fields")))]
#[serde(flatten)]
#[cfg_attr(feature = "builders", builder(default))]
pub other: serde_json::Map<String, Value>,
}
fn default_version() -> String {
"2.0".to_string()
}
#[cfg(test)]
mod test {
use super::*;
#[test]
#[cfg(feature = "vpc_lattice")]
fn example_vpc_lattice_v2_deserialize() {
let data = include_bytes!("../../fixtures/example-vpc-lattice-v2-request.json");
let parsed: VpcLatticeRequestV2 = serde_json::from_slice(data).unwrap();
assert_eq!(Some("/health".to_string()), parsed.path);
assert_eq!(Some(Method::GET), parsed.method);
assert_eq!(
"curl/7.68.0",
parsed.headers.get_all("user-agent").iter().next().unwrap()
);
let header_multi = parsed.headers.get_all("multi");
assert_eq!("x", header_multi.iter().next().unwrap());
assert_eq!("y", header_multi.iter().nth(1).unwrap());
assert_eq!("prod", parsed.query_string_parameters.first("state").unwrap());
let query_multi = parsed.query_string_parameters.all("multi").unwrap();
assert_eq!(&"a", query_multi.first().unwrap());
assert_eq!(&"DEF", query_multi.get(1).unwrap());
assert_eq!(&"g", query_multi.get(2).unwrap());
assert!(parsed.body.is_none());
assert!(!parsed.is_base64_encoded);
assert_eq!(
"arn:aws:vpc-lattice:ap-southeast-2:123456789012:service/svc-0a40eebed65f8d69c",
parsed.request_context.service_arn
);
assert_eq!(
"arn:aws:vpc-lattice:ap-southeast-2:123456789012:servicenetwork/sn-0bf3f2882e9cc805a",
parsed.request_context.service_network_arn
);
assert_eq!(
"arn:aws:vpc-lattice:ap-southeast-2:123456789012:targetgroup/tg-6d0ecf831eec9f09",
parsed.request_context.target_group_arn
);
assert_eq!("ap-southeast-2", parsed.request_context.region);
assert_eq!("1724875399456789", parsed.request_context.time_epoch);
let context = parsed.request_context.identity.as_ref().unwrap();
assert_eq!(
"arn:aws:ec2:ap-southeast-2:123456789012:vpc/vpc-0b8276c84697e7339",
context.clone().source_vpc_arn.unwrap()
);
assert_eq!("AWS_IAM", context.clone().identity_type.unwrap());
assert_eq!(
"arn:aws:iam::123456789012:role/service-role/HealthChecker",
context.clone().principal.unwrap()
);
assert_eq!("o-50dc6c495c0c9188", context.clone().principal_org_id.unwrap());
}
#[test]
#[cfg(feature = "vpc_lattice")]
fn example_vpc_lattice_v2_serde_round_trip() {
let data = include_bytes!("../../fixtures/example-vpc-lattice-v2-request.json");
let parsed: VpcLatticeRequestV2 = serde_json::from_slice(data).unwrap();
let output: String = serde_json::to_string(&parsed).unwrap();
let reparsed: VpcLatticeRequestV2 = serde_json::from_slice(output.as_bytes()).unwrap();
assert_eq!(parsed, reparsed);
}
#[test]
#[cfg(feature = "vpc_lattice")]
fn example_vpc_lattice_v2_serde_round_trip_base64_body() {
let data = include_bytes!("../../fixtures/example-vpc-lattice-v2-request-base64.json");
let parsed: VpcLatticeRequestV2 = serde_json::from_slice(data).unwrap();
let output: String = serde_json::to_string(&parsed).unwrap();
let reparsed: VpcLatticeRequestV2 = serde_json::from_slice(output.as_bytes()).unwrap();
assert_eq!(parsed, reparsed);
}
#[test]
#[cfg(feature = "vpc_lattice")]
fn example_vpc_lattice_v2_serde_round_trip_role_anywhere() {
let data = include_bytes!("../../fixtures/example-vpc-lattice-v2-request-roles-anywhere.json");
let parsed: VpcLatticeRequestV2 = serde_json::from_slice(data).unwrap();
let output: String = serde_json::to_string(&parsed).unwrap();
let reparsed: VpcLatticeRequestV2 = serde_json::from_slice(output.as_bytes()).unwrap();
assert_eq!(parsed, reparsed);
}
}