use std::{
collections::HashSet,
sync::{Arc, Weak},
};
use serde::Serialize;
pub use self::sync_subscription::SyncSubscription;
mod sync_subscription;
use crate::{
ditto::{Ditto, DittoFields},
dql::query::IntoQuery,
error::DittoError,
};
pub struct Sync {
ditto: Weak<DittoFields>,
}
impl Sync {
pub(crate) fn new(ditto: Weak<DittoFields>) -> Self {
Self { ditto }
}
pub fn subscriptions(&self) -> HashSet<SyncSubscription> {
let ditto = Ditto::upgrade(&self.ditto).expect("Ditto went out of scope");
let sync_subscriptions = ffi_sdk::dittoffi_sync_subscriptions(&ditto.ditto);
let sync_subscriptions: Vec<_> = sync_subscriptions.into();
sync_subscriptions
.into_iter()
.map(|handle| SyncSubscription { handle })
.collect::<HashSet<_>>()
}
pub fn register_subscription<Q>(&self, query: Q) -> Result<Arc<SyncSubscription>, DittoError>
where
Q: IntoQuery,
Q::Args: Serialize,
{
let ditto = Ditto::upgrade(&self.ditto)?;
let query = query.into_query()?;
let subscription =
SyncSubscription::new(&ditto, &query.string, query.args_cbor.as_deref())?;
let subscription = Arc::new(subscription);
Ok(subscription)
}
pub fn start(&self) -> Result<(), DittoError> {
let ditto = Ditto::upgrade(&self.ditto)?;
let result = ffi_sdk::dittoffi_ditto_try_start_sync(&ditto.ditto);
if let Some(error) = result.error {
if ffi_sdk::dittoffi_error_code(&*error)
== ffi_sdk::FfiErrorCode::ActivationNotActivated
{
return Err(crate::error::ErrorKind::NotActivated.into());
}
return Err(DittoError::from(error));
}
Ok(())
}
pub fn stop(&self) {
let ditto = Ditto::upgrade(&self.ditto).expect("Ditto went out of scope");
ffi_sdk::dittoffi_ditto_stop_sync(&ditto.ditto);
}
pub fn is_active(&self) -> bool {
let ditto = Ditto::upgrade(&self.ditto).expect("Ditto went out of scope");
ffi_sdk::dittoffi_ditto_is_sync_active(&ditto.ditto)
}
}