binaryninja/
metadata.rs

1use crate::rc::{Array, CoreArrayProvider, CoreArrayProviderInner, Guard, Ref, RefCountable};
2use crate::string::{raw_to_string, BnString, IntoCStr, IntoJson};
3use binaryninjacore_sys::*;
4use std::collections::HashMap;
5use std::fmt::{Debug, Display, Formatter};
6use std::os::raw::c_char;
7use std::slice;
8
9pub type MetadataType = BNMetadataType;
10
11pub struct Metadata {
12    pub(crate) handle: *mut BNMetadata,
13}
14
15impl Metadata {
16    pub(crate) unsafe fn from_raw(handle: *mut BNMetadata) -> Self {
17        debug_assert!(!handle.is_null());
18
19        Self { handle }
20    }
21
22    pub(crate) unsafe fn ref_from_raw(handle: *mut BNMetadata) -> Ref<Self> {
23        Ref::new(Self::from_raw(handle))
24    }
25
26    pub fn new_of_type(metadata_type: MetadataType) -> Ref<Self> {
27        unsafe { Self::ref_from_raw(BNCreateMetadataOfType(metadata_type)) }
28    }
29
30    pub fn get_type(&self) -> MetadataType {
31        unsafe { BNMetadataGetType(self.handle) }
32    }
33
34    pub fn get_boolean(&self) -> Option<bool> {
35        match self.get_type() {
36            MetadataType::BooleanDataType => Some(unsafe { BNMetadataGetBoolean(self.handle) }),
37            _ => None,
38        }
39    }
40
41    pub fn get_unsigned_integer(&self) -> Option<u64> {
42        match self.get_type() {
43            MetadataType::UnsignedIntegerDataType => {
44                Some(unsafe { BNMetadataGetUnsignedInteger(self.handle) })
45            }
46            _ => None,
47        }
48    }
49
50    pub fn get_signed_integer(&self) -> Option<i64> {
51        match self.get_type() {
52            MetadataType::SignedIntegerDataType => {
53                Some(unsafe { BNMetadataGetSignedInteger(self.handle) })
54            }
55            _ => None,
56        }
57    }
58
59    pub fn get_double(&self) -> Option<f64> {
60        match self.get_type() {
61            MetadataType::DoubleDataType => Some(unsafe { BNMetadataGetDouble(self.handle) }),
62            _ => None,
63        }
64    }
65
66    pub fn get_string(&self) -> Option<BnString> {
67        match self.get_type() {
68            MetadataType::StringDataType => {
69                let ptr: *mut c_char = unsafe { BNMetadataGetString(self.handle) };
70                if ptr.is_null() {
71                    return None;
72                }
73                Some(unsafe { BnString::from_raw(ptr) })
74            }
75            _ => None,
76        }
77    }
78
79    pub fn get_boolean_list(&self) -> Option<Vec<bool>> {
80        match self.get_type() {
81            MetadataType::ArrayDataType => {
82                let mut size: usize = 0;
83                let ptr: *mut bool = unsafe { BNMetadataGetBooleanList(self.handle, &mut size) };
84                if ptr.is_null() {
85                    return None;
86                }
87                let list = unsafe { slice::from_raw_parts(ptr, size) };
88                let vec = Vec::from(list);
89                unsafe { BNFreeMetadataBooleanList(ptr, size) };
90                Some(vec)
91            }
92            _ => None,
93        }
94    }
95
96    pub fn get_unsigned_integer_list(&self) -> Option<Vec<u64>> {
97        match self.get_type() {
98            MetadataType::ArrayDataType => {
99                let mut size: usize = 0;
100                let ptr: *mut u64 =
101                    unsafe { BNMetadataGetUnsignedIntegerList(self.handle, &mut size) };
102                if ptr.is_null() {
103                    return None;
104                }
105                let list = unsafe { slice::from_raw_parts(ptr, size) };
106                let vec = Vec::from(list);
107                unsafe { BNFreeMetadataUnsignedIntegerList(ptr, size) };
108                Some(vec)
109            }
110            _ => None,
111        }
112    }
113
114    pub fn get_signed_integer_list(&self) -> Option<Vec<i64>> {
115        match self.get_type() {
116            MetadataType::ArrayDataType => {
117                let mut size: usize = 0;
118                let ptr: *mut i64 =
119                    unsafe { BNMetadataGetSignedIntegerList(self.handle, &mut size) };
120                if ptr.is_null() {
121                    return None;
122                }
123                let list = unsafe { slice::from_raw_parts(ptr, size) };
124                let vec = Vec::from(list);
125                unsafe { BNFreeMetadataSignedIntegerList(ptr, size) };
126                Some(vec)
127            }
128            _ => None,
129        }
130    }
131
132    pub fn get_double_list(&self) -> Option<Vec<f64>> {
133        match self.get_type() {
134            MetadataType::ArrayDataType => {
135                let mut size: usize = 0;
136                let ptr: *mut f64 = unsafe { BNMetadataGetDoubleList(self.handle, &mut size) };
137                if ptr.is_null() {
138                    return None;
139                }
140                let list = unsafe { slice::from_raw_parts(ptr, size) };
141                let vec = Vec::from(list);
142                unsafe { BNFreeMetadataDoubleList(ptr, size) };
143                Some(vec)
144            }
145            _ => None,
146        }
147    }
148
149    pub fn get_string_list(&self) -> Option<Vec<BnString>> {
150        match self.get_type() {
151            MetadataType::ArrayDataType => {
152                let mut size: usize = 0;
153                let ptr: *mut *mut c_char =
154                    unsafe { BNMetadataGetStringList(self.handle, &mut size) };
155                if ptr.is_null() {
156                    return None;
157                }
158                let list = unsafe { slice::from_raw_parts(ptr, size) };
159                let vec = list
160                    .iter()
161                    .map(|ptr| unsafe { BnString::from_raw(*ptr) })
162                    .collect::<Vec<_>>();
163                unsafe { BNFreeMetadataStringList(ptr, size) };
164                Some(vec)
165            }
166            _ => None,
167        }
168    }
169
170    pub fn get_json_string(&self) -> Option<BnString> {
171        match self.get_type() {
172            MetadataType::StringDataType => {
173                let ptr: *mut c_char = unsafe { BNMetadataGetJsonString(self.handle) };
174                if ptr.is_null() {
175                    return None;
176                }
177                Some(unsafe { BnString::from_raw(ptr) })
178            }
179            _ => None,
180        }
181    }
182
183    pub fn get_raw(&self) -> Option<Vec<u8>> {
184        match self.get_type() {
185            MetadataType::RawDataType => {
186                let mut size: usize = 0;
187                let ptr: *mut u8 = unsafe { BNMetadataGetRaw(self.handle, &mut size) };
188                if ptr.is_null() {
189                    return None;
190                }
191
192                let list = unsafe { slice::from_raw_parts(ptr, size) };
193                let vec = Vec::from(list);
194                unsafe { BNFreeMetadataRaw(ptr) };
195                Some(vec)
196            }
197            _ => None,
198        }
199    }
200
201    pub fn get_array(&self) -> Option<Array<Metadata>> {
202        match self.get_type() {
203            MetadataType::ArrayDataType => {
204                let mut size: usize = 0;
205                let ptr: *mut *mut BNMetadata =
206                    unsafe { BNMetadataGetArray(self.handle, &mut size) };
207                if ptr.is_null() {
208                    return None;
209                }
210
211                Some(unsafe { Array::new(ptr, size, ()) })
212            }
213            _ => None,
214        }
215    }
216
217    pub fn get_value_store(&self) -> Option<HashMap<String, Ref<Metadata>>> {
218        match self.get_type() {
219            MetadataType::KeyValueDataType => {
220                let ptr: *mut BNMetadataValueStore =
221                    unsafe { BNMetadataGetValueStore(self.handle) };
222                if ptr.is_null() {
223                    return None;
224                }
225
226                let size = unsafe { (*ptr).size };
227                let keys_ptr: *mut *mut c_char = unsafe { (*ptr).keys };
228                let keys = unsafe { slice::from_raw_parts(keys_ptr, size) };
229                let values_ptr: *mut *mut BNMetadata = unsafe { (*ptr).values };
230                let values: &[*mut BNMetadata] = unsafe { slice::from_raw_parts(values_ptr, size) };
231
232                let mut map = HashMap::new();
233                for i in 0..size {
234                    let key = raw_to_string(keys[i]).unwrap();
235                    let value = unsafe { Ref::<Metadata>::new(Self { handle: values[i] }) };
236                    map.insert(key, value);
237                }
238
239                unsafe { BNFreeMetadataValueStore(ptr) };
240
241                Some(map)
242            }
243            _ => None,
244        }
245    }
246
247    pub fn len(&self) -> usize {
248        unsafe { BNMetadataSize(self.handle) }
249    }
250
251    pub fn is_empty(&self) -> bool {
252        unsafe { BNMetadataSize(self.handle) == 0 }
253    }
254
255    pub fn index(&self, index: usize) -> Result<Option<Ref<Metadata>>, ()> {
256        if self.get_type() != MetadataType::ArrayDataType {
257            return Err(());
258        }
259        let ptr: *mut BNMetadata = unsafe { BNMetadataGetForIndex(self.handle, index) };
260        if ptr.is_null() {
261            return Ok(None);
262        }
263        Ok(Some(unsafe { Self::ref_from_raw(ptr) }))
264    }
265
266    pub fn get(&self, key: &str) -> Result<Option<Ref<Metadata>>, ()> {
267        if self.get_type() != MetadataType::KeyValueDataType {
268            return Err(());
269        }
270        let raw_key = key.to_cstr();
271        let ptr: *mut BNMetadata = unsafe { BNMetadataGetForKey(self.handle, raw_key.as_ptr()) };
272        if ptr.is_null() {
273            return Ok(None);
274        }
275        Ok(Some(unsafe { Self::ref_from_raw(ptr) }))
276    }
277
278    pub fn push(&self, value: &Metadata) -> Result<(), ()> {
279        if self.get_type() != MetadataType::ArrayDataType {
280            return Err(());
281        }
282        unsafe { BNMetadataArrayAppend(self.handle, value.handle) };
283        Ok(())
284    }
285
286    pub fn insert(&self, key: &str, value: &Metadata) -> Result<(), ()> {
287        if self.get_type() != MetadataType::KeyValueDataType {
288            return Err(());
289        }
290        let raw_key = key.to_cstr();
291        unsafe { BNMetadataSetValueForKey(self.handle, raw_key.as_ptr(), value.handle) };
292        Ok(())
293    }
294
295    pub fn remove_index(&self, index: usize) -> Result<(), ()> {
296        if self.get_type() != MetadataType::ArrayDataType {
297            return Err(());
298        }
299
300        unsafe { BNMetadataRemoveIndex(self.handle, index) };
301        Ok(())
302    }
303
304    pub fn remove_key(&self, key: &str) -> Result<(), ()> {
305        if self.get_type() != MetadataType::KeyValueDataType {
306            return Err(());
307        }
308
309        let raw_key = key.to_cstr();
310        unsafe { BNMetadataRemoveKey(self.handle, raw_key.as_ptr()) };
311        Ok(())
312    }
313}
314
315impl Debug for Metadata {
316    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
317        f.debug_struct("Metadata")
318            .field("type", &self.get_type())
319            .field("len", &self.len())
320            // Display will give you the metadata value as a string.
321            .field("value", &self.to_string())
322            .finish()
323    }
324}
325
326impl Display for Metadata {
327    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
328        // Display will give you the metadata value as a string.
329        match self.get_type() {
330            MetadataType::BooleanDataType => match self.get_boolean() {
331                Some(val) => write!(f, "{}", val),
332                None => write!(f, "null"),
333            },
334            MetadataType::UnsignedIntegerDataType => match self.get_unsigned_integer() {
335                Some(val) => write!(f, "{}", val),
336                None => write!(f, "null"),
337            },
338            MetadataType::SignedIntegerDataType => match self.get_signed_integer() {
339                Some(val) => write!(f, "{}", val),
340                None => write!(f, "null"),
341            },
342            MetadataType::DoubleDataType => match self.get_double() {
343                Some(val) => write!(f, "{}", val),
344                None => write!(f, "null"),
345            },
346            MetadataType::StringDataType => match self.get_string() {
347                Some(val) => write!(f, "{}", val.to_string_lossy()),
348                None => write!(f, "null"),
349            },
350            MetadataType::ArrayDataType => {
351                match self.get_array() {
352                    Some(array) => {
353                        // TODO: This is extremely ugly
354                        write!(f, "[")?;
355                        for (i, val) in array.iter().enumerate() {
356                            if i > 0 {
357                                write!(f, ", ")?;
358                            }
359                            write!(f, "{}", *val)?;
360                        }
361                        write!(f, "]")?;
362                        Ok(())
363                    }
364                    None => write!(f, "null"),
365                }
366            }
367            MetadataType::InvalidDataType => {
368                write!(f, "null")
369            }
370            MetadataType::KeyValueDataType => match self.get_value_store() {
371                Some(map) => {
372                    write!(f, "{{")?;
373                    for (i, (key, val)) in map.iter().enumerate() {
374                        if i > 0 {
375                            write!(f, ", ")?;
376                        }
377                        write!(f, "{}: {}", key, val)?;
378                    }
379                    write!(f, "}}")?;
380                    Ok(())
381                }
382                None => write!(f, "null"),
383            },
384            MetadataType::RawDataType => match self.get_raw() {
385                Some(val) => write!(f, "{:x?}", val),
386                None => write!(f, "null"),
387            },
388        }
389    }
390}
391
392unsafe impl Sync for Metadata {}
393unsafe impl Send for Metadata {}
394
395unsafe impl RefCountable for Metadata {
396    unsafe fn inc_ref(handle: &Self) -> Ref<Self> {
397        Ref::new(Self {
398            handle: BNNewMetadataReference(handle.handle),
399        })
400    }
401
402    unsafe fn dec_ref(handle: &Self) {
403        BNFreeMetadata(handle.handle);
404    }
405}
406
407impl CoreArrayProvider for Metadata {
408    type Raw = *mut BNMetadata;
409    type Context = ();
410    type Wrapped<'a> = Guard<'a, Metadata>;
411}
412
413unsafe impl CoreArrayProviderInner for Metadata {
414    unsafe fn free(raw: *mut Self::Raw, _count: usize, _context: &Self::Context) {
415        // TODO: `count` is not passed into the core here...
416        BNFreeMetadataArray(raw);
417    }
418
419    unsafe fn wrap_raw<'a>(raw: &'a Self::Raw, context: &'a Self::Context) -> Self::Wrapped<'a> {
420        Guard::new(Self::from_raw(*raw), context)
421    }
422}
423
424impl ToOwned for Metadata {
425    type Owned = Ref<Self>;
426
427    fn to_owned(&self) -> Self::Owned {
428        unsafe { RefCountable::inc_ref(self) }
429    }
430}
431
432impl From<bool> for Ref<Metadata> {
433    fn from(value: bool) -> Self {
434        unsafe { Metadata::ref_from_raw(BNCreateMetadataBooleanData(value)) }
435    }
436}
437
438impl From<u64> for Ref<Metadata> {
439    fn from(value: u64) -> Self {
440        unsafe { Metadata::ref_from_raw(BNCreateMetadataUnsignedIntegerData(value)) }
441    }
442}
443
444impl From<i64> for Ref<Metadata> {
445    fn from(value: i64) -> Self {
446        unsafe { Metadata::ref_from_raw(BNCreateMetadataSignedIntegerData(value)) }
447    }
448}
449
450impl From<f64> for Ref<Metadata> {
451    fn from(value: f64) -> Self {
452        unsafe { Metadata::ref_from_raw(BNCreateMetadataDoubleData(value)) }
453    }
454}
455
456impl From<String> for Ref<Metadata> {
457    fn from(value: String) -> Self {
458        let raw_value = value.to_cstr();
459        unsafe { Metadata::ref_from_raw(BNCreateMetadataStringData(raw_value.as_ptr())) }
460    }
461}
462
463impl From<&str> for Ref<Metadata> {
464    fn from(value: &str) -> Self {
465        let raw_value = value.to_cstr();
466        unsafe { Metadata::ref_from_raw(BNCreateMetadataStringData(raw_value.as_ptr())) }
467    }
468}
469
470impl From<&Vec<u8>> for Ref<Metadata> {
471    fn from(value: &Vec<u8>) -> Self {
472        unsafe { Metadata::ref_from_raw(BNCreateMetadataRawData(value.as_ptr(), value.len())) }
473    }
474}
475
476impl From<&Vec<Ref<Metadata>>> for Ref<Metadata> {
477    fn from(value: &Vec<Ref<Metadata>>) -> Self {
478        let mut pointers: Vec<*mut BNMetadata> = vec![];
479        for v in value.iter() {
480            pointers.push(v.as_ref().handle);
481        }
482        unsafe {
483            Metadata::ref_from_raw(BNCreateMetadataArray(pointers.as_mut_ptr(), pointers.len()))
484        }
485    }
486}
487
488impl From<&Array<Metadata>> for Ref<Metadata> {
489    fn from(value: &Array<Metadata>) -> Self {
490        let mut pointers: Vec<*mut BNMetadata> = vec![];
491        for v in value.iter() {
492            pointers.push(v.as_ref().handle);
493        }
494        unsafe {
495            Metadata::ref_from_raw(BNCreateMetadataArray(pointers.as_mut_ptr(), pointers.len()))
496        }
497    }
498}
499
500impl<S: IntoCStr, T: Into<Ref<Metadata>>> From<HashMap<S, T>> for Ref<Metadata> {
501    fn from(value: HashMap<S, T>) -> Self {
502        let data: Vec<(S::Result, Ref<Metadata>)> = value
503            .into_iter()
504            .map(|(k, v)| (k.to_cstr(), v.into()))
505            .collect();
506        let mut keys: Vec<*const c_char> = data.iter().map(|(k, _)| k.as_ptr()).collect();
507        let mut values: Vec<*mut BNMetadata> = data.iter().map(|(_, v)| v.handle).collect();
508
509        unsafe {
510            Metadata::ref_from_raw(BNCreateMetadataValueStore(
511                keys.as_mut_ptr(),
512                values.as_mut_ptr(),
513                keys.len(),
514            ))
515        }
516    }
517}
518
519impl<S, T> From<&[(S, T)]> for Ref<Metadata>
520where
521    S: IntoCStr + Copy,
522    for<'a> &'a T: Into<Ref<Metadata>>,
523{
524    fn from(value: &[(S, T)]) -> Self {
525        let data: Vec<(S::Result, Ref<Metadata>)> =
526            value.iter().map(|(k, v)| (k.to_cstr(), v.into())).collect();
527        let mut keys: Vec<*const c_char> = data.iter().map(|(k, _)| k.as_ptr()).collect();
528        let mut values: Vec<*mut BNMetadata> = data.iter().map(|(_, v)| v.handle).collect();
529
530        unsafe {
531            Metadata::ref_from_raw(BNCreateMetadataValueStore(
532                keys.as_mut_ptr(),
533                values.as_mut_ptr(),
534                keys.len(),
535            ))
536        }
537    }
538}
539
540impl<S, T, const N: usize> From<[(S, T); N]> for Ref<Metadata>
541where
542    S: IntoCStr + Copy,
543    for<'a> &'a T: Into<Ref<Metadata>>,
544{
545    fn from(value: [(S, T); N]) -> Self {
546        let slice = &value[..];
547        // use the `impl From<&[(S, T)]>`
548        slice.into()
549    }
550}
551
552impl From<&Vec<bool>> for Ref<Metadata> {
553    fn from(value: &Vec<bool>) -> Self {
554        unsafe {
555            Metadata::ref_from_raw(BNCreateMetadataBooleanListData(
556                value.as_ptr() as *mut bool,
557                value.len(),
558            ))
559        }
560    }
561}
562
563impl From<&Vec<u64>> for Ref<Metadata> {
564    fn from(value: &Vec<u64>) -> Self {
565        unsafe {
566            Metadata::ref_from_raw(BNCreateMetadataUnsignedIntegerListData(
567                value.as_ptr() as *mut u64,
568                value.len(),
569            ))
570        }
571    }
572}
573
574impl From<&Vec<i64>> for Ref<Metadata> {
575    fn from(value: &Vec<i64>) -> Self {
576        unsafe {
577            Metadata::ref_from_raw(BNCreateMetadataSignedIntegerListData(
578                value.as_ptr() as *mut i64,
579                value.len(),
580            ))
581        }
582    }
583}
584
585impl From<&Vec<f64>> for Ref<Metadata> {
586    fn from(value: &Vec<f64>) -> Self {
587        unsafe {
588            Metadata::ref_from_raw(BNCreateMetadataDoubleListData(
589                value.as_ptr() as *mut f64,
590                value.len(),
591            ))
592        }
593    }
594}
595
596impl<S: IntoCStr> From<Vec<S>> for Ref<Metadata> {
597    fn from(value: Vec<S>) -> Self {
598        let mut refs = vec![];
599        for v in value {
600            refs.push(v.to_cstr());
601        }
602        let mut pointers = vec![];
603        for r in &refs {
604            pointers.push(r.as_ptr());
605        }
606        unsafe {
607            Metadata::ref_from_raw(BNCreateMetadataStringListData(
608                pointers.as_ptr() as *mut *const c_char,
609                pointers.len(),
610            ))
611        }
612    }
613}
614
615impl PartialEq for Metadata {
616    fn eq(&self, other: &Self) -> bool {
617        unsafe { BNMetadataIsEqual(self.handle, other.handle) }
618    }
619}
620
621impl Eq for Ref<Metadata> {}
622
623impl TryFrom<&Metadata> for bool {
624    type Error = ();
625
626    fn try_from(value: &Metadata) -> Result<Self, Self::Error> {
627        value.get_boolean().ok_or(())
628    }
629}
630
631impl TryFrom<&Metadata> for u64 {
632    type Error = ();
633
634    fn try_from(value: &Metadata) -> Result<Self, Self::Error> {
635        value.get_unsigned_integer().ok_or(())
636    }
637}
638
639impl TryFrom<&Metadata> for i64 {
640    type Error = ();
641
642    fn try_from(value: &Metadata) -> Result<Self, Self::Error> {
643        value.get_signed_integer().ok_or(())
644    }
645}
646
647impl TryFrom<&Metadata> for f64 {
648    type Error = ();
649
650    fn try_from(value: &Metadata) -> Result<Self, Self::Error> {
651        value.get_double().ok_or(())
652    }
653}
654
655impl TryFrom<&Metadata> for BnString {
656    type Error = ();
657
658    fn try_from(value: &Metadata) -> Result<Self, Self::Error> {
659        value.get_string().ok_or(())
660    }
661}
662
663impl TryFrom<&Metadata> for String {
664    type Error = ();
665
666    fn try_from(value: &Metadata) -> Result<Self, Self::Error> {
667        value
668            .get_string()
669            .map(|s| s.to_string_lossy().to_string())
670            .ok_or(())
671    }
672}
673
674impl TryFrom<&Metadata> for Vec<bool> {
675    type Error = ();
676
677    fn try_from(value: &Metadata) -> Result<Self, Self::Error> {
678        value.get_boolean_list().ok_or(())
679    }
680}
681
682impl TryFrom<&Metadata> for Vec<u64> {
683    type Error = ();
684
685    fn try_from(value: &Metadata) -> Result<Self, Self::Error> {
686        value.get_unsigned_integer_list().ok_or(())
687    }
688}
689
690impl TryFrom<&Metadata> for Vec<i64> {
691    type Error = ();
692
693    fn try_from(value: &Metadata) -> Result<Self, Self::Error> {
694        value.get_signed_integer_list().ok_or(())
695    }
696}
697
698impl TryFrom<&Metadata> for Vec<f64> {
699    type Error = ();
700
701    fn try_from(value: &Metadata) -> Result<Self, Self::Error> {
702        value.get_double_list().ok_or(())
703    }
704}
705
706impl TryFrom<&Metadata> for Vec<BnString> {
707    type Error = ();
708
709    fn try_from(value: &Metadata) -> Result<Self, Self::Error> {
710        value.get_string_list().ok_or(())
711    }
712}
713
714impl TryFrom<&Metadata> for Vec<String> {
715    type Error = ();
716
717    fn try_from(value: &Metadata) -> Result<Self, Self::Error> {
718        value
719            .get_string_list()
720            .map(|v| {
721                v.into_iter()
722                    .map(|s| s.to_string_lossy().to_string())
723                    .collect()
724            })
725            .ok_or(())
726    }
727}
728
729impl TryFrom<&Metadata> for Vec<u8> {
730    type Error = ();
731
732    fn try_from(value: &Metadata) -> Result<Self, Self::Error> {
733        value.get_raw().ok_or(())
734    }
735}
736
737impl TryFrom<&Metadata> for Array<Metadata> {
738    type Error = ();
739
740    fn try_from(value: &Metadata) -> Result<Self, Self::Error> {
741        value.get_array().ok_or(())
742    }
743}
744
745impl TryFrom<&Metadata> for HashMap<String, Ref<Metadata>> {
746    type Error = ();
747
748    fn try_from(value: &Metadata) -> Result<Self, Self::Error> {
749        value.get_value_store().ok_or(())
750    }
751}
752
753impl IntoJson for &Metadata {
754    type Output = BnString;
755    fn get_json_string(self) -> Result<BnString, ()> {
756        Metadata::get_json_string(self).ok_or(())
757    }
758}
759
760impl IntoJson for Ref<Metadata> {
761    type Output = BnString;
762    fn get_json_string(self) -> Result<BnString, ()> {
763        Metadata::get_json_string(&self).ok_or(())
764    }
765}