jsonrpcmsg/
batch.rs

1//! JSON-RPC batch types
2use serde::{Deserialize, Serialize};
3use crate::request::Request;
4use crate::response::Response;
5
6/// A message in a batch, which can be either a request or a response
7#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
8#[serde(untagged)]
9pub enum Message {
10    /// A request message
11    Request(Request),
12    /// A response message
13    Response(Response),
14}
15
16/// A batch of JSON-RPC messages
17#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
18pub struct Batch(Vec<Message>);
19
20impl Batch {
21    /// Create a new empty batch
22    pub fn new() -> Self {
23        Batch(Vec::new())
24    }
25    
26    /// Create a new batch with the given capacity
27    pub fn with_capacity(capacity: usize) -> Self {
28        Batch(Vec::with_capacity(capacity))
29    }
30    
31    /// Add a request to the batch
32    pub fn add_request(&mut self, request: Request) {
33        self.0.push(Message::Request(request));
34    }
35    
36    /// Add a response to the batch
37    pub fn add_response(&mut self, response: Response) {
38        self.0.push(Message::Response(response));
39    }
40    
41    /// Check if the batch is empty
42    pub fn is_empty(&self) -> bool {
43        self.0.is_empty()
44    }
45    
46    /// Get the number of messages in the batch
47    pub fn len(&self) -> usize {
48        self.0.len()
49    }
50    
51    /// Get a reference to the underlying vector
52    pub fn as_vec(&self) -> &Vec<Message> {
53        &self.0
54    }
55    
56    /// Get a mutable reference to the underlying vector
57    pub fn as_vec_mut(&mut self) -> &mut Vec<Message> {
58        &mut self.0
59    }
60}
61
62impl Message {
63    /// Check if this message is a request
64    pub fn is_request(&self) -> bool {
65        matches!(self, Message::Request(_))
66    }
67    
68    /// Check if this message is a response
69    pub fn is_response(&self) -> bool {
70        matches!(self, Message::Response(_))
71    }
72    
73    /// Get the message as a request, if it is one
74    pub fn as_request(&self) -> Option<&Request> {
75        match self {
76            Message::Request(req) => Some(req),
77            Message::Response(_) => None,
78        }
79    }
80    
81    /// Get the message as a response, if it is one
82    pub fn as_response(&self) -> Option<&Response> {
83        match self {
84            Message::Request(_) => None,
85            Message::Response(res) => Some(res),
86        }
87    }
88}
89
90// Implement Deref and DerefMut to allow using Batch like a Vec<Message>
91impl std::ops::Deref for Batch {
92    type Target = Vec<Message>;
93    
94    fn deref(&self) -> &Self::Target {
95        &self.0
96    }
97}
98
99impl std::ops::DerefMut for Batch {
100    fn deref_mut(&mut self) -> &mut Self::Target {
101        &mut self.0
102    }
103}
104
105// Implement IntoIterator to allow iterating over Batch
106impl IntoIterator for Batch {
107    type Item = Message;
108    type IntoIter = std::vec::IntoIter<Message>;
109    
110    fn into_iter(self) -> Self::IntoIter {
111        self.0.into_iter()
112    }
113}
114
115impl<'a> IntoIterator for &'a Batch {
116    type Item = &'a Message;
117    type IntoIter = std::slice::Iter<'a, Message>;
118    
119    fn into_iter(self) -> Self::IntoIter {
120        self.0.iter()
121    }
122}
123
124impl<'a> IntoIterator for &'a mut Batch {
125    type Item = &'a mut Message;
126    type IntoIter = std::slice::IterMut<'a, Message>;
127    
128    fn into_iter(self) -> Self::IntoIter {
129        self.0.iter_mut()
130    }
131}
132
133// Implement From<Vec<Message>> for Batch
134impl From<Vec<Message>> for Batch {
135    fn from(vec: Vec<Message>) -> Self {
136        Batch(vec)
137    }
138}