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 actix_rt::pin;
537 use actix_utils::future::poll_fn;
538 use futures_util::stream;
539
540 use super::*;
541 use crate::body::{self, EitherBody};
542
543 macro_rules! assert_poll_next {
544 ($pin:expr, $exp:expr) => {
545 assert_eq!(
546 poll_fn(|cx| $pin.as_mut().poll_next(cx))
547 .await
548 .unwrap() .unwrap(), $exp
551 );
552 };
553 }
554
555 macro_rules! assert_poll_next_none {
556 ($pin:expr) => {
557 assert!(poll_fn(|cx| $pin.as_mut().poll_next(cx)).await.is_none());
558 };
559 }
560
561 #[allow(unused_allocation)] #[actix_rt::test]
563 async fn boxing_equivalence() {
564 assert_eq!(().size(), BodySize::Sized(0));
565 assert_eq!(().size(), Box::new(()).size());
566 assert_eq!(().size(), Box::pin(()).size());
567
568 let pl = Box::new(());
569 pin!(pl);
570 assert_poll_next_none!(pl);
571
572 let mut pl = Box::pin(());
573 assert_poll_next_none!(pl);
574 }
575
576 #[actix_rt::test]
577 async fn mut_equivalence() {
578 assert_eq!(().size(), BodySize::Sized(0));
579 assert_eq!(().size(), (&(&mut ())).size());
580
581 let pl = &mut ();
582 pin!(pl);
583 assert_poll_next_none!(pl);
584
585 let pl = &mut Box::new(());
586 pin!(pl);
587 assert_poll_next_none!(pl);
588
589 let mut body = body::SizedStream::new(
590 8,
591 stream::iter([
592 Ok::<_, std::io::Error>(Bytes::from("1234")),
593 Ok(Bytes::from("5678")),
594 ]),
595 );
596 let body = &mut body;
597 assert_eq!(body.size(), BodySize::Sized(8));
598 pin!(body);
599 assert_poll_next!(body, Bytes::from_static(b"1234"));
600 assert_poll_next!(body, Bytes::from_static(b"5678"));
601 assert_poll_next_none!(body);
602 }
603
604 #[allow(clippy::let_unit_value)]
605 #[actix_rt::test]
606 async fn test_unit() {
607 let pl = ();
608 assert_eq!(pl.size(), BodySize::Sized(0));
609 pin!(pl);
610 assert_poll_next_none!(pl);
611 }
612
613 #[actix_rt::test]
614 async fn test_static_str() {
615 assert_eq!("".size(), BodySize::Sized(0));
616 assert_eq!("test".size(), BodySize::Sized(4));
617
618 let pl = "test";
619 pin!(pl);
620 assert_poll_next!(pl, Bytes::from("test"));
621 }
622
623 #[actix_rt::test]
624 async fn test_static_bytes() {
625 assert_eq!(b"".as_ref().size(), BodySize::Sized(0));
626 assert_eq!(b"test".as_ref().size(), BodySize::Sized(4));
627
628 let pl = b"test".as_ref();
629 pin!(pl);
630 assert_poll_next!(pl, Bytes::from("test"));
631 }
632
633 #[actix_rt::test]
634 async fn test_vec() {
635 assert_eq!(vec![0; 0].size(), BodySize::Sized(0));
636 assert_eq!(Vec::from("test").size(), BodySize::Sized(4));
637
638 let pl = Vec::from("test");
639 pin!(pl);
640 assert_poll_next!(pl, Bytes::from("test"));
641 }
642
643 #[actix_rt::test]
644 async fn test_bytes() {
645 assert_eq!(Bytes::new().size(), BodySize::Sized(0));
646 assert_eq!(Bytes::from_static(b"test").size(), BodySize::Sized(4));
647
648 let pl = Bytes::from_static(b"test");
649 pin!(pl);
650 assert_poll_next!(pl, Bytes::from("test"));
651 }
652
653 #[actix_rt::test]
654 async fn test_bytes_mut() {
655 assert_eq!(BytesMut::new().size(), BodySize::Sized(0));
656 assert_eq!(BytesMut::from(b"test".as_ref()).size(), BodySize::Sized(4));
657
658 let pl = BytesMut::from("test");
659 pin!(pl);
660 assert_poll_next!(pl, Bytes::from("test"));
661 }
662
663 #[actix_rt::test]
664 async fn test_string() {
665 assert_eq!(String::new().size(), BodySize::Sized(0));
666 assert_eq!("test".to_owned().size(), BodySize::Sized(4));
667
668 let pl = "test".to_owned();
669 pin!(pl);
670 assert_poll_next!(pl, Bytes::from("test"));
671 }
672
673 #[actix_rt::test]
674 async fn test_byte_string() {
675 let pl = bytestring::ByteString::from_static("test");
676 assert_eq!(pl.size(), BodySize::Sized(4));
677 pin!(pl);
678 assert_poll_next!(pl, Bytes::from_static(b"test"));
679 assert_poll_next_none!(pl);
680 }
681
682 #[actix_rt::test]
683 async fn complete_body_combinators() {
684 let body = Bytes::from_static(b"test");
685 let body = BoxBody::new(body);
686 let body = EitherBody::<_, ()>::left(body);
687 let body = EitherBody::<(), _>::right(body);
688 assert_eq!(body.try_into_bytes().unwrap(), Bytes::from("test"));
693 }
694
695 #[actix_rt::test]
696 async fn complete_body_combinators_poll() {
697 let body = Bytes::from_static(b"test");
698 let body = BoxBody::new(body);
699 let body = EitherBody::<_, ()>::left(body);
700 let body = EitherBody::<(), _>::right(body);
701 let mut body = body;
702
703 assert_eq!(body.size(), BodySize::Sized(4));
704 assert_poll_next!(Pin::new(&mut body), Bytes::from("test"));
705 assert_poll_next_none!(Pin::new(&mut body));
706 }
707
708 #[actix_rt::test]
709 async fn none_body_combinators() {
710 fn none_body() -> BoxBody {
711 let body = body::None;
712 let body = BoxBody::new(body);
713 let body = EitherBody::<_, ()>::left(body);
714 let body = EitherBody::<(), _>::right(body);
715 body.boxed()
716 }
717
718 assert_eq!(none_body().size(), BodySize::None);
719 assert_eq!(none_body().try_into_bytes().unwrap(), Bytes::new());
720 assert_poll_next_none!(Pin::new(&mut none_body()));
721 }
722
723 #[actix_rt::test]
726 async fn test_body_casting() {
727 let mut body = String::from("hello cast");
728 let resp_body: &mut dyn std::any::Any = &mut body;
730 let body = resp_body.downcast_ref::<String>().unwrap();
731 assert_eq!(body, "hello cast");
732 let body = &mut resp_body.downcast_mut::<String>().unwrap();
733 body.push('!');
734 let body = resp_body.downcast_ref::<String>().unwrap();
735 assert_eq!(body, "hello cast!");
736 let not_body = resp_body.downcast_ref::<()>();
737 assert!(not_body.is_none());
738 }
739
740 #[actix_rt::test]
741 async fn non_owning_to_bytes() {
742 let mut body = BoxBody::new(());
743 let bytes = body::to_bytes(&mut body).await.unwrap();
744 assert_eq!(bytes, Bytes::new());
745
746 let mut body = body::BodyStream::new(stream::iter([
747 Ok::<_, std::io::Error>(Bytes::from("1234")),
748 Ok(Bytes::from("5678")),
749 ]));
750 let bytes = body::to_bytes(&mut body).await.unwrap();
751 assert_eq!(bytes, Bytes::from_static(b"12345678"));
752 }
753}