Skip to main content

fa_bridge_sdk/
persistent.rs

1use std::io::{BufRead, Write};
2
3use crate::context::{ActionContext, RunMode};
4use crate::types::App;
5
6impl App {
7    pub fn run_persistent(&self) {
8        let caps = self.build_capabilities_json();
9        let hello_msg = format!(
10            "hello\x1F{}\x1F{}\x1F{}\n",
11            self.name,
12            self.version,
13            serde_json::to_string(&caps).unwrap()
14        );
15        std::io::stdout().write_all(hello_msg.as_bytes()).unwrap();
16        std::io::stdout().flush().unwrap();
17
18        let stdin = std::io::stdin();
19        let mut reader = std::io::BufReader::new(stdin.lock());
20
21        loop {
22            let mut line = String::new();
23            match reader.read_line(&mut line) {
24                Ok(0) => break,
25                Ok(_) => {}
26                Err(_) => break,
27            }
28
29            let line = line.trim_end_matches('\n').trim_end_matches('\r');
30            if line.is_empty() {
31                continue;
32            }
33
34            if line == "shutdown" {
35                println!("bye");
36                std::io::stdout().flush().unwrap();
37                break;
38            }
39
40            let parts: Vec<&str> = line.split('\x1F').collect();
41            if parts.is_empty() {
42                continue;
43            }
44
45            let msg_type = parts[0];
46            match msg_type {
47                "call" => {
48                    let domain_name = parts.get(1).unwrap_or(&"");
49                    let action_name = parts.get(2).unwrap_or(&"");
50                    let payload_str = parts.get(3).unwrap_or(&"{}");
51                    let payload: serde_json::Value =
52                        serde_json::from_str(payload_str).unwrap_or(serde_json::Value::Null);
53
54                    let mut found = false;
55                    for domain in &self.domains {
56                        if domain.name != *domain_name {
57                            continue;
58                        }
59                        for action in &domain.actions {
60                            if action.name != *action_name {
61                                continue;
62                            }
63                            found = true;
64
65                            let ctx = ActionContext {
66                                domain: domain.name.clone(),
67                                action: action.name.clone(),
68                                mode: RunMode::Persistent,
69                            };
70
71                            match (action.handler)(payload.clone(), &ctx) {
72                                Ok(result) => {
73                                    let resp = format!(
74                                        "ok\x1F{}\x1F{}\x1F{}\n",
75                                        domain.name,
76                                        action.name,
77                                        serde_json::to_string(&result).unwrap()
78                                    );
79                                    std::io::stdout()
80                                        .write_all(resp.as_bytes())
81                                        .unwrap();
82                                    std::io::stdout().flush().unwrap();
83                                }
84                                Err(e) => {
85                                    let err_obj = serde_json::json!({
86                                        "错误码": "HANDLER_ERROR",
87                                        "错误信息": format!("{}", e)
88                                    });
89                                    let resp = format!(
90                                        "error\x1F{}\x1F{}\x1F{}\n",
91                                        domain.name,
92                                        action.name,
93                                        serde_json::to_string(&err_obj).unwrap()
94                                    );
95                                    std::io::stdout()
96                                        .write_all(resp.as_bytes())
97                                        .unwrap();
98                                    std::io::stdout().flush().unwrap();
99                                }
100                            }
101                            break;
102                        }
103                        if found {
104                            break;
105                        }
106                    }
107
108                    if !found {
109                        let resp = format!(
110                            "error\x1F{}\x1F{}\x1F{}\n",
111                            domain_name,
112                            action_name,
113                            serde_json::to_string(&serde_json::json!({
114                                "错误码": "NOT_FOUND",
115                                "错误信息": format!("action not found: {} / {}", domain_name, action_name)
116                            }))
117                            .unwrap()
118                        );
119                        std::io::stdout().write_all(resp.as_bytes()).unwrap();
120                        std::io::stdout().flush().unwrap();
121                    }
122                }
123                _ => {
124                    let resp = format!(
125                        "error\x1F\x1F\x1F{}\n",
126                        serde_json::to_string(&serde_json::json!({
127                            "错误码": "UNKNOWN_MESSAGE",
128                            "错误信息": format!("unknown message type: {}", msg_type)
129                        }))
130                        .unwrap()
131                    );
132                    std::io::stdout().write_all(resp.as_bytes()).unwrap();
133                    std::io::stdout().flush().unwrap();
134                }
135            }
136        }
137    }
138}