use std::collections::BTreeMap;
use serde_json::{Value, json};
use sha2::{Digest, Sha256};
pub struct Context {
pub run_id: String,
pub time_ms: u128,
pub git_head: Option<String>,
pub fast: bool,
pub changed: Option<Option<String>>,
pub tags: BTreeMap<String, String>,
}
impl Context {
pub fn line(&self, kind: &str, fields: Value) -> Value {
let mut line = json!({
"v": 1,
"kind": kind,
"run_id": self.run_id,
"time_ms": self.time_ms,
"git_head": self.git_head,
"reqfile_version": env!("CARGO_PKG_VERSION"),
"fast": self.fast,
"changed": self.changed.is_some(),
"base": self.changed.clone().flatten(),
"tags": self.tags,
});
if let (Some(line), Value::Object(fields)) = (line.as_object_mut(), fields) {
line.extend(fields);
}
line
}
}
pub fn fingerprint(text: &str) -> String {
Sha256::digest(text)[..8]
.iter()
.map(|b| format!("{b:02x}"))
.collect()
}
pub fn parse_tags(tags: &[String]) -> Result<BTreeMap<String, String>, String> {
tags.iter()
.map(|tag| match tag.split_once('=') {
Some((key, value)) if !key.is_empty() => Ok((key.to_string(), value.to_string())),
_ => Err(format!("--log-tag must be KEY=VALUE, got `{tag}`")),
})
.collect()
}