1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//! uuid type

use crate::{
    ffi::{DartCObject, DartHandleFinalizer, DartTypedDataType},
    into_dart::{free_zero_copy_buffer_u8, DartTypedDataTypeTrait},
    IntoDart,
};

impl IntoDart for uuid::Uuid {
    /// delegate to `Vec<u8>` implementation
    ///
    /// on the other side of FFI, value should be reconstructed like:
    ///
    /// - hydrate into Dart [UuidValue](https://pub.dev/documentation/uuid/latest/uuid/UuidValue-class.html)
    ///   `UuidValue.fromByteList(raw);`
    ///
    /// - hydrate into Rust [Uuid](uuid::Uuid)
    ///   ```rust,ignore
    ///   uuid::Uuid::from_bytes(*<&[u8] as std::convert::TryInto<&[u8;16]>>::try_into(raw.as_slice()).expect("invalid uuid slice"));
    ///   ```
    fn into_dart(self) -> DartCObject {
        self.as_bytes().to_vec().into_dart()
    }
}

impl IntoDart for Vec<uuid::Uuid> {
    /// ⚠️ concatenated in a single `Vec<u8>` for performance optimization
    ///
    /// on the other side of FFI, value should be reconstructed like:
    ///
    /// - hydrate into Dart List<[UuidValue](https://pub.dev/documentation/uuid/latest/uuid/UuidValue-class.html)>
    ///   ```dart
    ///   return List<UuidValue>.generate(
    ///     raw.lengthInBytes / 16,
    ///     (int i) => UuidValue.fromByteList(Uint8List.view(raw.buffer, i * 16, 16)),
    ///     growable: false);
    ///   ```
    ///
    /// - hydrate into Rust Vec<[Uuid](uuid::Uuid)>
    ///   ```rust,ignore
    ///   raw
    ///   .as_slice()
    ///   .chunks(16)
    ///   .map(|x: &[u8]| uuid::Uuid::from_bytes(*<&[u8] as std::convert::TryInto<&[u8;16]>>::try_into(x).expect("invalid uuid slice")))
    ///   .collect();
    ///   ```
    ///
    /// note that buffer could end up being incomplete under the same conditions as of [std::io::Write::write](https://doc.rust-lang.org/std/io/trait.Write.html#tymethod.write).
    fn into_dart(self) -> DartCObject {
        use std::io::Write;
        let mut buffer = Vec::<u8>::with_capacity(self.len() * 16);
        for id in self {
            let _ = buffer.write(id.as_bytes());
        }
        buffer.into_dart()
    }
}

impl<const N: usize> IntoDart for [uuid::Uuid; N] {
    fn into_dart(self) -> DartCObject {
        let vec: Vec<_> = self.into();
        vec.into_dart()
    }
}

impl DartTypedDataTypeTrait for uuid::Uuid {
    fn dart_typed_data_type() -> DartTypedDataType {
        DartTypedDataType::Uint8
    }

    fn function_pointer_of_free_zero_copy_buffer() -> DartHandleFinalizer {
        free_zero_copy_buffer_u8
    }
}