bacnet_ops/watch/
sample.rs1use std::time::SystemTime;
6
7use tokio::sync::broadcast::{self, error::RecvError, error::TryRecvError};
8use tokio::time::Instant;
9
10use crate::format::RawRow;
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum Via {
15 First,
18 Notification,
20 Poll,
22}
23
24#[derive(Debug, Clone, PartialEq)]
26pub struct Sample {
27 pub values: Result<Vec<RawRow>, String>,
29 pub via: Via,
31 pub at: Instant,
33 pub time: SystemTime,
35}
36
37impl Sample {
38 pub(super) fn new(values: Result<Vec<RawRow>, String>, via: Via) -> Self {
39 Self::at(values, via, Instant::now(), SystemTime::now())
40 }
41
42 pub(super) fn at(
44 values: Result<Vec<RawRow>, String>,
45 via: Via,
46 at: Instant,
47 time: SystemTime,
48 ) -> Self {
49 Self {
50 values,
51 via,
52 at,
53 time,
54 }
55 }
56}
57
58#[derive(Debug)]
63pub struct Samples {
64 receiver: broadcast::Receiver<Sample>,
65 dropped: u64,
66}
67
68impl Samples {
69 pub(super) fn new(receiver: broadcast::Receiver<Sample>) -> Self {
70 Self {
71 receiver,
72 dropped: 0,
73 }
74 }
75
76 pub fn try_next(&mut self) -> Option<Sample> {
78 loop {
79 match self.receiver.try_recv() {
80 Ok(sample) => return Some(sample),
81 Err(TryRecvError::Lagged(missed)) => self.dropped += missed,
82 Err(TryRecvError::Empty | TryRecvError::Closed) => return None,
83 }
84 }
85 }
86
87 pub async fn next(&mut self) -> Option<Sample> {
90 loop {
91 match self.receiver.recv().await {
92 Ok(sample) => return Some(sample),
93 Err(RecvError::Lagged(missed)) => self.dropped += missed,
94 Err(RecvError::Closed) => return None,
95 }
96 }
97 }
98
99 pub fn dropped(&self) -> u64 {
101 self.dropped
102 }
103}