ferrijs_std/stream_web/utils/
queue.rs1use std::collections::VecDeque;
2
3use rquickjs::{class::Trace, Ctx, Exception, JsLifetime, Result, Value};
4
5use crate::stream_web::queuing_strategy::SizeValue;
6
7#[derive(JsLifetime, Trace, Default)]
10pub struct QueueWithSizes<'js> {
11 pub queue: VecDeque<ValueWithSize<'js>>,
12 pub queue_total_size: f64,
13}
14
15impl<'js> QueueWithSizes<'js> {
16 pub fn new() -> Self {
17 Self {
18 queue: VecDeque::new(),
19 queue_total_size: 0.0,
20 }
21 }
22
23 pub(crate) fn enqueue_value_with_size(
24 &mut self,
25 ctx: &Ctx<'js>,
26 value: Value<'js>,
27 size: SizeValue<'js>,
28 ) -> Result<()> {
29 let size = match is_non_negative_number(size) {
30 None => {
31 return Err(Exception::throw_range(
33 ctx,
34 "Size must be a finite, non-NaN, non-negative number.",
35 ));
36 },
37 Some(size) => size,
38 };
39
40 if size.is_infinite() {
42 return Err(Exception::throw_range(
43 ctx,
44 "Size must be a finite, non-NaN, non-negative number.",
45 ));
46 };
47
48 self.queue.push_back(ValueWithSize { value, size });
50
51 self.queue_total_size += size;
53
54 Ok(())
55 }
56
57 pub fn dequeue_value(&mut self) -> Value<'js> {
58 let value_with_size = self
61 .queue
62 .pop_front()
63 .expect("DequeueValue called with empty queue");
64 self.queue_total_size -= value_with_size.size;
66 if self.queue_total_size < 0.0 {
68 self.queue_total_size = 0.0
69 }
70 value_with_size.value
71 }
72
73 pub fn reset_queue(&mut self) {
74 self.queue.clear();
76 self.queue_total_size = 0.0;
78 }
79}
80
81#[derive(JsLifetime, Trace, Clone)]
82pub struct ValueWithSize<'js> {
83 pub value: Value<'js>,
84 size: f64,
85}
86
87fn is_non_negative_number(value: SizeValue<'_>) -> Option<f64> {
88 let number = value.as_number()?;
90 if number.is_nan() {
92 return None;
93 }
94
95 if number < 0.0 {
97 return None;
98 }
99
100 Some(number)
102}