1use crate::node::{Node, Nodes};
2use crate::plugin::Plugin;
3use lilv_sys as lib;
4use std::fmt::Debug;
5use std::ptr::NonNull;
6
7#[derive(Clone)]
8pub struct Port {
9 pub(crate) inner: NonNull<lib::LilvPort>,
10 pub(crate) plugin: Plugin,
11}
12
13impl Port {
14 #[must_use]
19 pub fn node(&self) -> Node {
20 let _life = self.plugin.life.inner.lock();
21 let plugin = self.plugin.inner.as_ptr();
22 let port = self.inner.as_ptr();
23
24 {
25 let ptr = NonNull::new(unsafe { lib::lilv_port_get_node(plugin, port) as _ }).unwrap();
26 let world = self.plugin.life.clone();
27 Node {
28 inner: ptr,
29 borrowed: true,
30 life: world,
31 }
32 }
33 }
34
35 #[must_use]
41 pub fn value(&self, predicate: &Node) -> Nodes {
42 let _life = self.plugin.life.inner.lock();
43 let plugin = self.plugin.inner.as_ptr();
44 let port = self.inner.as_ptr();
45 let predicate = predicate.inner.as_ptr();
46 let inner = unsafe { lib::lilv_port_get_value(plugin, port, predicate) };
47 let world = self.plugin.life.clone();
48 Nodes { inner, life: world }
49 }
50
51 #[must_use]
56 pub fn get(&self, predicate: &Node) -> Option<Node> {
57 let _life = self.plugin.life.inner.lock();
58 let plugin = self.plugin.inner.as_ptr();
59 let port = self.inner.as_ptr();
60 let predicate = predicate.inner.as_ptr();
61
62 Some({
63 let ptr = NonNull::new(unsafe { lib::lilv_port_get(plugin, port, predicate) })?;
64 let world = self.plugin.life.clone();
65 Node {
66 inner: ptr,
67 borrowed: false,
68 life: world,
69 }
70 })
71 }
72
73 #[must_use]
75 pub fn properties(&self) -> Nodes {
76 let _life = self.plugin.life.inner.lock();
77 let plugin = self.plugin.inner.as_ptr();
78 let port = self.inner.as_ptr();
79 let inner = unsafe { lib::lilv_port_get_properties(plugin, port) };
80 let world = self.plugin.life.clone();
81 Nodes { inner, life: world }
82 }
83
84 #[must_use]
86 pub fn has_property(&self, property_uri: &Node) -> bool {
87 let _life = self.plugin.life.inner.lock();
88 let plugin = self.plugin.inner.as_ptr();
89 let port = self.inner.as_ptr();
90 let property_uri = property_uri.inner.as_ptr();
91
92 unsafe { lib::lilv_port_has_property(plugin, port, property_uri) }
93 }
94
95 #[must_use]
101 pub fn supports_event(&self, event_type: &Node) -> bool {
102 let _life = self.plugin.life.inner.lock();
103 let plugin = self.plugin.inner.as_ptr();
104 let port = self.inner.as_ptr();
105 let event_type = event_type.inner.as_ptr();
106
107 unsafe { lib::lilv_port_supports_event(plugin, port, event_type) }
108 }
109
110 #[must_use]
112 pub fn index(&self) -> usize {
113 let _life = self.plugin.life.inner.lock();
114 let plugin = self.plugin.inner.as_ptr();
115 let port = self.inner.as_ptr();
116
117 unsafe { lib::lilv_port_get_index(plugin, port) as _ }
118 }
119
120 #[must_use]
124 pub fn symbol(&self) -> Option<Node> {
125 let _life = self.plugin.life.inner.lock();
126 let plugin = self.plugin.inner.as_ptr();
127 let port = self.inner.as_ptr();
128
129 {
130 let ptr = NonNull::new(unsafe { lib::lilv_port_get_symbol(plugin, port) as _ })?;
131 let world = self.plugin.life.clone();
132 Node {
133 inner: ptr,
134 borrowed: true,
135 life: world,
136 }
137 }
138 .into()
139 }
140
141 #[must_use]
146 pub fn name(&self) -> Option<Node> {
147 let _life = self.plugin.life.inner.lock();
148 let plugin = self.plugin.inner.as_ptr();
149 let port = self.inner.as_ptr();
150
151 Some({
152 let ptr = NonNull::new(unsafe { lib::lilv_port_get_name(plugin, port) })?;
153 let world = self.plugin.life.clone();
154 Node {
155 inner: ptr,
156 borrowed: false,
157 life: world,
158 }
159 })
160 }
161
162 #[must_use]
167 pub fn classes(&self) -> Nodes {
168 let _life = self.plugin.life.inner.lock();
169 let plugin = self.plugin.inner.as_ptr();
170 let port = self.inner.as_ptr();
171 let inner = unsafe { lib::lilv_port_get_classes(plugin, port) };
172 let world = self.plugin.life.clone();
173 Nodes { inner, life: world }
174 }
175
176 #[must_use]
178 pub fn is_a(&self, port_class: &Node) -> bool {
179 let _life = self.plugin.life.inner.lock();
180 let plugin = self.plugin.inner.as_ptr();
181 let port = self.inner.as_ptr();
182 let port_class = port_class.inner.as_ptr();
183
184 unsafe { lib::lilv_port_is_a(plugin, port, port_class) }
185 }
186
187 #[must_use]
192 pub fn range(&self) -> Range {
193 let _life = self.plugin.life.inner.lock();
194 let plugin = self.plugin.inner.as_ptr();
195 let port = self.inner.as_ptr();
196
197 let mut default_ptr: *mut lib::LilvNodeImpl = std::ptr::null_mut();
198 let mut minimum_ptr: *mut lib::LilvNodeImpl = std::ptr::null_mut();
199 let mut maximum_ptr: *mut lib::LilvNodeImpl = std::ptr::null_mut();
200
201 unsafe {
202 lib::lilv_port_get_range(
203 plugin,
204 port,
205 &mut default_ptr,
206 &mut minimum_ptr,
207 &mut maximum_ptr,
208 );
209 };
210 let ptr_to_node = |ptr: *mut lib::LilvNodeImpl| -> Option<Node> {
211 let ptr = NonNull::new(ptr.cast())?;
212 let world = self.plugin.life.clone();
213 Some(Node {
214 inner: ptr,
215 borrowed: false,
216 life: world,
217 })
218 };
219 Range {
220 default: ptr_to_node(default_ptr),
221 minimum: ptr_to_node(minimum_ptr),
222 maximum: ptr_to_node(maximum_ptr),
223 }
224 }
225
226 #[must_use]
231 pub fn scale_points(&self) -> ScalePoints {
232 let _life = self.plugin.life.inner.lock();
233 let plugin = self.plugin.inner.as_ptr() as *const _;
234 let port = self.inner.as_ptr() as *const _;
235
236 ScalePoints {
237 inner: unsafe { lib::lilv_port_get_scale_points(plugin, port) },
238 port: self.clone(),
239 refs: std::sync::Arc::new(1.into()),
240 }
241 }
242}
243
244impl Debug for Port {
245 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
246 f.debug_struct("Port")
247 .field("name", &self.name())
248 .field("symbol", &self.symbol())
249 .field("classes", &self.classes())
250 .field("range", &self.range())
251 .field("properties", &self.properties())
252 .finish()
253 }
254}
255
256unsafe impl Sync for ScalePoint {}
257
258#[derive(Clone)]
259pub struct ScalePoint {
260 pub(crate) inner: NonNull<lib::LilvScalePoint>,
261 pub(crate) port: Port,
262
263 _collection: ScalePoints,
266}
267
268impl ScalePoint {
269 #[must_use]
274 pub fn label(&self) -> Node {
275 let _life = self.port.plugin.life.inner.lock();
276 let inner = self.inner.as_ptr();
277
278 {
279 let ptr = NonNull::new(unsafe { lib::lilv_scale_point_get_label(inner) as _ }).unwrap();
280 let world = self.port.plugin.life.clone();
281 Node {
282 inner: ptr,
283 borrowed: true,
284 life: world,
285 }
286 }
287 }
288
289 #[must_use]
294 pub fn value(&self) -> Node {
295 let _life = self.port.plugin.life.inner.lock();
296 let inner = self.inner.as_ptr();
297
298 {
299 let ptr = NonNull::new(unsafe { lib::lilv_scale_point_get_value(inner) as _ }).unwrap();
300 let world = self.port.plugin.life.clone();
301 Node {
302 inner: ptr,
303 borrowed: true,
304 life: world,
305 }
306 }
307 }
308}
309
310impl Debug for ScalePoint {
311 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
312 f.debug_struct("ScalePoint")
313 .field("label", &self.label())
314 .field("value", &self.value())
315 .finish()
316 }
317}
318
319pub struct ScalePoints {
320 pub(crate) inner: *const lib::LilvScalePoints,
321 pub(crate) port: Port,
322 pub(crate) refs: std::sync::Arc<std::sync::atomic::AtomicUsize>,
323}
324
325impl ScalePoints {
326 #[must_use]
328 pub fn count(&self) -> usize {
329 let _life = self.port.plugin.life.inner.lock();
330 let size: u32 = unsafe { lib::lilv_scale_points_size(self.inner) };
331 size as usize
332 }
333
334 #[must_use]
336 pub fn iter(&self) -> ScalePointsIter {
337 let _life = self.port.plugin.life.inner.lock();
338 ScalePointsIter {
339 inner: self.clone(),
340 iter: unsafe { lib::lilv_scale_points_begin(self.inner) },
341 }
342 }
343}
344
345impl Drop for ScalePoints {
346 fn drop(&mut self) {
347 let refs = self.refs.fetch_sub(1, std::sync::atomic::Ordering::SeqCst);
348 if refs == 0 {
349 unsafe {
350 lib::lilv_scale_points_free(self.inner as *mut _);
351 }
352 }
353 }
354}
355
356impl Clone for ScalePoints {
357 fn clone(&self) -> Self {
358 self.refs.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
359 Self {
360 inner: self.inner,
361 port: self.port.clone(),
362 refs: self.refs.clone(),
363 }
364 }
365}
366
367impl Debug for ScalePoints {
368 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
369 let pts = self.iter().collect::<Vec<_>>();
370 f.debug_struct("ScalePoints")
371 .field("scale_points", &pts)
372 .finish()
373 }
374}
375
376impl IntoIterator for ScalePoints {
377 type Item = ScalePoint;
378
379 type IntoIter = ScalePointsIter;
380
381 fn into_iter(self) -> Self::IntoIter {
382 self.iter()
383 }
384}
385
386#[derive(Clone)]
388pub struct ScalePointsIter {
389 inner: ScalePoints,
390 iter: *mut lib::LilvIter,
391}
392
393impl Iterator for ScalePointsIter {
394 type Item = ScalePoint;
395
396 fn next(&mut self) -> Option<ScalePoint> {
397 let _life = self.inner.port.plugin.life.inner.lock();
398 let next_ptr =
399 unsafe { lib::lilv_scale_points_get(self.inner.inner, self.iter.cast()) } as *mut _;
400 let next = Some(ScalePoint {
401 inner: NonNull::new(next_ptr)?,
402 port: self.inner.port.clone(),
403 _collection: self.inner.clone(),
404 });
405 self.iter = unsafe { lib::lilv_scale_points_next(self.inner.inner, self.iter) };
406 next
407 }
408}
409
410#[allow(clippy::module_name_repetitions)]
412#[derive(Clone, Debug, PartialEq)]
413pub struct Range {
414 pub default: Option<Node>,
416 pub minimum: Option<Node>,
418 pub maximum: Option<Node>,
420}
421
422#[derive(Copy, Clone, Debug, PartialEq)]
424pub struct FloatRanges {
425 pub default: f32,
427 pub min: f32,
429 pub max: f32,
431}