aws_lambda_log_proxy/
emf.rs

1use serde_json::Value;
2
3/// Return if the line can be parsed as a valid JSON object
4/// with a top level key `"_aws"`.
5pub fn is_emf(line: &str) -> bool {
6  // perf: check if the line is wrapped with `{}` before parsing it as JSON
7  // so we can fast fail if it's not a JSON object.
8  // we trim the line in 2 steps to avoid unnecessary trimming.
9  let trimmed = line.trim_start();
10  if !trimmed.starts_with('{') {
11    return false;
12  }
13  let trimmed = trimmed.trim_end();
14  if !trimmed.ends_with('}') {
15    return false;
16  }
17
18  serde_json::from_str(trimmed)
19    .ok()
20    .map(|value: Value| value.get("_aws").is_some())
21    .unwrap_or(false)
22}
23
24#[cfg(test)]
25mod tests {
26  use super::*;
27
28  #[test]
29  fn check_emf() {
30    // compact
31    assert!(is_emf(r#"{"_aws":{"key":"value"}}"#));
32    // with whitespace
33    assert!(is_emf(r#"{"_aws": {"key": "value"}}"#));
34    assert!(is_emf(r#"  {  "_aws"  : {"key": "value"}  }  "#));
35
36    // missing "_aws"
37    assert!(!is_emf(r#"{"key": "value"}"#));
38    assert!(!is_emf(r#"{"  _aws":{"key":"value"}}"#));
39    // invalid JSON
40    assert!(!is_emf(r#"{"_aws": {"key": "value"}"#));
41    // not a JSON object
42    assert!(!is_emf("123"));
43    assert!(!is_emf("{"));
44  }
45}