Skip to main content

hapi_rs/parameter/
access.rs

1use super::{FloatParameter, IntParameter, NodeHandle, ParmBaseTrait, StringParameter};
2
3use std::ffi::CString;
4
5pub use crate::ffi::enums::ParmType;
6
7use crate::errors::Result;
8use crate::utils::uzize_to_i32;
9
10impl IntParameter {
11    /// Set parameter value at index.
12    pub fn set(&self, index: i32, value: i32) -> Result<()> {
13        let session = &self.0.info.1;
14        debug_assert!(self.0.node.is_valid(session)?);
15        let name = self.c_name()?;
16        crate::ffi::set_parm_int_value(self.0.node, session, &name, index, value)
17    }
18
19    /// Get parameter value at index.
20    pub fn get(&self, index: i32) -> Result<i32> {
21        let session = &self.0.info.1;
22        debug_assert!(self.0.node.is_valid(session)?);
23        let name = self.c_name()?;
24        crate::ffi::get_parm_int_value(self.0.node, session, &name, index)
25    }
26
27    /// Set all parameter tuple values
28    pub fn set_array(&self, val: impl AsRef<[i32]>) -> Result<()> {
29        let session = &self.0.info.1;
30        debug_assert!(self.0.node.is_valid(session)?);
31        crate::ffi::set_parm_int_values(
32            self.0.node,
33            session,
34            self.0.info.int_values_index(),
35            self.0.info.size(),
36            val.as_ref(),
37        )
38    }
39
40    /// Set parameter tuple values
41    pub fn get_array(&self) -> Result<Vec<i32>> {
42        let session = &self.0.info.1;
43        debug_assert!(self.0.node.is_valid(session)?);
44        crate::ffi::get_parm_int_values(
45            self.0.node,
46            session,
47            self.0.info.int_values_index(),
48            self.0.info.size(),
49        )
50    }
51
52    /// Emulates a button press action
53    pub fn press_button(&self) -> Result<()> {
54        if !matches!(self.0.info.parm_type(), ParmType::Button) {
55            log::warn!("Parm {} not a Button type", self.0.info.name()?);
56        }
57        self.set(0, 1)
58    }
59}
60
61impl FloatParameter {
62    /// Set parameter value at index.
63    pub fn set(&self, index: i32, value: f32) -> Result<()> {
64        let session = &self.0.info.1;
65        debug_assert!(self.0.node.is_valid(session)?);
66        let name = self.c_name()?;
67        crate::ffi::set_parm_float_value(self.0.node, session, &name, index, value)
68    }
69
70    /// Get parameter value at index.
71    pub fn get(&self, index: i32) -> Result<f32> {
72        let session = &self.0.info.1;
73        debug_assert!(self.0.node.is_valid(session)?);
74        let name = self.c_name()?;
75        crate::ffi::get_parm_float_value(self.0.node, session, &name, index)
76    }
77
78    /// Set all parameter tuple values
79    pub fn set_array(&self, values: impl AsRef<[f32]>) -> Result<()> {
80        let session = &self.0.info.1;
81        debug_assert!(self.0.node.is_valid(session)?);
82        let mut size = self.0.info.size() as usize;
83        let values = values.as_ref();
84        match values.len() {
85            len if len > size => {
86                log::warn!("Array length is greater than parm length: {size}");
87                size = values.len().min(size);
88            }
89            0 => {
90                log::warn!("Parameter::set_array got empty array");
91                return Ok(());
92            }
93            _ => {}
94        }
95        crate::ffi::set_parm_float_values(
96            self.0.node,
97            session,
98            self.0.info.float_values_index(),
99            uzize_to_i32(size),
100            values,
101        )
102    }
103
104    /// Get all parameter tuple values
105    pub fn get_array(&self) -> Result<Vec<f32>> {
106        let session = &self.0.info.1;
107        debug_assert!(self.0.node.is_valid(session)?);
108        crate::ffi::get_parm_float_values(
109            self.0.node,
110            session,
111            self.0.info.float_values_index(),
112            self.0.info.size(),
113        )
114    }
115}
116
117impl StringParameter {
118    /// Set parameter value at index.
119    pub fn set(&self, index: i32, value: impl AsRef<str>) -> Result<()> {
120        let session = &self.0.info.1;
121        debug_assert!(self.0.node.is_valid(session)?);
122        let value = CString::new(value.as_ref())?;
123        crate::ffi::set_parm_string_value(self.0.node, session, self.0.info.id(), index, &value)
124    }
125
126    /// Get parameter value at index.
127    pub fn get(&self, index: i32) -> Result<String> {
128        let session = &self.0.info.1;
129        debug_assert!(self.0.node.is_valid(session)?);
130        let name = self.c_name()?;
131        crate::ffi::get_parm_string_value(self.0.node, session, &name, index)
132    }
133    /// Set all parameter tuple values
134    pub fn set_array<T: AsRef<str>>(&self, val: impl AsRef<[T]>) -> Result<()> {
135        let session = &self.0.info.1;
136        debug_assert!(self.0.node.is_valid(session)?);
137        let values = val
138            .as_ref()
139            .iter()
140            .map(|s| CString::new(s.as_ref()))
141            .collect::<std::result::Result<Vec<_>, _>>()?;
142        crate::ffi::set_parm_string_values(self.0.node, session, self.0.info.id(), &values)
143    }
144
145    /// Get all parameter tuple values
146    pub fn get_array(&self) -> Result<Vec<String>> {
147        let session = &self.0.info.1;
148        debug_assert!(self.0.node.is_valid(session)?);
149        crate::ffi::get_parm_string_values(
150            self.0.node,
151            session,
152            self.0.info.string_values_index(),
153            self.0.info.size(),
154        )
155        .map(|array| array.into_iter().collect())
156    }
157
158    /// Save/Download a file referenced in this parameter to a given file.
159    /// `filename` must include the desired extension to work properly.
160    pub fn save_parm_file(&self, destination_dir: &std::path::Path, filename: &str) -> Result<()> {
161        log::debug!(
162            "Saving parameter file to: {}/{}",
163            destination_dir.display(),
164            filename
165        );
166        let dest_dir = crate::utils::path_to_cstring(destination_dir)?;
167        let dest_file = CString::new(filename)?;
168        crate::ffi::get_file_parm(
169            &self.0.info.1,
170            self.0.node,
171            &self.c_name()?,
172            &dest_dir,
173            &dest_file,
174        )
175    }
176
177    /// If parameter is a `ParmType::Node` type, set it to reference another node
178    pub fn set_value_as_node(&self, value: impl AsRef<NodeHandle>) -> Result<()> {
179        debug_assert!(self.0.node.is_valid(self.session())?);
180        if self.0.info.parm_type() == ParmType::Node {
181            crate::ffi::set_parm_node_value(
182                self.session(),
183                self.0.node,
184                &self.c_name()?,
185                *value.as_ref(),
186            )
187        } else {
188            Ok(())
189        }
190    }
191    /// Return a handle to a node if the parameter is of type `ParmType::Node`
192    pub fn get_value_as_node(&self) -> Result<Option<NodeHandle>> {
193        debug_assert!(self.0.node.is_valid(self.session())?);
194        if self.0.info.parm_type() == ParmType::Node {
195            crate::ffi::get_parm_node_value(self.session(), self.0.node, &self.c_name()?)
196        } else {
197            Ok(None)
198        }
199    }
200}