use crate::{Config, Error};
use http::HeaderMap;
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, convert::TryFrom};
#[doc(hidden)]
#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Diagnostic {
pub error_type: String,
pub error_message: String,
}
#[test]
fn round_trip_lambda_error() -> Result<(), Error> {
use serde_json::{json, Value};
let expected = json!({
"errorType": "InvalidEventDataError",
"errorMessage": "Error parsing event data.",
});
let actual: Diagnostic = serde_json::from_value(expected.clone())?;
let actual: Value = serde_json::to_value(actual)?;
assert_eq!(expected, actual);
Ok(())
}
#[derive(Debug, Clone, PartialEq)]
pub struct RequestId(pub String);
#[derive(Debug, Clone, PartialEq)]
pub struct InvocationDeadline(pub u64);
#[derive(Debug, Clone, PartialEq)]
pub struct FunctionArn(pub String);
#[derive(Debug, Clone, PartialEq)]
pub struct XRayTraceId(pub String);
#[derive(Debug, Clone, PartialEq)]
struct MobileClientContext(String);
#[derive(Debug, Clone, PartialEq)]
struct MobileClientIdentity(String);
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct ClientContext {
pub client: ClientApplication,
pub custom: HashMap<String, String>,
pub environment: HashMap<String, String>,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct ClientApplication {
pub installation_id: String,
pub app_title: String,
pub app_version_name: String,
pub app_version_code: String,
pub app_package_name: String,
}
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct CognitoIdentity {
pub identity_id: String,
pub identity_pool_id: String,
}
#[non_exhaustive]
#[derive(Clone, Debug, PartialEq, Default, Serialize, Deserialize)]
pub struct Context {
pub request_id: String,
pub deadline: u64,
pub invoked_function_arn: String,
pub xray_trace_id: String,
pub client_context: Option<ClientContext>,
pub identity: Option<CognitoIdentity>,
pub env_config: Config,
}
impl TryFrom<HeaderMap> for Context {
type Error = Error;
fn try_from(headers: HeaderMap) -> Result<Self, Self::Error> {
let ctx = Context {
request_id: headers["lambda-runtime-aws-request-id"]
.to_str()
.expect("Missing Request ID")
.to_owned(),
deadline: headers["lambda-runtime-deadline-ms"]
.to_str()?
.parse()
.expect("Missing deadline"),
invoked_function_arn: headers["lambda-runtime-invoked-function-arn"]
.to_str()
.expect("Missing arn; this is a bug")
.to_owned(),
xray_trace_id: headers["lambda-runtime-trace-id"]
.to_str()
.expect("Invalid XRayTraceID sent by Lambda; this is a bug")
.to_owned(),
..Default::default()
};
Ok(ctx)
}
}
impl Context {
pub fn with_config(self, config: &Config) -> Self {
Self {
env_config: config.clone(),
..self
}
}
}