fa_bridge_sdk/
persistent.rs1use 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}