hapi_rs/parameter/
access.rs

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