use serde_json::Value;
use std::collections::HashMap;
use std::env;
use std::fs;
pub mod input {
use super::*;
fn result_file_path() -> String {
let mount_dir = env::var("CODE_MOUNT_DIR").unwrap_or_else(|_| "bot".to_string());
format!("/{}/result.json", mount_dir)
}
fn write_result(content: &str) {
let path = result_file_path();
if let Err(e) = fs::write(&path, content) {
eprintln!("RESULT_ERROR: Failed to write result file: {}", e);
}
}
pub fn parse() -> (String, Value) {
let id = env::var("BOT_ID").expect("BOT_ID environment variable not set");
let config_str = env::var("BOT_CONFIG").expect("BOT_CONFIG environment variable not set");
let config: Value =
serde_json::from_str(&config_str).expect("Failed to parse BOT_CONFIG as JSON");
(id, config)
}
pub fn parse_as_map() -> (String, HashMap<String, Value>) {
let id = env::var("BOT_ID").expect("BOT_ID environment variable not set");
let config_str = env::var("BOT_CONFIG").expect("BOT_CONFIG environment variable not set");
let config: HashMap<String, Value> =
serde_json::from_str(&config_str).expect("Failed to parse BOT_CONFIG as JSON");
(id, config)
}
pub fn success(message: &str) {
let escaped = message.replace('\\', "\\\\").replace('"', "\\\"");
write_result(&format!(r#"{{"status":"success","message":"{}"}}"#, escaped));
}
pub fn error(message: &str) -> ! {
let escaped = message.replace('\\', "\\\\").replace('"', "\\\"");
write_result(&format!(r#"{{"status":"error","message":"{}"}}"#, escaped));
std::process::exit(1);
}
pub fn result(data: &Value) {
write_result(&serde_json::to_string(data).expect("Failed to serialize result"));
}
pub fn metric(metric_type: &str, data: &Value) {
let timestamp = chrono_now();
let mut output = data.as_object().cloned().unwrap_or_default();
output.insert("_metric".to_string(), Value::String(metric_type.to_string()));
output.insert("timestamp".to_string(), Value::String(timestamp));
println!("{}", serde_json::to_string(&output).expect("Failed to serialize metric"));
}
pub fn log(message: &str) {
println!(r#"{{"message":"{}"}}"#, message.replace('\\', "\\\\").replace('"', "\\\""));
}
fn chrono_now() -> String {
use std::time::{SystemTime, UNIX_EPOCH};
let duration = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap();
let secs = duration.as_secs();
let millis = duration.subsec_millis();
format!("{}Z", secs * 1000 + millis as u64)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_success_output() {
input::success("test message");
}
#[test]
fn test_result_output() {
let data = serde_json::json!({"key": "value"});
input::result(&data);
}
}