#![deny(missing_docs)]
#![forbid(unsafe_code)]
#![cfg_attr(all(doc, CHANNEL_NIGHTLY), feature(doc_auto_cfg))]
mod bindings;
pub mod compression;
pub mod constants;
mod error;
#[cfg(feature = "integration")]
pub mod integration;
pub mod local_transport;
pub mod server_helpers;
mod sync;
mod traits;
#[cfg(any(feature = "files", feature = "listen"))]
pub mod transfer;
pub use bindings::*;
pub use error::{AsConflict, ConflictError, Error, NetworkError};
pub use sync::*;
pub use traits::*;
use prost::{bytes::Buf, Message};
#[cfg(test)]
mod tests;
pub use sos_sdk as sdk;
pub type Result<T> = std::result::Result<T, Error>;
#[doc(hidden)]
pub trait ProtoMessage {
#[allow(async_fn_in_trait)]
async fn encode_proto(self) -> Result<Vec<u8>>;
#[allow(async_fn_in_trait)]
async fn decode_proto<B>(buffer: B) -> Result<Self>
where
B: Buf + Send + 'static,
Self: Sized;
}
impl<T> ProtoMessage for T
where
T: Message + Default + 'static,
{
async fn encode_proto(self) -> Result<Vec<u8>> {
tokio::task::spawn_blocking(move || {
let mut buf = Vec::new();
buf.reserve(self.encoded_len());
self.encode(&mut buf)?;
Ok(buf)
})
.await?
}
async fn decode_proto<B>(buffer: B) -> Result<Self>
where
B: Buf + Send + 'static,
Self: Sized,
{
tokio::task::spawn_blocking(move || Ok(Self::decode(buffer)?)).await?
}
}
trait ProtoBinding {
type Inner: Message + Default;
}
#[doc(hidden)]
pub trait WireEncodeDecode {
#[allow(async_fn_in_trait)]
async fn encode(self) -> Result<Vec<u8>>;
#[allow(async_fn_in_trait)]
async fn decode<B>(buffer: B) -> Result<Self>
where
B: Buf + Send + 'static,
Self: Sized;
}
impl<T> WireEncodeDecode for T
where
T: ProtoBinding + Send + 'static,
<T as ProtoBinding>::Inner: From<T> + 'static,
T: TryFrom<<T as ProtoBinding>::Inner, Error = Error>,
{
#[cfg(not(target_arch = "wasm32"))]
async fn encode(self) -> Result<Vec<u8>> {
tokio::task::spawn_blocking(move || {
let value: <Self as ProtoBinding>::Inner = self.into();
let mut buf = Vec::new();
buf.reserve(value.encoded_len());
value.encode(&mut buf)?;
Ok(buf)
})
.await?
}
#[cfg(not(target_arch = "wasm32"))]
async fn decode<B>(buffer: B) -> Result<Self>
where
B: Buf + Send + 'static,
Self: Sized,
{
tokio::task::spawn_blocking(move || {
let result = <<Self as ProtoBinding>::Inner>::decode(buffer)?;
Ok(result.try_into()?)
})
.await?
}
#[cfg(target_arch = "wasm32")]
async fn encode(self) -> Result<Vec<u8>> {
let value: <Self as ProtoBinding>::Inner = self.into();
let mut buf = Vec::new();
buf.reserve(value.encoded_len());
value.encode(&mut buf)?;
Ok(buf)
}
#[cfg(target_arch = "wasm32")]
async fn decode<B>(buffer: B) -> Result<Self>
where
B: Buf + Send + 'static,
Self: Sized,
{
let result = <<Self as ProtoBinding>::Inner>::decode(buffer)?;
Ok(result.try_into()?)
}
}
fn decode_uuid(id: &[u8]) -> Result<uuid::Uuid> {
let id: [u8; 16] = id.try_into()?;
Ok(uuid::Uuid::from_bytes(id))
}
fn encode_uuid(id: &uuid::Uuid) -> Vec<u8> {
id.as_bytes().to_vec()
}