neva/types/
notification.rs1use serde::{Serialize, Deserialize};
4use serde::de::DeserializeOwned;
5use crate::types::{RequestId, Message, JSONRPC_VERSION};
6#[cfg(feature = "server")]
7use crate::{error::Error, types::{FromRequest, Request}};
8
9pub use log_message::{
10 LogMessage,
11 LoggingLevel,
12 SetLevelRequestParams
13};
14
15#[cfg(feature = "server")]
16use crate::app::handler::{FromHandlerParams, HandlerParams};
17
18pub use progress::ProgressNotification;
19
20#[cfg(feature = "tracing")]
21pub use formatter::NotificationFormatter;
22
23mod progress;
24mod log_message;
25#[cfg(feature = "tracing")]
26mod formatter;
27#[cfg(feature = "tracing")]
28pub mod fmt;
29
30pub mod commands {
32 pub const INITIALIZED: &str = "notifications/initialized";
34
35 pub const CANCELLED: &str = "notifications/cancelled";
37
38 pub const MESSAGE: &str = "notifications/message";
40
41 pub const PROGRESS: &str = "notifications/progress";
43
44 pub const STDERR: &str = "notifications/stderr";
46
47 pub const SET_LOG_LEVEL: &str = "logging/setLevel";
49}
50
51#[derive(Debug, Clone, Serialize, Deserialize)]
53pub struct Notification {
54 pub jsonrpc: String,
58
59 pub method: String,
61
62 #[serde(skip_serializing_if = "Option::is_none")]
64 pub params: Option<serde_json::Value>,
65
66 #[serde(skip)]
68 pub session_id: Option<uuid::Uuid>,
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
82pub struct CancelledNotificationParams {
83 #[serde(rename = "requestId")]
87 pub request_id: RequestId,
88
89 #[serde(skip_serializing_if = "Option::is_none")]
92 pub reason: Option<String>,
93}
94
95impl From<Notification> for Message {
96 #[inline]
97 fn from(notification: Notification) -> Self {
98 Self::Notification(notification)
99 }
100}
101
102#[cfg(feature = "server")]
103impl FromHandlerParams for CancelledNotificationParams {
104 #[inline]
105 fn from_params(params: &HandlerParams) -> Result<Self, Error> {
106 let req = Request::from_params(params)?;
107 Self::from_request(req)
108 }
109}
110
111impl Notification {
112 #[inline]
114 pub fn new(method: &str, params: Option<serde_json::Value>) -> Self {
115 Self {
116 jsonrpc: JSONRPC_VERSION.into(),
117 session_id: None,
118 method: method.into(),
119 params
120 }
121 }
122
123 pub fn full_id(&self) -> RequestId {
125 let id = RequestId::default();
126 if let Some(session_id) = self.session_id {
127 id.concat(RequestId::Uuid(session_id))
128 } else {
129 id
130 }
131 }
132
133 #[inline]
135 pub fn params<T: DeserializeOwned>(&self) -> Option<T> {
136 match self.params {
137 Some(ref params) => serde_json::from_value(params.clone()).ok(),
138 None => None,
139 }
140 }
141
142 #[inline]
144 #[cfg(feature = "tracing")]
145 pub fn write(self) {
146 let is_stderr = self.is_stderr();
147 let Some(params) = self.params else { return; };
148 if is_stderr {
149 Self::write_err_internal(params);
150 } else {
151 match serde_json::from_value::<LogMessage>(params.clone()) {
152 Ok(log) => log.write(),
153 Err(err) => tracing::error!(logger = "neva", "{}", err),
154 }
155 }
156 }
157
158 #[inline]
160 pub fn is_stderr(&self) -> bool {
161 self.method.as_str() == commands::STDERR
162 }
163
164 #[inline]
166 #[cfg(feature = "tracing")]
167 pub fn write_err(self) {
168 if let Some(params) = self.params {
169 Self::write_err_internal(params)
170 }
171 }
172
173 pub fn to_json(self) -> String {
175 serde_json::to_string(&self).unwrap()
176 }
177
178 #[inline]
179 #[cfg(feature = "tracing")]
180 fn write_err_internal(params: serde_json::Value) {
181 let err = params
182 .get("content")
183 .unwrap_or(¶ms);
184 tracing::error!("{}", err);
185 }
186}
187
188#[cfg(test)]
189mod tests {
190 use serde_json::json;
191 use super::*;
192
193 #[test]
194 fn it_creates_new_notification() {
195 let notification = Notification::new("test", Some(json!({ "param": "value" })));
196
197 assert_eq!(notification.jsonrpc, "2.0");
198 assert_eq!(notification.method, "test");
199
200 let params_json = serde_json::to_string(¬ification.params.unwrap()).unwrap();
201
202 assert_eq!(params_json, r#"{"param":"value"}"#);
203 }
204}