nappgui/core/
dbind.rs

1use std::ffi::{c_void, CString};
2
3use nappgui_sys::dbindst_t;
4
5use crate::{core::Stream, prelude::NappguiError};
6
7/// Helper function to convert dbindst_t to Result<(), NappguiError>.
8fn convert_to_nappgui_result(result: dbindst_t) -> Result<(), NappguiError> {
9    if result == dbindst_t::ekDBIND_OK {
10        Ok(())
11    } else {
12        Err(NappguiError::from(result))
13    }
14}
15
16/// Adds a field from a structure to its internal table within DBind.
17pub fn dbind_imp(
18    type_: &str,
19    size: u16,
20    mname: &str,
21    mtype: &str,
22    moffset: u16,
23    msize: u16,
24) -> Result<(), NappguiError> {
25    let type_ = CString::new(type_).unwrap();
26    let mname = CString::new(mname).unwrap();
27    let mtype = CString::new(mtype).unwrap();
28    let result = unsafe {
29        nappgui_sys::dbind_imp(
30            type_.as_ptr(),
31            size,
32            mname.as_ptr(),
33            mtype.as_ptr(),
34            moffset,
35            msize,
36        )
37    };
38    convert_to_nappgui_result(result)
39}
40
41/// Registers a value of type enum.
42///
43/// # Remark
44/// dbind_enum(mode_t, ekIMAGE_ANALISYS, "Image Analisys") will use the string "Image Analisys" instead of "ekIMAGE_ANALISYS"
45/// for those I/O or interface operations that require displaying enumeration literals. For example, to populate the fields of
46/// a PopUp linked to a data field.
47pub fn dbind_enum_imp(
48    type_: &str,
49    name: &str,
50    value: i32,
51    alias: &str,
52) -> Result<(), NappguiError> {
53    let type_ = CString::new(type_).unwrap();
54    let name = CString::new(name).unwrap();
55    let alias = CString::new(alias).unwrap();
56    let result = unsafe {
57        nappgui_sys::dbind_enum_imp(type_.as_ptr(), name.as_ptr(), value, alias.as_ptr())
58    };
59    convert_to_nappgui_result(result)
60}
61
62/// Registers an alias for a data type (typedef).
63pub fn dbind_alias_imp(
64    type_: &str,
65    alias: &str,
66    type_size: u16,
67    alias_size: u16,
68) -> Result<(), NappguiError> {
69    let type_ = CString::new(type_).unwrap();
70    let alias = CString::new(alias).unwrap();
71    let result = unsafe {
72        nappgui_sys::dbind_alias_imp(type_.as_ptr(), alias.as_ptr(), type_size, alias_size)
73    };
74    convert_to_nappgui_result(result)
75}
76
77/// Removes a data type from the DBind record.
78pub fn dbind_unreg_imp(type_: &str) -> Result<(), NappguiError> {
79    let type_ = CString::new(type_).unwrap();
80    let result = unsafe { nappgui_sys::dbind_unreg_imp(type_.as_ptr()) };
81    convert_to_nappgui_result(result)
82}
83
84/// Creates an object of registered type, initializing its fields with the default values.
85pub fn dbind_create_imp(type_: &str) -> *mut u8 {
86    let type_ = CString::new(type_).unwrap();
87    unsafe { nappgui_sys::dbind_create_imp(type_.as_ptr()) }
88}
89
90/// Copies an object of registered type.
91pub fn dbind_copy_imp(obj: *mut u8, type_: &str) -> *mut u8 {
92    let type_ = CString::new(type_).unwrap();
93    unsafe { nappgui_sys::dbind_copy_imp(obj, type_.as_ptr()) }
94}
95
96/// Initializes the fields of a registered type object with the default values.
97pub fn dbind_init_imp(obj: *mut u8, type_: &str) {
98    let type_ = CString::new(type_).unwrap();
99    unsafe { nappgui_sys::dbind_init_imp(obj, type_.as_ptr()) }
100}
101
102/// Frees the memory reserved by the fields of an object of registered type, but does not destroy the object itself.
103pub fn dbind_remove_imp(obj: *mut u8, type_: &str) {
104    let type_ = CString::new(type_).unwrap();
105    unsafe { nappgui_sys::dbind_remove_imp(obj, type_.as_ptr()) }
106}
107
108/// Destroys an object of registered type. Memory allocated to fields and sub-objects will also be freed recursively.
109pub fn dbind_destroy_imp(obj: *mut *mut u8, type_: &str) {
110    let type_ = CString::new(type_).unwrap();
111    unsafe { nappgui_sys::dbind_destopt_imp(obj, type_.as_ptr()) }
112}
113
114/// Compares two objects of registered type.
115///
116/// Returns -1, 1 or 0 if obj1 is less than, greater than or equal to obj2.
117pub fn dbind_cmp_imp(obj1: *mut u8, obj2: *mut u8, type_: &str) -> i32 {
118    let type_ = CString::new(type_).unwrap();
119    unsafe { nappgui_sys::dbind_cmp_imp(obj1, obj2, type_.as_ptr()) }
120}
121
122/// Checks if two objects of registered type are the same.
123pub fn dbind_equ_imp(obj1: *mut u8, obj2: *mut u8, type_: &str) -> bool {
124    let type_ = CString::new(type_).unwrap();
125    unsafe { nappgui_sys::dbind_equ_imp(obj1, obj2, type_.as_ptr()) != 0 }
126}
127
128/// Creates a registered type object from data read from a stream.
129pub fn dbind_read(stream: &Stream, type_: &str) -> *mut u8 {
130    let type_ = CString::new(type_).unwrap();
131    unsafe { nappgui_sys::dbind_read_imp(stream.inner, type_.as_ptr()) }
132}
133
134/// Writes the contents of a registered type object to a write stream.
135pub fn dbind_write_imp(stream: &Stream, obj: *const c_void, type_: &str) {
136    let type_ = CString::new(type_).unwrap();
137    unsafe { nappgui_sys::dbind_write_imp(stream.inner, obj, type_.as_ptr()) }
138}
139
140/// Sets the default value of a field.
141pub fn dbind_default_imp(type_: &str, mname: &str, value: *const u8) {
142    let type_ = CString::new(type_).unwrap();
143    let mname = CString::new(mname).unwrap();
144    unsafe { nappgui_sys::dbind_default_imp(type_.as_ptr(), mname.as_ptr(), value) }
145}
146
147/// Sets the maximum and minimum value in numeric fields.
148pub fn dbind_range_imp(type_: &str, mname: &str, min: *const u8, max: *const u8) {
149    let type_ = CString::new(type_).unwrap();
150    let mname = CString::new(mname).unwrap();
151    unsafe { nappgui_sys::dbind_range_imp(type_.as_ptr(), mname.as_ptr(), min, max) }
152}
153
154/// Sets the jump between two consecutive real values.
155pub fn dbind_precision_imp(type_: &str, mname: &str, precision: *const u8) {
156    let type_ = CString::new(type_).unwrap();
157    let mname = CString::new(mname).unwrap();
158    unsafe { nappgui_sys::dbind_precision_imp(type_.as_ptr(), mname.as_ptr(), precision) }
159}
160
161/// Sets the increment of a numeric value, for example, when clicking an UpDown control.
162pub fn dbind_increment_imp(type_: &str, mname: &str, increment: *const u8) {
163    let type_ = CString::new(type_).unwrap();
164    let mname = CString::new(mname).unwrap();
165    unsafe { nappgui_sys::dbind_increment_imp(type_.as_ptr(), mname.as_ptr(), increment) }
166}
167
168/// Sets a suffix that will be added to the numeric value when converting to text.
169pub fn dbind_suffix_imp(type_: &str, mname: &str, suffix: &str) {
170    let type_ = CString::new(type_).unwrap();
171    let mname = CString::new(mname).unwrap();
172    let suffix = CString::new(suffix).unwrap();
173    unsafe { nappgui_sys::dbind_suffix_imp(type_.as_ptr(), mname.as_ptr(), suffix.as_ptr()) }
174}
175
176/// Adds a field from a structure to its internal table within DBind.
177#[macro_export]
178macro_rules! dbind {
179    ($struct: ty, $field: ident, $field_type: ty, $bind_type: literal) => {
180        nappgui::core::dbind::dbind_imp(
181            stringify!($struct),
182            size_of::<$struct>() as _,
183            stringify!($field),
184            $bind_type,
185            offset_of!($struct, $field) as _,
186            size_of::<$field_type>() as _,
187        )
188    };
189}
190
191/// Registers a value of type enum.
192///
193/// # Remark
194/// dbind_enum(mode_t, ekIMAGE_ANALISYS, "Image Analisys") will use the string "Image Analisys" instead of "ekIMAGE_ANALISYS"
195/// for those I/O or interface operations that require displaying enumeration literals. For example, to populate the fields of
196/// a PopUp linked to a data field.
197#[macro_export]
198macro_rules! dbind_enum {
199    ($enum: ty, $value: ident, $alias: literal) => {
200        nappgui::core::dbind::dbind_enum_imp(
201            stringify!($enum),
202            stringify!($value),
203            <$enum>::$value as _,
204            $alias,
205        )
206    };
207}
208
209/// Sets the maximum and minimum value in numeric fields.
210#[macro_export]
211macro_rules! dbind_range {
212    ($struct: ty, $field: ident, $min: literal, $max: literal) => {
213        nappgui::core::dbind::dbind_range_imp(
214            stringify!($struct),
215            stringify!($field),
216            $min.to_ne_bytes().as_ptr(),
217            $max.to_ne_bytes().as_ptr(),
218        );
219    };
220}
221
222
223/// Sets the increment of a numeric value, for example, when clicking an UpDown control.
224#[macro_export]
225macro_rules! dbind_increment {
226    ($struct: ty, $field: ident, $increment: literal) => {
227        nappgui::core::dbind::dbind_increment_imp(
228            stringify!($struct),
229            stringify!($field),
230            $increment.to_ne_bytes().as_ptr(),
231        );
232    };
233}