use momento_functions_bytes::{
Data,
encoding::{Encode, Json},
};
use crate::wit::momento::http::http;
pub struct AwsSigV4Secret {
pub access_key_id: String,
pub secret_access_key: String,
pub region: String,
pub service: String,
}
impl From<AwsSigV4Secret> for http::AwsSigv4Secret {
fn from(s: AwsSigV4Secret) -> Self {
http::AwsSigv4Secret {
access_key_id: s.access_key_id,
secret_access_key: s.secret_access_key,
region: s.region,
service: s.service,
}
}
}
pub struct IamRole {
pub role_arn: String,
pub service: String,
}
impl From<IamRole> for http::IamRole {
fn from(r: IamRole) -> Self {
http::IamRole {
role_arn: r.role_arn,
service: r.service,
}
}
}
pub enum Authorization {
None,
AwsSigV4Secret(AwsSigV4Secret),
Federated(IamRole),
}
impl From<Authorization> for http::Authorization {
fn from(a: Authorization) -> Self {
match a {
Authorization::None => http::Authorization::None,
Authorization::AwsSigV4Secret(s) => http::Authorization::AwsSigv4Secret(s.into()),
Authorization::Federated(r) => http::Authorization::Federated(r.into()),
}
}
}
pub struct Request {
url: String,
verb: String,
headers: Vec<(String, String)>,
body: Data,
authorization: Authorization,
}
impl Request {
pub fn new(url: impl Into<String>, verb: impl Into<String>) -> Self {
Self {
url: url.into(),
verb: verb.into(),
headers: Vec::new(),
body: Data::from(vec![]),
authorization: Authorization::None,
}
}
pub fn with_header(mut self, name: impl Into<String>, value: impl Into<String>) -> Self {
self.headers.push((name.into(), value.into()));
self
}
pub fn with_headers<K, V>(mut self, headers: impl IntoIterator<Item = (K, V)>) -> Self
where
K: Into<String>,
V: Into<String>,
{
self.headers
.extend(headers.into_iter().map(|(k, v)| (k.into(), v.into())));
self
}
pub fn json<T: serde::Serialize>(mut self, body: Json<T>) -> Result<Self, serde_json::Error> {
self.body = body.try_serialize()?;
if let Some(entry) = self
.headers
.iter_mut()
.find(|(k, _)| k.eq_ignore_ascii_case("content-type"))
{
entry.1 = "application/json".to_string();
} else {
self.headers
.push(("content-type".to_string(), "application/json".to_string()));
}
Ok(self)
}
pub fn with_body(mut self, body: impl Into<Data>) -> Self {
self.body = body.into();
self
}
pub fn with_authorization(mut self, authorization: Authorization) -> Self {
self.authorization = authorization;
self
}
}
impl From<Request> for http::Request {
fn from(r: Request) -> Self {
http::Request {
url: r.url,
verb: r.verb,
headers: r.headers,
body: r.body.into(),
authorization: r.authorization.into(),
}
}
}