fur_cli/renderer/
utils.rs

1use std::fs;
2use std::path::Path;
3use serde_json::Value;
4use chrono::{DateTime, FixedOffset, Local};
5
6use crate::frs::avatars::resolve_avatar;
7
8#[allow(dead_code)]
9pub struct MessageInfo {
10    pub date_str: String,
11    pub time_str: String,
12    pub name: String,
13    pub emoji: String,
14    pub text: String,
15    pub markdown: Option<String>,
16    pub attachment: Option<String>, 
17    #[allow(dead_code)]
18    pub children: Vec<String>,
19    pub branches: Vec<Vec<String>>,
20}
21
22
23
24pub fn load_message(fur_dir: &Path, msg_id: &str, avatars: &Value) -> Option<MessageInfo> {
25    let msg_path = fur_dir.join("messages").join(format!("{}.json", msg_id));
26    let msg_content = fs::read_to_string(&msg_path).ok()?;
27    let msg_json: Value = serde_json::from_str(&msg_content).ok()?;
28
29    // Timestamp
30    let raw_time = msg_json["timestamp"].as_str().unwrap_or("???");
31    let (date_str, time_str) = if let Ok(dt) = raw_time.parse::<DateTime<FixedOffset>>() {
32        let local_dt = dt.with_timezone(&Local);
33        (local_dt.format("%Y-%m-%d").to_string(), local_dt.format("%H:%M:%S").to_string())
34    } else {
35        (raw_time.to_string(), "".to_string())
36    };
37
38    // Avatar
39    let avatar_key = msg_json["avatar"].as_str().unwrap_or("???");
40    let (name, emoji) = resolve_avatar(avatars, avatar_key);
41
42    // Text & markdown
43    let text = msg_json["text"].as_str().unwrap_or("<no content>").to_string();
44    let markdown = msg_json["markdown"].as_str().map(|s| s.to_string());
45
46    // Children
47    let children = msg_json["children"]
48        .as_array()
49        .map(|arr| arr.iter().filter_map(|v| v.as_str().map(|s| s.to_string())).collect())
50        .unwrap_or_else(Vec::new);
51
52    // Branches
53    let branches = msg_json["branches"]
54        .as_array()
55        .map(|outer| {
56            outer.iter()
57                .filter_map(|block| {
58                    block.as_array().map(|arr| {
59                        arr.iter()
60                            .filter_map(|v| v.as_str().map(|s| s.to_string()))
61                            .collect::<Vec<_>>()
62                    })
63                })
64                .collect::<Vec<_>>()
65        })
66        .unwrap_or_else(Vec::new);
67
68    let attachment = msg_json["attachment"].as_str().map(|s| s.to_string());
69
70    Some(MessageInfo {
71        date_str,
72        time_str,
73        name,
74        emoji,
75        text,
76        markdown,
77        attachment,
78        children,
79        branches,
80    })
81}