mirror of
https://github.com/hexedtech/codemp.git
synced 2024-11-25 08:34:47 +01:00
134 lines
5 KiB
Rust
134 lines
5 KiB
Rust
//! # Code MultiPlexer - cooperative development
|
|
//!
|
|
//! `codemp` is an async client library to create cooperation tools for any text editor.
|
|
//!
|
|
//! It is built as a batteries-included client library managing an authenticated user, multiple
|
|
//! workspaces each containing any number of buffers.
|
|
//!
|
|
//! The [`Client`] is completely managed by the library itself, making its use simple across async
|
|
//! contexts and FFI boundaries. All memory is managed by the library itself, which gives out always
|
|
//! atomic reference-counted pointers to internally mutable objects. Asynchronous actions are
|
|
//! abstracted away by the [`api::Controller`], providing an unopinionated approach with both
|
|
//! callback-based and blocking-based APIs.
|
|
//!
|
|
//! The library also provides ready-to-use bindings in a growing number of other programming languages,
|
|
//! to support a potentially infinite number of editors.
|
|
//!
|
|
//! # Overview
|
|
//! The main entrypoint is [`Client::connect`], which establishes an authenticated connection with
|
|
//! a supported remote server and returns a [`Client`] handle to interact with it.
|
|
//!
|
|
//! ```no_run
|
|
//! # async {
|
|
//! let client = codemp::Client::connect(
|
|
//! codemp::api::Config::new(
|
|
//! "mail@example.net",
|
|
//! "dont-use-this-password"
|
|
//! )
|
|
//! )
|
|
//! .await
|
|
//! .expect("failed to connect!");
|
|
//! # };
|
|
//! ```
|
|
//!
|
|
//! A [`Client`] can acquire a [`Workspace`] handle by joining an existing one it can access with
|
|
//! [`Client::attach_workspace`] or create a new one with [`Client::create_workspace`].
|
|
//!
|
|
//! ```no_run
|
|
//! # async {
|
|
//! # let client = codemp::Client::connect(codemp::api::Config::new("", "")).await.unwrap();
|
|
//! client.create_workspace("my-workspace").await.expect("failed to create workspace!");
|
|
//! let workspace = client.attach_workspace("my-workspace").await.expect("failed to attach!");
|
|
//! # };
|
|
//! ```
|
|
//!
|
|
//! A [`Workspace`] handle can be used to acquire a [`cursor::Controller`] to track remote [`api::Cursor`]s
|
|
//! and one or more [`buffer::Controller`] to send and receive [`api::TextChange`]s.
|
|
//!
|
|
//! ```no_run
|
|
//! # async {
|
|
//! # let client = codemp::Client::connect(codemp::api::Config::new("", "")).await.unwrap();
|
|
//! # client.create_workspace("").await.unwrap();
|
|
//! # let workspace = client.attach_workspace("").await.unwrap();
|
|
//! use codemp::api::controller::{AsyncSender, AsyncReceiver}; // needed to access trait methods
|
|
//! let cursor = workspace.cursor();
|
|
//! let event = cursor.recv().await.expect("disconnected while waiting for event!");
|
|
//! println!("user {} moved on buffer {}", event.user, event.sel.buffer);
|
|
//! # };
|
|
//! ```
|
|
//!
|
|
//! Internally, [`buffer::Controller`]s store the buffer state as a [diamond_types] CRDT, guaranteeing
|
|
//! eventual consistency. Each [`api::TextChange`] is translated in a network counterpart that is
|
|
//! guaranteed to converge.
|
|
//!
|
|
//! ```no_run
|
|
//! # async {
|
|
//! # let client = codemp::Client::connect(codemp::api::Config::new("", "")).await.unwrap();
|
|
//! # client.create_workspace("").await.unwrap();
|
|
//! # let workspace = client.attach_workspace("").await.unwrap();
|
|
//! # use codemp::api::controller::{AsyncSender, AsyncReceiver};
|
|
//! let buffer = workspace.attach_buffer("/some/file.txt").await.expect("failed to attach");
|
|
//! buffer.content(); // force-sync
|
|
//! if let Some(mut update) = buffer.try_recv().await.unwrap() {
|
|
//! println!(
|
|
//! "content: {}, span: {}-{}",
|
|
//! update.change.content, update.change.start_idx, update.change.end_idx
|
|
//! );
|
|
//! buffer.ack(update.version);
|
|
//! } // if None, no changes are currently available
|
|
//! # };
|
|
//! ```
|
|
//!
|
|
//! ## FFI
|
|
//! As mentioned, we provide bindings in various programming languages. To obtain them, you can
|
|
//! compile with the appropriate feature flag. Currently, the following are supported:
|
|
//! * `lua`
|
|
//! * `javascript`
|
|
//! * `java` (requires additional build steps to be usable)
|
|
//! * `python`
|
|
//!
|
|
//! For some of these, ready-to-use packages are available in various registries:
|
|
//! * [npm (javascript)](https://www.npmjs.com/package/codemp)
|
|
//! * [PyPI (python)](https://pypi.org/project/codemp)
|
|
//! * [Maven Central (java)](https://central.sonatype.com/artifact/mp.code/codemp)
|
|
//! * [LuaRocks (lua)](https://luarocks.org/modules/alemi/codemp)
|
|
//!
|
|
#![doc(html_logo_url = "https://code.mp/static/logo-round.png")]
|
|
#![doc(html_favicon_url = "https://code.mp/static/favicon.ico")]
|
|
|
|
/// core structs and traits
|
|
pub mod api;
|
|
|
|
/// cursor related types and controller
|
|
pub mod cursor;
|
|
|
|
/// buffer related types and controller
|
|
pub mod buffer;
|
|
|
|
/// workspace handle and operations
|
|
pub mod workspace;
|
|
pub use workspace::Workspace;
|
|
|
|
/// client handle, containing all of the above
|
|
pub mod client;
|
|
pub use client::Client;
|
|
|
|
/// crate error types
|
|
pub mod errors;
|
|
|
|
/// all-in-one imports : `use codemp::prelude::*;`
|
|
pub mod prelude;
|
|
|
|
/// common utils used in this library and re-exposed
|
|
pub mod ext;
|
|
|
|
/// language-specific ffi "glue"
|
|
pub mod ffi;
|
|
|
|
/// internal network services and interceptors
|
|
pub(crate) mod network;
|
|
|
|
/// Get the current version of the client
|
|
pub fn version() -> &'static str {
|
|
env!("CARGO_PKG_VERSION")
|
|
}
|