1use std::convert::TryInto;
4use std::ffi::{CStr, CString};
5use std::str::FromStr;
6use std::{fmt, mem, slice};
7use libc::{self, c_char, c_long};
8use time::{get_time, Timespec};
9
10use crate::c;
11
12
13pub(crate) unsafe fn string_from(ptr: *const c_char) -> String {
14 CStr::from_ptr(ptr).to_string_lossy().into_owned()
15}
16
17fn cstring_from<I: Into<Vec<u8>>>(v: I) -> CString {
18 match CString::new(v) {
19 Ok(s) => s,
20 Err(err) => {
21 let end = err.nul_position();
22 let v = err.into_vec();
23 CString::new(&v[..end]).unwrap()
24 }
25 }
26}
27
28fn check_bool(val: i64) -> Result<bool, ()> {
29 if val == 0 { Ok(false) }
30 else if val == 1 { Ok(true) }
31 else { Err(()) }
32}
33
34
35#[derive(Debug, PartialEq, Eq, Clone, Copy)]
41pub enum TangoDataType {
42 Void = 0,
43 Boolean,
44 Short,
45 Long,
46 Float,
47 Double,
48 UShort,
49 ULong,
50 String,
51 CharArray,
52 ShortArray,
53 LongArray,
54 FloatArray,
55 DoubleArray,
56 UShortArray,
57 ULongArray,
58 StringArray,
59 LongStringArray,
60 DoubleStringArray,
61 State,
62 ConstString,
63 BooleanArray,
64 UChar,
65 Long64,
66 ULong64,
67 Long64Array,
68 ULong64Array,
69 Int,
70 Encoded,
71}
72
73impl TangoDataType {
74 fn from_c(val: c::TangoDataType) -> TangoDataType {
75 match val {
76 c::TangoDataType_DEV_VOID => TangoDataType::Void,
77 c::TangoDataType_DEV_BOOLEAN => TangoDataType::Boolean,
78 c::TangoDataType_DEV_SHORT => TangoDataType::Short,
79 c::TangoDataType_DEV_LONG => TangoDataType::Long,
80 c::TangoDataType_DEV_FLOAT => TangoDataType::Float,
81 c::TangoDataType_DEV_DOUBLE => TangoDataType::Double,
82 c::TangoDataType_DEV_USHORT => TangoDataType::UShort,
83 c::TangoDataType_DEV_ULONG => TangoDataType::ULong,
84 c::TangoDataType_DEV_STRING => TangoDataType::String,
85 c::TangoDataType_DEVVAR_CHARARRAY => TangoDataType::CharArray,
86 c::TangoDataType_DEVVAR_SHORTARRAY => TangoDataType::ShortArray,
87 c::TangoDataType_DEVVAR_LONGARRAY => TangoDataType::LongArray,
88 c::TangoDataType_DEVVAR_FLOATARRAY => TangoDataType::FloatArray,
89 c::TangoDataType_DEVVAR_DOUBLEARRAY => TangoDataType::DoubleArray,
90 c::TangoDataType_DEVVAR_USHORTARRAY => TangoDataType::UShortArray,
91 c::TangoDataType_DEVVAR_ULONGARRAY => TangoDataType::ULongArray,
92 c::TangoDataType_DEVVAR_STRINGARRAY => TangoDataType::StringArray,
93 c::TangoDataType_DEVVAR_LONGSTRINGARRAY => TangoDataType::LongStringArray,
94 c::TangoDataType_DEVVAR_DOUBLESTRINGARRAY => TangoDataType::DoubleStringArray,
95 c::TangoDataType_DEV_STATE => TangoDataType::State,
96 c::TangoDataType_CONST_DEV_STRING => TangoDataType::ConstString,
97 c::TangoDataType_DEVVAR_BOOLEANARRAY => TangoDataType::BooleanArray,
98 c::TangoDataType_DEV_UCHAR => TangoDataType::UChar,
99 c::TangoDataType_DEV_LONG64 => TangoDataType::Long64,
100 c::TangoDataType_DEV_ULONG64 => TangoDataType::ULong64,
101 c::TangoDataType_DEVVAR_LONG64ARRAY => TangoDataType::Long64Array,
102 c::TangoDataType_DEVVAR_ULONG64ARRAY => TangoDataType::ULong64Array,
103 c::TangoDataType_DEV_INT => TangoDataType::Int,
104 c::TangoDataType_DEV_ENCODED => TangoDataType::Encoded,
105 _ => panic!("unknown Tango data type tag={:?}", val)
106 }
107 }
108}
109
110pub type DevEncoded = (String, Vec<u8>);
112
113
114#[derive(Debug, PartialEq, Eq, Clone, Copy)]
116pub enum TangoDevState {
117 On,
118 Off,
119 Close,
120 Open,
121 Insert,
122 Extract,
123 Moving,
124 Standby,
125 Fault,
126 Init,
127 Running,
128 Alarm,
129 Disable,
130 Unknown,
131}
132
133impl TangoDevState {
134 fn from_c(val: c::TangoDevState) -> TangoDevState {
135 match val {
136 c::TangoDevState_ON => TangoDevState::On,
137 c::TangoDevState_OFF => TangoDevState::Off,
138 c::TangoDevState_CLOSE => TangoDevState::Close,
139 c::TangoDevState_OPEN => TangoDevState::Open,
140 c::TangoDevState_INSERT => TangoDevState::Insert,
141 c::TangoDevState_EXTRACT => TangoDevState::Extract,
142 c::TangoDevState_MOVING => TangoDevState::Moving,
143 c::TangoDevState_STANDBY => TangoDevState::Standby,
144 c::TangoDevState_FAULT => TangoDevState::Fault,
145 c::TangoDevState_INIT => TangoDevState::Init,
146 c::TangoDevState_RUNNING => TangoDevState::Running,
147 c::TangoDevState_ALARM => TangoDevState::Alarm,
148 c::TangoDevState_DISABLE => TangoDevState::Disable,
149 c::TangoDevState_UNKNOWN => TangoDevState::Unknown,
150 _ => unreachable!("no TangoDevState for {}", val)
151 }
152 }
153}
154
155impl fmt::Display for TangoDevState {
156 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
157 f.pad(match self {
158 TangoDevState::On => "ON",
159 TangoDevState::Off => "OFF",
160 TangoDevState::Close => "CLOSE",
161 TangoDevState::Open => "OPEN",
162 TangoDevState::Insert => "INSERT",
163 TangoDevState::Extract => "EXTRACT",
164 TangoDevState::Moving => "MOVING",
165 TangoDevState::Standby => "STANDBY",
166 TangoDevState::Fault => "FAULT",
167 TangoDevState::Init => "INIT",
168 TangoDevState::Running => "RUNNING",
169 TangoDevState::Alarm => "ALARM",
170 TangoDevState::Disable => "DISABLE",
171 TangoDevState::Unknown => "UNKNOWN",
172 })
173 }
174}
175
176impl FromStr for TangoDevState {
177 type Err = ();
178
179 fn from_str(s: &str) -> Result<Self, Self::Err> {
180 match s {
181 "ON" => Ok(TangoDevState::On),
182 "OFF" => Ok(TangoDevState::Off),
183 "CLOSE" => Ok(TangoDevState::Close),
184 "OPEN" => Ok(TangoDevState::Open),
185 "INSERT" => Ok(TangoDevState::Insert),
186 "EXTRACT" => Ok(TangoDevState::Extract),
187 "MOVING" => Ok(TangoDevState::Moving),
188 "STANDBY" => Ok(TangoDevState::Standby),
189 "FAULT" => Ok(TangoDevState::Fault),
190 "INIT" => Ok(TangoDevState::Init),
191 "RUNNING" => Ok(TangoDevState::Running),
192 "ALARM" => Ok(TangoDevState::Alarm),
193 "DISABLE" => Ok(TangoDevState::Disable),
194 "UNKNOWN" => Ok(TangoDevState::Unknown),
195 _ => Err(()),
196 }
197 }
198}
199
200
201#[derive(Debug, PartialEq, Eq, Clone, Copy)]
203pub enum AttrQuality {
204 Valid,
205 Invalid,
206 Alarm,
207 Changing,
208 Warning,
209}
210
211impl AttrQuality {
212 fn from_c(val: c::AttrQuality) -> AttrQuality {
213 match val {
214 c::AttrQuality_ATTR_VALID => AttrQuality::Valid,
215 c::AttrQuality_ATTR_INVALID => AttrQuality::Invalid,
216 c::AttrQuality_ATTR_ALARM => AttrQuality::Alarm,
217 c::AttrQuality_ATTR_CHANGING => AttrQuality::Changing,
218 c::AttrQuality_ATTR_WARNING => AttrQuality::Warning,
219 _ => unreachable!("no TangoAttrQuality for {}", val)
220 }
221 }
222}
223
224
225#[derive(Debug, PartialEq, Eq, Clone, Copy)]
227pub enum AttrWriteType {
228 Read,
229 ReadWithWrite,
230 Write,
231 ReadWrite,
232}
233
234impl AttrWriteType {
235 fn from_c(val: c::AttrWriteType) -> AttrWriteType {
236 match val {
237 c::AttrWriteType_READ => AttrWriteType::Read,
238 c::AttrWriteType_READ_WITH_WRITE => AttrWriteType::ReadWithWrite,
239 c::AttrWriteType_WRITE => AttrWriteType::Write,
240 c::AttrWriteType_READ_WRITE => AttrWriteType::ReadWrite,
241 _ => unreachable!("no TangoAttrWriteType for {}", val)
242 }
243 }
244}
245
246
247#[derive(Debug, PartialEq, Eq, Clone, Copy)]
249pub enum AttrDataFormat {
250 Scalar,
251 Spectrum,
252 Image,
253}
254
255impl AttrDataFormat {
256 fn from_c(val: c::AttrDataFormat) -> AttrDataFormat {
257 match val {
258 c::AttrDataFormat_SCALAR => AttrDataFormat::Scalar,
259 c::AttrDataFormat_SPECTRUM => AttrDataFormat::Spectrum,
260 c::AttrDataFormat_IMAGE => AttrDataFormat::Image,
261 _ => unreachable!("no TangoAttrDataFormat for {}", val)
262 }
263 }
264}
265
266
267#[derive(Debug, PartialEq, Eq, Clone, Copy)]
269pub enum DispLevel {
270 Operator,
271 Expert,
272}
273
274impl DispLevel {
275 fn from_c(val: c::DispLevel) -> DispLevel {
276 match val {
277 c::DispLevel_OPERATOR => DispLevel::Operator,
278 c::DispLevel_EXPERT => DispLevel::Expert,
279 _ => unreachable!("no TangoDispLevel for {}", val)
280 }
281 }
282}
283
284
285#[derive(Debug, PartialEq, Eq, Clone, Copy)]
287pub enum ErrSeverity {
288 Warn,
289 Err,
290 Panic,
291}
292
293impl ErrSeverity {
294 pub(crate) fn from_c(val: c::ErrSeverity) -> ErrSeverity {
295 match val {
296 c::ErrSeverity_WARN => ErrSeverity::Warn,
297 c::ErrSeverity_ERR => ErrSeverity::Err,
298 c::ErrSeverity_PANIC => ErrSeverity::Panic,
299 _ => unreachable!("no TangoErrSeverity for {}", val)
300 }
301 }
302}
303
304
305#[derive(Debug, PartialEq, Eq, Clone, Copy)]
307pub enum DevSource {
308 Dev,
309 Cache,
310 CacheDev,
311}
312
313impl DevSource {
314 pub(crate) fn from_c(val: c::DevSource) -> DevSource {
315 match val {
316 c::DevSource_DEV => DevSource::Dev,
317 c::DevSource_CACHE => DevSource::Cache,
318 c::DevSource_CACHE_DEV => DevSource::CacheDev,
319 _ => unreachable!("no TangoDevSource for {}", val)
320 }
321 }
322}
323
324
325#[derive(Debug)]
327pub struct CommandInfo {
328 pub name: String,
329 pub in_type: TangoDataType,
330 pub out_type: TangoDataType,
331 pub in_type_desc: String,
332 pub out_type_desc: String,
333 pub disp_level: DispLevel,
334}
335
336impl CommandInfo {
337 pub(crate) unsafe fn from_c(mut info: c::CommandInfo, free: bool) -> CommandInfo {
338 let res = CommandInfo {
339 name: string_from(info.cmd_name),
340 in_type: TangoDataType::from_c(info.in_type as u32),
341 out_type: TangoDataType::from_c(info.out_type as u32),
342 in_type_desc: string_from(info.in_type_desc),
343 out_type_desc: string_from(info.out_type_desc),
344 disp_level: DispLevel::from_c(info.disp_level),
345 };
346 if free {
347 c::tango_free_CommandInfo(&mut info);
348 }
349 res
350 }
351}
352
353
354#[derive(Debug, PartialEq, Clone)]
358pub enum CommandData {
359 Void,
360
361 Boolean(bool),
362 Short(i16),
363 UShort(u16),
364 Long(i32),
365 ULong(u32),
366 Long64(i64),
367 ULong64(u64),
368
369 Float(f32),
370 Double(f64),
371
372 String(Vec<u8>),
373 State(TangoDevState),
374 Encoded(DevEncoded),
375
376 BooleanArray(Vec<bool>),
377 CharArray(Vec<u8>),
378 ShortArray(Vec<i16>),
379 UShortArray(Vec<u16>),
380 LongArray(Vec<i32>),
381 ULongArray(Vec<u32>),
382 Long64Array(Vec<i64>),
383 ULong64Array(Vec<u64>),
384
385 FloatArray(Vec<f32>),
386 DoubleArray(Vec<f64>),
387
388 StringArray(Vec<Vec<u8>>),
389 LongStringArray(Vec<i32>, Vec<Vec<u8>>),
390 DoubleStringArray(Vec<f64>, Vec<Vec<u8>>),
391}
392
393impl CommandData {
394 pub fn from_str(s: &str) -> Self {
396 Self::String(s.to_owned().into_bytes())
397 }
398
399 pub fn convert(self, to: TangoDataType) -> Result<Self, Self> {
404 match self {
405 Self::Void => match to {
406 TangoDataType::Void => Ok(self),
407 _ => Err(self),
408 }
409 Self::Boolean(v) => match to {
410 TangoDataType::Boolean => Ok(self),
411 TangoDataType::Short => Ok(Self::Short(v as _)),
412 TangoDataType::UShort => Ok(Self::UShort(v as _)),
413 TangoDataType::Int |
414 TangoDataType::Long => Ok(Self::Long(v as _)),
415 TangoDataType::ULong => Ok(Self::ULong(v as _)),
416 TangoDataType::Long64 => Ok(Self::Long64(v as _)),
417 TangoDataType::ULong64 => Ok(Self::ULong64(v as _)),
418 TangoDataType::Float => Ok(Self::Float(v as i32 as _)),
419 TangoDataType::Double => Ok(Self::Double(v as i32 as _)),
420 _ => Err(self)
421 }
422 Self::Short(v) => match to {
423 TangoDataType::Boolean => check_bool(v as i64).map(Self::Boolean).map_err(|_| self),
424 TangoDataType::Short => Ok(self),
425 TangoDataType::UShort => v.try_into().map(Self::UShort).map_err(|_| self),
426 TangoDataType::Int |
427 TangoDataType::Long => Ok(Self::Long(v as _)),
428 TangoDataType::ULong => Ok(Self::ULong(v as _)),
429 TangoDataType::Long64 => Ok(Self::Long64(v as _)),
430 TangoDataType::ULong64 => Ok(Self::ULong64(v as _)),
431 TangoDataType::Float => Ok(Self::Float(v as _)),
432 TangoDataType::Double => Ok(Self::Double(v as _)),
433 _ => Err(self)
434 }
435 Self::UShort(v) => match to {
436 TangoDataType::Boolean => check_bool(v as i64).map(Self::Boolean).map_err(|_| self),
437 TangoDataType::Short => v.try_into().map(Self::Short).map_err(|_| self),
438 TangoDataType::UShort => Ok(self),
439 TangoDataType::Int |
440 TangoDataType::Long => Ok(Self::Long(v as _)),
441 TangoDataType::ULong => Ok(Self::ULong(v as _)),
442 TangoDataType::Long64 => Ok(Self::Long64(v as _)),
443 TangoDataType::ULong64 => Ok(Self::ULong64(v as _)),
444 TangoDataType::Float => Ok(Self::Float(v as _)),
445 TangoDataType::Double => Ok(Self::Double(v as _)),
446 _ => Err(self)
447 }
448 Self::Long(v) => match to {
449 TangoDataType::Boolean => check_bool(v as i64).map(Self::Boolean).map_err(|_| self),
450 TangoDataType::Short => v.try_into().map(Self::Short).map_err(|_| self),
451 TangoDataType::UShort => v.try_into().map(Self::UShort).map_err(|_| self),
452 TangoDataType::Int |
453 TangoDataType::Long => Ok(self),
454 TangoDataType::ULong => v.try_into().map(Self::ULong).map_err(|_| self),
455 TangoDataType::Long64 => Ok(Self::Long64(v as _)),
456 TangoDataType::ULong64 => Ok(Self::ULong64(v as _)),
457 TangoDataType::Float => Ok(Self::Float(v as _)),
458 TangoDataType::Double => Ok(Self::Double(v as _)),
459 _ => Err(self)
460 }
461 Self::ULong(v) => match to {
462 TangoDataType::Boolean => check_bool(v as i64).map(Self::Boolean).map_err(|_| self),
463 TangoDataType::Short => v.try_into().map(Self::Short).map_err(|_| self),
464 TangoDataType::UShort => v.try_into().map(Self::UShort).map_err(|_| self),
465 TangoDataType::Int |
466 TangoDataType::Long => v.try_into().map(Self::Long).map_err(|_| self),
467 TangoDataType::ULong => Ok(self),
468 TangoDataType::Long64 => Ok(Self::Long64(v as _)),
469 TangoDataType::ULong64 => Ok(Self::ULong64(v as _)),
470 TangoDataType::Float => Ok(Self::Float(v as _)),
471 TangoDataType::Double => Ok(Self::Double(v as _)),
472 _ => Err(self)
473 }
474 Self::Long64(v) => match to {
475 TangoDataType::Boolean => check_bool(v as i64).map(Self::Boolean).map_err(|_| self),
476 TangoDataType::Short => v.try_into().map(Self::Short).map_err(|_| self),
477 TangoDataType::UShort => v.try_into().map(Self::UShort).map_err(|_| self),
478 TangoDataType::Int |
479 TangoDataType::Long => v.try_into().map(Self::Long).map_err(|_| self),
480 TangoDataType::ULong => v.try_into().map(Self::ULong).map_err(|_| self),
481 TangoDataType::Long64 => Ok(self),
482 TangoDataType::ULong64 => v.try_into().map(Self::ULong64).map_err(|_| self),
483 TangoDataType::Float => Ok(Self::Float(v as _)),
484 TangoDataType::Double => Ok(Self::Double(v as _)),
485 _ => Err(self)
486 }
487 Self::ULong64(v) => match to {
488 TangoDataType::Boolean => check_bool(v as i64).map(Self::Boolean).map_err(|_| self),
489 TangoDataType::Short => v.try_into().map(Self::Short).map_err(|_| self),
490 TangoDataType::UShort => v.try_into().map(Self::UShort).map_err(|_| self),
491 TangoDataType::Int |
492 TangoDataType::Long => v.try_into().map(Self::Long).map_err(|_| self),
493 TangoDataType::ULong => v.try_into().map(Self::ULong).map_err(|_| self),
494 TangoDataType::Long64 => v.try_into().map(Self::Long64).map_err(|_| self),
495 TangoDataType::ULong64 => Ok(self),
496 TangoDataType::Float => Ok(Self::Float(v as _)),
497 TangoDataType::Double => Ok(Self::Double(v as _)),
498 _ => Err(self)
499 }
500 Self::Float(v) => match to {
501 TangoDataType::Float => Ok(self),
502 TangoDataType::Double => Ok(Self::Double(v as _)),
503 _ => Err(self)
504 }
505 Self::Double(v) => match to {
506 TangoDataType::Float => Ok(Self::Float(v as _)),
507 TangoDataType::Double => Ok(self),
508 _ => Err(self)
509 }
510 Self::String(ref v) => match to {
511 TangoDataType::ConstString |
512 TangoDataType::String => Ok(self),
513 TangoDataType::State => std::str::from_utf8(v).map_err(drop)
514 .and_then(|s| s.parse())
515 .map(Self::State)
516 .map_err(|_| self),
517 _ => Err(self)
518 }
519 Self::State(_) => match to {
520 TangoDataType::State => Ok(self),
521 _ => Err(self),
522 }
523 Self::Encoded(_) => match to {
524 TangoDataType::Encoded => Ok(self),
525 _ => Err(self),
526 }
527 Self::BooleanArray(v) => match to {
528 TangoDataType::BooleanArray => Ok(Self::BooleanArray(v)),
529 TangoDataType::CharArray => Ok(Self::CharArray(v.into_iter().map(|v| v as _).collect())),
530 TangoDataType::ShortArray => Ok(Self::ShortArray(v.into_iter().map(|v| v as _).collect())),
531 TangoDataType::UShortArray => Ok(Self::UShortArray(v.into_iter().map(|v| v as _).collect())),
532 TangoDataType::LongArray => Ok(Self::LongArray(v.into_iter().map(|v| v as _).collect())),
533 TangoDataType::ULongArray => Ok(Self::ULongArray(v.into_iter().map(|v| v as _).collect())),
534 TangoDataType::Long64Array => Ok(Self::Long64Array(v.into_iter().map(|v| v as _).collect())),
535 TangoDataType::ULong64Array => Ok(Self::ULong64Array(v.into_iter().map(|v| v as _).collect())),
536 TangoDataType::FloatArray => Ok(Self::FloatArray(v.into_iter().map(|v| v as i32 as _).collect())),
537 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v.into_iter().map(|v| v as i32 as _).collect())),
538 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
539 _ => Err(Self::BooleanArray(v)),
540 }
541 Self::CharArray(v) => match to {
542 TangoDataType::BooleanArray if v.len() == 0 => Ok(Self::BooleanArray(vec![])),
543 TangoDataType::CharArray => Ok(Self::CharArray(v)),
544 TangoDataType::ShortArray => Ok(Self::ShortArray(v.into_iter().map(|v| v as _).collect())),
545 TangoDataType::UShortArray => Ok(Self::UShortArray(v.into_iter().map(|v| v as _).collect())),
546 TangoDataType::LongArray => Ok(Self::LongArray(v.into_iter().map(|v| v as _).collect())),
547 TangoDataType::ULongArray => Ok(Self::ULongArray(v.into_iter().map(|v| v as _).collect())),
548 TangoDataType::Long64Array => Ok(Self::Long64Array(v.into_iter().map(|v| v as _).collect())),
549 TangoDataType::ULong64Array => Ok(Self::ULong64Array(v.into_iter().map(|v| v as _).collect())),
550 TangoDataType::FloatArray => Ok(Self::FloatArray(v.into_iter().map(|v| v as _).collect())),
551 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v.into_iter().map(|v| v as _).collect())),
552 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
553 _ => Err(Self::CharArray(v)),
554 }
555 Self::ShortArray(v) => match to {
556 TangoDataType::BooleanArray if v.len() == 0 => Ok(Self::BooleanArray(vec![])),
557 TangoDataType::CharArray => v.iter().map(|&v| v.try_into())
558 .collect::<Result<Vec<_>, _>>()
559 .map(Self::CharArray)
560 .map_err(|_| Self::ShortArray(v)),
561 TangoDataType::ShortArray => Ok(Self::ShortArray(v)),
562 TangoDataType::UShortArray => v.iter().map(|&v| v.try_into())
563 .collect::<Result<Vec<_>, _>>()
564 .map(Self::UShortArray)
565 .map_err(|_| Self::ShortArray(v)),
566 TangoDataType::LongArray => Ok(Self::LongArray(v.into_iter().map(|v| v as _).collect())),
567 TangoDataType::ULongArray => Ok(Self::ULongArray(v.into_iter().map(|v| v as _).collect())),
568 TangoDataType::Long64Array => Ok(Self::Long64Array(v.into_iter().map(|v| v as _).collect())),
569 TangoDataType::ULong64Array => Ok(Self::ULong64Array(v.into_iter().map(|v| v as _).collect())),
570 TangoDataType::FloatArray => Ok(Self::FloatArray(v.into_iter().map(|v| v as _).collect())),
571 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v.into_iter().map(|v| v as _).collect())),
572 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
573 _ => Err(Self::ShortArray(v)),
574 }
575 Self::UShortArray(v) => match to {
576 TangoDataType::BooleanArray if v.len() == 0 => Ok(Self::BooleanArray(vec![])),
577 TangoDataType::CharArray => v.iter().map(|&v| v.try_into())
578 .collect::<Result<Vec<_>, _>>()
579 .map(Self::CharArray)
580 .map_err(|_| Self::UShortArray(v)),
581 TangoDataType::ShortArray => v.iter().map(|&v| v.try_into())
582 .collect::<Result<Vec<_>, _>>()
583 .map(Self::ShortArray)
584 .map_err(|_| Self::UShortArray(v)),
585 TangoDataType::UShortArray => Ok(Self::UShortArray(v)),
586 TangoDataType::LongArray => Ok(Self::LongArray(v.into_iter().map(|v| v as _).collect())),
587 TangoDataType::ULongArray => Ok(Self::ULongArray(v.into_iter().map(|v| v as _).collect())),
588 TangoDataType::Long64Array => Ok(Self::Long64Array(v.into_iter().map(|v| v as _).collect())),
589 TangoDataType::ULong64Array => Ok(Self::ULong64Array(v.into_iter().map(|v| v as _).collect())),
590 TangoDataType::FloatArray => Ok(Self::FloatArray(v.into_iter().map(|v| v as _).collect())),
591 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v.into_iter().map(|v| v as _).collect())),
592 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
593 _ => Err(Self::UShortArray(v)),
594 }
595 Self::LongArray(v) => match to {
596 TangoDataType::BooleanArray if v.len() == 0 => Ok(Self::BooleanArray(vec![])),
597 TangoDataType::CharArray => v.iter().map(|&v| v.try_into())
598 .collect::<Result<Vec<_>, _>>()
599 .map(Self::CharArray)
600 .map_err(|_| Self::LongArray(v)),
601 TangoDataType::ShortArray => v.iter().map(|&v| v.try_into())
602 .collect::<Result<Vec<_>, _>>()
603 .map(Self::ShortArray)
604 .map_err(|_| Self::LongArray(v)),
605 TangoDataType::UShortArray => v.iter().map(|&v| v.try_into())
606 .collect::<Result<Vec<_>, _>>()
607 .map(Self::UShortArray)
608 .map_err(|_| Self::LongArray(v)),
609 TangoDataType::LongArray => Ok(Self::LongArray(v)),
610 TangoDataType::ULongArray => v.iter().map(|&v| v.try_into())
611 .collect::<Result<Vec<_>, _>>()
612 .map(Self::ULongArray)
613 .map_err(|_| Self::LongArray(v)),
614 TangoDataType::Long64Array => Ok(Self::Long64Array(v.into_iter().map(|v| v as _).collect())),
615 TangoDataType::ULong64Array => Ok(Self::ULong64Array(v.into_iter().map(|v| v as _).collect())),
616 TangoDataType::FloatArray => Ok(Self::FloatArray(v.into_iter().map(|v| v as _).collect())),
617 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v.into_iter().map(|v| v as _).collect())),
618 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
619 _ => Err(Self::LongArray(v)),
620 }
621 Self::ULongArray(v) => match to {
622 TangoDataType::BooleanArray if v.len() == 0 => Ok(Self::BooleanArray(vec![])),
623 TangoDataType::CharArray => v.iter().map(|&v| v.try_into())
624 .collect::<Result<Vec<_>, _>>()
625 .map(Self::CharArray)
626 .map_err(|_| Self::ULongArray(v)),
627 TangoDataType::ShortArray => v.iter().map(|&v| v.try_into())
628 .collect::<Result<Vec<_>, _>>()
629 .map(Self::ShortArray)
630 .map_err(|_| Self::ULongArray(v)),
631 TangoDataType::UShortArray => v.iter().map(|&v| v.try_into())
632 .collect::<Result<Vec<_>, _>>()
633 .map(Self::UShortArray)
634 .map_err(|_| Self::ULongArray(v)),
635 TangoDataType::LongArray => v.iter().map(|&v| v.try_into())
636 .collect::<Result<Vec<_>, _>>()
637 .map(Self::LongArray)
638 .map_err(|_| Self::ULongArray(v)),
639 TangoDataType::ULongArray => Ok(Self::ULongArray(v)),
640 TangoDataType::Long64Array => Ok(Self::Long64Array(v.into_iter().map(|v| v as _).collect())),
641 TangoDataType::ULong64Array => Ok(Self::ULong64Array(v.into_iter().map(|v| v as _).collect())),
642 TangoDataType::FloatArray => Ok(Self::FloatArray(v.into_iter().map(|v| v as _).collect())),
643 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v.into_iter().map(|v| v as _).collect())),
644 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
645 _ => Err(Self::ULongArray(v)),
646 }
647 Self::Long64Array(v) => match to {
648 TangoDataType::BooleanArray if v.len() == 0 => Ok(Self::BooleanArray(vec![])),
649 TangoDataType::CharArray => v.iter().map(|&v| v.try_into())
650 .collect::<Result<Vec<_>, _>>()
651 .map(Self::CharArray)
652 .map_err(|_| Self::Long64Array(v)),
653 TangoDataType::ShortArray => v.iter().map(|&v| v.try_into())
654 .collect::<Result<Vec<_>, _>>()
655 .map(Self::ShortArray)
656 .map_err(|_| Self::Long64Array(v)),
657 TangoDataType::UShortArray => v.iter().map(|&v| v.try_into())
658 .collect::<Result<Vec<_>, _>>()
659 .map(Self::UShortArray)
660 .map_err(|_| Self::Long64Array(v)),
661 TangoDataType::LongArray => v.iter().map(|&v| v.try_into())
662 .collect::<Result<Vec<_>, _>>()
663 .map(Self::LongArray)
664 .map_err(|_| Self::Long64Array(v)),
665 TangoDataType::ULongArray => v.iter().map(|&v| v.try_into())
666 .collect::<Result<Vec<_>, _>>()
667 .map(Self::ULongArray)
668 .map_err(|_| Self::Long64Array(v)),
669 TangoDataType::Long64Array => Ok(Self::Long64Array(v)),
670 TangoDataType::ULong64Array => v.iter().map(|&v| v.try_into())
671 .collect::<Result<Vec<_>, _>>()
672 .map(Self::ULong64Array)
673 .map_err(|_| Self::Long64Array(v)),
674 TangoDataType::FloatArray => Ok(Self::FloatArray(v.into_iter().map(|v| v as _).collect())),
675 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v.into_iter().map(|v| v as _).collect())),
676 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
677 _ => Err(Self::Long64Array(v)),
678 }
679 Self::ULong64Array(v) => match to {
680 TangoDataType::BooleanArray if v.len() == 0 => Ok(Self::BooleanArray(vec![])),
681 TangoDataType::CharArray => v.iter().map(|&v| v.try_into())
682 .collect::<Result<Vec<_>, _>>()
683 .map(Self::CharArray)
684 .map_err(|_| Self::ULong64Array(v)),
685 TangoDataType::ShortArray => v.iter().map(|&v| v.try_into())
686 .collect::<Result<Vec<_>, _>>()
687 .map(Self::ShortArray)
688 .map_err(|_| Self::ULong64Array(v)),
689 TangoDataType::UShortArray => v.iter().map(|&v| v.try_into())
690 .collect::<Result<Vec<_>, _>>()
691 .map(Self::UShortArray)
692 .map_err(|_| Self::ULong64Array(v)),
693 TangoDataType::LongArray => v.iter().map(|&v| v.try_into())
694 .collect::<Result<Vec<_>, _>>()
695 .map(Self::LongArray)
696 .map_err(|_| Self::ULong64Array(v)),
697 TangoDataType::ULongArray => v.iter().map(|&v| v.try_into())
698 .collect::<Result<Vec<_>, _>>()
699 .map(Self::ULongArray)
700 .map_err(|_| Self::ULong64Array(v)),
701 TangoDataType::Long64Array => v.iter().map(|&v| v.try_into())
702 .collect::<Result<Vec<_>, _>>()
703 .map(Self::Long64Array)
704 .map_err(|_| Self::ULong64Array(v)),
705 TangoDataType::ULong64Array => Ok(Self::ULong64Array(v)),
706 TangoDataType::FloatArray => Ok(Self::FloatArray(v.into_iter().map(|v| v as _).collect())),
707 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v.into_iter().map(|v| v as _).collect())),
708 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
709 _ => Err(Self::ULong64Array(v)),
710 }
711 Self::FloatArray(v) => match to {
712 TangoDataType::BooleanArray if v.len() == 0 => Ok(Self::BooleanArray(vec![])),
713 TangoDataType::CharArray if v.len() == 0 => Ok(Self::CharArray(vec![])),
714 TangoDataType::ShortArray if v.len() == 0 => Ok(Self::ShortArray(vec![])),
715 TangoDataType::UShortArray if v.len() == 0 => Ok(Self::UShortArray(vec![])),
716 TangoDataType::LongArray if v.len() == 0 => Ok(Self::LongArray(vec![])),
717 TangoDataType::ULongArray if v.len() == 0 => Ok(Self::ULongArray(vec![])),
718 TangoDataType::Long64Array if v.len() == 0 => Ok(Self::Long64Array(vec![])),
719 TangoDataType::ULong64Array if v.len() == 0 => Ok(Self::ULong64Array(vec![])),
720 TangoDataType::FloatArray => Ok(Self::FloatArray(v)),
721 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v.into_iter().map(|v| v as _).collect())),
722 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
723 _ => Err(Self::FloatArray(v)),
724 }
725 Self::DoubleArray(v) => match to {
726 TangoDataType::BooleanArray if v.len() == 0 => Ok(Self::BooleanArray(vec![])),
727 TangoDataType::CharArray if v.len() == 0 => Ok(Self::CharArray(vec![])),
728 TangoDataType::ShortArray if v.len() == 0 => Ok(Self::ShortArray(vec![])),
729 TangoDataType::UShortArray if v.len() == 0 => Ok(Self::UShortArray(vec![])),
730 TangoDataType::LongArray if v.len() == 0 => Ok(Self::LongArray(vec![])),
731 TangoDataType::ULongArray if v.len() == 0 => Ok(Self::ULongArray(vec![])),
732 TangoDataType::Long64Array if v.len() == 0 => Ok(Self::Long64Array(vec![])),
733 TangoDataType::ULong64Array if v.len() == 0 => Ok(Self::ULong64Array(vec![])),
734 TangoDataType::FloatArray => Ok(Self::FloatArray(v.into_iter().map(|v| v as _).collect())),
735 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v)),
736 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
737 _ => Err(Self::DoubleArray(v)),
738 }
739 Self::StringArray(v) => match to {
740 TangoDataType::BooleanArray if v.len() == 0 => Ok(Self::BooleanArray(vec![])),
741 TangoDataType::CharArray if v.len() == 0 => Ok(Self::CharArray(vec![])),
742 TangoDataType::ShortArray if v.len() == 0 => Ok(Self::ShortArray(vec![])),
743 TangoDataType::UShortArray if v.len() == 0 => Ok(Self::UShortArray(vec![])),
744 TangoDataType::LongArray if v.len() == 0 => Ok(Self::LongArray(vec![])),
745 TangoDataType::ULongArray if v.len() == 0 => Ok(Self::ULongArray(vec![])),
746 TangoDataType::Long64Array if v.len() == 0 => Ok(Self::Long64Array(vec![])),
747 TangoDataType::ULong64Array if v.len() == 0 => Ok(Self::ULong64Array(vec![])),
748 TangoDataType::FloatArray if v.len() == 0 => Ok(Self::FloatArray(vec![])),
749 TangoDataType::DoubleArray if v.len() == 0 => Ok(Self::DoubleArray(vec![])),
750 TangoDataType::StringArray => Ok(Self::StringArray(v)),
751 _ => Err(Self::StringArray(v)),
752 }
753 Self::LongStringArray(v, w) => match to {
754 TangoDataType::LongStringArray => Ok(Self::LongStringArray(v, w)),
755 _ => Err(Self::LongStringArray(v, w))
756 }
757 Self::DoubleStringArray(v, w) => match to {
758 TangoDataType::DoubleStringArray => Ok(Self::DoubleStringArray(v, w)),
759 _ => Err(Self::DoubleStringArray(v, w))
760 }
761 }
762 }
763
764 pub fn into_bool(self) -> Result<bool, Self> {
767 match self {
768 Self::Boolean(v) => Ok(v),
769 Self::Short(v) => check_bool(v as i64).map_err(|_| self),
770 Self::UShort(v) => check_bool(v as i64).map_err(|_| self),
771 Self::Long(v) => check_bool(v as i64).map_err(|_| self),
772 Self::ULong(v) => check_bool(v as i64).map_err(|_| self),
773 Self::Long64(v) => check_bool(v as i64).map_err(|_| self),
774 Self::ULong64(v) => check_bool(v as i64).map_err(|_| self),
775 _ => Err(self),
776 }
777 }
778
779 pub fn into_i32(self) -> Result<i32, Self> {
782 match self {
783 Self::Boolean(v) => Ok(v as i32),
784 Self::Short(v) => Ok(v as i32),
785 Self::UShort(v) => Ok(v as i32),
786 Self::Long(v) => Ok(v),
787 Self::ULong(v) => v.try_into().map_err(|_| self),
788 Self::Long64(v) => v.try_into().map_err(|_| self),
789 Self::ULong64(v) => v.try_into().map_err(|_| self),
790 _ => Err(self),
791 }
792 }
793
794 pub fn into_i64(self) -> Result<i64, Self> {
797 match self {
798 Self::Boolean(v) => Ok(v as i64),
799 Self::Short(v) => Ok(v as i64),
800 Self::UShort(v) => Ok(v as i64),
801 Self::Long(v) => Ok(v as i64),
802 Self::ULong(v) => Ok(v as i64),
803 Self::Long64(v) => Ok(v),
804 Self::ULong64(v) => v.try_into().map_err(|_| self),
805 _ => Err(self),
806 }
807 }
808
809 pub fn into_u32(self) -> Result<u32, Self> {
812 match self {
813 Self::Boolean(v) => Ok(v as u32),
814 Self::Short(v) => Ok(v as u32),
815 Self::UShort(v) => Ok(v as u32),
816 Self::Long(v) => v.try_into().map_err(|_| self),
817 Self::ULong(v) => Ok(v),
818 Self::Long64(v) => v.try_into().map_err(|_| self),
819 Self::ULong64(v) => v.try_into().map_err(|_| self),
820 _ => Err(self),
821 }
822 }
823
824 pub fn into_u64(self) -> Result<u64, Self> {
827 match self {
828 Self::Boolean(v) => Ok(v as u64),
829 Self::Short(v) => Ok(v as u64),
830 Self::Long(v) => Ok(v as u64),
831 Self::UShort(v) => Ok(v as u64),
832 Self::ULong(v) => Ok(v as u64),
833 Self::Long64(v) => v.try_into().map_err(|_| self),
834 Self::ULong64(v) => Ok(v),
835 _ => Err(self),
836 }
837 }
838
839 pub fn into_f32(self) -> Result<f32, Self> {
841 match self {
842 Self::Boolean(v) => Ok(v as i32 as f32),
843 Self::Short(v) => Ok(v as f32),
844 Self::Long(v) => Ok(v as f32),
845 Self::Long64(v) => Ok(v as f32),
846 Self::UShort(v) => Ok(v as f32),
847 Self::ULong(v) => Ok(v as f32),
848 Self::ULong64(v) => Ok(v as f32),
849 Self::Float(v) => Ok(v),
850 Self::Double(v) => Ok(v as f32),
851 _ => Err(self),
852 }
853 }
854
855 pub fn into_f64(self) -> Result<f64, Self> {
857 match self {
858 Self::Boolean(v) => Ok(v as i32 as f64),
859 Self::Short(v) => Ok(v as f64),
860 Self::Long(v) => Ok(v as f64),
861 Self::Long64(v) => Ok(v as f64),
862 Self::UShort(v) => Ok(v as f64),
863 Self::ULong(v) => Ok(v as f64),
864 Self::ULong64(v) => Ok(v as f64),
865 Self::Float(v) => Ok(v as f64),
866 Self::Double(v) => Ok(v),
867 _ => Err(self),
868 }
869 }
870
871 pub fn into_bytes(self) -> Result<Vec<u8>, Self> {
874 match self {
875 Self::String(s) => Ok(s),
876 Self::Encoded((_, s)) => Ok(s),
877 Self::CharArray(s) => Ok(s),
878 _ => Err(self),
879 }
880 }
881
882 pub fn into_string(self) -> Result<String, Self> {
885 match self {
886 Self::String(s) => String::from_utf8(s).map_err(|e| Self::String(e.into_bytes())),
887 Self::Encoded((f, s)) => String::from_utf8(s).map_err(|e| Self::Encoded((f, e.into_bytes()))),
888 Self::CharArray(s) => String::from_utf8(s).map_err(|e| Self::CharArray(e.into_bytes())),
889 _ => Err(self),
890 }
891 }
892
893 pub(crate) unsafe fn from_c(mut cmd_data: c::CommandData) -> Self {
894 let tag = TangoDataType::from_c(cmd_data.arg_type);
895 let data = cmd_data.cmd_data;
896 let res = match tag {
897 TangoDataType::Void => Self::Void,
898 TangoDataType::Boolean => Self::Boolean(data.bool_val),
899 TangoDataType::Short => Self::Short(data.short_val),
900 TangoDataType::Long | TangoDataType::Int => Self::Long(data.long_val),
901 TangoDataType::Float => Self::Float(data.float_val),
902 TangoDataType::Double => Self::Double(data.double_val),
903 TangoDataType::UShort => Self::UShort(data.ushort_val),
904 TangoDataType::ULong => Self::ULong(data.ulong_val),
905 TangoDataType::UChar => unimplemented!(), TangoDataType::Long64 => Self::Long64(data.long64_val),
907 TangoDataType::ULong64 => Self::ULong64(data.ulong64_val),
908 TangoDataType::State => Self::State(TangoDevState::from_c(data.state_val)),
909 TangoDataType::String | TangoDataType::ConstString => Self::String({
912 let ptr = data.string_val;
913 let len = libc::strlen(ptr);
914 Vec::from(slice::from_raw_parts(ptr as *mut u8, len))
915 }),
916 TangoDataType::CharArray => Self::CharArray({
917 let ptr = data.char_arr;
918 Vec::from(slice::from_raw_parts(ptr.sequence, ptr.length as usize))
919 }),
920 TangoDataType::ShortArray => Self::ShortArray({
921 let ptr = data.short_arr;
922 Vec::from(slice::from_raw_parts(ptr.sequence, ptr.length as usize))
923 }),
924 TangoDataType::LongArray => Self::LongArray({
925 let ptr = data.long_arr;
926 Vec::from(slice::from_raw_parts(ptr.sequence, ptr.length as usize))
927 }),
928 TangoDataType::FloatArray => Self::FloatArray({
929 let ptr = data.float_arr;
930 Vec::from(slice::from_raw_parts(ptr.sequence, ptr.length as usize))
931 }),
932 TangoDataType::DoubleArray => Self::DoubleArray({
933 let ptr = data.double_arr;
934 Vec::from(slice::from_raw_parts(ptr.sequence, ptr.length as usize))
935 }),
936 TangoDataType::UShortArray => Self::UShortArray({
937 let ptr = data.ushort_arr;
938 Vec::from(slice::from_raw_parts(ptr.sequence, ptr.length as usize))
939 }),
940 TangoDataType::ULongArray => Self::ULongArray({
941 let ptr = data.ulong_arr;
942 Vec::from(slice::from_raw_parts(ptr.sequence, ptr.length as usize))
943 }),
944 TangoDataType::StringArray => Self::StringArray({
945 let ptr = data.string_arr;
946 let mut res = Vec::with_capacity(ptr.length as usize);
947 for i in 0..ptr.length {
948 let raw = *ptr.sequence.offset(i as isize);
949 let len = libc::strlen(raw);
950 res.push(Vec::from(slice::from_raw_parts(raw as *mut u8, len)));
951 }
952 res
953 }),
954 TangoDataType::LongStringArray => {
955 let ptr = data.long_string_arr;
956 let mut strvec = Vec::with_capacity(ptr.string_length as usize);
957 for i in 0..ptr.string_length {
958 let raw = *ptr.string_sequence.offset(i as isize);
959 let len = libc::strlen(raw);
960 strvec.push(Vec::from(slice::from_raw_parts(raw as *mut u8, len)));
961 }
962 Self::LongStringArray(
963 Vec::from(slice::from_raw_parts(ptr.long_sequence, ptr.long_length as usize)),
964 strvec
965 )
966 },
967 TangoDataType::DoubleStringArray => {
968 let ptr = data.double_string_arr;
969 let mut strvec = Vec::with_capacity(ptr.string_length as usize);
970 for i in 0..ptr.string_length {
971 let raw = *ptr.string_sequence.offset(i as isize);
972 let len = libc::strlen(raw);
973 strvec.push(Vec::from(slice::from_raw_parts(raw as *mut u8, len)));
974 }
975 Self::DoubleStringArray(
976 Vec::from(slice::from_raw_parts(ptr.double_sequence, ptr.double_length as usize)),
977 strvec
978 )
979 },
980 TangoDataType::BooleanArray => Self::BooleanArray({
981 let ptr = data.bool_arr;
982 Vec::from(slice::from_raw_parts(ptr.sequence, ptr.length as usize))
983 }),
984 TangoDataType::Long64Array => Self::Long64Array({
985 let ptr = data.long64_arr;
986 Vec::from(slice::from_raw_parts(ptr.sequence, ptr.length as usize))
987 }),
988 TangoDataType::ULong64Array => Self::ULong64Array({
989 let ptr = data.ulong64_arr;
990 Vec::from(slice::from_raw_parts(ptr.sequence, ptr.length as usize))
991 }),
992 TangoDataType::Encoded => {
993 let ptr = data.encoded_val;
994 let format = string_from(ptr.encoded_format);
995 Self::Encoded((
996 format,
997 Vec::from(slice::from_raw_parts(ptr.encoded_data, ptr.encoded_length as usize))))
998 },
999 };
1000 c::tango_free_CommandData(&mut cmd_data);
1001 res
1002 }
1003
1004 pub(crate) unsafe fn into_c(self) -> c::CommandData {
1005 let mut content = mem::zeroed::<c::TangoCommandData>();
1006
1007 macro_rules! impl_array {
1008 ($val:ident, $alt:ident, $arr:ident, $ctype:ty) => {
1009 {
1010 let array = &mut content.$arr;
1011 array.length = $val.len() as u32;
1012 array.sequence = Box::into_raw($val.into_boxed_slice()) as *mut $ctype;
1013 TangoDataType::$alt
1014 }
1015 }
1016 }
1017
1018 let tag = match self {
1019 Self::Void => {
1020 TangoDataType::Void
1021 }
1022 Self::Boolean(v) => {
1023 content.bool_val = v;
1024 TangoDataType::Boolean
1025 }
1026 Self::Short(v) => {
1027 content.short_val = v;
1028 TangoDataType::Short
1029 }
1030 Self::Long(v) => {
1031 content.long_val = v;
1032 TangoDataType::Long
1033 }
1034 Self::Float(v) => {
1035 content.float_val = v;
1036 TangoDataType::Float
1037 }
1038 Self::Double(v) => {
1039 content.double_val = v;
1040 TangoDataType::Double
1041 }
1042 Self::UShort(v) => {
1043 content.ushort_val = v;
1044 TangoDataType::UShort
1045 }
1046 Self::ULong(v) => {
1047 content.ulong_val = v;
1048 TangoDataType::ULong
1049 }
1050 Self::Long64(v) => {
1051 content.long64_val = v;
1052 TangoDataType::Long64
1053 }
1054 Self::ULong64(v) => {
1055 content.ulong64_val = v;
1056 TangoDataType::ULong64
1057 }
1058 Self::String(v) => {
1059 let cstr = cstring_from(v);
1060 content.string_val = cstr.into_raw();
1061 TangoDataType::String
1062 }
1063 Self::Encoded((format, data)) => {
1064 let ptr = &mut content.encoded_val;
1065 ptr.encoded_format = cstring_from(format).into_raw();
1066 ptr.encoded_length = data.len() as u32;
1067 ptr.encoded_data = Box::into_raw(data.into_boxed_slice()) as *mut u8;
1068 TangoDataType::Encoded
1069 }
1070 Self::BooleanArray(v) => impl_array!(v, BooleanArray, bool_arr, bool),
1071 Self::CharArray(v) => impl_array!(v, CharArray, char_arr, u8),
1072 Self::ShortArray(v) => impl_array!(v, ShortArray, short_arr, i16),
1073 Self::UShortArray(v) => impl_array!(v, UShortArray, ushort_arr, u16),
1074 Self::LongArray(v) => impl_array!(v, LongArray, long_arr, i32),
1075 Self::ULongArray(v) => impl_array!(v, ULongArray, ulong_arr, u32),
1076 Self::Long64Array(v) => impl_array!(v, Long64Array, long64_arr, i64),
1077 Self::ULong64Array(v) => impl_array!(v, ULong64Array, ulong64_arr, u64),
1078 Self::FloatArray(v) => impl_array!(v, FloatArray, float_arr, f32),
1079 Self::DoubleArray(v) => impl_array!(v, DoubleArray, double_arr, f64),
1080 Self::StringArray(v) => {
1081 let array = &mut content.string_arr;
1082 let mut vec = Vec::with_capacity(v.len());
1083 array.length = v.len() as u32;
1084 for s in v.into_iter() {
1085 vec.push(cstring_from(s).into_raw());
1086 }
1087 array.sequence = Box::into_raw(vec.into_boxed_slice()) as *mut *mut c_char;
1088 TangoDataType::StringArray
1089 },
1090 Self::LongStringArray(vl, vs) => {
1091 let array = &mut content.long_string_arr;
1092 array.long_length = vl.len() as u32;
1093 array.long_sequence = Box::into_raw(vl.into_boxed_slice()) as *mut i32;
1094 let mut vec = Vec::with_capacity(vs.len());
1095 array.string_length = vs.len() as u32;
1096 for s in vs.into_iter() {
1097 vec.push(cstring_from(s).into_raw());
1098 }
1099 array.string_sequence = Box::into_raw(vec.into_boxed_slice()) as *mut *mut c_char;
1100 TangoDataType::LongStringArray
1101 },
1102 Self::DoubleStringArray(vd, vs) => {
1103 let array = &mut content.double_string_arr;
1104 array.double_length = vd.len() as u32;
1105 array.double_sequence = Box::into_raw(vd.into_boxed_slice()) as *mut f64;
1106 let mut vec = Vec::with_capacity(vs.len());
1107 array.string_length = vs.len() as u32;
1108 for s in vs.into_iter() {
1109 vec.push(cstring_from(s).into_raw());
1110 }
1111 array.string_sequence = Box::into_raw(vec.into_boxed_slice()) as *mut *mut c_char;
1112 TangoDataType::DoubleStringArray
1113 },
1114 Self::State(_) => panic!("Cannot send input argument of type State")
1115 };
1116 c::CommandData { arg_type: tag as u32, cmd_data: content }
1117 }
1118
1119 pub(crate) unsafe fn free_c_data(cmd_data: c::CommandData) {
1120 let data = cmd_data.cmd_data;
1121 match TangoDataType::from_c(cmd_data.arg_type) {
1122 TangoDataType::Void |
1123 TangoDataType::Boolean |
1124 TangoDataType::UChar |
1125 TangoDataType::Short |
1126 TangoDataType::Long |
1127 TangoDataType::Int |
1128 TangoDataType::Float |
1129 TangoDataType::Double |
1130 TangoDataType::UShort |
1131 TangoDataType::ULong |
1132 TangoDataType::Long64 |
1133 TangoDataType::ULong64 |
1134 TangoDataType::State => {}
1135 TangoDataType::String | TangoDataType::ConstString => {
1136 drop(CString::from_raw(data.string_val));
1137 }
1138 TangoDataType::Encoded => {
1139 drop(CString::from_raw(data.encoded_val.encoded_format));
1140 drop(Box::from_raw(data.encoded_val.encoded_data));
1141 }
1142 TangoDataType::BooleanArray => drop(Box::from_raw(data.bool_arr.sequence)),
1143 TangoDataType::CharArray => drop(Box::from_raw(data.char_arr.sequence)),
1144 TangoDataType::ShortArray => drop(Box::from_raw(data.short_arr.sequence)),
1145 TangoDataType::UShortArray => drop(Box::from_raw(data.ushort_arr.sequence)),
1146 TangoDataType::LongArray => drop(Box::from_raw(data.long_arr.sequence)),
1147 TangoDataType::ULongArray => drop(Box::from_raw(data.ulong_arr.sequence)),
1148 TangoDataType::Long64Array => drop(Box::from_raw(data.long64_arr.sequence)),
1149 TangoDataType::ULong64Array => drop(Box::from_raw(data.ulong64_arr.sequence)),
1150 TangoDataType::FloatArray => drop(Box::from_raw(data.float_arr.sequence)),
1151 TangoDataType::DoubleArray => drop(Box::from_raw(data.double_arr.sequence)),
1152 TangoDataType::StringArray => {
1153 for i in 0..data.string_arr.length {
1154 drop(CString::from_raw(*data.string_arr.sequence.offset(i as isize) as *mut c_char));
1155 }
1156 drop(Box::from_raw(data.string_arr.sequence));
1157 }
1158 TangoDataType::LongStringArray => {
1159 for i in 0..data.long_string_arr.string_length {
1160 drop(CString::from_raw(*data.long_string_arr
1161 .string_sequence.offset(i as isize) as *mut c_char));
1162 }
1163 drop(Box::from_raw(data.long_string_arr.string_sequence));
1164 drop(Box::from_raw(data.long_string_arr.long_sequence));
1165 }
1166 TangoDataType::DoubleStringArray => {
1167 for i in 0..data.double_string_arr.string_length {
1168 drop(CString::from_raw(*data.double_string_arr
1169 .string_sequence.offset(i as isize) as *mut c_char));
1170 }
1171 drop(Box::from_raw(data.double_string_arr.string_sequence));
1172 drop(Box::from_raw(data.double_string_arr.double_sequence));
1173 }
1174 }
1175 }
1176}
1177
1178impl fmt::Display for CommandData {
1179 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1180 match self {
1181 Self::Void => f.pad("<Void>"),
1182 Self::Boolean(v) => fmt::Display::fmt(&v, f),
1183 Self::Short(v) => fmt::Display::fmt(&v, f),
1184 Self::UShort(v) => fmt::Display::fmt(&v, f),
1185 Self::Long(v) => fmt::Display::fmt(&v, f),
1186 Self::ULong(v) => fmt::Display::fmt(&v, f),
1187 Self::Long64(v) => fmt::Display::fmt(&v, f),
1188 Self::ULong64(v) => fmt::Display::fmt(&v, f),
1189 Self::Float(v) => fmt::Display::fmt(&v, f),
1190 Self::Double(v) => fmt::Display::fmt(&v, f),
1191 Self::String(v) => fmt::Display::fmt(&String::from_utf8_lossy(v), f),
1192 Self::State(v) => fmt::Display::fmt(&v, f),
1193 Self::Encoded(_) => f.pad("<DevEncoded>"),
1194
1195 Self::BooleanArray(v) => slice_display(v, |x| x, f),
1196 Self::CharArray(v) => slice_display(v, |x| x, f),
1197 Self::ShortArray(v) => slice_display(v, |x| x, f),
1198 Self::UShortArray(v) => slice_display(v, |x| x, f),
1199 Self::LongArray(v) => slice_display(v, |x| x, f),
1200 Self::ULongArray(v) => slice_display(v, |x| x, f),
1201 Self::Long64Array(v) => slice_display(v, |x| x, f),
1202 Self::ULong64Array(v) => slice_display(v, |x| x, f),
1203 Self::FloatArray(v) => slice_display(v, |x| x, f),
1204 Self::DoubleArray(v) => slice_display(v, |x| x, f),
1205 Self::StringArray(v) => slice_display(v, |x| String::from_utf8_lossy(x), f),
1206 Self::LongStringArray(vi, vs) => {
1207 slice_display(vi, |x| x, f)?;
1208 slice_display(vs, |x| String::from_utf8_lossy(x), f)
1209 },
1210 Self::DoubleStringArray(vd, vs) => {
1211 slice_display(vd, |x| x, f)?;
1212 slice_display(vs, |x| String::from_utf8_lossy(x), f)
1213 },
1214 }
1215 }
1216}
1217
1218impl fmt::LowerHex for CommandData {
1219 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1220 match self {
1221 Self::Void => f.pad("<Void>"),
1222 Self::Boolean(v) => fmt::Display::fmt(&v, f),
1223 Self::Short(v) => fmt::LowerHex::fmt(&v, f),
1224 Self::UShort(v) => fmt::LowerHex::fmt(&v, f),
1225 Self::Long(v) => fmt::LowerHex::fmt(&v, f),
1226 Self::ULong(v) => fmt::LowerHex::fmt(&v, f),
1227 Self::Long64(v) => fmt::LowerHex::fmt(&v, f),
1228 Self::ULong64(v) => fmt::LowerHex::fmt(&v, f),
1229 Self::Float(v) => fmt::Display::fmt(&v, f),
1230 Self::Double(v) => fmt::Display::fmt(&v, f),
1231 Self::String(v) => fmt::Display::fmt(&String::from_utf8_lossy(v), f),
1232 Self::State(v) => fmt::Display::fmt(&v, f),
1233 Self::Encoded(_) => f.pad("<DevEncoded>"),
1234
1235 Self::BooleanArray(v) => slice_display(v, |x| x, f),
1236 Self::CharArray(v) => slice_lower_hex(v, |x| x, f),
1237 Self::ShortArray(v) => slice_lower_hex(v, |x| x, f),
1238 Self::UShortArray(v) => slice_lower_hex(v, |x| x, f),
1239 Self::LongArray(v) => slice_lower_hex(v, |x| x, f),
1240 Self::ULongArray(v) => slice_lower_hex(v, |x| x, f),
1241 Self::Long64Array(v) => slice_lower_hex(v, |x| x, f),
1242 Self::ULong64Array(v) => slice_lower_hex(v, |x| x, f),
1243 Self::FloatArray(v) => slice_display(v, |x| x, f),
1244 Self::DoubleArray(v) => slice_display(v, |x| x, f),
1245 Self::StringArray(v) => slice_display(v, |x| String::from_utf8_lossy(x), f),
1246 Self::LongStringArray(vi, vs) => {
1247 slice_lower_hex(vi, |x| x, f)?;
1248 slice_display(vs, |x| String::from_utf8_lossy(x), f)
1249 },
1250 Self::DoubleStringArray(vd, vs) => {
1251 slice_display(vd, |x| x, f)?;
1252 slice_display(vs, |x| String::from_utf8_lossy(x), f)
1253 },
1254 }
1255 }
1256}
1257
1258impl fmt::UpperHex for CommandData {
1259 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1260 match self {
1261 Self::Void => f.pad("<Void>"),
1262 Self::Boolean(v) => fmt::Display::fmt(&v, f),
1263 Self::Short(v) => fmt::UpperHex::fmt(&v, f),
1264 Self::UShort(v) => fmt::UpperHex::fmt(&v, f),
1265 Self::Long(v) => fmt::UpperHex::fmt(&v, f),
1266 Self::ULong(v) => fmt::UpperHex::fmt(&v, f),
1267 Self::Long64(v) => fmt::UpperHex::fmt(&v, f),
1268 Self::ULong64(v) => fmt::UpperHex::fmt(&v, f),
1269 Self::Float(v) => fmt::Display::fmt(&v, f),
1270 Self::Double(v) => fmt::Display::fmt(&v, f),
1271 Self::String(v) => fmt::Display::fmt(&String::from_utf8_lossy(v), f),
1272 Self::State(v) => fmt::Display::fmt(&v, f),
1273 Self::Encoded(_) => f.pad("<DevEncoded>"),
1274
1275 Self::BooleanArray(v) => slice_display(v, |x| x, f),
1276 Self::CharArray(v) => slice_upper_hex(v, |x| x, f),
1277 Self::ShortArray(v) => slice_upper_hex(v, |x| x, f),
1278 Self::UShortArray(v) => slice_upper_hex(v, |x| x, f),
1279 Self::LongArray(v) => slice_upper_hex(v, |x| x, f),
1280 Self::ULongArray(v) => slice_upper_hex(v, |x| x, f),
1281 Self::Long64Array(v) => slice_upper_hex(v, |x| x, f),
1282 Self::ULong64Array(v) => slice_upper_hex(v, |x| x, f),
1283 Self::FloatArray(v) => slice_display(v, |x| x, f),
1284 Self::DoubleArray(v) => slice_display(v, |x| x, f),
1285 Self::StringArray(v) => slice_display(v, |x| String::from_utf8_lossy(x), f),
1286 Self::LongStringArray(vi, vs) => {
1287 slice_upper_hex(vi, |x| x, f)?;
1288 slice_display(vs, |x| String::from_utf8_lossy(x), f)
1289 },
1290 Self::DoubleStringArray(vd, vs) => {
1291 slice_display(vd, |x| x, f)?;
1292 slice_display(vs, |x| String::from_utf8_lossy(x), f)
1293 },
1294 }
1295 }
1296}
1297
1298impl fmt::LowerExp for CommandData {
1299 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1300 match self {
1301 Self::Void => f.pad("<Void>"),
1302 Self::Boolean(v) => fmt::Display::fmt(&v, f),
1303 Self::Short(v) => fmt::Display::fmt(&v, f),
1304 Self::UShort(v) => fmt::Display::fmt(&v, f),
1305 Self::Long(v) => fmt::Display::fmt(&v, f),
1306 Self::ULong(v) => fmt::Display::fmt(&v, f),
1307 Self::Long64(v) => fmt::Display::fmt(&v, f),
1308 Self::ULong64(v) => fmt::Display::fmt(&v, f),
1309 Self::Float(v) => fmt::LowerExp::fmt(&v, f),
1310 Self::Double(v) => fmt::LowerExp::fmt(&v, f),
1311 Self::String(v) => fmt::Display::fmt(&String::from_utf8_lossy(v), f),
1312 Self::State(v) => fmt::Display::fmt(&v, f),
1313 Self::Encoded(_) => f.pad("<DevEncoded>"),
1314
1315 Self::BooleanArray(v) => slice_display(v, |x| x, f),
1316 Self::CharArray(v) => slice_display(v, |x| x, f),
1317 Self::ShortArray(v) => slice_display(v, |x| x, f),
1318 Self::UShortArray(v) => slice_display(v, |x| x, f),
1319 Self::LongArray(v) => slice_display(v, |x| x, f),
1320 Self::ULongArray(v) => slice_display(v, |x| x, f),
1321 Self::Long64Array(v) => slice_display(v, |x| x, f),
1322 Self::ULong64Array(v) => slice_display(v, |x| x, f),
1323 Self::FloatArray(v) => slice_lower_exp(v, |x| x, f),
1324 Self::DoubleArray(v) => slice_lower_exp(v, |x| x, f),
1325 Self::StringArray(v) => slice_display(v, |x| String::from_utf8_lossy(x), f),
1326 Self::LongStringArray(vi, vs) => {
1327 slice_display(vi, |x| x, f)?;
1328 slice_display(vs, |x| String::from_utf8_lossy(x), f)
1329 },
1330 Self::DoubleStringArray(vd, vs) => {
1331 slice_lower_exp(vd, |x| x, f)?;
1332 slice_display(vs, |x| String::from_utf8_lossy(x), f)
1333 },
1334 }
1335 }
1336}
1337
1338impl fmt::UpperExp for CommandData {
1339 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1340 match self {
1341 Self::Void => f.pad("<Void>"),
1342 Self::Boolean(v) => fmt::Display::fmt(&v, f),
1343 Self::Short(v) => fmt::Display::fmt(&v, f),
1344 Self::UShort(v) => fmt::Display::fmt(&v, f),
1345 Self::Long(v) => fmt::Display::fmt(&v, f),
1346 Self::ULong(v) => fmt::Display::fmt(&v, f),
1347 Self::Long64(v) => fmt::Display::fmt(&v, f),
1348 Self::ULong64(v) => fmt::Display::fmt(&v, f),
1349 Self::Float(v) => fmt::UpperExp::fmt(&v, f),
1350 Self::Double(v) => fmt::UpperExp::fmt(&v, f),
1351 Self::String(v) => fmt::Display::fmt(&String::from_utf8_lossy(v), f),
1352 Self::State(v) => fmt::Display::fmt(&v, f),
1353 Self::Encoded(_) => f.pad("<DevEncoded>"),
1354
1355 Self::BooleanArray(v) => slice_display(v, |x| x, f),
1356 Self::CharArray(v) => slice_display(v, |x| x, f),
1357 Self::ShortArray(v) => slice_display(v, |x| x, f),
1358 Self::UShortArray(v) => slice_display(v, |x| x, f),
1359 Self::LongArray(v) => slice_display(v, |x| x, f),
1360 Self::ULongArray(v) => slice_display(v, |x| x, f),
1361 Self::Long64Array(v) => slice_display(v, |x| x, f),
1362 Self::ULong64Array(v) => slice_display(v, |x| x, f),
1363 Self::FloatArray(v) => slice_upper_exp(v, |x| x, f),
1364 Self::DoubleArray(v) => slice_upper_exp(v, |x| x, f),
1365 Self::StringArray(v) => slice_display(v, |x| String::from_utf8_lossy(x), f),
1366 Self::LongStringArray(vi, vs) => {
1367 slice_display(vi, |x| x, f)?;
1368 slice_display(vs, |x| String::from_utf8_lossy(x), f)
1369 },
1370 Self::DoubleStringArray(vd, vs) => {
1371 slice_upper_exp(vd, |x| x, f)?;
1372 slice_display(vs, |x| String::from_utf8_lossy(x), f)
1373 },
1374 }
1375 }
1376}
1377
1378
1379#[derive(Debug)]
1381pub struct AttributeInfo {
1382 pub name: String,
1383 pub writable: AttrWriteType,
1384 pub data_type: TangoDataType,
1385 pub data_format: AttrDataFormat,
1386 pub max_dim_x: usize,
1387 pub max_dim_y: usize,
1388 pub description: String,
1389 pub label: String,
1390 pub unit: String,
1391 pub standard_unit: String,
1392 pub display_unit: String,
1393 pub format: String,
1394 pub min_value: String,
1395 pub max_value: String,
1396 pub min_alarm: String,
1397 pub max_alarm: String,
1398 pub writable_attr_name: String,
1399 pub disp_level: DispLevel,
1400}
1401
1402impl AttributeInfo {
1403 pub(crate) unsafe fn from_c(info: c::AttributeInfo) -> AttributeInfo {
1404 AttributeInfo {
1405 name: string_from(info.name),
1406 writable: AttrWriteType::from_c(info.writable),
1407 data_type: TangoDataType::from_c(info.data_type),
1408 data_format: AttrDataFormat::from_c(info.data_format),
1409 max_dim_x: info.max_dim_x as usize,
1410 max_dim_y: info.max_dim_y as usize,
1411 description: string_from(info.description),
1412 label: string_from(info.label),
1413 unit: string_from(info.unit),
1414 standard_unit: string_from(info.standard_unit),
1415 display_unit: string_from(info.display_unit),
1416 format: string_from(info.format),
1417 min_value: string_from(info.min_value),
1418 max_value: string_from(info.max_value),
1419 min_alarm: string_from(info.min_alarm),
1420 max_alarm: string_from(info.max_alarm),
1421 writable_attr_name: string_from(info.writable_attr_name),
1422 disp_level: DispLevel::from_c(info.disp_level),
1423 }
1424 }
1425}
1426
1427
1428#[derive(Debug, Clone, PartialEq)]
1430pub struct AttributeData {
1431 pub data: AttrValue,
1432 pub written_data: Option<AttrValue>,
1433 pub format: AttrDataFormat,
1434 pub quality: AttrQuality,
1435 pub name: String,
1436 pub dim_x: usize,
1437 pub dim_y: usize,
1438 pub time_stamp: Timespec,
1439}
1440
1441impl AttributeData {
1442 pub fn simple(name: &str, data: AttrValue) -> AttributeData {
1445 AttributeData {
1446 dim_x: data.len(),
1447 dim_y: 0,
1448 data,
1449 written_data: None, format: AttrDataFormat::Scalar, quality: AttrQuality::Valid,
1452 name: name.into(),
1453 time_stamp: get_time(),
1454 }
1455 }
1456
1457 pub(crate) unsafe fn from_c(mut attr_data: c::AttributeData, free: bool) -> AttributeData {
1458 use AttrValue::*;
1459
1460 let tag = TangoDataType::from_c(attr_data.data_type);
1461 let data = attr_data.attr_data;
1462 let is_scalar = AttrDataFormat::from_c(attr_data.data_format) == AttrDataFormat::Scalar;
1463 let (res_read, res_written) = if is_scalar {
1464 macro_rules! impl_simple {
1465 ($alt:ident, $arr:ident) => {
1466 {
1467 let ptr = data.$arr;
1468 if ptr.length == 1 {
1469 ($alt(*ptr.sequence), $alt(Default::default()))
1470 } else {
1471 ($alt(*ptr.sequence), $alt(*ptr.sequence.offset(1)))
1472 }
1473 }
1474 }
1475 }
1476
1477 match tag {
1478 TangoDataType::UChar => impl_simple!(UChar, char_arr),
1479 TangoDataType::Short => impl_simple!(Short, short_arr),
1480 TangoDataType::UShort => impl_simple!(UShort, ushort_arr),
1481 TangoDataType::Long => impl_simple!(Long, long_arr),
1482 TangoDataType::ULong => impl_simple!(ULong, ulong_arr),
1483 TangoDataType::Long64 => impl_simple!(Long64, long64_arr),
1484 TangoDataType::ULong64 => impl_simple!(ULong64, ulong64_arr),
1485 TangoDataType::Float => impl_simple!(Float, float_arr),
1486 TangoDataType::Double => impl_simple!(Double, double_arr),
1487 TangoDataType::Boolean => impl_simple!(Boolean, bool_arr),
1488 TangoDataType::State => {
1489 let r = TangoDevState::from_c(*data.state_arr.sequence);
1490 let w = if data.string_arr.length == 1 {
1491 TangoDevState::Unknown
1492 } else {
1493 TangoDevState::from_c(*data.state_arr.sequence.offset(1))
1494 };
1495 (State(r), State(w))
1496 }
1497 TangoDataType::String => {
1498 let rawr = *data.string_arr.sequence;
1499 let lenr = libc::strlen(rawr);
1500 let r = Vec::from(slice::from_raw_parts(rawr as *mut u8, lenr));
1501 let w = if data.string_arr.length == 1 {
1502 Vec::new()
1503 } else {
1504 let raww = *data.string_arr.sequence.offset(1);
1505 let lenw = libc::strlen(raww);
1506 Vec::from(slice::from_raw_parts(raww as *mut u8, lenw))
1507 };
1508 (String(r), String(w))
1509 },
1510 TangoDataType::Encoded => {
1511 let rawr = *data.encoded_arr.sequence;
1512 let r = (string_from(rawr.encoded_format),
1513 Vec::from(slice::from_raw_parts(rawr.encoded_data as *mut u8,
1514 rawr.encoded_length as usize)));
1515 let w = if data.string_arr.length == 1 {
1516 ("".into(), Vec::new())
1517 } else {
1518 let raww = *data.encoded_arr.sequence.offset(1);
1519 (string_from(raww.encoded_format),
1520 Vec::from(slice::from_raw_parts(raww.encoded_data as *mut u8,
1521 raww.encoded_length as usize)))
1522 };
1523 (Encoded(r), Encoded(w))
1524 },
1525 _ => panic!("data type {:?} not allowed for attributes", tag)
1526 }
1527 } else {
1528 macro_rules! impl_simple {
1529 ($alt:ident, $arr:ident) => {
1530 {
1531 let ptr = data.$arr;
1532 let slice = slice::from_raw_parts(ptr.sequence, ptr.length as usize);
1533 let (p1, p2) = slice.split_at(attr_data.nb_read as usize);
1534 ($alt(Vec::from(p1)), $alt(Vec::from(p2)))
1535 }
1536 }
1537 }
1538
1539 match tag {
1540 TangoDataType::UChar => impl_simple!(UCharArray, char_arr),
1541 TangoDataType::Short => impl_simple!(ShortArray, short_arr),
1542 TangoDataType::UShort => impl_simple!(UShortArray, ushort_arr),
1543 TangoDataType::Long => impl_simple!(LongArray, long_arr),
1544 TangoDataType::ULong => impl_simple!(ULongArray, ulong_arr),
1545 TangoDataType::Long64 => impl_simple!(Long64Array, long64_arr),
1546 TangoDataType::ULong64 => impl_simple!(ULong64Array, ulong64_arr),
1547 TangoDataType::Float => impl_simple!(FloatArray, float_arr),
1548 TangoDataType::Double => impl_simple!(DoubleArray, double_arr),
1549 TangoDataType::Boolean => impl_simple!(BooleanArray, bool_arr),
1550 TangoDataType::State => {
1551 let ptr = data.state_arr;
1552 let slice = slice::from_raw_parts(ptr.sequence, ptr.length as usize);
1553 let (p1, p2) = slice.split_at(attr_data.nb_read as usize);
1554 (StateArray(p1.iter().map(|&v| TangoDevState::from_c(v)).collect()),
1555 StateArray(p2.iter().map(|&v| TangoDevState::from_c(v)).collect()))
1556 },
1557 TangoDataType::String => {
1558 let ptr = data.string_arr;
1559 let mut res = Vec::with_capacity(ptr.length as usize);
1560 for i in 0..ptr.length {
1561 let raw = *ptr.sequence.offset(i as isize);
1562 let len = libc::strlen(raw);
1563 res.push(Vec::from(slice::from_raw_parts(raw as *mut u8, len)));
1564 }
1565 let res2 = res.split_off(attr_data.nb_read as usize);
1566 (StringArray(res), StringArray(res2))
1567 },
1568 TangoDataType::Encoded => {
1569 let ptr = data.encoded_arr;
1570 let mut res = Vec::with_capacity(ptr.length as usize);
1571 for i in 0..ptr.length {
1572 let raw = *ptr.sequence.offset(i as isize);
1573 res.push((string_from(raw.encoded_format),
1574 Vec::from(slice::from_raw_parts(raw.encoded_data as *mut u8,
1575 raw.encoded_length as usize))));
1576 }
1577 let res2 = res.split_off(attr_data.nb_read as usize);
1578 (EncodedArray(res), EncodedArray(res2))
1579 },
1580 _ => panic!("data type {:?} not allowed for attributes", tag)
1581 }
1582 };
1583 let res = AttributeData {
1584 data: res_read,
1585 written_data: Some(res_written),
1586 format: AttrDataFormat::from_c(attr_data.data_format),
1587 quality: AttrQuality::from_c(attr_data.quality),
1588 name: string_from(attr_data.name),
1589 dim_x: attr_data.dim_x as usize,
1590 dim_y: attr_data.dim_y as usize,
1591 time_stamp: Timespec::new(attr_data.time_stamp.tv_sec.into(),
1592 1000 * attr_data.time_stamp.tv_usec as i32),
1593 };
1594 if free {
1595 c::tango_free_AttributeData(&mut attr_data);
1596 }
1597 res
1598 }
1599
1600 pub(crate) unsafe fn into_c(self) -> c::AttributeData {
1601 let mut content = mem::zeroed::<c::TangoAttributeData>();
1602
1603 macro_rules! impl_simple {
1604 ($val:ident, $alt:ident, $arr:ident, $ctype:ty) => {
1605 {
1606 let array = &mut content.$arr;
1607 array.length = 1;
1608 array.sequence = Box::into_raw(Box::new($val)) as *mut $ctype;
1609 TangoDataType::$alt
1610 }
1611 }
1612 }
1613
1614 macro_rules! impl_array {
1615 ($val:ident, $alt:ident, $arr:ident, $ctype:ty) => {
1616 {
1617 let array = &mut content.$arr;
1618 array.length = $val.len() as u32;
1619 array.sequence = Box::into_raw($val.into_boxed_slice()) as *mut $ctype;
1620 TangoDataType::$alt
1621 }
1622 }
1623 }
1624
1625 let tag = match self.data {
1626 AttrValue::Boolean(v) => impl_simple!(v, Boolean, bool_arr, bool),
1627 AttrValue::UChar(v) => impl_simple!(v, UChar, char_arr, u8),
1628 AttrValue::Short(v) => impl_simple!(v, Short, short_arr, i16),
1629 AttrValue::UShort(v) => impl_simple!(v, UShort, ushort_arr, u16),
1630 AttrValue::Long(v) => impl_simple!(v, Long, long_arr, i32),
1631 AttrValue::ULong(v) => impl_simple!(v, ULong, ulong_arr, u32),
1632 AttrValue::Long64(v) => impl_simple!(v, Long64, long64_arr, i64),
1633 AttrValue::ULong64(v) => impl_simple!(v, ULong64, ulong64_arr, u64),
1634 AttrValue::Float(v) => impl_simple!(v, Float, float_arr, f32),
1635 AttrValue::Double(v) => impl_simple!(v, Double, double_arr, f64),
1636 AttrValue::State(v) => impl_simple!(v, State, state_arr, c::TangoDevState),
1637 AttrValue::String(v) => {
1638 let array = &mut content.string_arr;
1639 array.length = 1;
1640 let mut vec = Vec::with_capacity(1);
1641 vec.push(cstring_from(v).into_raw());
1642 array.sequence = Box::into_raw(vec.into_boxed_slice()) as *mut *mut c_char;
1643 TangoDataType::String
1644 }
1645 AttrValue::Encoded((format, data)) => {
1646 let array = &mut content.encoded_arr;
1647 array.length = 1;
1648 let mut vec = Vec::with_capacity(1);
1649 let encoded = c::TangoDevEncoded {
1650 encoded_format: cstring_from(format).into_raw(),
1651 encoded_length: data.len() as u32,
1652 encoded_data: Box::into_raw(data.into_boxed_slice()) as *mut u8,
1653 };
1654 vec.push(Box::into_raw(Box::new(encoded)));
1655 array.sequence = Box::into_raw(vec.into_boxed_slice()) as *mut c::TangoDevEncoded;
1656 TangoDataType::Encoded
1657 }
1658 AttrValue::BooleanArray(v) => impl_array!(v, Boolean, bool_arr, bool),
1659 AttrValue::UCharArray(v) => impl_array!(v, UChar, char_arr, u8),
1660 AttrValue::ShortArray(v) => impl_array!(v, Short, short_arr, i16),
1661 AttrValue::UShortArray(v) => impl_array!(v, UShort, ushort_arr, u16),
1662 AttrValue::LongArray(v) => impl_array!(v, Long, long_arr, i32),
1663 AttrValue::ULongArray(v) => impl_array!(v, ULong, ulong_arr, u32),
1664 AttrValue::Long64Array(v) => impl_array!(v, Long64, long64_arr, i64),
1665 AttrValue::ULong64Array(v) => impl_array!(v, ULong64, ulong64_arr, u64),
1666 AttrValue::FloatArray(v) => impl_array!(v, Float, float_arr, f32),
1667 AttrValue::DoubleArray(v) => impl_array!(v, Double, double_arr, f64),
1668 AttrValue::StateArray(v) => impl_array!(v, State, state_arr, c::TangoDevState),
1669 AttrValue::StringArray(v) => {
1670 let array = &mut content.string_arr;
1671 let mut vec = Vec::with_capacity(v.len());
1672 array.length = v.len() as u32;
1673 for s in v.into_iter() {
1674 vec.push(cstring_from(s).into_raw());
1675 }
1676 array.sequence = Box::into_raw(vec.into_boxed_slice()) as *mut *mut c_char;
1677 TangoDataType::String
1678 }
1679 AttrValue::EncodedArray(v) => {
1680 let array = &mut content.encoded_arr;
1681 array.length = v.len() as u32;
1682 let mut vec = Vec::with_capacity(v.len());
1683 for (format, data) in v.into_iter() {
1684 let encoded = c::TangoDevEncoded {
1685 encoded_format: cstring_from(format).into_raw(),
1686 encoded_length: data.len() as u32,
1687 encoded_data: Box::into_raw(data.into_boxed_slice()) as *mut u8,
1688 };
1689 vec.push(Box::into_raw(Box::new(encoded)));
1690 }
1691 array.sequence = Box::into_raw(vec.into_boxed_slice()) as *mut c::TangoDevEncoded;
1692 TangoDataType::Encoded
1693 }
1694 };
1695 c::AttributeData {
1696 name: cstring_from(self.name).into_raw(),
1697 data_type: tag as u32,
1698 data_format: self.format as u32,
1699 attr_data: content,
1700 nb_read: 0, quality: self.quality as u32,
1702 dim_x: self.dim_x as i32,
1703 dim_y: self.dim_y as i32,
1704 time_stamp: c::timeval { tv_sec: self.time_stamp.sec as c_long,
1705 tv_usec: self.time_stamp.nsec as c_long / 1000 }
1706 }
1707 }
1708
1709 pub(crate) unsafe fn free_c_data(attr_data: c::AttributeData) {
1710 let data = attr_data.attr_data;
1711 drop(CString::from_raw(attr_data.name));
1712 match TangoDataType::from_c(attr_data.data_type) {
1713 TangoDataType::Boolean => drop(Box::from_raw(data.bool_arr.sequence)),
1714 TangoDataType::UChar => drop(Box::from_raw(data.char_arr.sequence)),
1715 TangoDataType::Short => drop(Box::from_raw(data.short_arr.sequence)),
1716 TangoDataType::UShort => drop(Box::from_raw(data.ushort_arr.sequence)),
1717 TangoDataType::Long => drop(Box::from_raw(data.long_arr.sequence)),
1718 TangoDataType::ULong => drop(Box::from_raw(data.ulong_arr.sequence)),
1719 TangoDataType::Long64 => drop(Box::from_raw(data.long64_arr.sequence)),
1720 TangoDataType::ULong64 => drop(Box::from_raw(data.ulong64_arr.sequence)),
1721 TangoDataType::Float => drop(Box::from_raw(data.float_arr.sequence)),
1722 TangoDataType::Double => drop(Box::from_raw(data.double_arr.sequence)),
1723 TangoDataType::State => drop(Box::from_raw(data.state_arr.sequence)),
1724 TangoDataType::String => {
1725 for i in 0..data.string_arr.length {
1726 drop(CString::from_raw(*data.string_arr.sequence.offset(i as isize) as *mut c_char));
1727 }
1728 drop(Box::from_raw(data.string_arr.sequence));
1729 }
1730 TangoDataType::Encoded => {
1731 for i in 0..data.encoded_arr.length {
1732 let ptr = data.encoded_arr.sequence.offset(i as isize) as *mut c::TangoDevEncoded;
1733 drop(CString::from_raw((*ptr).encoded_format as *mut c_char));
1734 drop(Box::from_raw((*ptr).encoded_data));
1735 }
1736 drop(Box::from_raw(data.encoded_arr.sequence));
1737 }
1738 val => panic!("invalid attribute data tag={:?}", val)
1739 }
1740 }
1741}
1742
1743
1744#[derive(Debug, Clone, PartialEq)]
1748pub enum AttrValue {
1749 Boolean(bool),
1750 UChar(u8),
1751 Short(i16),
1752 UShort(u16),
1753 Long(i32),
1754 ULong(u32),
1755 Long64(i64),
1756 ULong64(u64),
1757
1758 Float(f32),
1759 Double(f64),
1760
1761 String(Vec<u8>),
1762 State(TangoDevState),
1763 Encoded(DevEncoded),
1764
1765 BooleanArray(Vec<bool>),
1766 UCharArray(Vec<u8>),
1767 ShortArray(Vec<i16>),
1768 UShortArray(Vec<u16>),
1769 LongArray(Vec<i32>),
1770 ULongArray(Vec<u32>),
1771 Long64Array(Vec<i64>),
1772 ULong64Array(Vec<u64>),
1773
1774 FloatArray(Vec<f32>),
1775 DoubleArray(Vec<f64>),
1776
1777 StringArray(Vec<Vec<u8>>),
1778 StateArray(Vec<TangoDevState>),
1779 EncodedArray(Vec<DevEncoded>),
1780}
1781
1782impl AttrValue {
1783 pub fn len(&self) -> usize {
1787 match self {
1788 Self::Boolean(_) |
1789 Self::UChar(_) |
1790 Self::Short(_) |
1791 Self::UShort(_) |
1792 Self::Long(_) |
1793 Self::ULong(_) |
1794 Self::Long64(_) |
1795 Self::ULong64(_) |
1796 Self::Float(_) |
1797 Self::Double(_) |
1798 Self::String(_) |
1799 Self::State(_) |
1800 Self::Encoded(_) => 1,
1801
1802 Self::BooleanArray(v) => v.len(),
1803 Self::UCharArray(v) => v.len(),
1804 Self::ShortArray(v) => v.len(),
1805 Self::UShortArray(v) => v.len(),
1806 Self::LongArray(v) => v.len(),
1807 Self::ULongArray(v) => v.len(),
1808 Self::Long64Array(v) => v.len(),
1809 Self::ULong64Array(v) => v.len(),
1810 Self::FloatArray(v) => v.len(),
1811 Self::DoubleArray(v) => v.len(),
1812 Self::StringArray(v) => v.len(),
1813 Self::StateArray(v) => v.len(),
1814 Self::EncodedArray(v) => v.len(),
1815 }
1816 }
1817
1818 pub fn convert(self, to: TangoDataType) -> Result<Self, Self> {
1823 match self {
1824 Self::Boolean(v) => match to {
1825 TangoDataType::Boolean => Ok(self),
1826 TangoDataType::UChar => Ok(Self::UChar(v as _)),
1827 TangoDataType::Short => Ok(Self::Short(v as _)),
1828 TangoDataType::UShort => Ok(Self::UShort(v as _)),
1829 TangoDataType::Int |
1830 TangoDataType::Long => Ok(Self::Long(v as _)),
1831 TangoDataType::ULong => Ok(Self::ULong(v as _)),
1832 TangoDataType::Long64 => Ok(Self::Long64(v as _)),
1833 TangoDataType::ULong64 => Ok(Self::ULong64(v as _)),
1834 TangoDataType::Float => Ok(Self::Float(v as i32 as _)),
1835 TangoDataType::Double => Ok(Self::Double(v as i32 as _)),
1836 _ => Err(self)
1837 }
1838 Self::UChar(v) => match to {
1839 TangoDataType::Boolean => check_bool(v as i64).map(Self::Boolean).map_err(|_| self),
1840 TangoDataType::UChar => Ok(self),
1841 TangoDataType::Short => Ok(Self::Short(v as _)),
1842 TangoDataType::UShort => Ok(Self::Short(v as _)),
1843 TangoDataType::Int |
1844 TangoDataType::Long => Ok(Self::Long(v as _)),
1845 TangoDataType::ULong => Ok(Self::ULong(v as _)),
1846 TangoDataType::Long64 => Ok(Self::Long64(v as _)),
1847 TangoDataType::ULong64 => Ok(Self::ULong64(v as _)),
1848 TangoDataType::Float => Ok(Self::Float(v as _)),
1849 TangoDataType::Double => Ok(Self::Double(v as _)),
1850 _ => Err(self)
1851 }
1852 Self::Short(v) => match to {
1853 TangoDataType::Boolean => check_bool(v as i64).map(Self::Boolean).map_err(|_| self),
1854 TangoDataType::UChar => v.try_into().map(Self::UChar).map_err(|_| self),
1855 TangoDataType::Short => Ok(self),
1856 TangoDataType::UShort => v.try_into().map(Self::UShort).map_err(|_| self),
1857 TangoDataType::Int |
1858 TangoDataType::Long => Ok(Self::Long(v as _)),
1859 TangoDataType::ULong => Ok(Self::ULong(v as _)),
1860 TangoDataType::Long64 => Ok(Self::Long64(v as _)),
1861 TangoDataType::ULong64 => Ok(Self::ULong64(v as _)),
1862 TangoDataType::Float => Ok(Self::Float(v as _)),
1863 TangoDataType::Double => Ok(Self::Double(v as _)),
1864 _ => Err(self)
1865 }
1866 Self::UShort(v) => match to {
1867 TangoDataType::Boolean => check_bool(v as i64).map(Self::Boolean).map_err(|_| self),
1868 TangoDataType::UChar => v.try_into().map(Self::UChar).map_err(|_| self),
1869 TangoDataType::Short => v.try_into().map(Self::Short).map_err(|_| self),
1870 TangoDataType::UShort => Ok(self),
1871 TangoDataType::Int |
1872 TangoDataType::Long => Ok(Self::Long(v as _)),
1873 TangoDataType::ULong => Ok(Self::ULong(v as _)),
1874 TangoDataType::Long64 => Ok(Self::Long64(v as _)),
1875 TangoDataType::ULong64 => Ok(Self::ULong64(v as _)),
1876 TangoDataType::Float => Ok(Self::Float(v as _)),
1877 TangoDataType::Double => Ok(Self::Double(v as _)),
1878 _ => Err(self)
1879 }
1880 Self::Long(v) => match to {
1881 TangoDataType::Boolean => check_bool(v as i64).map(Self::Boolean).map_err(|_| self),
1882 TangoDataType::UChar => v.try_into().map(Self::UChar).map_err(|_| self),
1883 TangoDataType::Short => v.try_into().map(Self::Short).map_err(|_| self),
1884 TangoDataType::UShort => v.try_into().map(Self::UShort).map_err(|_| self),
1885 TangoDataType::Int |
1886 TangoDataType::Long => Ok(self),
1887 TangoDataType::ULong => v.try_into().map(Self::ULong).map_err(|_| self),
1888 TangoDataType::Long64 => Ok(Self::Long64(v as _)),
1889 TangoDataType::ULong64 => Ok(Self::ULong64(v as _)),
1890 TangoDataType::Float => Ok(Self::Float(v as _)),
1891 TangoDataType::Double => Ok(Self::Double(v as _)),
1892 _ => Err(self)
1893 }
1894 Self::ULong(v) => match to {
1895 TangoDataType::Boolean => check_bool(v as i64).map(Self::Boolean).map_err(|_| self),
1896 TangoDataType::UChar => v.try_into().map(Self::UChar).map_err(|_| self),
1897 TangoDataType::Short => v.try_into().map(Self::Short).map_err(|_| self),
1898 TangoDataType::UShort => v.try_into().map(Self::UShort).map_err(|_| self),
1899 TangoDataType::Int |
1900 TangoDataType::Long => v.try_into().map(Self::Long).map_err(|_| self),
1901 TangoDataType::ULong => Ok(self),
1902 TangoDataType::Long64 => Ok(Self::Long64(v as _)),
1903 TangoDataType::ULong64 => Ok(Self::ULong64(v as _)),
1904 TangoDataType::Float => Ok(Self::Float(v as _)),
1905 TangoDataType::Double => Ok(Self::Double(v as _)),
1906 _ => Err(self)
1907 }
1908 Self::Long64(v) => match to {
1909 TangoDataType::Boolean => check_bool(v as i64).map(Self::Boolean).map_err(|_| self),
1910 TangoDataType::UChar => v.try_into().map(Self::UChar).map_err(|_| self),
1911 TangoDataType::Short => v.try_into().map(Self::Short).map_err(|_| self),
1912 TangoDataType::UShort => v.try_into().map(Self::UShort).map_err(|_| self),
1913 TangoDataType::Int |
1914 TangoDataType::Long => v.try_into().map(Self::Long).map_err(|_| self),
1915 TangoDataType::ULong => v.try_into().map(Self::ULong).map_err(|_| self),
1916 TangoDataType::Long64 => Ok(self),
1917 TangoDataType::ULong64 => v.try_into().map(Self::ULong64).map_err(|_| self),
1918 TangoDataType::Float => Ok(Self::Float(v as _)),
1919 TangoDataType::Double => Ok(Self::Double(v as _)),
1920 _ => Err(self)
1921 }
1922 Self::ULong64(v) => match to {
1923 TangoDataType::Boolean => check_bool(v as i64).map(Self::Boolean).map_err(|_| self),
1924 TangoDataType::UChar => v.try_into().map(Self::UChar).map_err(|_| self),
1925 TangoDataType::Short => v.try_into().map(Self::Short).map_err(|_| self),
1926 TangoDataType::UShort => v.try_into().map(Self::UShort).map_err(|_| self),
1927 TangoDataType::Int |
1928 TangoDataType::Long => v.try_into().map(Self::Long).map_err(|_| self),
1929 TangoDataType::ULong => v.try_into().map(Self::ULong).map_err(|_| self),
1930 TangoDataType::Long64 => v.try_into().map(Self::Long64).map_err(|_| self),
1931 TangoDataType::ULong64 => Ok(self),
1932 TangoDataType::Float => Ok(Self::Float(v as _)),
1933 TangoDataType::Double => Ok(Self::Double(v as _)),
1934 _ => Err(self)
1935 }
1936 Self::Float(v) => match to {
1937 TangoDataType::Float => Ok(self),
1938 TangoDataType::Double => Ok(Self::Double(v as _)),
1939 _ => Err(self)
1940 }
1941 Self::Double(v) => match to {
1942 TangoDataType::Float => Ok(Self::Float(v as _)),
1943 TangoDataType::Double => Ok(self),
1944 _ => Err(self)
1945 }
1946 Self::String(ref v) => match to {
1947 TangoDataType::ConstString |
1948 TangoDataType::String => Ok(self),
1949 TangoDataType::State => std::str::from_utf8(v).map_err(drop)
1950 .and_then(|s| s.parse())
1951 .map(Self::State)
1952 .map_err(|_| self),
1953 _ => Err(self)
1954 }
1955 Self::State(_) => match to {
1956 TangoDataType::State => Ok(self),
1957 _ => Err(self),
1958 }
1959 Self::Encoded(_) => match to {
1960 TangoDataType::Encoded => Ok(self),
1961 _ => Err(self),
1962 }
1963 Self::BooleanArray(v) => match to {
1964 TangoDataType::BooleanArray => Ok(Self::BooleanArray(v)),
1965 TangoDataType::CharArray => Ok(Self::UCharArray(v.into_iter().map(|v| v as _).collect())),
1966 TangoDataType::ShortArray => Ok(Self::ShortArray(v.into_iter().map(|v| v as _).collect())),
1967 TangoDataType::UShortArray => Ok(Self::UShortArray(v.into_iter().map(|v| v as _).collect())),
1968 TangoDataType::LongArray => Ok(Self::LongArray(v.into_iter().map(|v| v as _).collect())),
1969 TangoDataType::ULongArray => Ok(Self::ULongArray(v.into_iter().map(|v| v as _).collect())),
1970 TangoDataType::Long64Array => Ok(Self::Long64Array(v.into_iter().map(|v| v as _).collect())),
1971 TangoDataType::ULong64Array => Ok(Self::ULong64Array(v.into_iter().map(|v| v as _).collect())),
1972 TangoDataType::FloatArray => Ok(Self::FloatArray(v.into_iter().map(|v| v as i32 as _).collect())),
1973 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v.into_iter().map(|v| v as i32 as _).collect())),
1974 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
1975 _ => Err(Self::BooleanArray(v)),
1976 }
1977 Self::UCharArray(v) => match to {
1978 TangoDataType::BooleanArray if v.len() == 0 => Ok(Self::BooleanArray(vec![])),
1979 TangoDataType::CharArray => Ok(Self::UCharArray(v)),
1980 TangoDataType::ShortArray => Ok(Self::ShortArray(v.into_iter().map(|v| v as _).collect())),
1981 TangoDataType::UShortArray => Ok(Self::UShortArray(v.into_iter().map(|v| v as _).collect())),
1982 TangoDataType::LongArray => Ok(Self::LongArray(v.into_iter().map(|v| v as _).collect())),
1983 TangoDataType::ULongArray => Ok(Self::ULongArray(v.into_iter().map(|v| v as _).collect())),
1984 TangoDataType::Long64Array => Ok(Self::Long64Array(v.into_iter().map(|v| v as _).collect())),
1985 TangoDataType::ULong64Array => Ok(Self::ULong64Array(v.into_iter().map(|v| v as _).collect())),
1986 TangoDataType::FloatArray => Ok(Self::FloatArray(v.into_iter().map(|v| v as _).collect())),
1987 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v.into_iter().map(|v| v as _).collect())),
1988 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
1989 _ => Err(Self::UCharArray(v)),
1990 }
1991 Self::ShortArray(v) => match to {
1992 TangoDataType::BooleanArray if v.len() == 0 => Ok(Self::BooleanArray(vec![])),
1993 TangoDataType::CharArray => v.iter().map(|&v| v.try_into())
1994 .collect::<Result<Vec<_>, _>>()
1995 .map(Self::UCharArray)
1996 .map_err(|_| Self::ShortArray(v)),
1997 TangoDataType::ShortArray => Ok(Self::ShortArray(v)),
1998 TangoDataType::UShortArray => v.iter().map(|&v| v.try_into())
1999 .collect::<Result<Vec<_>, _>>()
2000 .map(Self::UShortArray)
2001 .map_err(|_| Self::ShortArray(v)),
2002 TangoDataType::LongArray => Ok(Self::LongArray(v.into_iter().map(|v| v as _).collect())),
2003 TangoDataType::ULongArray => Ok(Self::ULongArray(v.into_iter().map(|v| v as _).collect())),
2004 TangoDataType::Long64Array => Ok(Self::Long64Array(v.into_iter().map(|v| v as _).collect())),
2005 TangoDataType::ULong64Array => Ok(Self::ULong64Array(v.into_iter().map(|v| v as _).collect())),
2006 TangoDataType::FloatArray => Ok(Self::FloatArray(v.into_iter().map(|v| v as _).collect())),
2007 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v.into_iter().map(|v| v as _).collect())),
2008 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
2009 _ => Err(Self::ShortArray(v)),
2010 }
2011 Self::UShortArray(v) => match to {
2012 TangoDataType::BooleanArray if v.len() == 0 => Ok(Self::BooleanArray(vec![])),
2013 TangoDataType::CharArray => v.iter().map(|&v| v.try_into())
2014 .collect::<Result<Vec<_>, _>>()
2015 .map(Self::UCharArray)
2016 .map_err(|_| Self::UShortArray(v)),
2017 TangoDataType::ShortArray => v.iter().map(|&v| v.try_into())
2018 .collect::<Result<Vec<_>, _>>()
2019 .map(Self::ShortArray)
2020 .map_err(|_| Self::UShortArray(v)),
2021 TangoDataType::UShortArray => Ok(Self::UShortArray(v)),
2022 TangoDataType::LongArray => Ok(Self::LongArray(v.into_iter().map(|v| v as _).collect())),
2023 TangoDataType::ULongArray => Ok(Self::ULongArray(v.into_iter().map(|v| v as _).collect())),
2024 TangoDataType::Long64Array => Ok(Self::Long64Array(v.into_iter().map(|v| v as _).collect())),
2025 TangoDataType::ULong64Array => Ok(Self::ULong64Array(v.into_iter().map(|v| v as _).collect())),
2026 TangoDataType::FloatArray => Ok(Self::FloatArray(v.into_iter().map(|v| v as _).collect())),
2027 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v.into_iter().map(|v| v as _).collect())),
2028 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
2029 _ => Err(Self::UShortArray(v)),
2030 }
2031 Self::LongArray(v) => match to {
2032 TangoDataType::BooleanArray if v.len() == 0 => Ok(Self::BooleanArray(vec![])),
2033 TangoDataType::CharArray => v.iter().map(|&v| v.try_into())
2034 .collect::<Result<Vec<_>, _>>()
2035 .map(Self::UCharArray)
2036 .map_err(|_| Self::LongArray(v)),
2037 TangoDataType::ShortArray => v.iter().map(|&v| v.try_into())
2038 .collect::<Result<Vec<_>, _>>()
2039 .map(Self::ShortArray)
2040 .map_err(|_| Self::LongArray(v)),
2041 TangoDataType::UShortArray => v.iter().map(|&v| v.try_into())
2042 .collect::<Result<Vec<_>, _>>()
2043 .map(Self::UShortArray)
2044 .map_err(|_| Self::LongArray(v)),
2045 TangoDataType::LongArray => Ok(Self::LongArray(v)),
2046 TangoDataType::ULongArray => v.iter().map(|&v| v.try_into())
2047 .collect::<Result<Vec<_>, _>>()
2048 .map(Self::ULongArray)
2049 .map_err(|_| Self::LongArray(v)),
2050 TangoDataType::Long64Array => Ok(Self::Long64Array(v.into_iter().map(|v| v as _).collect())),
2051 TangoDataType::ULong64Array => Ok(Self::ULong64Array(v.into_iter().map(|v| v as _).collect())),
2052 TangoDataType::FloatArray => Ok(Self::FloatArray(v.into_iter().map(|v| v as _).collect())),
2053 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v.into_iter().map(|v| v as _).collect())),
2054 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
2055 _ => Err(Self::LongArray(v)),
2056 }
2057 Self::ULongArray(v) => match to {
2058 TangoDataType::BooleanArray if v.len() == 0 => Ok(Self::BooleanArray(vec![])),
2059 TangoDataType::CharArray => v.iter().map(|&v| v.try_into())
2060 .collect::<Result<Vec<_>, _>>()
2061 .map(Self::UCharArray)
2062 .map_err(|_| Self::ULongArray(v)),
2063 TangoDataType::ShortArray => v.iter().map(|&v| v.try_into())
2064 .collect::<Result<Vec<_>, _>>()
2065 .map(Self::ShortArray)
2066 .map_err(|_| Self::ULongArray(v)),
2067 TangoDataType::UShortArray => v.iter().map(|&v| v.try_into())
2068 .collect::<Result<Vec<_>, _>>()
2069 .map(Self::UShortArray)
2070 .map_err(|_| Self::ULongArray(v)),
2071 TangoDataType::LongArray => v.iter().map(|&v| v.try_into())
2072 .collect::<Result<Vec<_>, _>>()
2073 .map(Self::LongArray)
2074 .map_err(|_| Self::ULongArray(v)),
2075 TangoDataType::ULongArray => Ok(Self::ULongArray(v)),
2076 TangoDataType::Long64Array => Ok(Self::Long64Array(v.into_iter().map(|v| v as _).collect())),
2077 TangoDataType::ULong64Array => Ok(Self::ULong64Array(v.into_iter().map(|v| v as _).collect())),
2078 TangoDataType::FloatArray => Ok(Self::FloatArray(v.into_iter().map(|v| v as _).collect())),
2079 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v.into_iter().map(|v| v as _).collect())),
2080 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
2081 _ => Err(Self::ULongArray(v)),
2082 }
2083 Self::Long64Array(v) => match to {
2084 TangoDataType::BooleanArray if v.len() == 0 => Ok(Self::BooleanArray(vec![])),
2085 TangoDataType::CharArray => v.iter().map(|&v| v.try_into())
2086 .collect::<Result<Vec<_>, _>>()
2087 .map(Self::UCharArray)
2088 .map_err(|_| Self::Long64Array(v)),
2089 TangoDataType::ShortArray => v.iter().map(|&v| v.try_into())
2090 .collect::<Result<Vec<_>, _>>()
2091 .map(Self::ShortArray)
2092 .map_err(|_| Self::Long64Array(v)),
2093 TangoDataType::UShortArray => v.iter().map(|&v| v.try_into())
2094 .collect::<Result<Vec<_>, _>>()
2095 .map(Self::UShortArray)
2096 .map_err(|_| Self::Long64Array(v)),
2097 TangoDataType::LongArray => v.iter().map(|&v| v.try_into())
2098 .collect::<Result<Vec<_>, _>>()
2099 .map(Self::LongArray)
2100 .map_err(|_| Self::Long64Array(v)),
2101 TangoDataType::ULongArray => v.iter().map(|&v| v.try_into())
2102 .collect::<Result<Vec<_>, _>>()
2103 .map(Self::ULongArray)
2104 .map_err(|_| Self::Long64Array(v)),
2105 TangoDataType::Long64Array => Ok(Self::Long64Array(v)),
2106 TangoDataType::ULong64Array => v.iter().map(|&v| v.try_into())
2107 .collect::<Result<Vec<_>, _>>()
2108 .map(Self::ULong64Array)
2109 .map_err(|_| Self::Long64Array(v)),
2110 TangoDataType::FloatArray => Ok(Self::FloatArray(v.into_iter().map(|v| v as _).collect())),
2111 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v.into_iter().map(|v| v as _).collect())),
2112 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
2113 _ => Err(Self::Long64Array(v)),
2114 }
2115 Self::ULong64Array(v) => match to {
2116 TangoDataType::BooleanArray if v.len() == 0 => Ok(Self::BooleanArray(vec![])),
2117 TangoDataType::CharArray => v.iter().map(|&v| v.try_into())
2118 .collect::<Result<Vec<_>, _>>()
2119 .map(Self::UCharArray)
2120 .map_err(|_| Self::ULong64Array(v)),
2121 TangoDataType::ShortArray => v.iter().map(|&v| v.try_into())
2122 .collect::<Result<Vec<_>, _>>()
2123 .map(Self::ShortArray)
2124 .map_err(|_| Self::ULong64Array(v)),
2125 TangoDataType::UShortArray => v.iter().map(|&v| v.try_into())
2126 .collect::<Result<Vec<_>, _>>()
2127 .map(Self::UShortArray)
2128 .map_err(|_| Self::ULong64Array(v)),
2129 TangoDataType::LongArray => v.iter().map(|&v| v.try_into())
2130 .collect::<Result<Vec<_>, _>>()
2131 .map(Self::LongArray)
2132 .map_err(|_| Self::ULong64Array(v)),
2133 TangoDataType::ULongArray => v.iter().map(|&v| v.try_into())
2134 .collect::<Result<Vec<_>, _>>()
2135 .map(Self::ULongArray)
2136 .map_err(|_| Self::ULong64Array(v)),
2137 TangoDataType::Long64Array => v.iter().map(|&v| v.try_into())
2138 .collect::<Result<Vec<_>, _>>()
2139 .map(Self::Long64Array)
2140 .map_err(|_| Self::ULong64Array(v)),
2141 TangoDataType::ULong64Array => Ok(Self::ULong64Array(v)),
2142 TangoDataType::FloatArray => Ok(Self::FloatArray(v.into_iter().map(|v| v as _).collect())),
2143 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v.into_iter().map(|v| v as _).collect())),
2144 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
2145 _ => Err(Self::ULong64Array(v)),
2146 }
2147 Self::FloatArray(v) => match to {
2148 TangoDataType::BooleanArray if v.len() == 0 => Ok(Self::BooleanArray(vec![])),
2149 TangoDataType::CharArray if v.len() == 0 => Ok(Self::UCharArray(vec![])),
2150 TangoDataType::ShortArray if v.len() == 0 => Ok(Self::ShortArray(vec![])),
2151 TangoDataType::UShortArray if v.len() == 0 => Ok(Self::UShortArray(vec![])),
2152 TangoDataType::LongArray if v.len() == 0 => Ok(Self::LongArray(vec![])),
2153 TangoDataType::ULongArray if v.len() == 0 => Ok(Self::ULongArray(vec![])),
2154 TangoDataType::Long64Array if v.len() == 0 => Ok(Self::Long64Array(vec![])),
2155 TangoDataType::ULong64Array if v.len() == 0 => Ok(Self::ULong64Array(vec![])),
2156 TangoDataType::FloatArray => Ok(Self::FloatArray(v)),
2157 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v.into_iter().map(|v| v as _).collect())),
2158 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
2159 _ => Err(Self::FloatArray(v)),
2160 }
2161 Self::DoubleArray(v) => match to {
2162 TangoDataType::BooleanArray if v.len() == 0 => Ok(Self::BooleanArray(vec![])),
2163 TangoDataType::CharArray if v.len() == 0 => Ok(Self::UCharArray(vec![])),
2164 TangoDataType::ShortArray if v.len() == 0 => Ok(Self::ShortArray(vec![])),
2165 TangoDataType::UShortArray if v.len() == 0 => Ok(Self::UShortArray(vec![])),
2166 TangoDataType::LongArray if v.len() == 0 => Ok(Self::LongArray(vec![])),
2167 TangoDataType::ULongArray if v.len() == 0 => Ok(Self::ULongArray(vec![])),
2168 TangoDataType::Long64Array if v.len() == 0 => Ok(Self::Long64Array(vec![])),
2169 TangoDataType::ULong64Array if v.len() == 0 => Ok(Self::ULong64Array(vec![])),
2170 TangoDataType::FloatArray => Ok(Self::FloatArray(v.into_iter().map(|v| v as _).collect())),
2171 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v)),
2172 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
2173 _ => Err(Self::DoubleArray(v)),
2174 }
2175 Self::StringArray(v) => match to {
2176 TangoDataType::BooleanArray if v.len() == 0 => Ok(Self::BooleanArray(vec![])),
2177 TangoDataType::CharArray if v.len() == 0 => Ok(Self::UCharArray(vec![])),
2178 TangoDataType::ShortArray if v.len() == 0 => Ok(Self::ShortArray(vec![])),
2179 TangoDataType::UShortArray if v.len() == 0 => Ok(Self::UShortArray(vec![])),
2180 TangoDataType::LongArray if v.len() == 0 => Ok(Self::LongArray(vec![])),
2181 TangoDataType::ULongArray if v.len() == 0 => Ok(Self::ULongArray(vec![])),
2182 TangoDataType::Long64Array if v.len() == 0 => Ok(Self::Long64Array(vec![])),
2183 TangoDataType::ULong64Array if v.len() == 0 => Ok(Self::ULong64Array(vec![])),
2184 TangoDataType::FloatArray if v.len() == 0 => Ok(Self::FloatArray(vec![])),
2185 TangoDataType::DoubleArray if v.len() == 0 => Ok(Self::DoubleArray(vec![])),
2186 TangoDataType::StringArray => Ok(Self::StringArray(v)),
2187 _ => Err(Self::StringArray(v)),
2188 }
2189 Self::StateArray(_) | Self::EncodedArray(_) => Err(self)
2190 }
2191 }
2192
2193 pub fn into_bool(self) -> Result<bool, Self> {
2196 match self {
2197 Self::Boolean(v) => Ok(v),
2198 Self::UChar(v) => check_bool(v as i64).map_err(|_| self),
2199 Self::Short(v) => check_bool(v as i64).map_err(|_| self),
2200 Self::UShort(v) => check_bool(v as i64).map_err(|_| self),
2201 Self::Long(v) => check_bool(v as i64).map_err(|_| self),
2202 Self::ULong(v) => check_bool(v as i64).map_err(|_| self),
2203 Self::Long64(v) => check_bool(v as i64).map_err(|_| self),
2204 Self::ULong64(v) => check_bool(v as i64).map_err(|_| self),
2205 _ => Err(self),
2206 }
2207 }
2208
2209 pub fn into_i32(self) -> Result<i32, Self> {
2212 match self {
2213 Self::Boolean(v) => Ok(v as i32),
2214 Self::UChar(v) => Ok(v as i32),
2215 Self::Short(v) => Ok(v as i32),
2216 Self::UShort(v) => Ok(v as i32),
2217 Self::Long(v) => Ok(v),
2218 Self::ULong(v) => v.try_into().map_err(|_| self),
2219 Self::Long64(v) => v.try_into().map_err(|_| self),
2220 Self::ULong64(v) => v.try_into().map_err(|_| self),
2221 _ => Err(self),
2222 }
2223 }
2224
2225 pub fn into_i64(self) -> Result<i64, Self> {
2228 match self {
2229 Self::Boolean(v) => Ok(v as i64),
2230 Self::UChar(v) => Ok(v as i64),
2231 Self::Short(v) => Ok(v as i64),
2232 Self::UShort(v) => Ok(v as i64),
2233 Self::Long(v) => Ok(v as i64),
2234 Self::ULong(v) => Ok(v as i64),
2235 Self::Long64(v) => Ok(v),
2236 Self::ULong64(v) => v.try_into().map_err(|_| self),
2237 _ => Err(self),
2238 }
2239 }
2240
2241 pub fn into_u32(self) -> Result<u32, Self> {
2244 match self {
2245 Self::Boolean(v) => Ok(v as u32),
2246 Self::UChar(v) => Ok(v as u32),
2247 Self::Short(v) => Ok(v as u32),
2248 Self::UShort(v) => Ok(v as u32),
2249 Self::Long(v) => v.try_into().map_err(|_| self),
2250 Self::ULong(v) => Ok(v as u32),
2251 Self::Long64(v) => v.try_into().map_err(|_| self),
2252 Self::ULong64(v) => v.try_into().map_err(|_| self),
2253 _ => Err(self),
2254 }
2255 }
2256
2257 pub fn into_u64(self) -> Result<u64, Self> {
2260 match self {
2261 Self::Boolean(v) => Ok(v as u64),
2262 Self::UChar(v) => Ok(v as u64),
2263 Self::Short(v) => Ok(v as u64),
2264 Self::UShort(v) => Ok(v as u64),
2265 Self::Long(v) => Ok(v as u64),
2266 Self::ULong(v) => Ok(v as u64),
2267 Self::Long64(v) => v.try_into().map_err(|_| self),
2268 Self::ULong64(v) => Ok(v),
2269 _ => Err(self),
2270 }
2271 }
2272
2273 pub fn into_f32(self) -> Result<f32, Self> {
2275 match self {
2276 Self::Boolean(v) => Ok(v as i32 as f32),
2277 Self::UChar(v) => Ok(v as f32),
2278 Self::Short(v) => Ok(v as f32),
2279 Self::Long(v) => Ok(v as f32),
2280 Self::Long64(v) => Ok(v as f32),
2281 Self::UShort(v) => Ok(v as f32),
2282 Self::ULong(v) => Ok(v as f32),
2283 Self::ULong64(v) => Ok(v as f32),
2284 Self::Float(v) => Ok(v),
2285 Self::Double(v) => Ok(v as f32),
2286 _ => Err(self),
2287 }
2288 }
2289
2290 pub fn into_f64(self) -> Result<f64, Self> {
2292 match self {
2293 Self::Boolean(v) => Ok(v as i32 as f64),
2294 Self::UChar(v) => Ok(v as f64),
2295 Self::Short(v) => Ok(v as f64),
2296 Self::Long(v) => Ok(v as f64),
2297 Self::Long64(v) => Ok(v as f64),
2298 Self::UShort(v) => Ok(v as f64),
2299 Self::ULong(v) => Ok(v as f64),
2300 Self::ULong64(v) => Ok(v as f64),
2301 Self::Float(v) => Ok(v as f64),
2302 Self::Double(v) => Ok(v),
2303 _ => Err(self),
2304 }
2305 }
2306
2307 pub fn into_bytes(self) -> Result<Vec<u8>, Self> {
2310 match self {
2311 Self::String(s) => Ok(s),
2312 Self::Encoded((_, s)) => Ok(s),
2313 Self::UCharArray(s) => Ok(s),
2314 _ => Err(self),
2315 }
2316 }
2317
2318 pub fn into_string(self) -> Result<String, Self> {
2321 match self {
2322 Self::String(s) => String::from_utf8(s).map_err(
2323 |e| Self::String(e.into_bytes())),
2324 Self::Encoded((f, s)) => String::from_utf8(s).map_err(
2325 |e| Self::Encoded((f, e.into_bytes()))),
2326 Self::UCharArray(s) => String::from_utf8(s).map_err(
2327 |e| Self::String(e.into_bytes())),
2328 _ => Err(self),
2329 }
2330 }
2331}
2332
2333impl fmt::Display for AttrValue {
2334 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2335 match self {
2336 Self::Boolean(v) => fmt::Display::fmt(&v, f),
2337 Self::UChar(v) => fmt::Display::fmt(&v, f),
2338 Self::Short(v) => fmt::Display::fmt(&v, f),
2339 Self::UShort(v) => fmt::Display::fmt(&v, f),
2340 Self::Long(v) => fmt::Display::fmt(&v, f),
2341 Self::ULong(v) => fmt::Display::fmt(&v, f),
2342 Self::Long64(v) => fmt::Display::fmt(&v, f),
2343 Self::ULong64(v) => fmt::Display::fmt(&v, f),
2344 Self::Float(v) => fmt::Display::fmt(&v, f),
2345 Self::Double(v) => fmt::Display::fmt(&v, f),
2346 Self::String(v) => fmt::Display::fmt(&String::from_utf8_lossy(v), f),
2347 Self::State(v) => fmt::Display::fmt(&v, f),
2348 Self::Encoded(_) => f.pad("<DevEncoded>"),
2349
2350 Self::BooleanArray(v) => slice_display(v, |x| x, f),
2351 Self::UCharArray(v) => slice_display(v, |x| x, f),
2352 Self::ShortArray(v) => slice_display(v, |x| x, f),
2353 Self::UShortArray(v) => slice_display(v, |x| x, f),
2354 Self::LongArray(v) => slice_display(v, |x| x, f),
2355 Self::ULongArray(v) => slice_display(v, |x| x, f),
2356 Self::Long64Array(v) => slice_display(v, |x| x, f),
2357 Self::ULong64Array(v) => slice_display(v, |x| x, f),
2358 Self::FloatArray(v) => slice_display(v, |x| x, f),
2359 Self::DoubleArray(v) => slice_display(v, |x| x, f),
2360 Self::StringArray(v) => slice_display(v, |x| String::from_utf8_lossy(x), f),
2361 Self::StateArray(v) => slice_display(v, |x| x, f),
2362 Self::EncodedArray(v) => slice_display(v, |_| "<DevEncoded>", f),
2363 }
2364 }
2365}
2366
2367impl fmt::LowerHex for AttrValue {
2368 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2369 match self {
2370 Self::Boolean(v) => fmt::Display::fmt(&v, f),
2371 Self::UChar(v) => fmt::LowerHex::fmt(&v, f),
2372 Self::Short(v) => fmt::LowerHex::fmt(&v, f),
2373 Self::UShort(v) => fmt::LowerHex::fmt(&v, f),
2374 Self::Long(v) => fmt::LowerHex::fmt(&v, f),
2375 Self::ULong(v) => fmt::LowerHex::fmt(&v, f),
2376 Self::Long64(v) => fmt::LowerHex::fmt(&v, f),
2377 Self::ULong64(v) => fmt::LowerHex::fmt(&v, f),
2378 Self::Float(v) => fmt::Display::fmt(&v, f),
2379 Self::Double(v) => fmt::Display::fmt(&v, f),
2380 Self::String(v) => fmt::Display::fmt(&String::from_utf8_lossy(v), f),
2381 Self::State(v) => fmt::Display::fmt(&v, f),
2382 Self::Encoded(_) => f.pad("<DevEncoded>"),
2383
2384 Self::BooleanArray(v) => slice_display(v, |x| x, f),
2385 Self::UCharArray(v) => slice_lower_hex(v, |x| x, f),
2386 Self::ShortArray(v) => slice_lower_hex(v, |x| x, f),
2387 Self::UShortArray(v) => slice_lower_hex(v, |x| x, f),
2388 Self::LongArray(v) => slice_lower_hex(v, |x| x, f),
2389 Self::ULongArray(v) => slice_lower_hex(v, |x| x, f),
2390 Self::Long64Array(v) => slice_lower_hex(v, |x| x, f),
2391 Self::ULong64Array(v) => slice_lower_hex(v, |x| x, f),
2392 Self::FloatArray(v) => slice_display(v, |x| x, f),
2393 Self::DoubleArray(v) => slice_display(v, |x| x, f),
2394 Self::StringArray(v) => slice_display(v, |x| String::from_utf8_lossy(x), f),
2395 Self::StateArray(v) => slice_display(v, |x| x, f),
2396 Self::EncodedArray(v) => slice_display(v, |_| "<DevEncoded>", f),
2397 }
2398 }
2399}
2400
2401impl fmt::UpperHex for AttrValue {
2402 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2403 match self {
2404 Self::Boolean(v) => fmt::Display::fmt(&v, f),
2405 Self::UChar(v) => fmt::UpperHex::fmt(&v, f),
2406 Self::Short(v) => fmt::UpperHex::fmt(&v, f),
2407 Self::UShort(v) => fmt::UpperHex::fmt(&v, f),
2408 Self::Long(v) => fmt::UpperHex::fmt(&v, f),
2409 Self::ULong(v) => fmt::UpperHex::fmt(&v, f),
2410 Self::Long64(v) => fmt::UpperHex::fmt(&v, f),
2411 Self::ULong64(v) => fmt::UpperHex::fmt(&v, f),
2412 Self::Float(v) => fmt::Display::fmt(&v, f),
2413 Self::Double(v) => fmt::Display::fmt(&v, f),
2414 Self::String(v) => fmt::Display::fmt(&String::from_utf8_lossy(v), f),
2415 Self::State(v) => fmt::Display::fmt(&v, f),
2416 Self::Encoded(_) => f.pad("<DevEncoded>"),
2417
2418 Self::BooleanArray(v) => slice_display(v, |x| x, f),
2419 Self::UCharArray(v) => slice_upper_hex(v, |x| x, f),
2420 Self::ShortArray(v) => slice_upper_hex(v, |x| x, f),
2421 Self::UShortArray(v) => slice_upper_hex(v, |x| x, f),
2422 Self::LongArray(v) => slice_upper_hex(v, |x| x, f),
2423 Self::ULongArray(v) => slice_upper_hex(v, |x| x, f),
2424 Self::Long64Array(v) => slice_upper_hex(v, |x| x, f),
2425 Self::ULong64Array(v) => slice_upper_hex(v, |x| x, f),
2426 Self::FloatArray(v) => slice_display(v, |x| x, f),
2427 Self::DoubleArray(v) => slice_display(v, |x| x, f),
2428 Self::StringArray(v) => slice_display(v, |x| String::from_utf8_lossy(x), f),
2429 Self::StateArray(v) => slice_display(v, |x| x, f),
2430 Self::EncodedArray(v) => slice_display(v, |_| "<DevEncoded>", f),
2431 }
2432 }
2433}
2434
2435impl fmt::LowerExp for AttrValue {
2436 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2437 match self {
2438 Self::Boolean(v) => fmt::Display::fmt(&v, f),
2439 Self::UChar(v) => fmt::Display::fmt(&v, f),
2440 Self::Short(v) => fmt::Display::fmt(&v, f),
2441 Self::UShort(v) => fmt::Display::fmt(&v, f),
2442 Self::Long(v) => fmt::Display::fmt(&v, f),
2443 Self::ULong(v) => fmt::Display::fmt(&v, f),
2444 Self::Long64(v) => fmt::Display::fmt(&v, f),
2445 Self::ULong64(v) => fmt::Display::fmt(&v, f),
2446 Self::Float(v) => fmt::LowerExp::fmt(&v, f),
2447 Self::Double(v) => fmt::LowerExp::fmt(&v, f),
2448 Self::String(v) => fmt::Display::fmt(&String::from_utf8_lossy(v), f),
2449 Self::State(v) => fmt::Display::fmt(&v, f),
2450 Self::Encoded(_) => f.pad("<DevEncoded>"),
2451
2452 Self::BooleanArray(v) => slice_display(v, |x| x, f),
2453 Self::UCharArray(v) => slice_display(v, |x| x, f),
2454 Self::ShortArray(v) => slice_display(v, |x| x, f),
2455 Self::UShortArray(v) => slice_display(v, |x| x, f),
2456 Self::LongArray(v) => slice_display(v, |x| x, f),
2457 Self::ULongArray(v) => slice_display(v, |x| x, f),
2458 Self::Long64Array(v) => slice_display(v, |x| x, f),
2459 Self::ULong64Array(v) => slice_display(v, |x| x, f),
2460 Self::FloatArray(v) => slice_lower_exp(v, |x| x, f),
2461 Self::DoubleArray(v) => slice_lower_exp(v, |x| x, f),
2462 Self::StringArray(v) => slice_display(v, |x| String::from_utf8_lossy(x), f),
2463 Self::StateArray(v) => slice_display(v, |x| x, f),
2464 Self::EncodedArray(v) => slice_display(v, |_| "<DevEncoded>", f),
2465 }
2466 }
2467}
2468
2469impl fmt::UpperExp for AttrValue {
2470 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2471 match self {
2472 Self::Boolean(v) => fmt::Display::fmt(&v, f),
2473 Self::UChar(v) => fmt::Display::fmt(&v, f),
2474 Self::Short(v) => fmt::Display::fmt(&v, f),
2475 Self::UShort(v) => fmt::Display::fmt(&v, f),
2476 Self::Long(v) => fmt::Display::fmt(&v, f),
2477 Self::ULong(v) => fmt::Display::fmt(&v, f),
2478 Self::Long64(v) => fmt::Display::fmt(&v, f),
2479 Self::ULong64(v) => fmt::Display::fmt(&v, f),
2480 Self::Float(v) => fmt::UpperExp::fmt(&v, f),
2481 Self::Double(v) => fmt::UpperExp::fmt(&v, f),
2482 Self::String(v) => fmt::Display::fmt(&String::from_utf8_lossy(v), f),
2483 Self::State(v) => fmt::Display::fmt(&v, f),
2484 Self::Encoded(_) => f.pad("<DevEncoded>"),
2485
2486 Self::BooleanArray(v) => slice_display(v, |x| x, f),
2487 Self::UCharArray(v) => slice_display(v, |x| x, f),
2488 Self::ShortArray(v) => slice_display(v, |x| x, f),
2489 Self::UShortArray(v) => slice_display(v, |x| x, f),
2490 Self::LongArray(v) => slice_display(v, |x| x, f),
2491 Self::ULongArray(v) => slice_display(v, |x| x, f),
2492 Self::Long64Array(v) => slice_display(v, |x| x, f),
2493 Self::ULong64Array(v) => slice_display(v, |x| x, f),
2494 Self::FloatArray(v) => slice_upper_exp(v, |x| x, f),
2495 Self::DoubleArray(v) => slice_upper_exp(v, |x| x, f),
2496 Self::StringArray(v) => slice_display(v, |x| String::from_utf8_lossy(x), f),
2497 Self::StateArray(v) => slice_display(v, |x| x, f),
2498 Self::EncodedArray(v) => slice_display(v, |_| "<DevEncoded>", f),
2499 }
2500 }
2501}
2502
2503
2504#[derive(Debug, Clone, PartialEq)]
2506pub struct DbDatum {
2507 pub name: String,
2508 pub data: PropertyValue,
2509 pub wrong_data_type: bool,
2510 request_type: Option<TangoDataType>,
2511}
2512
2513impl DbDatum {
2514 pub fn new(name: &str, data: PropertyValue) -> DbDatum {
2516 DbDatum {
2517 name: name.into(),
2518 data,
2519 wrong_data_type: false,
2520 request_type: None,
2521 }
2522 }
2523
2524 pub fn for_request(name: &str, typ: TangoDataType) -> DbDatum {
2526 DbDatum {
2527 name: name.into(),
2528 data: PropertyValue::Empty,
2529 wrong_data_type: false,
2530 request_type: Some(typ),
2531 }
2532 }
2533
2534 pub fn name_only(name: &str) -> DbDatum {
2536 DbDatum {
2537 name: name.into(),
2538 data: PropertyValue::Empty,
2539 wrong_data_type: false,
2540 request_type: None
2541 }
2542 }
2543
2544 pub(crate) unsafe fn from_c(mut db_datum: c::DbDatum, free: bool) -> DbDatum {
2545 let data = if db_datum.is_empty {
2546 PropertyValue::Empty
2547 } else {
2548 let data = db_datum.prop_data;
2549 match TangoDataType::from_c(db_datum.data_type) {
2550 TangoDataType::Boolean => PropertyValue::Boolean(data.bool_val),
2551 TangoDataType::UChar => PropertyValue::UChar(data.char_val),
2552 TangoDataType::Short => PropertyValue::Short(data.short_val),
2553 TangoDataType::UShort => PropertyValue::UShort(data.ushort_val),
2554 TangoDataType::Long | TangoDataType::Int => PropertyValue::Long(data.long_val),
2555 TangoDataType::ULong => PropertyValue::ULong(data.ulong_val),
2556 TangoDataType::Long64 => PropertyValue::Long64(data.long64_val),
2557 TangoDataType::ULong64 => PropertyValue::ULong64(data.ulong64_val),
2558 TangoDataType::Float => PropertyValue::Float(data.float_val),
2559 TangoDataType::Double => PropertyValue::Double(data.double_val),
2560 TangoDataType::String | TangoDataType::ConstString => PropertyValue::String({
2561 let ptr = data.string_val;
2562 let len = libc::strlen(ptr);
2563 Vec::from(slice::from_raw_parts(ptr as *mut u8, len))
2564 }),
2565 TangoDataType::ShortArray => PropertyValue::ShortArray({
2566 let ptr = data.short_arr;
2567 Vec::from(slice::from_raw_parts(ptr.sequence, ptr.length as usize))
2568 }),
2569 TangoDataType::UShortArray => PropertyValue::UShortArray({
2570 let ptr = data.ushort_arr;
2571 Vec::from(slice::from_raw_parts(ptr.sequence, ptr.length as usize))
2572 }),
2573 TangoDataType::LongArray => PropertyValue::LongArray({
2574 let ptr = data.long_arr;
2575 Vec::from(slice::from_raw_parts(ptr.sequence, ptr.length as usize))
2576 }),
2577 TangoDataType::ULongArray => PropertyValue::ULongArray({
2578 let ptr = data.ulong_arr;
2579 Vec::from(slice::from_raw_parts(ptr.sequence, ptr.length as usize))
2580 }),
2581 TangoDataType::Long64Array => PropertyValue::Long64Array({
2582 let ptr = data.long64_arr;
2583 Vec::from(slice::from_raw_parts(ptr.sequence, ptr.length as usize))
2584 }),
2585 TangoDataType::ULong64Array => PropertyValue::ULong64Array({
2586 let ptr = data.ulong64_arr;
2587 Vec::from(slice::from_raw_parts(ptr.sequence, ptr.length as usize))
2588 }),
2589 TangoDataType::FloatArray => PropertyValue::FloatArray({
2590 let ptr = data.float_arr;
2591 Vec::from(slice::from_raw_parts(ptr.sequence, ptr.length as usize))
2592 }),
2593 TangoDataType::DoubleArray => PropertyValue::DoubleArray({
2594 let ptr = data.double_arr;
2595 Vec::from(slice::from_raw_parts(ptr.sequence, ptr.length as usize))
2596 }),
2597 TangoDataType::StringArray => PropertyValue::StringArray({
2598 let ptr = data.string_arr;
2599 let mut res = Vec::with_capacity(ptr.length as usize);
2600 for i in 0..ptr.length {
2601 let raw = *ptr.sequence.offset(i as isize);
2602 let len = libc::strlen(raw);
2603 res.push(Vec::from(slice::from_raw_parts(raw as *mut u8, len)));
2604 }
2605 res
2606 }),
2607 _ => panic!("data type {:?} not allowed for attributes", db_datum.data_type)
2608 }
2609 };
2610 let res = DbDatum {
2611 name: string_from(db_datum.property_name),
2612 data,
2613 wrong_data_type: db_datum.wrong_data_type,
2614 request_type: None,
2615 };
2616 if free {
2617 c::tango_free_DbDatum(&mut db_datum);
2618 }
2619 res
2620 }
2621
2622 pub(crate) unsafe fn into_c(self) -> (c::DbDatum, CString) {
2623 let mut content = mem::zeroed::<c::DbDatum>();
2624
2625 let name_string = cstring_from(self.name);
2628 content.property_name = name_string.as_ptr() as *mut c_char;
2629
2630 macro_rules! impl_array {
2631 ($val:ident, $alt:ident, $arr:ident, $ctype:ty) => {
2632 {
2633 let array = &mut content.prop_data.$arr;
2634 array.length = $val.len() as u32;
2635 array.sequence = Box::into_raw($val.into_boxed_slice()) as *mut $ctype;
2636 TangoDataType::$alt as u32
2637 }
2638 }
2639 }
2640
2641 if self.wrong_data_type {
2642 content.wrong_data_type = true;
2643 }
2644
2645 if let Some(typ) = self.request_type {
2646 content.data_type = typ as u32;
2647 } else {
2648 let tag = match self.data {
2649 PropertyValue::Empty => {
2650 content.is_empty = true;
2651 0
2652 }
2653 PropertyValue::Boolean(v) => {
2654 content.prop_data.bool_val = v;
2655 TangoDataType::Boolean as u32
2656 }
2657 PropertyValue::Short(v) => {
2658 content.prop_data.short_val = v;
2659 TangoDataType::Short as u32
2660 }
2661 PropertyValue::Long(v) => {
2662 content.prop_data.long_val = v;
2663 TangoDataType::Long as u32
2664 }
2665 PropertyValue::Float(v) => {
2666 content.prop_data.float_val = v;
2667 TangoDataType::Float as u32
2668 }
2669 PropertyValue::Double(v) => {
2670 content.prop_data.double_val = v;
2671 TangoDataType::Double as u32
2672 }
2673 PropertyValue::UShort(v) => {
2674 content.prop_data.ushort_val = v;
2675 TangoDataType::UShort as u32
2676 }
2677 PropertyValue::ULong(v) => {
2678 content.prop_data.ulong_val = v;
2679 TangoDataType::ULong as u32
2680 }
2681 PropertyValue::Long64(v) => {
2682 content.prop_data.long64_val = v;
2683 TangoDataType::Long64 as u32
2684 }
2685 PropertyValue::ULong64(v) => {
2686 content.prop_data.ulong64_val = v;
2687 TangoDataType::ULong64 as u32
2688 }
2689 PropertyValue::String(v) => {
2690 let cstr = cstring_from(v);
2691 content.prop_data.string_val = cstr.into_raw();
2692 TangoDataType::String as u32
2693 }
2694 PropertyValue::ShortArray(v) => impl_array!(v, ShortArray, short_arr, i16),
2695 PropertyValue::UShortArray(v) => impl_array!(v, UShortArray, ushort_arr, u16),
2696 PropertyValue::LongArray(v) => impl_array!(v, LongArray, long_arr, i32),
2697 PropertyValue::ULongArray(v) => impl_array!(v, ULongArray, ulong_arr, u32),
2698 PropertyValue::Long64Array(v) => impl_array!(v, Long64Array, long64_arr, i64),
2699 PropertyValue::ULong64Array(v) => impl_array!(v, ULong64Array, ulong64_arr, u64),
2700 PropertyValue::FloatArray(v) => impl_array!(v, FloatArray, float_arr, f32),
2701 PropertyValue::DoubleArray(v) => impl_array!(v, DoubleArray, double_arr, f64),
2702 PropertyValue::StringArray(v) => {
2703 let array = &mut content.prop_data.string_arr;
2704 let mut vec = Vec::with_capacity(v.len());
2705 array.length = v.len() as u32;
2706 for s in v.into_iter() {
2707 vec.push(cstring_from(s).into_raw());
2708 }
2709 array.sequence = Box::into_raw(vec.into_boxed_slice()) as *mut *mut c_char;
2710 TangoDataType::StringArray as u32
2711 },
2712 _ => panic!("Cannot send property value of type {:?}", self.data)
2713 };
2714 content.data_type = tag;
2715 }
2716 (content, name_string)
2717 }
2718
2719 pub(crate) unsafe fn free_c_data(db_datum: c::DbDatum) {
2720 let data = db_datum.prop_data;
2721 match TangoDataType::from_c(db_datum.data_type) {
2722 TangoDataType::Void |
2723 TangoDataType::Boolean |
2724 TangoDataType::UChar |
2725 TangoDataType::Short |
2726 TangoDataType::Long |
2727 TangoDataType::Int |
2728 TangoDataType::Float |
2729 TangoDataType::Double |
2730 TangoDataType::UShort |
2731 TangoDataType::ULong |
2732 TangoDataType::Long64 |
2733 TangoDataType::ULong64 |
2734 TangoDataType::State => {}
2735 TangoDataType::String | TangoDataType::ConstString => {
2736 drop(CString::from_raw(data.string_val));
2737 }
2738 TangoDataType::ShortArray => drop(Box::from_raw(data.short_arr.sequence)),
2739 TangoDataType::UShortArray => drop(Box::from_raw(data.ushort_arr.sequence)),
2740 TangoDataType::LongArray => drop(Box::from_raw(data.long_arr.sequence)),
2741 TangoDataType::ULongArray => drop(Box::from_raw(data.ulong_arr.sequence)),
2742 TangoDataType::Long64Array => drop(Box::from_raw(data.long64_arr.sequence)),
2743 TangoDataType::ULong64Array => drop(Box::from_raw(data.ulong64_arr.sequence)),
2744 TangoDataType::FloatArray => drop(Box::from_raw(data.float_arr.sequence)),
2745 TangoDataType::DoubleArray => drop(Box::from_raw(data.double_arr.sequence)),
2746 TangoDataType::StringArray => {
2747 for i in 0..data.string_arr.length {
2748 drop(CString::from_raw(*data.string_arr.sequence.offset(i as isize) as *mut c_char));
2749 }
2750 drop(Box::from_raw(data.string_arr.sequence));
2751 }
2752 _ => unreachable!()
2753 }
2754 }
2755}
2756
2757
2758#[derive(Debug, Clone, PartialEq)]
2762pub enum PropertyValue {
2763 Empty,
2764
2765 Boolean(bool),
2766 UChar(u8),
2767 Short(i16),
2768 UShort(u16),
2769 Long(i32),
2770 ULong(u32),
2771 Long64(i64),
2772 ULong64(u64),
2773
2774 Float(f32),
2775 Double(f64),
2776
2777 String(Vec<u8>),
2778
2779 ShortArray(Vec<i16>),
2780 UShortArray(Vec<u16>),
2781 LongArray(Vec<i32>),
2782 ULongArray(Vec<u32>),
2783 Long64Array(Vec<i64>),
2784 ULong64Array(Vec<u64>),
2785
2786 FloatArray(Vec<f32>),
2787 DoubleArray(Vec<f64>),
2788
2789 StringArray(Vec<Vec<u8>>),
2790}
2791
2792impl PropertyValue {
2793 pub fn from_str(s: &str) -> Self {
2795 Self::String(s.to_owned().into_bytes())
2796 }
2797
2798 pub fn len(&self) -> usize {
2802 match self {
2803 Self::ShortArray(a) => a.len(),
2804 Self::UShortArray(a) => a.len(),
2805 Self::LongArray(a) => a.len(),
2806 Self::ULongArray(a) => a.len(),
2807 Self::Long64Array(a) => a.len(),
2808 Self::ULong64Array(a) => a.len(),
2809 Self::FloatArray(a) => a.len(),
2810 Self::DoubleArray(a) => a.len(),
2811 Self::StringArray(a) => a.len(),
2812 Self::Empty => 0,
2813 _ => 1,
2814 }
2815 }
2816
2817 pub fn convert(self, to: TangoDataType) -> Result<Self, Self> {
2822 match self {
2823 Self::Empty => match to {
2824 TangoDataType::Void => Ok(self),
2825 _ => Err(self),
2826 }
2827 Self::Boolean(v) => match to {
2828 TangoDataType::Boolean => Ok(self),
2829 TangoDataType::UChar => Ok(Self::UChar(v as _)),
2830 TangoDataType::Short => Ok(Self::Short(v as _)),
2831 TangoDataType::UShort => Ok(Self::UShort(v as _)),
2832 TangoDataType::Int |
2833 TangoDataType::Long => Ok(Self::Long(v as _)),
2834 TangoDataType::ULong => Ok(Self::ULong(v as _)),
2835 TangoDataType::Long64 => Ok(Self::Long64(v as _)),
2836 TangoDataType::ULong64 => Ok(Self::ULong64(v as _)),
2837 TangoDataType::Float => Ok(Self::Float(v as i32 as _)),
2838 TangoDataType::Double => Ok(Self::Double(v as i32 as _)),
2839 _ => Err(self)
2840 }
2841 Self::UChar(v) => match to {
2842 TangoDataType::Boolean => check_bool(v as i64).map(Self::Boolean).map_err(|_| self),
2843 TangoDataType::UChar => Ok(self),
2844 TangoDataType::Short => Ok(Self::Short(v as _)),
2845 TangoDataType::UShort => Ok(Self::Short(v as _)),
2846 TangoDataType::Int |
2847 TangoDataType::Long => Ok(Self::Long(v as _)),
2848 TangoDataType::ULong => Ok(Self::ULong(v as _)),
2849 TangoDataType::Long64 => Ok(Self::Long64(v as _)),
2850 TangoDataType::ULong64 => Ok(Self::ULong64(v as _)),
2851 TangoDataType::Float => Ok(Self::Float(v as _)),
2852 TangoDataType::Double => Ok(Self::Double(v as _)),
2853 _ => Err(self)
2854 }
2855 Self::Short(v) => match to {
2856 TangoDataType::Boolean => check_bool(v as i64).map(Self::Boolean).map_err(|_| self),
2857 TangoDataType::UChar => v.try_into().map(Self::UChar).map_err(|_| self),
2858 TangoDataType::Short => Ok(self),
2859 TangoDataType::UShort => v.try_into().map(Self::UShort).map_err(|_| self),
2860 TangoDataType::Int |
2861 TangoDataType::Long => Ok(Self::Long(v as _)),
2862 TangoDataType::ULong => Ok(Self::ULong(v as _)),
2863 TangoDataType::Long64 => Ok(Self::Long64(v as _)),
2864 TangoDataType::ULong64 => Ok(Self::ULong64(v as _)),
2865 TangoDataType::Float => Ok(Self::Float(v as _)),
2866 TangoDataType::Double => Ok(Self::Double(v as _)),
2867 _ => Err(self)
2868 }
2869 Self::UShort(v) => match to {
2870 TangoDataType::Boolean => check_bool(v as i64).map(Self::Boolean).map_err(|_| self),
2871 TangoDataType::UChar => v.try_into().map(Self::UChar).map_err(|_| self),
2872 TangoDataType::Short => v.try_into().map(Self::Short).map_err(|_| self),
2873 TangoDataType::UShort => Ok(self),
2874 TangoDataType::Int |
2875 TangoDataType::Long => Ok(Self::Long(v as _)),
2876 TangoDataType::ULong => Ok(Self::ULong(v as _)),
2877 TangoDataType::Long64 => Ok(Self::Long64(v as _)),
2878 TangoDataType::ULong64 => Ok(Self::ULong64(v as _)),
2879 TangoDataType::Float => Ok(Self::Float(v as _)),
2880 TangoDataType::Double => Ok(Self::Double(v as _)),
2881 _ => Err(self)
2882 }
2883 Self::Long(v) => match to {
2884 TangoDataType::Boolean => check_bool(v as i64).map(Self::Boolean).map_err(|_| self),
2885 TangoDataType::UChar => v.try_into().map(Self::UChar).map_err(|_| self),
2886 TangoDataType::Short => v.try_into().map(Self::Short).map_err(|_| self),
2887 TangoDataType::UShort => v.try_into().map(Self::UShort).map_err(|_| self),
2888 TangoDataType::Int |
2889 TangoDataType::Long => Ok(self),
2890 TangoDataType::ULong => v.try_into().map(Self::ULong).map_err(|_| self),
2891 TangoDataType::Long64 => Ok(Self::Long64(v as _)),
2892 TangoDataType::ULong64 => Ok(Self::ULong64(v as _)),
2893 TangoDataType::Float => Ok(Self::Float(v as _)),
2894 TangoDataType::Double => Ok(Self::Double(v as _)),
2895 _ => Err(self)
2896 }
2897 Self::ULong(v) => match to {
2898 TangoDataType::Boolean => check_bool(v as i64).map(Self::Boolean).map_err(|_| self),
2899 TangoDataType::UChar => v.try_into().map(Self::UChar).map_err(|_| self),
2900 TangoDataType::Short => v.try_into().map(Self::Short).map_err(|_| self),
2901 TangoDataType::UShort => v.try_into().map(Self::UShort).map_err(|_| self),
2902 TangoDataType::Int |
2903 TangoDataType::Long => v.try_into().map(Self::Long).map_err(|_| self),
2904 TangoDataType::ULong => Ok(self),
2905 TangoDataType::Long64 => Ok(Self::Long64(v as _)),
2906 TangoDataType::ULong64 => Ok(Self::ULong64(v as _)),
2907 TangoDataType::Float => Ok(Self::Float(v as _)),
2908 TangoDataType::Double => Ok(Self::Double(v as _)),
2909 _ => Err(self)
2910 }
2911 Self::Long64(v) => match to {
2912 TangoDataType::Boolean => check_bool(v as i64).map(Self::Boolean).map_err(|_| self),
2913 TangoDataType::UChar => v.try_into().map(Self::UChar).map_err(|_| self),
2914 TangoDataType::Short => v.try_into().map(Self::Short).map_err(|_| self),
2915 TangoDataType::UShort => v.try_into().map(Self::UShort).map_err(|_| self),
2916 TangoDataType::Int |
2917 TangoDataType::Long => v.try_into().map(Self::Long).map_err(|_| self),
2918 TangoDataType::ULong => v.try_into().map(Self::ULong).map_err(|_| self),
2919 TangoDataType::Long64 => Ok(self),
2920 TangoDataType::ULong64 => v.try_into().map(Self::ULong64).map_err(|_| self),
2921 TangoDataType::Float => Ok(Self::Float(v as _)),
2922 TangoDataType::Double => Ok(Self::Double(v as _)),
2923 _ => Err(self)
2924 }
2925 Self::ULong64(v) => match to {
2926 TangoDataType::Boolean => check_bool(v as i64).map(Self::Boolean).map_err(|_| self),
2927 TangoDataType::UChar => v.try_into().map(Self::UChar).map_err(|_| self),
2928 TangoDataType::Short => v.try_into().map(Self::Short).map_err(|_| self),
2929 TangoDataType::UShort => v.try_into().map(Self::UShort).map_err(|_| self),
2930 TangoDataType::Int |
2931 TangoDataType::Long => v.try_into().map(Self::Long).map_err(|_| self),
2932 TangoDataType::ULong => v.try_into().map(Self::ULong).map_err(|_| self),
2933 TangoDataType::Long64 => v.try_into().map(Self::Long64).map_err(|_| self),
2934 TangoDataType::ULong64 => Ok(self),
2935 TangoDataType::Float => Ok(Self::Float(v as _)),
2936 TangoDataType::Double => Ok(Self::Double(v as _)),
2937 _ => Err(self)
2938 }
2939 Self::Float(v) => match to {
2940 TangoDataType::Float => Ok(self),
2941 TangoDataType::Double => Ok(Self::Double(v as _)),
2942 _ => Err(self)
2943 }
2944 Self::Double(v) => match to {
2945 TangoDataType::Float => Ok(Self::Float(v as _)),
2946 TangoDataType::Double => Ok(self),
2947 _ => Err(self)
2948 }
2949 Self::String(_) => match to {
2950 TangoDataType::ConstString |
2951 TangoDataType::String => Ok(self),
2952 _ => Err(self)
2953 }
2954 Self::ShortArray(v) => match to {
2955 TangoDataType::ShortArray => Ok(Self::ShortArray(v)),
2956 TangoDataType::UShortArray => v.iter().map(|&v| v.try_into())
2957 .collect::<Result<Vec<_>, _>>()
2958 .map(Self::UShortArray)
2959 .map_err(|_| Self::ShortArray(v)),
2960 TangoDataType::LongArray => Ok(Self::LongArray(v.into_iter().map(|v| v as _).collect())),
2961 TangoDataType::ULongArray => Ok(Self::ULongArray(v.into_iter().map(|v| v as _).collect())),
2962 TangoDataType::Long64Array => Ok(Self::Long64Array(v.into_iter().map(|v| v as _).collect())),
2963 TangoDataType::ULong64Array => Ok(Self::ULong64Array(v.into_iter().map(|v| v as _).collect())),
2964 TangoDataType::FloatArray => Ok(Self::FloatArray(v.into_iter().map(|v| v as _).collect())),
2965 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v.into_iter().map(|v| v as _).collect())),
2966 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
2967 _ => Err(Self::ShortArray(v)),
2968 }
2969 Self::UShortArray(v) => match to {
2970 TangoDataType::ShortArray => v.iter().map(|&v| v.try_into())
2971 .collect::<Result<Vec<_>, _>>()
2972 .map(Self::ShortArray)
2973 .map_err(|_| Self::UShortArray(v)),
2974 TangoDataType::UShortArray => Ok(Self::UShortArray(v)),
2975 TangoDataType::LongArray => Ok(Self::LongArray(v.into_iter().map(|v| v as _).collect())),
2976 TangoDataType::ULongArray => Ok(Self::ULongArray(v.into_iter().map(|v| v as _).collect())),
2977 TangoDataType::Long64Array => Ok(Self::Long64Array(v.into_iter().map(|v| v as _).collect())),
2978 TangoDataType::ULong64Array => Ok(Self::ULong64Array(v.into_iter().map(|v| v as _).collect())),
2979 TangoDataType::FloatArray => Ok(Self::FloatArray(v.into_iter().map(|v| v as _).collect())),
2980 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v.into_iter().map(|v| v as _).collect())),
2981 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
2982 _ => Err(Self::UShortArray(v)),
2983 }
2984 Self::LongArray(v) => match to {
2985 TangoDataType::ShortArray => v.iter().map(|&v| v.try_into())
2986 .collect::<Result<Vec<_>, _>>()
2987 .map(Self::ShortArray)
2988 .map_err(|_| Self::LongArray(v)),
2989 TangoDataType::UShortArray => v.iter().map(|&v| v.try_into())
2990 .collect::<Result<Vec<_>, _>>()
2991 .map(Self::UShortArray)
2992 .map_err(|_| Self::LongArray(v)),
2993 TangoDataType::LongArray => Ok(Self::LongArray(v)),
2994 TangoDataType::ULongArray => v.iter().map(|&v| v.try_into())
2995 .collect::<Result<Vec<_>, _>>()
2996 .map(Self::ULongArray)
2997 .map_err(|_| Self::LongArray(v)),
2998 TangoDataType::Long64Array => Ok(Self::Long64Array(v.into_iter().map(|v| v as _).collect())),
2999 TangoDataType::ULong64Array => Ok(Self::ULong64Array(v.into_iter().map(|v| v as _).collect())),
3000 TangoDataType::FloatArray => Ok(Self::FloatArray(v.into_iter().map(|v| v as _).collect())),
3001 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v.into_iter().map(|v| v as _).collect())),
3002 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
3003 _ => Err(Self::LongArray(v)),
3004 }
3005 Self::ULongArray(v) => match to {
3006 TangoDataType::ShortArray => v.iter().map(|&v| v.try_into())
3007 .collect::<Result<Vec<_>, _>>()
3008 .map(Self::ShortArray)
3009 .map_err(|_| Self::ULongArray(v)),
3010 TangoDataType::UShortArray => v.iter().map(|&v| v.try_into())
3011 .collect::<Result<Vec<_>, _>>()
3012 .map(Self::UShortArray)
3013 .map_err(|_| Self::ULongArray(v)),
3014 TangoDataType::LongArray => v.iter().map(|&v| v.try_into())
3015 .collect::<Result<Vec<_>, _>>()
3016 .map(Self::LongArray)
3017 .map_err(|_| Self::ULongArray(v)),
3018 TangoDataType::ULongArray => Ok(Self::ULongArray(v)),
3019 TangoDataType::Long64Array => Ok(Self::Long64Array(v.into_iter().map(|v| v as _).collect())),
3020 TangoDataType::ULong64Array => Ok(Self::ULong64Array(v.into_iter().map(|v| v as _).collect())),
3021 TangoDataType::FloatArray => Ok(Self::FloatArray(v.into_iter().map(|v| v as _).collect())),
3022 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v.into_iter().map(|v| v as _).collect())),
3023 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
3024 _ => Err(Self::ULongArray(v)),
3025 }
3026 Self::Long64Array(v) => match to {
3027 TangoDataType::ShortArray => v.iter().map(|&v| v.try_into())
3028 .collect::<Result<Vec<_>, _>>()
3029 .map(Self::ShortArray)
3030 .map_err(|_| Self::Long64Array(v)),
3031 TangoDataType::UShortArray => v.iter().map(|&v| v.try_into())
3032 .collect::<Result<Vec<_>, _>>()
3033 .map(Self::UShortArray)
3034 .map_err(|_| Self::Long64Array(v)),
3035 TangoDataType::LongArray => v.iter().map(|&v| v.try_into())
3036 .collect::<Result<Vec<_>, _>>()
3037 .map(Self::LongArray)
3038 .map_err(|_| Self::Long64Array(v)),
3039 TangoDataType::ULongArray => v.iter().map(|&v| v.try_into())
3040 .collect::<Result<Vec<_>, _>>()
3041 .map(Self::ULongArray)
3042 .map_err(|_| Self::Long64Array(v)),
3043 TangoDataType::Long64Array => Ok(Self::Long64Array(v)),
3044 TangoDataType::ULong64Array => v.iter().map(|&v| v.try_into())
3045 .collect::<Result<Vec<_>, _>>()
3046 .map(Self::ULong64Array)
3047 .map_err(|_| Self::Long64Array(v)),
3048 TangoDataType::FloatArray => Ok(Self::FloatArray(v.into_iter().map(|v| v as _).collect())),
3049 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v.into_iter().map(|v| v as _).collect())),
3050 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
3051 _ => Err(Self::Long64Array(v)),
3052 }
3053 Self::ULong64Array(v) => match to {
3054 TangoDataType::ShortArray => v.iter().map(|&v| v.try_into())
3055 .collect::<Result<Vec<_>, _>>()
3056 .map(Self::ShortArray)
3057 .map_err(|_| Self::ULong64Array(v)),
3058 TangoDataType::UShortArray => v.iter().map(|&v| v.try_into())
3059 .collect::<Result<Vec<_>, _>>()
3060 .map(Self::UShortArray)
3061 .map_err(|_| Self::ULong64Array(v)),
3062 TangoDataType::LongArray => v.iter().map(|&v| v.try_into())
3063 .collect::<Result<Vec<_>, _>>()
3064 .map(Self::LongArray)
3065 .map_err(|_| Self::ULong64Array(v)),
3066 TangoDataType::ULongArray => v.iter().map(|&v| v.try_into())
3067 .collect::<Result<Vec<_>, _>>()
3068 .map(Self::ULongArray)
3069 .map_err(|_| Self::ULong64Array(v)),
3070 TangoDataType::Long64Array => v.iter().map(|&v| v.try_into())
3071 .collect::<Result<Vec<_>, _>>()
3072 .map(Self::Long64Array)
3073 .map_err(|_| Self::ULong64Array(v)),
3074 TangoDataType::ULong64Array => Ok(Self::ULong64Array(v)),
3075 TangoDataType::FloatArray => Ok(Self::FloatArray(v.into_iter().map(|v| v as _).collect())),
3076 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v.into_iter().map(|v| v as _).collect())),
3077 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
3078 _ => Err(Self::ULong64Array(v)),
3079 }
3080 Self::FloatArray(v) => match to {
3081 TangoDataType::ShortArray if v.len() == 0 => Ok(Self::ShortArray(vec![])),
3082 TangoDataType::UShortArray if v.len() == 0 => Ok(Self::UShortArray(vec![])),
3083 TangoDataType::LongArray if v.len() == 0 => Ok(Self::LongArray(vec![])),
3084 TangoDataType::ULongArray if v.len() == 0 => Ok(Self::ULongArray(vec![])),
3085 TangoDataType::Long64Array if v.len() == 0 => Ok(Self::Long64Array(vec![])),
3086 TangoDataType::ULong64Array if v.len() == 0 => Ok(Self::ULong64Array(vec![])),
3087 TangoDataType::FloatArray => Ok(Self::FloatArray(v)),
3088 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v.into_iter().map(|v| v as _).collect())),
3089 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
3090 _ => Err(Self::FloatArray(v)),
3091 }
3092 Self::DoubleArray(v) => match to {
3093 TangoDataType::ShortArray if v.len() == 0 => Ok(Self::ShortArray(vec![])),
3094 TangoDataType::UShortArray if v.len() == 0 => Ok(Self::UShortArray(vec![])),
3095 TangoDataType::LongArray if v.len() == 0 => Ok(Self::LongArray(vec![])),
3096 TangoDataType::ULongArray if v.len() == 0 => Ok(Self::ULongArray(vec![])),
3097 TangoDataType::Long64Array if v.len() == 0 => Ok(Self::Long64Array(vec![])),
3098 TangoDataType::ULong64Array if v.len() == 0 => Ok(Self::ULong64Array(vec![])),
3099 TangoDataType::FloatArray => Ok(Self::FloatArray(v.into_iter().map(|v| v as _).collect())),
3100 TangoDataType::DoubleArray => Ok(Self::DoubleArray(v)),
3101 TangoDataType::StringArray if v.len() == 0 => Ok(Self::StringArray(vec![])),
3102 _ => Err(Self::DoubleArray(v)),
3103 }
3104 Self::StringArray(v) => match to {
3105 TangoDataType::ShortArray if v.len() == 0 => Ok(Self::ShortArray(vec![])),
3106 TangoDataType::UShortArray if v.len() == 0 => Ok(Self::UShortArray(vec![])),
3107 TangoDataType::LongArray if v.len() == 0 => Ok(Self::LongArray(vec![])),
3108 TangoDataType::ULongArray if v.len() == 0 => Ok(Self::ULongArray(vec![])),
3109 TangoDataType::Long64Array if v.len() == 0 => Ok(Self::Long64Array(vec![])),
3110 TangoDataType::ULong64Array if v.len() == 0 => Ok(Self::ULong64Array(vec![])),
3111 TangoDataType::FloatArray if v.len() == 0 => Ok(Self::FloatArray(vec![])),
3112 TangoDataType::DoubleArray if v.len() == 0 => Ok(Self::DoubleArray(vec![])),
3113 TangoDataType::StringArray => Ok(Self::StringArray(v)),
3114 _ => Err(Self::StringArray(v)),
3115 }
3116 }
3117 }
3118
3119 pub fn into_bool(self) -> Result<bool, Self> {
3122 match self {
3123 Self::Boolean(v) => Ok(v),
3124 Self::UChar(v) => check_bool(v as i64).map_err(|_| self),
3125 Self::Short(v) => check_bool(v as i64).map_err(|_| self),
3126 Self::UShort(v) => check_bool(v as i64).map_err(|_| self),
3127 Self::Long(v) => check_bool(v as i64).map_err(|_| self),
3128 Self::ULong(v) => check_bool(v as i64).map_err(|_| self),
3129 Self::Long64(v) => check_bool(v as i64).map_err(|_| self),
3130 Self::ULong64(v) => check_bool(v as i64).map_err(|_| self),
3131 _ => Err(self),
3132 }
3133 }
3134
3135 pub fn into_i32(self) -> Result<i32, Self> {
3138 match self {
3139 Self::Boolean(v) => Ok(v as i32),
3140 Self::UChar(v) => Ok(v as i32),
3141 Self::Short(v) => Ok(v as i32),
3142 Self::UShort(v) => Ok(v as i32),
3143 Self::Long(v) => Ok(v),
3144 Self::ULong(v) => v.try_into().map_err(|_| self),
3145 Self::Long64(v) => v.try_into().map_err(|_| self),
3146 Self::ULong64(v) => v.try_into().map_err(|_| self),
3147 _ => Err(self),
3148 }
3149 }
3150
3151 pub fn into_i64(self) -> Result<i64, Self> {
3154 match self {
3155 Self::Boolean(v) => Ok(v as i64),
3156 Self::UChar(v) => Ok(v as i64),
3157 Self::Short(v) => Ok(v as i64),
3158 Self::UShort(v) => Ok(v as i64),
3159 Self::Long(v) => Ok(v as i64),
3160 Self::ULong(v) => Ok(v as i64),
3161 Self::Long64(v) => Ok(v),
3162 Self::ULong64(v) => v.try_into().map_err(|_| self),
3163 _ => Err(self),
3164 }
3165 }
3166
3167 pub fn into_u32(self) -> Result<u32, Self> {
3170 match self {
3171 Self::Boolean(v) => Ok(v as u32),
3172 Self::UChar(v) => Ok(v as u32),
3173 Self::Short(v) => Ok(v as u32),
3174 Self::UShort(v) => Ok(v as u32),
3175 Self::Long(v) => v.try_into().map_err(|_| self),
3176 Self::ULong(v) => Ok(v as u32),
3177 Self::Long64(v) => v.try_into().map_err(|_| self),
3178 Self::ULong64(v) => v.try_into().map_err(|_| self),
3179 _ => Err(self),
3180 }
3181 }
3182
3183 pub fn into_u64(self) -> Result<u64, Self> {
3186 match self {
3187 Self::Boolean(v) => Ok(v as u64),
3188 Self::UChar(v) => Ok(v as u64),
3189 Self::Short(v) => Ok(v as u64),
3190 Self::UShort(v) => Ok(v as u64),
3191 Self::Long(v) => Ok(v as u64),
3192 Self::ULong(v) => Ok(v as u64),
3193 Self::Long64(v) => v.try_into().map_err(|_| self),
3194 Self::ULong64(v) => Ok(v),
3195 _ => Err(self),
3196 }
3197 }
3198
3199 pub fn into_f32(self) -> Result<f32, Self> {
3201 match self {
3202 Self::Boolean(v) => Ok(v as i32 as f32),
3203 Self::UChar(v) => Ok(v as f32),
3204 Self::Short(v) => Ok(v as f32),
3205 Self::Long(v) => Ok(v as f32),
3206 Self::Long64(v) => Ok(v as f32),
3207 Self::UShort(v) => Ok(v as f32),
3208 Self::ULong(v) => Ok(v as f32),
3209 Self::ULong64(v) => Ok(v as f32),
3210 Self::Float(v) => Ok(v),
3211 Self::Double(v) => Ok(v as f32),
3212 _ => Err(self),
3213 }
3214 }
3215
3216 pub fn into_f64(self) -> Result<f64, Self> {
3218 match self {
3219 Self::Boolean(v) => Ok(v as i32 as f64),
3220 Self::UChar(v) => Ok(v as f64),
3221 Self::Short(v) => Ok(v as f64),
3222 Self::Long(v) => Ok(v as f64),
3223 Self::Long64(v) => Ok(v as f64),
3224 Self::UShort(v) => Ok(v as f64),
3225 Self::ULong(v) => Ok(v as f64),
3226 Self::ULong64(v) => Ok(v as f64),
3227 Self::Float(v) => Ok(v as f64),
3228 Self::Double(v) => Ok(v),
3229 _ => Err(self),
3230 }
3231 }
3232
3233 pub fn into_bytes(self) -> Result<Vec<u8>, Self> {
3236 match self {
3237 Self::String(s) => Ok(s),
3238 _ => Err(self),
3239 }
3240 }
3241
3242 pub fn into_string(self) -> Result<String, Self> {
3245 match self {
3246 Self::String(s) => String::from_utf8(s).map_err(
3247 |e| Self::String(e.into_bytes())),
3248 _ => Err(self),
3249 }
3250 }
3251}
3252
3253impl fmt::Display for PropertyValue {
3254 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3255 match self {
3256 Self::Empty => f.pad("<Empty>"),
3257 Self::Boolean(v) => fmt::Display::fmt(&v, f),
3258 Self::UChar(v) => fmt::Display::fmt(&v, f),
3259 Self::Short(v) => fmt::Display::fmt(&v, f),
3260 Self::UShort(v) => fmt::Display::fmt(&v, f),
3261 Self::Long(v) => fmt::Display::fmt(&v, f),
3262 Self::ULong(v) => fmt::Display::fmt(&v, f),
3263 Self::Long64(v) => fmt::Display::fmt(&v, f),
3264 Self::ULong64(v) => fmt::Display::fmt(&v, f),
3265 Self::Float(v) => fmt::Display::fmt(&v, f),
3266 Self::Double(v) => fmt::Display::fmt(&v, f),
3267 Self::String(v) => fmt::Display::fmt(&String::from_utf8_lossy(v), f),
3268
3269 Self::ShortArray(v) => slice_display(v, |x| x, f),
3270 Self::UShortArray(v) => slice_display(v, |x| x, f),
3271 Self::LongArray(v) => slice_display(v, |x| x, f),
3272 Self::ULongArray(v) => slice_display(v, |x| x, f),
3273 Self::Long64Array(v) => slice_display(v, |x| x, f),
3274 Self::ULong64Array(v) => slice_display(v, |x| x, f),
3275 Self::FloatArray(v) => slice_display(v, |x| x, f),
3276 Self::DoubleArray(v) => slice_display(v, |x| x, f),
3277 Self::StringArray(v) => slice_display(v, |x| String::from_utf8_lossy(x), f),
3278 }
3279 }
3280}
3281
3282impl fmt::LowerHex for PropertyValue {
3283 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3284 match self {
3285 Self::Empty => f.pad("<Empty>"),
3286 Self::Boolean(v) => fmt::Display::fmt(&v, f),
3287 Self::UChar(v) => fmt::LowerHex::fmt(&v, f),
3288 Self::Short(v) => fmt::LowerHex::fmt(&v, f),
3289 Self::UShort(v) => fmt::LowerHex::fmt(&v, f),
3290 Self::Long(v) => fmt::LowerHex::fmt(&v, f),
3291 Self::ULong(v) => fmt::LowerHex::fmt(&v, f),
3292 Self::Long64(v) => fmt::LowerHex::fmt(&v, f),
3293 Self::ULong64(v) => fmt::LowerHex::fmt(&v, f),
3294 Self::Float(v) => fmt::Display::fmt(&v, f),
3295 Self::Double(v) => fmt::Display::fmt(&v, f),
3296 Self::String(v) => fmt::Display::fmt(&String::from_utf8_lossy(v), f),
3297
3298 Self::ShortArray(v) => slice_lower_hex(v, |x| x, f),
3299 Self::UShortArray(v) => slice_lower_hex(v, |x| x, f),
3300 Self::LongArray(v) => slice_lower_hex(v, |x| x, f),
3301 Self::ULongArray(v) => slice_lower_hex(v, |x| x, f),
3302 Self::Long64Array(v) => slice_lower_hex(v, |x| x, f),
3303 Self::ULong64Array(v) => slice_lower_hex(v, |x| x, f),
3304 Self::FloatArray(v) => slice_display(v, |x| x, f),
3305 Self::DoubleArray(v) => slice_display(v, |x| x, f),
3306 Self::StringArray(v) => slice_display(v, |x| String::from_utf8_lossy(x), f),
3307 }
3308 }
3309}
3310
3311impl fmt::UpperHex for PropertyValue {
3312 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3313 match self {
3314 Self::Empty => f.pad("<Empty>"),
3315 Self::Boolean(v) => fmt::Display::fmt(&v, f),
3316 Self::UChar(v) => fmt::UpperHex::fmt(&v, f),
3317 Self::Short(v) => fmt::UpperHex::fmt(&v, f),
3318 Self::UShort(v) => fmt::UpperHex::fmt(&v, f),
3319 Self::Long(v) => fmt::UpperHex::fmt(&v, f),
3320 Self::ULong(v) => fmt::UpperHex::fmt(&v, f),
3321 Self::Long64(v) => fmt::UpperHex::fmt(&v, f),
3322 Self::ULong64(v) => fmt::UpperHex::fmt(&v, f),
3323 Self::Float(v) => fmt::Display::fmt(&v, f),
3324 Self::Double(v) => fmt::Display::fmt(&v, f),
3325 Self::String(v) => fmt::Display::fmt(&String::from_utf8_lossy(v), f),
3326
3327 Self::ShortArray(v) => slice_upper_hex(v, |x| x, f),
3328 Self::UShortArray(v) => slice_upper_hex(v, |x| x, f),
3329 Self::LongArray(v) => slice_upper_hex(v, |x| x, f),
3330 Self::ULongArray(v) => slice_upper_hex(v, |x| x, f),
3331 Self::Long64Array(v) => slice_upper_hex(v, |x| x, f),
3332 Self::ULong64Array(v) => slice_upper_hex(v, |x| x, f),
3333 Self::FloatArray(v) => slice_display(v, |x| x, f),
3334 Self::DoubleArray(v) => slice_display(v, |x| x, f),
3335 Self::StringArray(v) => slice_display(v, |x| String::from_utf8_lossy(x), f),
3336 }
3337 }
3338}
3339
3340impl fmt::LowerExp for PropertyValue {
3341 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3342 match self {
3343 Self::Empty => f.pad("<Empty>"),
3344 Self::Boolean(v) => fmt::Display::fmt(&v, f),
3345 Self::UChar(v) => fmt::Display::fmt(&v, f),
3346 Self::Short(v) => fmt::Display::fmt(&v, f),
3347 Self::UShort(v) => fmt::Display::fmt(&v, f),
3348 Self::Long(v) => fmt::Display::fmt(&v, f),
3349 Self::ULong(v) => fmt::Display::fmt(&v, f),
3350 Self::Long64(v) => fmt::Display::fmt(&v, f),
3351 Self::ULong64(v) => fmt::Display::fmt(&v, f),
3352 Self::Float(v) => fmt::LowerExp::fmt(&v, f),
3353 Self::Double(v) => fmt::LowerExp::fmt(&v, f),
3354 Self::String(v) => fmt::Display::fmt(&String::from_utf8_lossy(v), f),
3355
3356 Self::ShortArray(v) => slice_display(v, |x| x, f),
3357 Self::UShortArray(v) => slice_display(v, |x| x, f),
3358 Self::LongArray(v) => slice_display(v, |x| x, f),
3359 Self::ULongArray(v) => slice_display(v, |x| x, f),
3360 Self::Long64Array(v) => slice_display(v, |x| x, f),
3361 Self::ULong64Array(v) => slice_display(v, |x| x, f),
3362 Self::FloatArray(v) => slice_lower_exp(v, |x| x, f),
3363 Self::DoubleArray(v) => slice_lower_exp(v, |x| x, f),
3364 Self::StringArray(v) => slice_display(v, |x| String::from_utf8_lossy(x), f),
3365 }
3366 }
3367}
3368
3369impl fmt::UpperExp for PropertyValue {
3370 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
3371 match self {
3372 Self::Empty => f.pad("<Empty>"),
3373 Self::Boolean(v) => fmt::Display::fmt(&v, f),
3374 Self::UChar(v) => fmt::Display::fmt(&v, f),
3375 Self::Short(v) => fmt::Display::fmt(&v, f),
3376 Self::UShort(v) => fmt::Display::fmt(&v, f),
3377 Self::Long(v) => fmt::Display::fmt(&v, f),
3378 Self::ULong(v) => fmt::Display::fmt(&v, f),
3379 Self::Long64(v) => fmt::Display::fmt(&v, f),
3380 Self::ULong64(v) => fmt::Display::fmt(&v, f),
3381 Self::Float(v) => fmt::UpperExp::fmt(&v, f),
3382 Self::Double(v) => fmt::UpperExp::fmt(&v, f),
3383 Self::String(v) => fmt::Display::fmt(&String::from_utf8_lossy(v), f),
3384
3385 Self::ShortArray(v) => slice_display(v, |x| x, f),
3386 Self::UShortArray(v) => slice_display(v, |x| x, f),
3387 Self::LongArray(v) => slice_display(v, |x| x, f),
3388 Self::ULongArray(v) => slice_display(v, |x| x, f),
3389 Self::Long64Array(v) => slice_display(v, |x| x, f),
3390 Self::ULong64Array(v) => slice_display(v, |x| x, f),
3391 Self::FloatArray(v) => slice_upper_exp(v, |x| x, f),
3392 Self::DoubleArray(v) => slice_upper_exp(v, |x| x, f),
3393 Self::StringArray(v) => slice_display(v, |x| String::from_utf8_lossy(x), f),
3394 }
3395 }
3396}
3397
3398
3399macro_rules! impl_slice_fmter {
3400 ($fn:ident, $tn:ident) => {
3401 fn $fn<'a, T, D: fmt::$tn>(slice: &'a [T], mkdisp: impl Fn(&'a T) -> D,
3402 f: &mut fmt::Formatter) -> fmt::Result {
3403 write!(f, "[")?;
3404 for (i, item) in slice.iter().enumerate() {
3405 if i != 0 {
3406 write!(f, ", ")?;
3407 }
3408 fmt::$tn::fmt(&mkdisp(item), f)?;
3409 }
3410 write!(f, "]")
3411 }
3412 }
3413}
3414
3415impl_slice_fmter!(slice_display, Display);
3416impl_slice_fmter!(slice_lower_hex, LowerHex);
3417impl_slice_fmter!(slice_upper_hex, UpperHex);
3418impl_slice_fmter!(slice_lower_exp, LowerExp);
3419impl_slice_fmter!(slice_upper_exp, UpperExp);