binary_cookies/tokio/
bc.rs

1//! binarycookies mod
2
3use tokio::io::AsyncReadExt;
4
5use super::{cursor::CookieCursor, meta::MetaDecoder};
6use crate::{
7    decode::{binary_cookies::BinaryCookieFsm, meta::MetaOffset, pages::PagesOffset, DecodeResult},
8    error::Result,
9    tokio::page::PagesHandle,
10};
11
12pub trait DecodeBinaryCookie {
13    type File: CookieCursor;
14
15    #[expect(async_fn_in_trait, reason = "allow")]
16    async fn decode(&self) -> Result<BinaryCookiesHandle<'_, Self::File>>;
17}
18
19impl<F> DecodeBinaryCookie for F
20where
21    F: CookieCursor,
22{
23    type File = F;
24
25    #[expect(clippy::future_not_send, reason = "allow")]
26    async fn decode(&self) -> Result<BinaryCookiesHandle<'_, F>> {
27        let mut fsm = BinaryCookieFsm::new();
28        let mut rd = self.cursor_at(0);
29        loop {
30            rd.read_exact(fsm.buffer.space())
31                .await?;
32            let count = fsm.buffer.available_space();
33            fsm.buffer.fill(count);
34            match fsm.process()? {
35                DecodeResult::Continue(fsm_) => {
36                    fsm = fsm_;
37                    continue;
38                },
39                DecodeResult::Done((meta_offset, pages_offset, _)) => {
40                    return Ok(BinaryCookiesHandle {
41                        file: self,
42                        meta_offset,
43                        pages_offset,
44                    })
45                },
46            }
47        }
48    }
49}
50
51#[derive(Clone)]
52#[derive(Debug)]
53pub struct BinaryCookiesHandle<'a, F: CookieCursor> {
54    pub(crate) file: &'a F,
55    pub(crate) meta_offset: MetaOffset,
56    pub(crate) pages_offset: PagesOffset,
57}
58
59impl<'a, F: CookieCursor> BinaryCookiesHandle<'a, F> {
60    pub fn into_handles(
61        self,
62    ) -> (
63        PagesHandle<'a, F>,
64        MetaDecoder<<F as CookieCursor>::Cursor<'a>>,
65    ) {
66        let pages_handle = PagesHandle {
67            file: self.file,
68            offset: self.pages_offset,
69        };
70        let meta_handle = MetaDecoder {
71            rd: self
72                .file
73                .cursor_at(self.meta_offset),
74        };
75        (pages_handle, meta_handle)
76    }
77}