use regex::Regex;
use serde::{Deserialize, Serialize};
type PatternHandler = Box<dyn Fn(&mut EchoScriptMemory, String)>;
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct EchoScriptMemory {
pub emotion: Option<String>,
pub tone: Option<String>,
pub speaker: Option<String>,
pub license: Option<String>,
pub lock: Option<String>,
pub reem: Option<String>,
pub audit: Option<String>,
pub prompts: Vec<String>,
pub links: Vec<String>,
pub timestamp: Option<String>,
}
pub fn parse_echoscript(input: &str) -> Result<EchoScriptMemory, String> {
let mut memory = EchoScriptMemory::default();
let patterns: Vec<(&str, PatternHandler)> = vec![
(r"::emotion\[(.*?)\]", Box::new(|m, v| m.emotion = Some(v))),
(r"::tone\[(.*?)\]", Box::new(|m, v| m.tone = Some(v))),
(r"::speaker\[(.*?)\]", Box::new(|m, v| m.speaker = Some(v))),
(r"::license\((.*?)\)", Box::new(|m, v| m.license = Some(v))),
(r"::lock\((.*?)\)", Box::new(|m, v| m.lock = Some(v))),
(r"::reem\[(.*?)\]", Box::new(|m, v| m.reem = Some(v))),
(r"::audit\[(.*?)\]", Box::new(|m, v| m.audit = Some(v))),
(
r"::timestamp\[(.*?)\]",
Box::new(|m, v| m.timestamp = Some(v)),
),
];
for (pattern, apply) in patterns {
let re = Regex::new(pattern).map_err(|e| e.to_string())?;
if let Some(cap) = re.captures(input) {
if let Some(value) = cap.get(1) {
apply(&mut memory, value.as_str().trim().to_string());
}
}
}
let prompt_re = Regex::new(r"::prompt\[(.*?)\]").map_err(|e| e.to_string())?;
for cap in prompt_re.captures_iter(input) {
if let Some(value) = cap.get(1) {
memory.prompts.push(value.as_str().trim().to_string());
}
}
let link_re_tagged = Regex::new(r"::link\[(.*?)\]").map_err(|e| e.to_string())?;
let link_re_short = Regex::new(r"::link_(https?://\S+)").map_err(|e| e.to_string())?;
for cap in link_re_tagged.captures_iter(input) {
if let Some(value) = cap.get(1) {
memory.links.push(value.as_str().trim().to_string());
}
}
for cap in link_re_short.captures_iter(input) {
if let Some(value) = cap.get(1) {
memory.links.push(value.as_str().trim().to_string());
}
}
Ok(memory)
}
pub fn serialize_echoscript(meta: &EchoScriptMemory) -> Result<String, String> {
serde_json::to_string_pretty(meta)
.map_err(|e| format!("โ Failed to serialize EchoScript: {e}"))
}
pub fn decode_reem_glyph(code: &str) -> &'static str {
match code {
"REEM-JY1" => "Joy โ Celebrate",
"REEM-SQ2" => "Sadness โ Grieve",
"REEM-AZ3" => "Anger โ Resist",
"REEM-FR9" => "Fear โ Reflect",
"REEM-JD7" => "Joy โ Aspire",
_ => "Unknown REEM Code",
}
}