lv2_core/feature/
cache.rs1use crate::feature::*;
2use std::collections::{hash_map, HashMap};
3use std::ffi::{c_void, CStr};
4use std::iter::Map;
5
6#[derive(Clone)]
12pub struct FeatureCache<'a> {
13 internal: HashMap<&'a CStr, *const c_void>,
14}
15
16impl<'a> FeatureCache<'a> {
17 pub unsafe fn from_raw(raw: *const *const ::sys::LV2_Feature) -> Self {
25 let mut internal_map = HashMap::new();
26 let mut feature_ptr = raw;
27
28 if !raw.is_null() {
29 while !(*feature_ptr).is_null() {
30 let uri = CStr::from_ptr((**feature_ptr).URI);
31 let data = (**feature_ptr).data as *const c_void;
32 internal_map.insert(uri, data);
33 feature_ptr = feature_ptr.add(1);
34 }
35 }
36
37 Self {
38 internal: internal_map,
39 }
40 }
41
42 pub fn contains<T: Feature>(&self) -> bool {
44 self.internal.contains_key(T::uri())
45 }
46
47 pub fn retrieve_feature<F: Feature, T: FromResolvedFeature<F>>(
53 &mut self,
54 class: ThreadingClass,
55 ) -> Result<T, MissingFeatureError> {
56 T::from_resolved_feature(
57 self.internal
58 .remove(F::uri())
59 .and_then(|ptr| unsafe { F::from_feature_ptr(ptr, class) }),
60 )
61 }
62}
63
64type HashMapIterator<'a> = hash_map::IntoIter<&'a CStr, *const c_void>;
65type DescriptorBuildFn<'a> = fn((&'a CStr, *const c_void)) -> FeatureDescriptor<'a>;
66
67impl<'a> std::iter::IntoIterator for FeatureCache<'a> {
68 type Item = FeatureDescriptor<'a>;
69 type IntoIter = Map<HashMapIterator<'a>, DescriptorBuildFn<'a>>;
70
71 fn into_iter(self) -> Self::IntoIter {
72 self.internal.into_iter().map(|element| {
73 let uri = element.0;
74 let data = element.1;
75 FeatureDescriptor { uri, data }
76 })
77 }
78}
79
80impl<'a> FeatureCollection<'a> for FeatureCache<'a> {
81 fn from_cache(
82 cache: &mut FeatureCache<'a>,
83 _: ThreadingClass,
84 ) -> Result<Self, MissingFeatureError> {
85 Ok(FeatureCache {
86 internal: cache.internal.clone(),
87 })
88 }
89}
90
91pub trait FromResolvedFeature<F: Feature>: Sized {
100 fn from_resolved_feature(feature: Option<F>) -> Result<Self, MissingFeatureError>;
101}
102
103impl<F: Feature> FromResolvedFeature<F> for F {
104 fn from_resolved_feature(feature: Option<F>) -> Result<Self, MissingFeatureError> {
105 feature.ok_or_else(|| MissingFeatureError { uri: F::uri() })
106 }
107}
108
109impl<F: Feature> FromResolvedFeature<F> for Option<F> {
110 #[inline]
111 fn from_resolved_feature(feature: Option<F>) -> Result<Self, MissingFeatureError> {
112 Ok(feature)
113 }
114}