Skip to main content

fur_cli/renderer/
utils.rs

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