1use std::{
4 convert::Infallible,
5 error::Error as StdError,
6 mem,
7 pin::Pin,
8 task::{Context, Poll},
9};
10
11use bytes::{Bytes, BytesMut};
12use futures_core::ready;
13use pin_project_lite::pin_project;
14
15use super::{BodySize, BoxBody};
16
17pub trait MessageBody {
56 type Error: Into<Box<dyn StdError>>;
61
62 fn size(&self) -> BodySize;
66
67 fn poll_next(
85 self: Pin<&mut Self>,
86 cx: &mut Context<'_>,
87 ) -> Poll<Option<Result<Bytes, Self::Error>>>;
88
89 #[inline]
101 fn try_into_bytes(self) -> Result<Bytes, Self>
102 where
103 Self: Sized,
104 {
105 Err(self)
106 }
107
108 #[inline]
114 fn boxed(self) -> BoxBody
115 where
116 Self: Sized + 'static,
117 {
118 BoxBody::new(self)
119 }
120}
121
122mod foreign_impls {
123 use std::{borrow::Cow, ops::DerefMut};
124
125 use super::*;
126
127 impl<B> MessageBody for &mut B
128 where
129 B: MessageBody + Unpin + ?Sized,
130 {
131 type Error = B::Error;
132
133 fn size(&self) -> BodySize {
134 (**self).size()
135 }
136
137 fn poll_next(
138 mut self: Pin<&mut Self>,
139 cx: &mut Context<'_>,
140 ) -> Poll<Option<Result<Bytes, Self::Error>>> {
141 Pin::new(&mut **self).poll_next(cx)
142 }
143 }
144
145 impl MessageBody for Infallible {
146 type Error = Infallible;
147
148 fn size(&self) -> BodySize {
149 match *self {}
150 }
151
152 fn poll_next(
153 self: Pin<&mut Self>,
154 _cx: &mut Context<'_>,
155 ) -> Poll<Option<Result<Bytes, Self::Error>>> {
156 match *self {}
157 }
158 }
159
160 impl MessageBody for () {
161 type Error = Infallible;
162
163 #[inline]
164 fn size(&self) -> BodySize {
165 BodySize::Sized(0)
166 }
167
168 #[inline]
169 fn poll_next(
170 self: Pin<&mut Self>,
171 _cx: &mut Context<'_>,
172 ) -> Poll<Option<Result<Bytes, Self::Error>>> {
173 Poll::Ready(None)
174 }
175
176 #[inline]
177 fn try_into_bytes(self) -> Result<Bytes, Self> {
178 Ok(Bytes::new())
179 }
180 }
181
182 impl<B> MessageBody for Box<B>
183 where
184 B: MessageBody + Unpin + ?Sized,
185 {
186 type Error = B::Error;
187
188 #[inline]
189 fn size(&self) -> BodySize {
190 self.as_ref().size()
191 }
192
193 #[inline]
194 fn poll_next(
195 self: Pin<&mut Self>,
196 cx: &mut Context<'_>,
197 ) -> Poll<Option<Result<Bytes, Self::Error>>> {
198 Pin::new(self.get_mut().as_mut()).poll_next(cx)
199 }
200 }
201
202 impl<T, B> MessageBody for Pin<T>
203 where
204 T: DerefMut<Target = B> + Unpin,
205 B: MessageBody + ?Sized,
206 {
207 type Error = B::Error;
208
209 #[inline]
210 fn size(&self) -> BodySize {
211 self.as_ref().size()
212 }
213
214 #[inline]
215 fn poll_next(
216 self: Pin<&mut Self>,
217 cx: &mut Context<'_>,
218 ) -> Poll<Option<Result<Bytes, Self::Error>>> {
219 self.get_mut().as_mut().poll_next(cx)
220 }
221 }
222
223 impl MessageBody for &'static [u8] {
224 type Error = Infallible;
225
226 #[inline]
227 fn size(&self) -> BodySize {
228 BodySize::Sized(self.len() as u64)
229 }
230
231 #[inline]
232 fn poll_next(
233 self: Pin<&mut Self>,
234 _cx: &mut Context<'_>,
235 ) -> Poll<Option<Result<Bytes, Self::Error>>> {
236 if self.is_empty() {
237 Poll::Ready(None)
238 } else {
239 Poll::Ready(Some(Ok(Bytes::from_static(mem::take(self.get_mut())))))
240 }
241 }
242
243 #[inline]
244 fn try_into_bytes(self) -> Result<Bytes, Self> {
245 Ok(Bytes::from_static(self))
246 }
247 }
248
249 impl MessageBody for Bytes {
250 type Error = Infallible;
251
252 #[inline]
253 fn size(&self) -> BodySize {
254 BodySize::Sized(self.len() as u64)
255 }
256
257 #[inline]
258 fn poll_next(
259 self: Pin<&mut Self>,
260 _cx: &mut Context<'_>,
261 ) -> Poll<Option<Result<Bytes, Self::Error>>> {
262 if self.is_empty() {
263 Poll::Ready(None)
264 } else {
265 Poll::Ready(Some(Ok(mem::take(self.get_mut()))))
266 }
267 }
268
269 #[inline]
270 fn try_into_bytes(self) -> Result<Bytes, Self> {
271 Ok(self)
272 }
273 }
274
275 impl MessageBody for BytesMut {
276 type Error = Infallible;
277
278 #[inline]
279 fn size(&self) -> BodySize {
280 BodySize::Sized(self.len() as u64)
281 }
282
283 #[inline]
284 fn poll_next(
285 self: Pin<&mut Self>,
286 _cx: &mut Context<'_>,
287 ) -> Poll<Option<Result<Bytes, Self::Error>>> {
288 if self.is_empty() {
289 Poll::Ready(None)
290 } else {
291 Poll::Ready(Some(Ok(mem::take(self.get_mut()).freeze())))
292 }
293 }
294
295 #[inline]
296 fn try_into_bytes(self) -> Result<Bytes, Self> {
297 Ok(self.freeze())
298 }
299 }
300
301 impl MessageBody for Vec<u8> {
302 type Error = Infallible;
303
304 #[inline]
305 fn size(&self) -> BodySize {
306 BodySize::Sized(self.len() as u64)
307 }
308
309 #[inline]
310 fn poll_next(
311 self: Pin<&mut Self>,
312 _cx: &mut Context<'_>,
313 ) -> Poll<Option<Result<Bytes, Self::Error>>> {
314 if self.is_empty() {
315 Poll::Ready(None)
316 } else {
317 Poll::Ready(Some(Ok(mem::take(self.get_mut()).into())))
318 }
319 }
320
321 #[inline]
322 fn try_into_bytes(self) -> Result<Bytes, Self> {
323 Ok(Bytes::from(self))
324 }
325 }
326
327 impl MessageBody for Cow<'static, [u8]> {
328 type Error = Infallible;
329
330 #[inline]
331 fn size(&self) -> BodySize {
332 BodySize::Sized(self.len() as u64)
333 }
334
335 #[inline]
336 fn poll_next(
337 self: Pin<&mut Self>,
338 _cx: &mut Context<'_>,
339 ) -> Poll<Option<Result<Bytes, Self::Error>>> {
340 if self.is_empty() {
341 Poll::Ready(None)
342 } else {
343 let bytes = match mem::take(self.get_mut()) {
344 Cow::Borrowed(b) => Bytes::from_static(b),
345 Cow::Owned(b) => Bytes::from(b),
346 };
347 Poll::Ready(Some(Ok(bytes)))
348 }
349 }
350
351 #[inline]
352 fn try_into_bytes(self) -> Result<Bytes, Self> {
353 match self {
354 Cow::Borrowed(b) => Ok(Bytes::from_static(b)),
355 Cow::Owned(b) => Ok(Bytes::from(b)),
356 }
357 }
358 }
359
360 impl MessageBody for &'static str {
361 type Error = Infallible;
362
363 #[inline]
364 fn size(&self) -> BodySize {
365 BodySize::Sized(self.len() as u64)
366 }
367
368 #[inline]
369 fn poll_next(
370 self: Pin<&mut Self>,
371 _cx: &mut Context<'_>,
372 ) -> Poll<Option<Result<Bytes, Self::Error>>> {
373 if self.is_empty() {
374 Poll::Ready(None)
375 } else {
376 let string = mem::take(self.get_mut());
377 let bytes = Bytes::from_static(string.as_bytes());
378 Poll::Ready(Some(Ok(bytes)))
379 }
380 }
381
382 #[inline]
383 fn try_into_bytes(self) -> Result<Bytes, Self> {
384 Ok(Bytes::from_static(self.as_bytes()))
385 }
386 }
387
388 impl MessageBody for String {
389 type Error = Infallible;
390
391 #[inline]
392 fn size(&self) -> BodySize {
393 BodySize::Sized(self.len() as u64)
394 }
395
396 #[inline]
397 fn poll_next(
398 self: Pin<&mut Self>,
399 _cx: &mut Context<'_>,
400 ) -> Poll<Option<Result<Bytes, Self::Error>>> {
401 if self.is_empty() {
402 Poll::Ready(None)
403 } else {
404 let string = mem::take(self.get_mut());
405 Poll::Ready(Some(Ok(Bytes::from(string))))
406 }
407 }
408
409 #[inline]
410 fn try_into_bytes(self) -> Result<Bytes, Self> {
411 Ok(Bytes::from(self))
412 }
413 }
414
415 impl MessageBody for Cow<'static, str> {
416 type Error = Infallible;
417
418 #[inline]
419 fn size(&self) -> BodySize {
420 BodySize::Sized(self.len() as u64)
421 }
422
423 #[inline]
424 fn poll_next(
425 self: Pin<&mut Self>,
426 _cx: &mut Context<'_>,
427 ) -> Poll<Option<Result<Bytes, Self::Error>>> {
428 if self.is_empty() {
429 Poll::Ready(None)
430 } else {
431 let bytes = match mem::take(self.get_mut()) {
432 Cow::Borrowed(s) => Bytes::from_static(s.as_bytes()),
433 Cow::Owned(s) => Bytes::from(s.into_bytes()),
434 };
435 Poll::Ready(Some(Ok(bytes)))
436 }
437 }
438
439 #[inline]
440 fn try_into_bytes(self) -> Result<Bytes, Self> {
441 match self {
442 Cow::Borrowed(s) => Ok(Bytes::from_static(s.as_bytes())),
443 Cow::Owned(s) => Ok(Bytes::from(s.into_bytes())),
444 }
445 }
446 }
447
448 impl MessageBody for bytestring::ByteString {
449 type Error = Infallible;
450
451 #[inline]
452 fn size(&self) -> BodySize {
453 BodySize::Sized(self.len() as u64)
454 }
455
456 #[inline]
457 fn poll_next(
458 self: Pin<&mut Self>,
459 _cx: &mut Context<'_>,
460 ) -> Poll<Option<Result<Bytes, Self::Error>>> {
461 if self.is_empty() {
462 Poll::Ready(None)
463 } else {
464 let string = mem::take(self.get_mut());
465 Poll::Ready(Some(Ok(string.into_bytes())))
466 }
467 }
468
469 #[inline]
470 fn try_into_bytes(self) -> Result<Bytes, Self> {
471 Ok(self.into_bytes())
472 }
473 }
474}
475
476pin_project! {
477 pub(crate) struct MessageBodyMapErr<B, F> {
478 #[pin]
479 body: B,
480 mapper: Option<F>,
481 }
482}
483
484impl<B, F, E> MessageBodyMapErr<B, F>
485where
486 B: MessageBody,
487 F: FnOnce(B::Error) -> E,
488{
489 pub(crate) fn new(body: B, mapper: F) -> Self {
490 Self {
491 body,
492 mapper: Some(mapper),
493 }
494 }
495}
496
497impl<B, F, E> MessageBody for MessageBodyMapErr<B, F>
498where
499 B: MessageBody,
500 F: FnOnce(B::Error) -> E,
501 E: Into<Box<dyn StdError>>,
502{
503 type Error = E;
504
505 #[inline]
506 fn size(&self) -> BodySize {
507 self.body.size()
508 }
509
510 fn poll_next(
511 mut self: Pin<&mut Self>,
512 cx: &mut Context<'_>,
513 ) -> Poll<Option<Result<Bytes, Self::Error>>> {
514 let this = self.as_mut().project();
515
516 match ready!(this.body.poll_next(cx)) {
517 Some(Err(err)) => {
518 let f = self.as_mut().project().mapper.take().unwrap();
519 let mapped_err = (f)(err);
520 Poll::Ready(Some(Err(mapped_err)))
521 }
522 Some(Ok(val)) => Poll::Ready(Some(Ok(val))),
523 None => Poll::Ready(None),
524 }
525 }
526
527 #[inline]
528 fn try_into_bytes(self) -> Result<Bytes, Self> {
529 let Self { body, mapper } = self;
530 body.try_into_bytes().map_err(|body| Self { body, mapper })
531 }
532}
533
534#[cfg(test)]
535mod tests {
536 use std::pin::pin;
537
538 use actix_utils::future::poll_fn;
539 use futures_util::stream;
540
541 use super::*;
542 use crate::body::{self, EitherBody};
543
544 macro_rules! assert_poll_next {
545 ($pin:expr, $exp:expr) => {
546 assert_eq!(
547 poll_fn(|cx| $pin.as_mut().poll_next(cx))
548 .await
549 .unwrap() .unwrap(), $exp
552 );
553 };
554 }
555
556 macro_rules! assert_poll_next_none {
557 ($pin:expr) => {
558 assert!(poll_fn(|cx| $pin.as_mut().poll_next(cx)).await.is_none());
559 };
560 }
561
562 #[allow(unused_allocation)] #[actix_rt::test]
564 async fn boxing_equivalence() {
565 assert_eq!(().size(), BodySize::Sized(0));
566 assert_eq!(().size(), Box::new(()).size());
567 assert_eq!(().size(), Box::pin(()).size());
568
569 let pl = Box::new(());
570 let mut pl = pin!(pl);
571 assert_poll_next_none!(pl);
572
573 let mut pl = Box::pin(());
574 assert_poll_next_none!(pl);
575 }
576
577 #[actix_rt::test]
578 async fn mut_equivalence() {
579 assert_eq!(().size(), BodySize::Sized(0));
580 assert_eq!(().size(), (&(&mut ())).size());
581
582 let pl = &mut ();
583 let mut pl = pin!(pl);
584 assert_poll_next_none!(pl);
585
586 let pl = &mut Box::new(());
587 let mut pl = pin!(pl);
588 assert_poll_next_none!(pl);
589
590 let mut body = body::SizedStream::new(
591 8,
592 stream::iter([
593 Ok::<_, std::io::Error>(Bytes::from("1234")),
594 Ok(Bytes::from("5678")),
595 ]),
596 );
597 let body = &mut body;
598 assert_eq!(body.size(), BodySize::Sized(8));
599 let mut body = pin!(body);
600 assert_poll_next!(body, Bytes::from_static(b"1234"));
601 assert_poll_next!(body, Bytes::from_static(b"5678"));
602 assert_poll_next_none!(body);
603 }
604
605 #[allow(clippy::let_unit_value)]
606 #[actix_rt::test]
607 async fn test_unit() {
608 let pl = ();
609 assert_eq!(pl.size(), BodySize::Sized(0));
610 let mut pl = pin!(pl);
611 assert_poll_next_none!(pl);
612 }
613
614 #[actix_rt::test]
615 async fn test_static_str() {
616 assert_eq!("".size(), BodySize::Sized(0));
617 assert_eq!("test".size(), BodySize::Sized(4));
618
619 let pl = "test";
620 let mut pl = pin!(pl);
621 assert_poll_next!(pl, Bytes::from("test"));
622 }
623
624 #[actix_rt::test]
625 async fn test_static_bytes() {
626 assert_eq!(b"".as_ref().size(), BodySize::Sized(0));
627 assert_eq!(b"test".as_ref().size(), BodySize::Sized(4));
628
629 let pl = b"test".as_ref();
630 let mut pl = pin!(pl);
631 assert_poll_next!(pl, Bytes::from("test"));
632 }
633
634 #[actix_rt::test]
635 async fn test_vec() {
636 assert_eq!(vec![0; 0].size(), BodySize::Sized(0));
637 assert_eq!(Vec::from("test").size(), BodySize::Sized(4));
638
639 let pl = Vec::from("test");
640 let mut pl = pin!(pl);
641 assert_poll_next!(pl, Bytes::from("test"));
642 }
643
644 #[actix_rt::test]
645 async fn test_bytes() {
646 assert_eq!(Bytes::new().size(), BodySize::Sized(0));
647 assert_eq!(Bytes::from_static(b"test").size(), BodySize::Sized(4));
648
649 let pl = Bytes::from_static(b"test");
650 let mut pl = pin!(pl);
651 assert_poll_next!(pl, Bytes::from("test"));
652 }
653
654 #[actix_rt::test]
655 async fn test_bytes_mut() {
656 assert_eq!(BytesMut::new().size(), BodySize::Sized(0));
657 assert_eq!(BytesMut::from(b"test".as_ref()).size(), BodySize::Sized(4));
658
659 let pl = BytesMut::from("test");
660 let mut pl = pin!(pl);
661 assert_poll_next!(pl, Bytes::from("test"));
662 }
663
664 #[actix_rt::test]
665 async fn test_string() {
666 assert_eq!(String::new().size(), BodySize::Sized(0));
667 assert_eq!("test".to_owned().size(), BodySize::Sized(4));
668
669 let pl = "test".to_owned();
670 let mut pl = pin!(pl);
671 assert_poll_next!(pl, Bytes::from("test"));
672 }
673
674 #[actix_rt::test]
675 async fn test_byte_string() {
676 let pl = bytestring::ByteString::from_static("test");
677 assert_eq!(pl.size(), BodySize::Sized(4));
678 let mut pl = pin!(pl);
679 assert_poll_next!(pl, Bytes::from_static(b"test"));
680 assert_poll_next_none!(pl);
681 }
682
683 #[actix_rt::test]
684 async fn complete_body_combinators() {
685 let body = Bytes::from_static(b"test");
686 let body = BoxBody::new(body);
687 let body = EitherBody::<_, ()>::left(body);
688 let body = EitherBody::<(), _>::right(body);
689 assert_eq!(body.try_into_bytes().unwrap(), Bytes::from("test"));
694 }
695
696 #[actix_rt::test]
697 async fn complete_body_combinators_poll() {
698 let body = Bytes::from_static(b"test");
699 let body = BoxBody::new(body);
700 let body = EitherBody::<_, ()>::left(body);
701 let body = EitherBody::<(), _>::right(body);
702 let mut body = body;
703
704 assert_eq!(body.size(), BodySize::Sized(4));
705 assert_poll_next!(Pin::new(&mut body), Bytes::from("test"));
706 assert_poll_next_none!(Pin::new(&mut body));
707 }
708
709 #[actix_rt::test]
710 async fn none_body_combinators() {
711 fn none_body() -> BoxBody {
712 let body = body::None;
713 let body = BoxBody::new(body);
714 let body = EitherBody::<_, ()>::left(body);
715 let body = EitherBody::<(), _>::right(body);
716 body.boxed()
717 }
718
719 assert_eq!(none_body().size(), BodySize::None);
720 assert_eq!(none_body().try_into_bytes().unwrap(), Bytes::new());
721 assert_poll_next_none!(Pin::new(&mut none_body()));
722 }
723
724 #[actix_rt::test]
727 async fn test_body_casting() {
728 let mut body = String::from("hello cast");
729 let resp_body: &mut dyn std::any::Any = &mut body;
731 let body = resp_body.downcast_ref::<String>().unwrap();
732 assert_eq!(body, "hello cast");
733 let body = &mut resp_body.downcast_mut::<String>().unwrap();
734 body.push('!');
735 let body = resp_body.downcast_ref::<String>().unwrap();
736 assert_eq!(body, "hello cast!");
737 let not_body = resp_body.downcast_ref::<()>();
738 assert!(not_body.is_none());
739 }
740
741 #[actix_rt::test]
742 async fn non_owning_to_bytes() {
743 let mut body = BoxBody::new(());
744 let bytes = body::to_bytes(&mut body).await.unwrap();
745 assert_eq!(bytes, Bytes::new());
746
747 let mut body = body::BodyStream::new(stream::iter([
748 Ok::<_, std::io::Error>(Bytes::from("1234")),
749 Ok(Bytes::from("5678")),
750 ]));
751 let bytes = body::to_bytes(&mut body).await.unwrap();
752 assert_eq!(bytes, Bytes::from_static(b"12345678"));
753 }
754}