sark_http/payload/owned/
mod.rs1use std::{num::NonZero, ops::ControlFlow};
2
3use o3::{
4 buffer::{resident, storage},
5 mem,
6};
7
8pub mod flatten;
9pub mod iter;
10
11mod error;
12mod segment;
13mod segments;
14
15pub use error::Error;
16use flatten::State;
17pub use segment::Segment;
18pub use segments::Segments;
19
20#[must_use = "step or release the retained body"]
22pub struct Flatten<'d>(State<'d>);
23
24impl<'d> Flatten<'d> {
25 pub const fn new(source: Segments<'d>) -> Self {
26 Self(State::Input(source))
27 }
28
29 pub fn try_push(
30 self,
31 segment: Segment<'d>,
32 ) -> Result<Self, mem::Rejected<(Self, Segment<'d>), flatten::Error>> {
33 match self.0 {
34 State::Input(source) => match source.try_push(segment) {
35 Ok(source) => Ok(Self::new(source)),
36 Err(rejected) => {
37 let ((source, segment), error) = rejected.into_parts();
38 Err(mem::Rejected::new(
39 (Self::new(source), segment),
40 flatten::Error::Assembly(error),
41 ))
42 }
43 },
44 state @ State::Copying(_) => Err(mem::Rejected::new(
45 (Self(state), segment),
46 flatten::Error::Finished,
47 )),
48 }
49 }
50
51 pub fn try_step(
54 self,
55 budget: NonZero<usize>,
56 ) -> Result<ControlFlow<resident::Shared<'d>, Self>, mem::Rejected<Self, storage::AllocError>>
57 {
58 use o3::buffer::segments;
59
60 let copy = match self.0 {
61 State::Input(source) => match source.storage {
62 segments::Shape::Empty => return Ok(ControlFlow::Break(resident::Shared::new())),
63 segments::Shape::One(owner) => return Ok(ControlFlow::Break(owner.into_inner())),
64 segments::Shape::Many(source) => match segments::Flatten::try_new(source) {
65 Ok(copy) => copy,
66 Err(rejected) => {
67 let (source, error) = rejected.into_parts();
68 return Err(mem::Rejected::new(
69 Self::new(Segments::from(segments::Shape::Many(source))),
70 error,
71 ));
72 }
73 },
74 },
75 State::Copying(copy) => copy,
76 };
77 Ok(match copy.step(budget) {
78 ControlFlow::Break(output) => ControlFlow::Break(resident::Shared::from(output)),
79 ControlFlow::Continue(copy) => ControlFlow::Continue(Self(State::Copying(copy))),
80 })
81 }
82}