dittolive_ditto/presence/
observer.rs1use_prelude!();
2
3use std::hash::Hash;
4
5use ffi_sdk::{FfiDynPresenceCallback, FfiPresenceObserver};
6use uuid::Uuid;
7
8use crate::error::Result;
9
10trait_alias! {
11 pub trait PresenceCallback = FnMut(&PresenceGraph) + Send + Sync + 'static
12}
13
14pub struct PresenceObserver {
36 pub(crate) handle: repr_c::Box<FfiPresenceObserver>,
37}
38
39impl PresenceObserver {
40 pub(crate) fn new<F>(ditto: &ffi_sdk::BoxedDitto, mut observer: F) -> Result<PresenceObserver>
42 where
43 F: PresenceCallback,
44 {
45 let ffi_callback: repr_c::Box<FfiDynPresenceCallback> = {
46 fn make_callback<F>(f: F) -> repr_c::Box<FfiDynPresenceCallback>
47 where
48 F: 'static + Send + FnMut(c_slice::Box<u8>),
49 {
50 Box::new(f).into()
51 }
52
53 make_callback(move |graph: c_slice::Box<u8>| {
54 let graph =
55 serde_json::from_slice(&graph).expect("should deserialize presence graph");
56 observer(&graph);
57 })
58 };
59
60 let handle = ffi_sdk::dittoffi_presence_register_observer_throws(ditto, ffi_callback)
61 .into_rust_result()?;
62 Ok(Self { handle })
63 }
64
65 pub fn cancel(&self) {
67 ffi_sdk::dittoffi_presence_observer_cancel(&self.handle);
68 }
69
70 pub fn is_cancelled(&self) -> bool {
72 ffi_sdk::dittoffi_presence_observer_is_cancelled(&self.handle)
73 }
74
75 fn id(&self) -> Uuid {
77 let buffer = ffi_sdk::dittoffi_presence_observer_id(&self.handle);
78 Uuid::from_slice(buffer.as_slice()).expect("bug: expected valid UUID")
79 }
80}
81
82impl Eq for PresenceObserver {}
83impl PartialEq for PresenceObserver {
84 fn eq(&self, other: &Self) -> bool {
85 self.id() == other.id()
86 }
87}
88
89impl Hash for PresenceObserver {
90 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
91 self.id().hash(state);
92 }
93}