use std::{
collections::HashSet,
ops::Deref,
sync::{Arc, Weak},
};
use serde::Serialize;
pub use self::sync_subscription::SyncSubscription;
mod sync_subscription;
use crate::{
ditto::{Ditto, DittoFields},
dql::{query_v2::IntoQuery, *},
error::{DittoError, ErrorKind},
utils::SetArc,
};
pub struct Sync {
ditto: Weak<DittoFields>,
}
impl Sync {
pub(crate) fn new(ditto: Weak<DittoFields>) -> Self {
Self { ditto }
}
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(ErrorKind::NotActivated.into());
}
return Err(DittoError::from(error));
}
Ok(())
}
pub fn stop(&self) {
if let Ok(ditto) = Ditto::upgrade(&self.ditto) {
ffi_sdk::dittoffi_ditto_stop_sync(&ditto.ditto);
}
}
pub fn is_active(&self) -> bool {
match Ditto::upgrade(&self.ditto) {
Ok(ditto) => ffi_sdk::dittoffi_ditto_is_sync_active(&ditto.ditto),
Err(_) => false,
}
}
#[doc(hidden)]
#[deprecated(note = "Use `ditto.sync().subscriptions_v2()` instead.")]
pub fn subscriptions(&self) -> impl '_ + Deref<Target = SetArc<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();
let sync_subscriptions = sync_subscriptions
.into_iter()
.map(|handle| Arc::new(SyncSubscription { handle }))
.collect::<SetArc<_>>();
Box::new(sync_subscriptions)
}
pub fn subscriptions_v2(&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<_>>()
}
#[deprecated = "Use `ditto.sync().register_subscription_v2(...) instead"]
#[allow(deprecated)]
#[doc(hidden)]
pub fn register_subscription<Q>(
&self,
query: Q,
query_args: Option<QueryArguments>,
) -> Result<Arc<SyncSubscription>, DittoError>
where
Q: TryInto<Query, Error = DittoError>,
{
let ditto = Ditto::upgrade(&self.ditto)?;
let query: Query = query.try_into()?;
let query_args = query_args.as_ref().map(|a| a.cbor());
let subscription = SyncSubscription::new(&ditto, &query.inner_string, query_args)?;
let subscription = Arc::new(subscription);
Ok(subscription)
}
pub fn register_subscription_v2<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)
}
}