Skip to main content

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}