mirror of
https://github.com/hexedtech/codemp.git
synced 2024-11-21 23:04:49 +01:00
feat: instance is sync and way more elegant
This commit is contained in:
parent
bd6132dc1e
commit
4f3e09abd3
3 changed files with 40 additions and 76 deletions
|
@ -26,6 +26,6 @@ lazy_static = { version = "1.4", optional = true }
|
|||
tonic-build = "0.9"
|
||||
|
||||
[features]
|
||||
default = ["proto", "static"]
|
||||
default = ["proto", "global"]
|
||||
proto = ["dep:prost"]
|
||||
static = ["dep:lazy_static"]
|
||||
global = ["dep:lazy_static"]
|
||||
|
|
107
src/instance.rs
107
src/instance.rs
|
@ -1,106 +1,73 @@
|
|||
use std::sync::Arc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use tokio::sync::Mutex;
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
use crate::{
|
||||
buffer::controller::BufferController,
|
||||
errors::Error, client::Client, cursor::controller::CursorController,
|
||||
};
|
||||
|
||||
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
pub static ref RUNTIME : Runtime = Runtime::new().expect("could not create tokio runtime");
|
||||
pub static ref INSTANCE : Instance = Instance::default();
|
||||
#[cfg(feature = "global")]
|
||||
pub mod global {
|
||||
lazy_static::lazy_static! {
|
||||
pub static ref INSTANCE : super::Instance = super::Instance::default();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Instance {
|
||||
client: Mutex<Option<Client>>,
|
||||
runtime: Runtime,
|
||||
}
|
||||
|
||||
impl Default for Instance {
|
||||
fn default() -> Self {
|
||||
Instance { client: Mutex::new(None) }
|
||||
Instance {
|
||||
client: Mutex::new(None),
|
||||
runtime: Runtime::new().expect("could not start tokio runtime"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO these methods repeat a lot of code but Mutex makes it hard to simplify
|
||||
|
||||
impl Instance {
|
||||
pub async fn connect(&self, addr: &str) -> Result<(), Error> {
|
||||
*self.client.lock().await = Some(Client::new(addr).await?);
|
||||
|
||||
fn if_client<T>(&self, op: impl FnOnce(&mut Client) -> T) -> Result<T, Error> {
|
||||
if let Some(c) = self.client.lock().expect("client mutex poisoned").as_mut() {
|
||||
Ok(op(c))
|
||||
} else {
|
||||
Err(Error::InvalidState { msg: "connect first".into() })
|
||||
}
|
||||
}
|
||||
|
||||
pub fn connect(&self, addr: &str) -> Result<(), Error> {
|
||||
*self.client.lock().expect("client mutex poisoned") = Some(self.runtime.block_on(Client::new(addr))?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn join(&self, session: &str) -> Result<Arc<CursorController>, Error> {
|
||||
self.client
|
||||
.lock()
|
||||
.await
|
||||
.as_mut()
|
||||
.ok_or(Error::InvalidState { msg: "connect first".into() })?
|
||||
.join(session)
|
||||
.await
|
||||
pub fn join(&self, session: &str) -> Result<Arc<CursorController>, Error> {
|
||||
self.if_client(|c| self.runtime.block_on(c.join(session)))?
|
||||
}
|
||||
|
||||
pub async fn create(&self, path: &str, content: Option<&str>) -> Result<(), Error> {
|
||||
self.client
|
||||
.lock()
|
||||
.await
|
||||
.as_mut()
|
||||
.ok_or(Error::InvalidState { msg: "connect first".into() })?
|
||||
.create(path, content)
|
||||
.await
|
||||
pub fn create(&self, path: &str, content: Option<&str>) -> Result<(), Error> {
|
||||
self.if_client(|c| self.runtime.block_on(c.create(path, content)))?
|
||||
}
|
||||
|
||||
pub async fn attach(&self, path: &str) -> Result<Arc<BufferController>, Error> {
|
||||
self.client
|
||||
.lock()
|
||||
.await
|
||||
.as_mut()
|
||||
.ok_or(Error::InvalidState { msg: "connect first".into() })?
|
||||
.attach(path)
|
||||
.await
|
||||
pub fn attach(&self, path: &str) -> Result<Arc<BufferController>, Error> {
|
||||
self.if_client(|c| self.runtime.block_on(c.attach(path)))?
|
||||
}
|
||||
|
||||
pub async fn get_cursor(&self) -> Result<Arc<CursorController>, Error> {
|
||||
self.client
|
||||
.lock()
|
||||
.await
|
||||
.as_mut()
|
||||
.ok_or(Error::InvalidState { msg: "connect first".into() })?
|
||||
.get_cursor()
|
||||
.ok_or(Error::InvalidState { msg: "join a workspace first".into() })
|
||||
pub fn get_cursor(&self) -> Result<Arc<CursorController>, Error> {
|
||||
self.if_client(|c| c.get_cursor().ok_or(Error::InvalidState { msg: "join workspace first".into() }))?
|
||||
}
|
||||
|
||||
pub async fn get_buffer(&self, path: &str) -> Result<Arc<BufferController>, Error> {
|
||||
self.client
|
||||
.lock()
|
||||
.await
|
||||
.as_mut()
|
||||
.ok_or(Error::InvalidState { msg: "connect first".into() })?
|
||||
.get_buffer(path)
|
||||
.ok_or(Error::InvalidState { msg: "join a workspace or create requested buffer first".into() })
|
||||
pub fn get_buffer(&self, path: &str) -> Result<Arc<BufferController>, Error> {
|
||||
self.if_client(|c| c.get_buffer(path).ok_or(Error::InvalidState { msg: "join workspace or create requested buffer first".into() }))?
|
||||
}
|
||||
|
||||
pub async fn leave_workspace(&self) -> Result<(), Error> {
|
||||
self.client
|
||||
.lock()
|
||||
.await
|
||||
.as_mut()
|
||||
.ok_or(Error::InvalidState { msg: "connect first".into() })?
|
||||
.leave_workspace();
|
||||
Ok(())
|
||||
pub fn leave_workspace(&self) -> Result<(), Error> {
|
||||
self.if_client(|c| c.leave_workspace())
|
||||
}
|
||||
|
||||
pub async fn disconnect_buffer(&self, path: &str) -> Result<bool, Error> {
|
||||
Ok(
|
||||
self.client
|
||||
.lock()
|
||||
.await
|
||||
.as_mut()
|
||||
.ok_or(Error::InvalidState { msg: "connect first".into() })?
|
||||
.disconnect_buffer(path)
|
||||
)
|
||||
pub fn disconnect_buffer(&self, path: &str) -> Result<bool, Error> {
|
||||
self.if_client(|c| c.disconnect_buffer(path))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
pub mod cursor;
|
||||
pub mod errors;
|
||||
pub mod buffer;
|
||||
|
||||
pub mod errors;
|
||||
pub mod client;
|
||||
|
||||
#[cfg(feature = "static")]
|
||||
pub mod instance;
|
||||
|
||||
pub mod prelude;
|
||||
|
|
Loading…
Reference in a new issue