Skip to main content

orbit_rs/fleet/
cursor.rs

1use std::marker::PhantomData;
2
3use crate::fleet::Fleet;
4use crate::ring::Frame;
5use crate::ring::cursor::{RingCursor, RingFrameSource, RingPoll, poll_ring};
6use crate::typed::OrbitTyped;
7
8struct FleetRingSource<'a, T: OrbitTyped> {
9    fleet: &'a Fleet,
10    _t: PhantomData<T>,
11}
12
13impl<'a, T: OrbitTyped> FleetRingSource<'a, T> {
14    fn new(fleet: &'a Fleet) -> Self {
15        Self {
16            fleet,
17            _t: PhantomData,
18        }
19    }
20}
21
22impl<T: OrbitTyped> RingFrameSource for FleetRingSource<'_, T> {
23    fn kind(&self) -> u8 {
24        T::KIND
25    }
26
27    fn head(&self) -> u64 {
28        self.fleet.head::<T>()
29    }
30
31    fn capacity(&self) -> usize {
32        self.fleet.ring_capacity::<T>()
33    }
34
35    fn read_at(&self, counter: u64) -> Option<Frame> {
36        self.fleet.read_at::<T>(counter)
37    }
38}
39
40impl Fleet {
41    /// Cursor that starts after the latest frame currently published for
42    /// `T`. Useful for subscribers that only want future frames.
43    pub fn cursor_at_head<T: OrbitTyped>(&self) -> RingCursor {
44        RingCursor::from_counter(self.head::<T>())
45    }
46
47    /// Cursor that starts at counter 0 for `T`.
48    pub const fn cursor_from_start<T: OrbitTyped>(&self) -> RingCursor {
49        let _ = self;
50        let _ = PhantomData::<T>;
51        RingCursor::from_start()
52    }
53
54    /// Walk `cursor` over the ring for `T`, advancing it to the current
55    /// head and reporting skipped counters as [`crate::ring::cursor::RingLoss`].
56    pub fn poll_ring<T: OrbitTyped>(&self, cursor: &mut RingCursor) -> RingPoll {
57        poll_ring(&FleetRingSource::<T>::new(self), cursor)
58    }
59}