diff --git a/Cargo.toml b/Cargo.toml index 5d7838f..fc279d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,24 +9,31 @@ name = "codemp" [dependencies] # core tracing = "0.1" -tonic = { version = "0.9", features = ["tls", "tls-roots"] } +# ot +operational-transform = { version = "0.6", features = ["serde"], optional = true } +# proto +tonic = { version = "0.9", features = ["tls", "tls-roots"], optional = true } prost = { version = "0.11.8", optional = true } -md5 = "0.7.0" -uuid = { version = "1.3.1", features = ["v4"] } -operational-transform = { version = "0.6", features = ["serde"] } -tokio = { version = "1.0", features = ["macros", "rt-multi-thread", "sync", "full"], optional = false } -tokio-stream = { version = "0.1", optional = false } -serde = { version = "1", optional = false } -serde_json = { version = "1", optional = false } -tracing-subscriber = { version = "0.3", optional = true } -similar = { version = "2.2", features = ["inline"] } +# api +similar = { version = "2.2", features = ["inline"], optional = true } +tokio = { version = "1.0", features = ["macros", "rt-multi-thread", "sync", "full"], optional = true } +async-trait = { version = "0.1", optional = true } +# client +md5 = { version = "0.7.0", optional = true } +uuid = { version = "1.3.1", features = ["v4"], optional = true } +serde_json = { version = "1", optional = true } +tokio-stream = { version = "0.1", optional = true } +# global lazy_static = { version = "1.4", optional = true } [build-dependencies] tonic-build = "0.9" [features] -default = ["proto"] -proto = ["dep:prost"] -global = ["dep:lazy_static"] -sync = [] +default = ["client"] +api = ["ot", "dep:similar", "dep:tokio", "dep:async-trait"] +ot = ["dep:operational-transform"] +proto = ["dep:prost", "dep:tonic"] +client = ["proto", "api", "dep:tokio", "dep:tokio-stream", "dep:uuid", "dep:md5", "dep:serde_json"] +global = ["client", "dep:lazy_static"] +sync = ["client"] diff --git a/src/api/controller.rs b/src/api/controller.rs index 216407a..d7f3874 100644 --- a/src/api/controller.rs +++ b/src/api/controller.rs @@ -7,7 +7,7 @@ use crate::Result; use std::sync::Arc; use tokio::runtime::Runtime; -#[tonic::async_trait] +#[async_trait::async_trait] pub(crate) trait ControllerWorker { type Controller : Controller; type Tx; @@ -27,7 +27,7 @@ pub(crate) trait ControllerWorker { /// * if possible, prefer a pure [Controller::recv] consumer /// * a second possibility in preference is using a [Controller::callback] /// * if neither is feasible a [Controller::poll]/[Controller::try_recv] approach is available -#[tonic::async_trait] +#[async_trait::async_trait] pub trait Controller : Sized + Send + Sync { /// type of upstream values, used in [Self::send] type Input; diff --git a/src/errors.rs b/src/errors.rs index 58d7806..c076cc8 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -4,8 +4,6 @@ use std::{result::Result as StdResult, error::Error as StdError, fmt::Display}; -use tokio::sync::{mpsc, broadcast, watch}; -use tonic::{Status, Code}; use tracing::warn; /// an error which can be ignored with just a warning entry @@ -51,7 +49,7 @@ pub type Result = StdResult; pub enum Error { /// errors caused by tonic http layer Transport { - status: Code, + status: String, message: String, }, /// errors caused by async channels @@ -81,34 +79,43 @@ impl Display for Error { } } -impl From for Error { - fn from(status: Status) -> Self { - Error::Transport { status: status.code(), message: status.message().to_string() } - } -} - -impl From for Error { - fn from(err: tonic::transport::Error) -> Self { +#[cfg(feature = "client")] +impl From for Error { + fn from(status: tonic::Status) -> Self { Error::Transport { - status: Code::Unknown, message: format!("underlying transport error: {:?}", err) + status: status.code().to_string(), + message: status.message().to_string() } } } -impl From> for Error { - fn from(_value: mpsc::error::SendError) -> Self { +#[cfg(feature = "client")] +impl From for Error { + fn from(err: tonic::transport::Error) -> Self { + Error::Transport { + status: tonic::Code::Unknown.to_string(), + message: format!("underlying transport error: {:?}", err) + } + } +} + +#[cfg(feature = "client")] +impl From> for Error { + fn from(_value: tokio::sync::mpsc::error::SendError) -> Self { Error::Channel { send: true } } } -impl From for Error { - fn from(_value: broadcast::error::RecvError) -> Self { +#[cfg(feature = "client")] +impl From for Error { + fn from(_value: tokio::sync::broadcast::error::RecvError) -> Self { Error::Channel { send: false } } } -impl From for Error { - fn from(_value: watch::error::RecvError) -> Self { +#[cfg(feature = "client")] +impl From for Error { + fn from(_value: tokio::sync::watch::error::RecvError) -> Self { Error::Channel { send: false } } } diff --git a/src/lib.rs b/src/lib.rs index 4a48d0c..fe28ca9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -143,27 +143,33 @@ /// public traits exposed to clients +#[cfg(feature = "api")] pub mod api; /// cursor related types and controller +#[cfg(feature = "client")] pub mod cursor; /// buffer operations, factory, controller and types +#[cfg(feature = "client")] pub mod buffer; /// crate error types and helpers pub mod errors; /// underlying client session manager +#[cfg(feature = "client")] pub mod client; /// client wrapper to handle memory persistence +#[cfg(feature = "client")] pub mod instance; /// all-in-one imports : `use codemp::prelude::*;` pub mod prelude; /// underlying OperationalTransform library used, re-exported +#[cfg(feature = "ot")] pub use operational_transform as ot; /// protocol types and services auto-generated by grpc @@ -175,11 +181,12 @@ pub mod proto { } - -pub use api::Controller; -pub use client::Client; pub use errors::Error; pub use errors::Result; -#[cfg(feature = "sync")] pub use instance::sync::Instance; -#[cfg(not(feature = "sync"))] pub use instance::a_sync::Instance; + +#[cfg(all(feature = "client", feature = "sync"))] +pub use instance::sync::Instance; + +#[cfg(all(feature = "client", not(feature = "sync")))] +pub use instance::a_sync::Instance; diff --git a/src/prelude.rs b/src/prelude.rs index 40320ff..2c3e5fa 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -5,21 +5,31 @@ pub use crate::{ Error as CodempError, Result as CodempResult, - - Client as CodempClient, +}; + +#[cfg(feature = "ot")] +pub use crate::ot::OperationSeq as CodempOperationSeq; + +#[cfg(feature = "api")] +pub use crate::{ api::Controller as CodempController, api::OperationFactory as CodempOperationFactory, +}; + +#[cfg(feature = "client")] +pub use crate::{ + client::Client as CodempClient, cursor::Controller as CodempCursorController, buffer::Controller as CodempBufferController, - - ot::OperationSeq as CodempOperationSeq, buffer::TextChange as CodempTextChange, + Instance as CodempInstance, +}; +#[cfg(feature = "proto")] +pub use crate::{ proto::CursorPosition as CodempCursorPosition, proto::CursorEvent as CodempCursorEvent, proto::RowCol as CodempRowCol, - - Instance as CodempInstance, }; #[cfg(feature = "global")]