flare_core/context/
context.rs

1use crate::error::{FlareErr, Result};
2use log::debug;
3use prost::Message;
4use std::collections::HashMap;
5use std::str::FromStr;
6use std::sync::{Arc, Mutex};
7use crate::flare_net::net::Command;
8
9#[derive(Default)]
10pub struct AppContext {
11    remote_addr: String,
12    command: Option<Command>,
13    data: Vec<u8>,
14    values: Arc<Mutex<HashMap<String, String>>>,
15    user_id: Option<String>,
16    platform: Option<i32>,
17    client_id: Option<String>,     // 客户端标识
18    language: Option<String>,
19    conn_id: String,
20    client_msg_id: String,
21}
22
23impl AppContext {
24    // 基础信息获取
25    pub fn remote_addr(&self) -> String {
26        self.remote_addr.clone()
27    }
28
29    pub fn command(&self) -> Option<Command> {
30        self.command
31    }
32
33    pub fn user_id(&self) -> Option<String> {
34        self.user_id.clone()
35    }
36
37    pub fn platform(&self) -> Option<i32> {
38        self.platform
39    }
40
41    pub fn client_id(&self) -> Option<String> {
42        self.client_id.clone()
43    }
44
45    pub fn language(&self) -> Option<String> {
46        self.language.clone()
47    }
48
49    // 数据操作相关
50    pub fn data(&self) -> &[u8] {
51        &self.data
52    }
53
54    pub fn set_data(&mut self, data: Vec<u8>) {
55        self.data = data;
56    }
57
58    pub fn get_data_as<T: Message + Default>(&self) -> Result<T> {
59        T::decode(&self.data[..])
60            .map_err(|e| FlareErr::DecodeError(e))
61    }
62
63    // 数据类型转换
64    pub fn msg_id(&self) -> Result<String> {
65        String::from_utf8(self.data.clone())
66            .map_err(|e| FlareErr::DecodeError(prost::DecodeError::new(e.to_string())))
67    }
68
69    pub fn bool_data(&self) -> Result<bool> {
70        if self.data.is_empty() {
71            return Err(FlareErr::InvalidParams("数据为空".to_string()));
72        }
73        Ok(self.data[0] != 0)
74    }
75
76    pub fn string_data(&self) -> Result<String> {
77        String::from_utf8(self.data.clone())
78            .map_err(|e| FlareErr::DecodeError(prost::DecodeError::new(e.to_string())))
79    }
80
81    pub fn int_data(&self) -> Result<i64> {
82        if self.data.len() < 8 {
83            return Err(FlareErr::InvalidParams("数据长度不足".to_string()));
84        }
85        let mut bytes = [0u8; 8];
86        bytes.copy_from_slice(&self.data[0..8]);
87        Ok(i64::from_le_bytes(bytes))
88    }
89
90    pub fn float_data(&self) -> Result<f64> {
91        if self.data.len() < 8 {
92            return Err(FlareErr::InvalidParams("数据长度不足".to_string()));
93        }
94        let mut bytes = [0u8; 8];
95        bytes.copy_from_slice(&self.data[0..8]);
96        Ok(f64::from_le_bytes(bytes))
97    }
98
99    // 新增值操作方法
100    pub fn set_val<T: ToString>(&self, key: &str, value: T) {
101        self.values.lock().unwrap().insert(
102            key.to_string(),
103            value.to_string()
104        );
105    }
106
107    pub fn get_val<T: FromStr>(&self, key: &str) -> Option<T> {
108        self.values.lock().unwrap()
109            .get(key)
110            .and_then(|v| T::from_str(v).ok())
111    }
112
113    pub fn del_val(&self, key: &str) -> Option<String> {
114        self.values.lock().unwrap().remove(key)
115    }
116
117    // 生命周期管理
118    pub fn destroy(&mut self) {
119        debug!("Destroying AppContext for connection: {}", self.remote_addr);
120        self.values.lock().unwrap().clear();
121        self.data.clear();
122        self.command = None;
123        self.user_id = None;
124        self.platform = None;
125        self.client_id = None;
126        self.language = None;
127        self.conn_id = String::new();
128        self.client_msg_id = String::new();
129    }
130
131    pub fn values(&self) -> &Arc<Mutex<HashMap<String, String>>> {
132        &self.values
133    }
134
135    pub fn conn_id(&self) -> String {
136        self.conn_id.clone()
137    }
138
139    pub fn client_msg_id(&self) -> String {
140        self.client_msg_id.clone()
141    }
142}
143
144impl Clone for AppContext {
145    fn clone(&self) -> Self {
146        Self {
147            remote_addr: self.remote_addr.clone(),
148            command: self.command.clone(),
149            data: self.data.clone(),
150            values: self.values.clone(),
151            user_id: self.user_id.clone(),
152            platform: self.platform.clone(),
153            client_id: self.client_id.clone(),
154            language: self.language.clone(),
155            conn_id: self.conn_id.clone(),
156            client_msg_id: self.client_msg_id.clone(),
157        }
158    }
159}
160
161#[derive(Default)]
162pub struct AppContextBuilder {
163    remote_addr: Option<String>,
164    command: Option<Command>,
165    language: Option<String>,
166    data: Option<Vec<u8>>,
167    values: Option<Arc<Mutex<HashMap<String, String>>>>,
168    user_id: Option<String>,
169    platform: Option<i32>,
170    client_id: Option<String>,
171    client_msg_id: Option<String>,
172    conn_id: Option<String>,
173}
174
175impl AppContextBuilder {
176    pub fn new() -> Self {
177        Self::default()
178    }
179
180    pub fn remote_addr(mut self, addr: String) -> Self {
181        self.remote_addr = Some(addr);
182        self
183    }
184
185    pub fn command(mut self, cmd: Option<Command>) -> Self {
186        self.command = cmd;
187        self
188    }
189
190    pub fn data(mut self, data: Vec<u8>) -> Self {
191        self.data = Some(data);
192        self
193    }
194
195    pub fn values(mut self, values: Arc<Mutex<HashMap<String, String>>>) -> Self {
196        self.values = Some(values);
197        self
198    }
199
200    pub fn user_id(mut self, user_id: String) -> Self {
201        self.user_id = Some(user_id);
202        self
203    }
204
205    pub fn platform(mut self, platform: i32) -> Self {
206        self.platform = Some(platform);
207        self
208    }
209
210    pub fn client_id(mut self, client_id: String) -> Self {
211        self.client_id = Some(client_id);
212        self
213    }
214
215    pub fn with_language(mut self, language: Option<String>) -> Self {
216        match language {
217            Some(lang) => self.language = Some(lang.to_string()),
218            None => self.language = None,
219        }
220        self
221    }
222    pub fn with_conn_id(mut self, conn_id: String) -> Self {
223        self.conn_id = Some(conn_id);
224        self
225    }
226    pub fn with_client_msg_id(mut self, client_msg_id: String) -> Self {
227        self.client_msg_id = Some(client_msg_id);
228        self
229    }
230
231    pub fn build(self) -> Result<AppContext> {
232        Ok(AppContext {
233            remote_addr: self.remote_addr.ok_or_else(|| anyhow::anyhow!("remote_addr is required"))?,
234            command: self.command,
235            data: self.data.unwrap_or_default(),
236            values: self.values.unwrap_or_else(|| Arc::new(Mutex::new(HashMap::new()))),
237            user_id: self.user_id,
238            platform: self.platform,
239            client_id: self.client_id,
240            language: self.language,
241            conn_id: self.conn_id.unwrap_or_else(String::new),
242            client_msg_id: self.client_msg_id.unwrap_or_else(String::new),
243        })
244    }
245}