1use crate::{sys, SBProcess, SBQueueItem, SBThread};
8use std::ffi::CStr;
9
10pub struct SBQueue {
37 pub raw: sys::SBQueueRef,
39}
40
41impl SBQueue {
42 pub(crate) fn wrap(raw: sys::SBQueueRef) -> SBQueue {
44 SBQueue { raw }
45 }
46
47 pub(crate) fn maybe_wrap(raw: sys::SBQueueRef) -> Option<SBQueue> {
49 if unsafe { sys::SBQueueIsValid(raw) } {
50 Some(SBQueue { raw })
51 } else {
52 None
53 }
54 }
55
56 pub fn is_valid(&self) -> bool {
58 unsafe { sys::SBQueueIsValid(self.raw) }
59 }
60
61 #[allow(missing_docs)]
62 pub fn process(&self) -> SBProcess {
63 SBProcess::wrap(unsafe { sys::SBQueueGetProcess(self.raw) })
64 }
65
66 pub fn queue_id(&self) -> u64 {
72 unsafe { sys::SBQueueGetQueueID(self.raw) }
73 }
74
75 pub fn name(&self) -> &str {
77 unsafe {
78 match CStr::from_ptr(sys::SBQueueGetName(self.raw)).to_str() {
79 Ok(s) => s,
80 _ => panic!("Invalid string?"),
81 }
82 }
83 }
84
85 pub fn threads(&self) -> SBQueueThreadIter {
89 SBQueueThreadIter {
90 queue: self,
91 idx: 0,
92 }
93 }
94
95 pub fn pending_items(&self) -> SBQueueQueueItemIter {
99 SBQueueQueueItemIter {
100 queue: self,
101 idx: 0,
102 }
103 }
104
105 pub fn num_running_items(&self) -> u32 {
110 unsafe { sys::SBQueueGetNumRunningItems(self.raw) }
111 }
112
113 pub fn kind(&self) -> sys::QueueKind {
115 unsafe { sys::SBQueueGetKind(self.raw) }
116 }
117}
118
119impl Clone for SBQueue {
120 fn clone(&self) -> SBQueue {
121 SBQueue {
122 raw: unsafe { sys::CloneSBQueue(self.raw) },
123 }
124 }
125}
126
127impl Drop for SBQueue {
128 fn drop(&mut self) {
129 unsafe { sys::DisposeSBQueue(self.raw) };
130 }
131}
132
133unsafe impl Send for SBQueue {}
134unsafe impl Sync for SBQueue {}
135
136pub struct SBQueueThreadIter<'d> {
141 queue: &'d SBQueue,
142 idx: usize,
143}
144
145impl Iterator for SBQueueThreadIter<'_> {
146 type Item = SBThread;
147
148 fn next(&mut self) -> Option<SBThread> {
149 if self.idx < unsafe { sys::SBQueueGetNumThreads(self.queue.raw) as usize } {
150 let r = Some(SBThread::wrap(unsafe {
151 sys::SBQueueGetThreadAtIndex(self.queue.raw, self.idx as u32)
152 }));
153 self.idx += 1;
154 r
155 } else {
156 None
157 }
158 }
159
160 fn size_hint(&self) -> (usize, Option<usize>) {
161 let sz = unsafe { sys::SBQueueGetNumThreads(self.queue.raw) } as usize;
162 (sz - self.idx, Some(sz))
163 }
164}
165
166impl ExactSizeIterator for SBQueueThreadIter<'_> {}
167
168pub struct SBQueueQueueItemIter<'d> {
173 queue: &'d SBQueue,
174 idx: usize,
175}
176
177impl Iterator for SBQueueQueueItemIter<'_> {
178 type Item = SBQueueItem;
179
180 fn next(&mut self) -> Option<SBQueueItem> {
181 if self.idx < unsafe { sys::SBQueueGetNumPendingItems(self.queue.raw) as usize } {
182 let r = Some(SBQueueItem::wrap(unsafe {
183 sys::SBQueueGetPendingItemAtIndex(self.queue.raw, self.idx as u32)
184 }));
185 self.idx += 1;
186 r
187 } else {
188 None
189 }
190 }
191
192 fn size_hint(&self) -> (usize, Option<usize>) {
193 let sz = unsafe { sys::SBQueueGetNumPendingItems(self.queue.raw) } as usize;
194 (sz - self.idx, Some(sz))
195 }
196}
197
198impl ExactSizeIterator for SBQueueQueueItemIter<'_> {}
199
200#[cfg(feature = "graphql")]
201#[juniper::graphql_object]
202impl SBQueue {
203 fn queue_id() -> i32 {
205 self.queue_id() as i32
206 }
207
208 fn name() -> &str {
209 self.name()
210 }
211
212 fn threads() -> Vec<SBThread> {
213 self.threads().collect()
214 }
215
216 fn pending_items() -> Vec<SBQueueItem> {
217 self.pending_items().collect()
218 }
219
220 fn num_running_items() -> i32 {
222 self.num_running_items() as i32
223 }
224}