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
use std::collections::HashMap;

use libc::c_void;
use serde::Serialize;

use self::ffi::map_new;

use super::{go_type::FFIError, util::ref_free_drop};

pub mod ffi {
    use crate::{util::{util::{ffi::FfiNosqldbPtrAndErrorNewReturn, c_char_to_str}, go_type::{FFIError, GoString}}, str_to_gostr};

    use super::GoMap;

    extern "C" {
        fn ffi_map_new(json: GoString) -> FfiNosqldbPtrAndErrorNewReturn;
    }

    pub fn map_new(json: String) -> Result<GoMap, FFIError> {
        str_to_gostr!(json);
        let FfiNosqldbPtrAndErrorNewReturn{ ptr: go_map_ptr, go_error_ptr } = unsafe{ ffi_map_new(json) };
        if go_error_ptr.is_null() {
            Ok(GoMap { go_map_ptr })
        } else {
            Err(FFIError::GoError(c_char_to_str(go_error_ptr)?))
        }
    }
}

#[derive(Debug)]
pub struct GoMap {
    pub(crate) go_map_ptr: *const c_void
}

impl GoMap {
    pub fn from_hash_map<T: AsRef<str> + Serialize, V: Serialize> (map: HashMap<T, V>) -> Result<Self, FFIError> {
        match serde_json::to_string::<HashMap<T, V>>(&map) {
            Ok(json) => {
                map_new(json)
            }
            Err(e) => {
                Err(FFIError::OtherError(e.to_string()))
            }
        }
    }
}

impl Drop for GoMap {
    fn drop(&mut self) {
        ref_free_drop(self.go_map_ptr);
    }
}