foundry_local_sdk/item_queue.rs
1//! The [`ItemQueue`] handle: a thread-safe stream of [`Item`]s.
2//!
3//! Unlike [`Item`]/[`Request`](crate::Request)/[`Response`](crate::Response),
4//! `ItemQueue` is *handle-backed*: it wraps a native `flItemQueue` and shares it
5//! across clones (an `Arc`), because the queue has a lifetime and identity that
6//! must be preserved. Create one from a [`Session`](crate::Session) via
7//! [`Session::create_input_queue`](crate::Session::create_input_queue) and attach
8//! it to a [`Request`](crate::Request) for incremental / streaming input.
9
10use std::sync::Arc;
11
12use crate::detail::session::NativeItemQueue;
13use crate::error::Result;
14use crate::item::Item;
15
16/// A thread-safe, multi-producer / multi-consumer queue of [`Item`]s.
17///
18/// Cloning an `ItemQueue` yields another handle to the *same* underlying native
19/// queue, so items pushed through one clone are visible to all.
20#[derive(Clone)]
21pub struct ItemQueue {
22 inner: Arc<NativeItemQueue>,
23}
24
25impl ItemQueue {
26 pub(crate) fn from_native(inner: Arc<NativeItemQueue>) -> Self {
27 Self { inner }
28 }
29
30 /// Borrow the underlying native queue (for request wiring within the crate).
31 pub(crate) fn native(&self) -> &NativeItemQueue {
32 &self.inner
33 }
34
35 /// Consume this handle, yielding the shared native queue.
36 pub(crate) fn into_native(self) -> Arc<NativeItemQueue> {
37 self.inner
38 }
39
40 /// Push an item onto the queue, transferring a native copy into it.
41 pub fn push(&self, item: &Item) -> Result<()> {
42 self.inner.push_value(item)
43 }
44
45 /// Pop the next available item, or `None` if the queue is currently empty.
46 pub fn try_pop(&self) -> Result<Option<Item>> {
47 self.inner.try_pop_value()
48 }
49
50 /// The number of items currently buffered.
51 pub fn len(&self) -> usize {
52 self.inner.size()
53 }
54
55 /// Whether the queue currently holds no items.
56 pub fn is_empty(&self) -> bool {
57 self.len() == 0
58 }
59
60 /// Signal that no more items will be pushed. A consumer draining the queue
61 /// can then stop once it is empty.
62 pub fn mark_finished(&self) {
63 self.inner.mark_finished();
64 }
65
66 /// Whether [`mark_finished`](Self::mark_finished) has been called.
67 pub fn is_finished(&self) -> bool {
68 self.inner.is_finished()
69 }
70}
71
72impl std::fmt::Debug for ItemQueue {
73 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
74 f.debug_struct("ItemQueue")
75 .field("len", &self.len())
76 .field("finished", &self.is_finished())
77 .finish()
78 }
79}