#![allow(clippy::boxed_local)]
ffi_gen_macro::ffi_gen!("api/tlfs.rsh");
use anyhow::Result;
use futures::{Stream, StreamExt};
use std::path::Path;
use tlfs::Permission;
pub struct Sdk(tlfs::Sdk);
pub async fn create_persistent(path: &str, package: &[u8]) -> Result<Sdk> {
Ok(Sdk(tlfs::Sdk::persistent(Path::new(path), package).await?))
}
pub async fn create_memory(package: &[u8]) -> Result<Sdk> {
Ok(Sdk(tlfs::Sdk::memory(package).await?))
}
impl Sdk {
pub fn get_peerid(&self) -> String {
self.0.peer_id().to_string()
}
pub fn add_address(&self, peer_id: &str, addr: &str) -> Result<()> {
self.0.add_address(peer_id.parse()?, addr.parse()?);
Ok(())
}
pub fn remove_address(&self, peer_id: &str, addr: &str) -> Result<()> {
self.0.remove_address(peer_id.parse()?, addr.parse()?);
Ok(())
}
pub async fn addresses(&self) -> Vec<String> {
self.0
.addresses()
.await
.into_iter()
.map(|addr| addr.to_string())
.collect()
}
pub fn subscribe_addresses(&self) -> impl Stream<Item = i32> {
self.0.subscribe_addresses().map(|_| 0)
}
pub async fn local_peers(&self) -> Vec<String> {
self.0
.local_peers()
.await
.into_iter()
.map(|peer| peer.to_string())
.collect()
}
pub fn subscribe_local_peers(&self) -> impl Stream<Item = i32> {
self.0.subscribe_local_peers().map(|_| 0)
}
pub async fn connected_peers(&self) -> Vec<String> {
self.0
.connected_peers()
.await
.into_iter()
.map(|peer| peer.to_string())
.collect()
}
pub fn subscribe_connected_peers(&self) -> impl Stream<Item = i32> {
self.0.subscribe_connected_peers().map(|_| 0)
}
pub fn docs(&self, schema: String) -> Result<Vec<String>> {
self.0.docs(schema).map(|id| Ok(id?.to_string())).collect()
}
pub fn subscribe_docs(&self) -> impl Stream<Item = i32> {
self.0.subscribe_docs().map(|_| 0)
}
pub async fn create_doc(&self, schema: &str) -> Result<Doc> {
Ok(Doc(self.0.create_doc(schema).await?))
}
pub fn open_doc(&self, doc_id: &str) -> Result<Doc> {
Ok(Doc(self.0.doc(doc_id.parse()?)?))
}
pub fn add_doc(&self, doc_id: &str, schema: &str) -> Result<Doc> {
Ok(Doc(self.0.add_doc(doc_id.parse()?, schema)?))
}
pub fn remove_doc(&self, doc_id: &str) -> Result<()> {
self.0.remove_doc(&doc_id.parse()?)
}
pub async fn invites(&self) -> Vec<(String, String)> {
self.0
.invites()
.await
.into_iter()
.map(|inv| (inv.doc.to_string(), inv.schema))
.collect()
}
pub fn subscribe_invites(&self) -> impl Stream<Item = i32> {
self.0.subscribe_invites().map(|_| 0)
}
}
pub struct Doc(tlfs::Doc);
impl Doc {
pub fn id(&self) -> String {
self.0.id().to_string()
}
pub fn create_cursor(&self) -> Cursor {
Cursor(self.0.cursor())
}
pub fn apply_causal(&self, causal: Box<Causal>) -> Result<()> {
self.0.apply(causal.0)
}
pub fn invite_peer(&self, peer: String) -> Result<()> {
self.0.invite(peer.parse()?)
}
}
#[derive(Clone)]
pub struct Cursor<'a>(tlfs::Cursor<'a>);
impl<'a> Cursor<'a> {
pub fn flag_enabled(&self) -> Result<bool> {
self.0.enabled()
}
pub fn flag_enable(&self) -> Result<Causal> {
Ok(Causal(self.0.enable()?))
}
pub fn flag_disable(&self) -> Result<Causal> {
Ok(Causal(self.0.disable()?))
}
pub fn reg_bools(&self) -> Result<Vec<bool>> {
self.0.bools()?.collect()
}
pub fn reg_u64s(&self) -> Result<Vec<u64>> {
self.0.u64s()?.collect()
}
pub fn reg_i64s(&self) -> Result<Vec<i64>> {
self.0.i64s()?.collect()
}
pub fn reg_strs(&self) -> Result<Vec<String>> {
self.0.strs()?.collect()
}
pub fn reg_assign_bool(&self, value: bool) -> Result<Causal> {
Ok(Causal(self.0.assign_bool(value)?))
}
pub fn reg_assign_u64(&self, value: u64) -> Result<Causal> {
Ok(Causal(self.0.assign_u64(value)?))
}
pub fn reg_assign_i64(&self, value: i64) -> Result<Causal> {
Ok(Causal(self.0.assign_i64(value)?))
}
pub fn reg_assign_str(&self, value: &str) -> Result<Causal> {
Ok(Causal(self.0.assign_str(value)?))
}
pub fn struct_field(&mut self, field: &str) -> Result<()> {
self.0.field(field)?;
Ok(())
}
pub fn map_key_bool(&mut self, key: bool) -> Result<()> {
self.0.key_bool(key)?;
Ok(())
}
pub fn map_key_u64(&mut self, key: u64) -> Result<()> {
self.0.key_u64(key)?;
Ok(())
}
pub fn map_key_i64(&mut self, key: i64) -> Result<()> {
self.0.key_i64(key)?;
Ok(())
}
pub fn map_key_str(&mut self, key: &str) -> Result<()> {
self.0.key_str(key)?;
Ok(())
}
pub fn map_keys_bool(&self) -> Result<Vec<bool>> {
Ok(self.0.keys_bool()?.collect())
}
pub fn map_keys_u64(&self) -> Result<Vec<u64>> {
Ok(self.0.keys_u64()?.collect())
}
pub fn map_keys_i64(&self) -> Result<Vec<i64>> {
Ok(self.0.keys_i64()?.collect())
}
pub fn map_keys_str(&self) -> Result<Vec<String>> {
Ok(self.0.keys_str()?.collect())
}
pub fn map_remove(&self) -> Result<Causal> {
Ok(Causal(self.0.remove()?))
}
pub fn array_length(&mut self) -> Result<u32> {
self.0.len()
}
pub fn array_index(&mut self, index: usize) -> Result<()> {
self.0.index(index)?;
Ok(())
}
pub fn array_move(&mut self, index: usize) -> Result<Causal> {
Ok(Causal(self.0.r#move(index)?))
}
pub fn array_remove(&mut self) -> Result<Causal> {
Ok(Causal(self.0.delete()?))
}
pub fn can(&self, peer_id: &str, perm: u8) -> Result<bool> {
let perm = parse_perm(perm)?;
self.0.can(&peer_id.parse()?, perm)
}
pub fn say_can(&self, actor: Option<String>, perm: u8) -> Result<Causal> {
let actor = actor.map(|s| s.parse()).transpose()?;
let perm = parse_perm(perm)?;
Ok(Causal(self.0.say_can(actor, perm)?))
}
pub fn cond(&self, actor: Box<Actor>, perm: u8) -> Result<Can> {
let perm = parse_perm(perm)?;
Ok(Can(self.0.cond(actor.0, perm)))
}
pub fn say_can_if(&self, actor: Box<Actor>, perm: u8, cond: Box<Can>) -> Result<Causal> {
let perm = parse_perm(perm)?;
Ok(Causal(self.0.say_can_if(actor.0, perm, cond.0)?))
}
pub fn subscribe(&self) -> impl Stream<Item = i32> {
self.0.subscribe().map(|_batch| 0)
}
}
pub struct Causal(tlfs::Causal);
impl Causal {
pub fn join(&mut self, other: Box<Causal>) {
self.0.join(&other.0);
}
}
pub struct Can(tlfs::Can);
fn parse_perm(perm: u8) -> Result<Permission> {
Ok(match perm {
0 => Permission::Read,
1 => Permission::Write,
2 => Permission::Control,
3 => Permission::Own,
_ => anyhow::bail!("invalid permission"),
})
}
pub struct Actor(tlfs::Actor);
impl Actor {
pub fn peer(id: &str) -> Result<Self> {
Ok(Self(tlfs::Actor::Peer(id.parse()?)))
}
pub fn anonymous() -> Self {
Self(tlfs::Actor::Anonymous)
}
pub fn unbound() -> Self {
Self(tlfs::Actor::Unbound)
}
}