jsonrpsee_core/middleware/
mod.rs1pub mod layer;
4
5use std::{
6 borrow::Cow,
7 future::Future,
8 pin::Pin,
9 task::{Context, Poll},
10};
11
12use crate::server::MethodResponse;
13use futures_util::future::Either;
14use jsonrpsee_types::{ErrorObject, Id};
15use pin_project::pin_project;
16use serde_json::value::RawValue;
17use tower::layer::{
18 util::{Identity, Stack},
19 LayerFn,
20};
21
22pub type Notification<'a> = jsonrpsee_types::Notification<'a, Option<Cow<'a, RawValue>>>;
24pub use jsonrpsee_types::Request;
26
27#[derive(Debug)]
30pub struct BatchEntryErr<'a> {
31 id: Id<'a>,
32 err: ErrorObject<'a>,
33}
34
35impl<'a> BatchEntryErr<'a> {
36 pub const fn new(id: Id<'a>, err: ErrorObject<'a>) -> Self {
38 Self { id, err }
39 }
40
41 pub fn into_parts(self) -> (ErrorObject<'a>, Id<'a>) {
43 (self.err, self.id)
44 }
45}
46
47#[derive(Debug)]
49pub struct Batch<'a> {
50 inner: Vec<Result<BatchEntry<'a>, BatchEntryErr<'a>>>,
51}
52
53impl<'a> IntoIterator for Batch<'a> {
54 type Item = Result<BatchEntry<'a>, BatchEntryErr<'a>>;
55 type IntoIter = std::vec::IntoIter<Self::Item>;
56
57 fn into_iter(self) -> Self::IntoIter {
58 self.inner.into_iter()
59 }
60}
61
62impl<'a> Batch<'a> {
63 pub fn from(entries: Vec<Result<BatchEntry<'a>, BatchEntryErr<'a>>>) -> Self {
65 Self { inner: entries }
66 }
67
68 pub fn len(&self) -> usize {
70 self.inner.len()
71 }
72
73 pub fn is_empty(&self) -> bool {
75 self.inner.is_empty()
76 }
77
78 pub fn iter(&self) -> impl Iterator<Item = &Result<BatchEntry<'a>, BatchEntryErr<'a>>> {
80 self.inner.iter()
81 }
82
83 pub fn iter_mut(
85 &mut self,
86 ) -> impl Iterator<Item = &mut Result<BatchEntry<'a>, BatchEntryErr<'a>>> {
87 self.inner.iter_mut()
88 }
89}
90
91#[derive(Debug, Clone)]
94pub enum BatchEntry<'a> {
95 Call(Request<'a>),
97 Notification(Notification<'a>),
99}
100
101impl<'a> BatchEntry<'a> {
102 pub fn method_name(&self) -> &str {
104 match self {
105 BatchEntry::Call(req) => req.method_name(),
106 BatchEntry::Notification(n) => n.method_name(),
107 }
108 }
109
110 pub fn params(&self) -> Option<&Cow<'a, RawValue>> {
112 match self {
113 BatchEntry::Call(req) => req.params.as_ref(),
114 BatchEntry::Notification(n) => n.params.as_ref(),
115 }
116 }
117}
118
119pub trait RpcServiceT {
123 fn call<'a>(&self, request: Request<'a>) -> impl Future<Output = MethodResponse> + Send + 'a;
125
126 fn batch<'a>(&self, requests: Batch<'a>) -> impl Future<Output = MethodResponse> + Send + 'a;
136
137 fn notification<'a>(
139 &self,
140 n: Notification<'a>,
141 ) -> impl Future<Output = MethodResponse> + Send + 'a;
142}
143
144#[derive(Debug, Clone)]
147pub struct RpcServiceBuilder<L>(tower::ServiceBuilder<L>);
148
149impl Default for RpcServiceBuilder<Identity> {
150 fn default() -> Self {
151 RpcServiceBuilder(tower::ServiceBuilder::new())
152 }
153}
154
155impl RpcServiceBuilder<Identity> {
156 pub fn new() -> Self {
158 Self(tower::ServiceBuilder::new())
159 }
160}
161
162impl<L> RpcServiceBuilder<L> {
163 pub fn option_layer<T>(
167 self,
168 layer: Option<T>,
169 ) -> RpcServiceBuilder<Stack<layer::Either<T, Identity>, L>> {
170 let layer = if let Some(layer) = layer {
171 layer::Either::Left(layer)
172 } else {
173 layer::Either::Right(Identity::new())
174 };
175 RpcServiceBuilder(self.0.layer(layer))
176 }
177
178 pub fn layer<T>(self, layer: T) -> RpcServiceBuilder<Stack<T, L>> {
182 RpcServiceBuilder(self.0.layer(layer))
183 }
184
185 pub fn layer_fn<F>(self, f: F) -> RpcServiceBuilder<Stack<LayerFn<F>, L>> {
190 RpcServiceBuilder(self.0.layer_fn(f))
191 }
192
193 pub fn service<S>(&self, service: S) -> L::Service
195 where
196 L: tower::Layer<S>,
197 {
198 self.0.service(service)
199 }
200}
201
202#[derive(Debug)]
204#[pin_project]
205pub struct ResponseFuture<F, R>(#[pin] futures_util::future::Either<F, std::future::Ready<R>>);
206
207impl<F, R> ResponseFuture<F, R> {
208 pub fn future(f: F) -> ResponseFuture<F, R> {
210 ResponseFuture(Either::Left(f))
211 }
212
213 pub fn ready(response: R) -> ResponseFuture<F, R> {
215 ResponseFuture(Either::Right(std::future::ready(response)))
216 }
217}
218
219impl<F, R> Future for ResponseFuture<F, R>
220where
221 F: Future<Output = R>,
222{
223 type Output = F::Output;
224
225 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
226 match self.project().0.poll(cx) {
227 Poll::Ready(rp) => Poll::Ready(rp),
228 Poll::Pending => Poll::Pending,
229 }
230 }
231}