1use std::fmt;
4use std::fmt::{Debug, Formatter};
5use serde::{Serialize, Deserialize};
6use super::{ProgressToken, Message, JSONRPC_VERSION};
7
8#[cfg(feature = "server")]
9use crate::Context;
10
11#[cfg(feature = "http-server")]
12use {
13 crate::auth::DefaultClaims,
14 volga::headers::HeaderMap
15};
16
17pub use from_request::FromRequest;
18pub use request_id::RequestId;
19
20pub mod from_request;
21pub mod request_id;
22
23#[derive(Debug, Clone, Serialize, Deserialize)]
25pub struct Request {
26 pub jsonrpc: String,
30
31 pub id: RequestId,
33
34 pub method: String,
36
37 #[serde(skip_serializing_if = "Option::is_none")]
39 pub params: Option<serde_json::Value>,
40
41 #[serde(skip)]
43 pub session_id: Option<uuid::Uuid>,
44
45 #[serde(skip)]
47 #[cfg(feature = "http-server")]
48 pub headers: HeaderMap,
49
50 #[serde(skip)]
52 #[cfg(feature = "http-server")]
53 pub claims: Option<Box<DefaultClaims>>,
54}
55
56#[derive(Default, Clone, Deserialize, Serialize)]
61pub struct RequestParamsMeta {
62 #[serde(rename = "progressToken", skip_serializing_if = "Option::is_none")]
66 pub progress_token: Option<ProgressToken>,
67
68 #[serde(skip)]
70 #[cfg(feature = "server")]
71 pub(crate) context: Option<Context>
72}
73
74impl Debug for RequestParamsMeta {
75 #[inline]
76 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
77 f.debug_struct("RequestParamsMeta")
78 .field("progress_token", &self.progress_token)
79 .finish()
80 }
81}
82
83impl From<Request> for Message {
84 #[inline]
85 fn from(request: Request) -> Self {
86 Self::Request(request)
87 }
88}
89
90impl RequestParamsMeta {
91 pub fn new(id: &RequestId) -> Self {
93 Self {
94 progress_token: Some(ProgressToken::from(id)),
95 #[cfg(feature = "server")]
96 context: None
97 }
98 }
99}
100
101impl Request {
102 pub fn new<T: Serialize>(id: Option<RequestId>, method: &str, params: Option<T>) -> Self {
104 Self {
105 jsonrpc: JSONRPC_VERSION.into(),
106 session_id: None,
107 id: id.unwrap_or_default(),
108 method: method.into(),
109 params: params.and_then(|p| serde_json::to_value(p).ok()),
110 #[cfg(feature = "http-server")]
111 headers: HeaderMap::with_capacity(8),
112 #[cfg(feature = "http-server")]
113 claims: None,
114 }
115 }
116
117 pub fn id(&self) -> RequestId {
121 self.id.clone()
122 }
123
124 pub fn full_id(&self) -> RequestId {
126 let id = self.id.clone();
127 if let Some(session_id) = self.session_id {
128 id.concat(RequestId::Uuid(session_id))
129 } else {
130 id
131 }
132 }
133
134 pub fn meta(&self) -> Option<RequestParamsMeta> {
136 self.params.as_ref()?
137 .get("_meta")
138 .cloned()
139 .and_then(|meta| serde_json::from_value(meta).ok())
140 }
141}
142
143#[cfg(test)]
144mod tests {
145
146}