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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
use crate::contact::group::Group;
use crate::message;
use crate::plugin::cast_ref;
use atri_ffi::error::FFIResult;
use atri_ffi::ffi::ForFFI;
use atri_ffi::future::FFIFuture;
use atri_ffi::message::FFIMessageChain;
use atri_ffi::{Managed, ManagedCloneable, RustStr, RustVec};

pub extern "C" fn group_get_id(group: *const ()) -> i64 {
    let group: &Group = cast_ref(group);
    group.id()
}

pub extern "C" fn group_get_name(group: *const ()) -> RustStr {
    let group: &Group = cast_ref(group);
    let s = group.name();
    RustStr::from(s)
}

pub extern "C" fn group_get_client(group: *const ()) -> ManagedCloneable {
    let group: &Group = cast_ref(group);
    ManagedCloneable::from_value(group.client().clone())
}

pub extern "C" fn group_get_members(group: *const ()) -> FFIFuture<RustVec<ManagedCloneable>> {
    FFIFuture::from(async move {
        let group: &Group = cast_ref(group);

        let named: Vec<ManagedCloneable> = group
            .members()
            .await
            .into_iter()
            .map(ManagedCloneable::from_value)
            .collect();

        RustVec::from(named)
    })
}

pub extern "C" fn group_find_member(group: *const (), id: i64) -> ManagedCloneable {
    let group: &Group = cast_ref(group);
    group
        .find_member(id)
        .map(ManagedCloneable::from_value)
        .unwrap_or_else(|| unsafe { ManagedCloneable::null() })
}

pub extern "C" fn group_find_or_refresh_member(
    group: *const (),
    id: i64,
) -> FFIFuture<ManagedCloneable> {
    FFIFuture::from(async move {
        let group: &Group = cast_ref(group);
        group
            .find_or_refresh_member(id)
            .await
            .map(ManagedCloneable::from_value)
            .unwrap_or_else(|| unsafe { ManagedCloneable::null() })
    })
}

pub extern "C" fn group_send_message(
    group: *const (),
    chain: FFIMessageChain,
) -> FFIFuture<FFIResult<Managed>> {
    FFIFuture::from(async move {
        let group: &Group = cast_ref(group);
        let result = group
            .send_message(message::MessageChain::from_ffi(chain))
            .await
            .map(Managed::from_value);

        FFIResult::from(result)
    })
}

pub extern "C" fn group_upload_image(
    group: *const (),
    data: RustVec<u8>,
) -> FFIFuture<FFIResult<Managed>> {
    FFIFuture::from(async move {
        let group: &Group = cast_ref(group);
        let data = data.into_vec();
        let result = group.upload_image(data).await.map(Managed::from_value);

        FFIResult::from(result)
    })
}

pub extern "C" fn group_change_name(group: *const (), name: RustStr) -> FFIFuture<FFIResult<()>> {
    let s = name.as_ref().to_owned();
    FFIFuture::from(async move {
        let group: &Group = cast_ref(group);
        let result = group.change_name(s).await;

        FFIResult::from(result)
    })
}

pub extern "C" fn group_quit(group: *const ()) -> FFIFuture<bool> {
    let group: &Group = cast_ref(group);
    FFIFuture::from(group.quit())
}