rust_icu_uformattable/
lib.rs1use {
18 rust_icu_common as common, rust_icu_sys as sys,
19 rust_icu_sys::versioned_function,
20 rust_icu_ustring as ustring,
21 std::{convert::TryFrom, ffi, os::raw, ptr},
22};
23
24#[derive(Debug)]
36pub struct UFormattable<'a> {
37 rep: ptr::NonNull<sys::UFormattable>,
39 owner: Option<&'a Self>,
40}
41
42impl<'a> Drop for crate::UFormattable<'a> {
43 fn drop(&mut self) {
45 if let None = self.owner {
46 unsafe { versioned_function!(ufmt_close)(self.rep.as_ptr()) };
47 }
48 }
49}
50
51macro_rules! simple_getter {
62 ($method_name:ident, $impl_function_name:ident, $return_type:ty) => {
63 #[doc = concat!("Implements `", stringify!($impl_function_name), "`.")]
64 pub fn $method_name(&self) -> Result<$return_type, common::Error> {
67 let mut status = common::Error::OK_CODE;
68 let ret = unsafe {
69 assert!(common::Error::is_ok(status));
70 versioned_function!($impl_function_name)(self.rep.as_ptr(), &mut status)
71 };
72 common::Error::ok_or_warning(status)?;
73 Ok(ret)
74 }
75 };
76}
77
78impl<'a> crate::UFormattable<'a> {
79 pub fn try_new<'b>() -> Result<crate::UFormattable<'b>, common::Error> {
84 let mut status = common::Error::OK_CODE;
85 let rep = unsafe {
88 assert!(common::Error::is_ok(status));
89 versioned_function!(ufmt_open)(&mut status)
90 };
91 common::Error::ok_or_warning(status)?;
92 Ok(UFormattable {
93 rep: ptr::NonNull::new(rep).unwrap(),
94 owner: None,
95 })
96 }
97
98 #[doc(hidden)]
105 pub fn as_mut_ptr(&mut self) -> *mut sys::UFormattable {
106 self.rep.as_ptr()
107 }
108
109 pub fn as_ptr(&self) -> *const sys::UFormattable {
110 self.rep.as_ptr()
111 }
112
113 pub fn is_numeric(&self) -> bool {
117 let ubool = unsafe { versioned_function!(ufmt_isNumeric)(self.rep.as_ptr()) };
118 match ubool {
119 0i8 => false,
120 _ => true,
121 }
122 }
123
124 simple_getter!(get_type, ufmt_getType, sys::UFormattableType);
130
131 simple_getter!(get_date, ufmt_getDate, sys::UDate);
133
134 simple_getter!(get_double, ufmt_getDouble, f64);
136
137 simple_getter!(get_i32, ufmt_getLong, i32);
139
140 simple_getter!(get_i64, ufmt_getInt64, i64);
142
143 simple_getter!(get_array_length, ufmt_getArrayLength, i32);
145
146 pub fn get_ustring(&self) -> Result<ustring::UChar, common::Error> {
148 let mut status = common::Error::OK_CODE;
149 let mut ustrlen = 0i32;
150 let raw = unsafe {
151 assert!(common::Error::is_ok(status));
152 versioned_function!(ufmt_getUChars)(self.rep.as_ptr(), &mut ustrlen, &mut status)
153 } as *mut sys::UChar;
154 common::Error::ok_or_warning(status)?;
155 let ret = unsafe {
156 assert_ne!(raw, 0 as *mut sys::UChar);
157 assert!(ustrlen >= 0);
158 ustring::UChar::clone_from_raw_parts(raw, ustrlen)
159 };
160 Ok(ret)
161 }
162
163 pub fn get_str(&self) -> Result<String, common::Error> {
165 let ustr = self.get_ustring()?;
166 String::try_from(&ustr)
167 }
168
169 pub fn get_array_item_by_index(
175 &'a self,
176 index: i32,
177 ) -> Result<crate::UFormattable<'a>, common::Error> {
178 let mut status = common::Error::OK_CODE;
179 let raw: *mut sys::UFormattable = unsafe {
180 assert!(common::Error::is_ok(status));
181 versioned_function!(ufmt_getArrayItemByIndex)(self.rep.as_ptr(), index, &mut status)
182 };
183 common::Error::ok_or_warning(status)?;
184 assert_ne!(raw, 0 as *mut sys::UFormattable);
185 Ok(UFormattable {
186 rep: ptr::NonNull::new(raw).unwrap(),
187 owner: Some(&self),
188 })
189 }
190
191 pub fn get_dec_num_chars(&self) -> Result<String, common::Error> {
193 let mut status = common::Error::OK_CODE;
194 let mut cstrlen = 0i32;
195 let raw: *const raw::c_char = unsafe {
196 assert!(common::Error::is_ok(status));
197 versioned_function!(ufmt_getDecNumChars)(self.rep.as_ptr(), &mut cstrlen, &mut status)
198 };
199 common::Error::ok_or_warning(status)?;
200 let ret = unsafe {
201 assert_ne!(raw, 0 as *const raw::c_char);
202 assert!(cstrlen >= 0);
203 ffi::CStr::from_ptr(raw)
204 };
205 Ok(ret
206 .to_str()
207 .map_err(|e: std::str::Utf8Error| common::Error::from(e))?
208 .to_string())
209 }
210}
211
212#[cfg(test)]
213mod tests {
214 use crate::*;
215
216 #[test]
221 fn basic() {
222 let n = crate::UFormattable::try_new().expect("try_new");
223 assert_eq!(
224 sys::UFormattableType::UFMT_LONG,
225 n.get_type().expect("get_type")
226 );
227 assert_eq!(0, n.get_i32().expect("get_i32"));
228 assert_eq!("0", n.get_dec_num_chars().expect("get_dec_num_chars"));
229 }
230}