Skip to main content

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