1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//! Types related to getting and setting a property on a DOM node.
use crate::dom::element::DomElement;
/// An error when attempting to retrieve a property from a DOM node.
#[derive(Debug)]
pub enum DomNodeGetPropertyStringError {
/// The key was too long.
KeyTooLong,
/// The key's bytes were not valid UTF-8.
KeyNotUtf8,
/// The property exists, but the value is not a string.
ValueNotString,
/// The out buffer was smaller than the length of the input element's value.
OutBufferBelowMinimumSize,
/// The out buffer was smaller than the length of the local storage item's value.
#[allow(missing_docs)]
OutBufferSmallerThanValue { value_len: usize },
#[allow(missing_docs)]
Other { error_code: i32 },
}
/// An error when attempting to retrieve a boolean property from a DOM node.
#[derive(Debug)]
pub enum DomNodeGetPropertyBoolError {
/// The key was too long.
KeyTooLong,
/// The key's bytes were not valid UTF-8.
KeyNotUtf8,
/// The property exists, but the value is not a boolean.
ValueNotBool,
#[allow(missing_docs)]
Other { error_code: i32 },
}
impl DomElement {
/// Get DOM node's property.
/// The property is expected to have a string value, otherwise an error is returned.
pub fn get_property_string<'out>(
&self,
key: &str,
out_buffer: &'out mut [u8],
) -> Result<&'out str, DomNodeGetPropertyStringError> {
let returned = unsafe {
afia_component_sys::dom_node_get_property_string(
self.component_imports_ptr(),
self.to_i64(),
key.as_ptr(),
key.len(),
out_buffer.as_mut_ptr(),
out_buffer.len(),
)
};
match returned {
length if length >= 0 => {
let length = length as usize;
// SAFETY: here we are trusting that the Afia host worked as expected and wrote a
// utf8 string to the buffer.
let string = unsafe { std::str::from_utf8_unchecked(&out_buffer[0..length]) };
Ok(string)
}
-1 => Err(DomNodeGetPropertyStringError::KeyTooLong),
-2 => Err(DomNodeGetPropertyStringError::KeyNotUtf8),
-3 => Err(DomNodeGetPropertyStringError::ValueNotString),
-4 => Err(DomNodeGetPropertyStringError::OutBufferBelowMinimumSize),
-5 => {
let mut val_len = [0; 4];
val_len.copy_from_slice(&out_buffer[0..4]);
let val = i32::from_le_bytes(val_len);
Err(DomNodeGetPropertyStringError::OutBufferSmallerThanValue {
value_len: val as usize,
})
}
unknown_error_code => Err(DomNodeGetPropertyStringError::Other {
error_code: unknown_error_code,
}),
}
}
/// Get DOM node's property.
/// The property is expected to have a bool value, otherwise an error is returned.
pub fn get_property_bool<'out>(&self, key: &str) -> Result<bool, DomNodeGetPropertyBoolError> {
let returned = unsafe {
afia_component_sys::dom_node_get_property_bool(
self.component_imports_ptr(),
self.to_i64(),
key.as_ptr(),
key.len(),
)
};
match returned {
0 => Ok(false),
1 => Ok(true),
-1 => Err(DomNodeGetPropertyBoolError::KeyTooLong),
-2 => Err(DomNodeGetPropertyBoolError::KeyNotUtf8),
-3 => Err(DomNodeGetPropertyBoolError::ValueNotBool),
unknown_error_code => Err(DomNodeGetPropertyBoolError::Other {
error_code: unknown_error_code,
}),
}
}
/// Set DOM node's property to a string value.
pub fn set_property_string(&self, key: &str, value: &str) {
unsafe {
afia_component_sys::dom_node_set_property_string(
self.component_imports_ptr(),
self.to_i64(),
key.as_ptr(),
key.len(),
value.as_ptr(),
value.len(),
)
}
}
/// Set DOM node's property to a boolean value.
pub fn set_property_bool(&self, key: &str, value: bool) {
let value: i32 = if value { 1 } else { 0 };
unsafe {
afia_component_sys::dom_node_set_property_bool(
self.component_imports_ptr(),
self.to_i64(),
key.as_ptr(),
key.len(),
value,
);
}
}
}