dope_core/driver/settings/
receive.rs1use std::num;
2
3use crate::{
4 driver::settings::{Buffers, Ring, demands, errors},
5 io::{datagram::payload, transfer},
6};
7
8#[derive(Clone, Copy, PartialEq, Eq)]
9pub struct Receive {
10 pub(in crate::driver::settings) entries: Buffers,
11 pub(in crate::driver::settings) len: transfer::NonZero,
12}
13
14impl Receive {
15 pub const DEFAULT: Self = Self::fixed::<4096, 4096>();
16 pub const MIN_DATAGRAM_SLOT: transfer::NonZero =
17 transfer::NonZero::from_payload(payload::Len::fixed::<1>());
18
19 pub const fn fixed<const ENTRIES: u16, const LEN: u32>() -> Self {
20 const {
21 assert!(ENTRIES >= 2);
22 assert!(ENTRIES.is_power_of_two());
23 assert!(LEN != 0);
24 assert!(LEN <= transfer::MAX_BYTES as u32);
25 assert!((ENTRIES as usize) <= (isize::MAX as usize) / (LEN as usize));
26 Self {
27 entries: Buffers(num::NonZero::<u16>::MIN.saturating_add(ENTRIES - 1)),
28 len: transfer::NonZero::fixed::<LEN>(),
29 }
30 }
31 }
32
33 pub(super) const fn from_parts(entries: Buffers, len: transfer::NonZero) -> Self {
34 Self { entries, len }
35 }
36
37 pub fn resolve(self, need: demands::Receive) -> Result<Self, errors::Claim> {
38 let base = demands::Receive::from(self);
39 let entries = if base.entries().get() >= need.entries().get() {
40 base.entries()
41 } else {
42 need.entries()
43 };
44 let len = base.buffer_len().max(need.buffer_len());
45 Self::exact(demands::Receive::new(entries, len))
46 }
47
48 pub fn exact(need: demands::Receive) -> Result<Self, errors::Claim> {
49 let entries = Ring::try_round(need.entries().get())?;
50 let len = transfer::NonZero::try_from(need.buffer_len())
51 .map_err(errors::Config::ReceiveBuffer)?;
52 Ok(Self::from_parts(entries.buffers(), len))
53 }
54
55 pub const fn buffers(self) -> Buffers {
56 self.entries
57 }
58 pub(crate) const fn entries(self) -> u16 {
59 self.entries.get()
60 }
61 pub(crate) const fn count(self) -> num::NonZero<u16> {
62 self.entries.0
63 }
64 pub(crate) const fn accounts(self) -> u32 {
66 self.entries.get() as u32 - 1
67 }
68 pub const fn buffer_len(self) -> transfer::NonZero {
70 self.len
71 }
72}