neovim-gtk/src/nvim/client.rs

142 lines
3.4 KiB
Rust
Raw Normal View History

2017-10-15 11:34:48 +00:00
use std::ops::{Deref, DerefMut};
2017-11-10 15:36:54 +00:00
use std::cell::{Cell, RefCell, RefMut};
use std::sync::{Arc, Mutex, MutexGuard};
2017-10-15 11:34:48 +00:00
use neovim_lib::Neovim;
2017-11-10 15:36:54 +00:00
#[derive(Clone, Copy, PartialEq)]
2017-10-15 11:34:48 +00:00
enum NeovimClientState {
Uninitialized,
InitInProgress,
2017-11-10 15:36:54 +00:00
Initialized,
2017-10-15 11:34:48 +00:00
Error,
}
2017-11-10 15:36:54 +00:00
pub enum NeovimRef<'a> {
SingleThreaded(RefMut<'a, Neovim>),
MultiThreaded(MutexGuard<'a, Option<Neovim>>),
2017-11-10 15:36:54 +00:00
}
impl<'a> NeovimRef<'a> {
fn from_nvim(nvim: RefMut<'a, Neovim>) -> Self {
NeovimRef::SingleThreaded(nvim)
2017-10-15 11:34:48 +00:00
}
2017-11-10 15:36:54 +00:00
fn from_nvim_async(nvim_async: &'a NeovimClientAsync) -> Option<NeovimRef<'a>> {
let guard = nvim_async.nvim.lock().unwrap();
if guard.is_some() {
Some(NeovimRef::MultiThreaded(guard))
2017-11-10 15:36:54 +00:00
} else {
None
2017-10-15 11:34:48 +00:00
}
}
2017-11-10 15:36:54 +00:00
}
2017-10-15 11:34:48 +00:00
2017-11-10 15:36:54 +00:00
impl<'a> Deref for NeovimRef<'a> {
type Target = Neovim;
fn deref(&self) -> &Neovim {
2017-10-15 11:34:48 +00:00
match *self {
2017-11-10 15:36:54 +00:00
NeovimRef::SingleThreaded(ref nvim) => &*nvim,
NeovimRef::MultiThreaded(ref nvim) => (&*nvim).as_ref().unwrap(),
2017-10-15 11:34:48 +00:00
}
}
2017-11-10 15:36:54 +00:00
}
2017-10-15 11:34:48 +00:00
2017-11-10 15:36:54 +00:00
impl<'a> DerefMut for NeovimRef<'a> {
fn deref_mut(&mut self) -> &mut Neovim {
2017-10-15 11:34:48 +00:00
match *self {
2017-11-10 15:36:54 +00:00
NeovimRef::SingleThreaded(ref mut nvim) => &mut *nvim,
NeovimRef::MultiThreaded(ref mut nvim) => (&mut *nvim).as_mut().unwrap(),
2017-10-15 11:34:48 +00:00
}
}
}
2017-11-10 15:36:54 +00:00
pub struct NeovimClientAsync {
nvim: Arc<Mutex<Option<Neovim>>>,
2017-10-15 11:34:48 +00:00
}
2017-11-10 15:36:54 +00:00
impl NeovimClientAsync {
fn new() -> Self {
NeovimClientAsync { nvim: Arc::new(Mutex::new(None)) }
2017-10-15 11:34:48 +00:00
}
pub fn borrow(&self) -> Option<NeovimRef> {
NeovimRef::from_nvim_async(self)
2017-10-15 11:34:48 +00:00
}
2017-11-10 15:36:54 +00:00
}
2017-10-15 11:34:48 +00:00
2017-11-10 15:36:54 +00:00
impl Clone for NeovimClientAsync {
fn clone(&self) -> Self {
NeovimClientAsync {
nvim: self.nvim.clone()
}
2017-10-15 11:34:48 +00:00
}
2017-11-10 15:36:54 +00:00
}
pub struct NeovimClient {
state: Cell<NeovimClientState>,
nvim: RefCell<Option<Neovim>>,
nvim_async: NeovimClientAsync,
2017-11-10 15:36:54 +00:00
}
2017-10-15 11:34:48 +00:00
2017-11-10 15:36:54 +00:00
impl NeovimClient {
pub fn new() -> Self {
NeovimClient {
state: Cell::new(NeovimClientState::Uninitialized),
nvim: RefCell::new(None),
nvim_async: NeovimClientAsync::new(),
2017-11-10 15:36:54 +00:00
}
2017-10-15 11:34:48 +00:00
}
2017-11-10 15:36:54 +00:00
pub fn async_to_sync(&self) {
let mut lock = self.nvim_async
.nvim
.lock()
.unwrap();
let nvim = lock.take().unwrap();
*self.nvim.borrow_mut() = Some(nvim);
2017-10-15 11:34:48 +00:00
}
2017-11-10 15:36:54 +00:00
pub fn set_nvim_async(&self, nvim: Neovim) -> NeovimClientAsync {
*self.nvim_async.nvim.lock().unwrap() = Some(nvim);
self.nvim_async.clone()
2017-10-15 11:34:48 +00:00
}
2017-11-10 15:36:54 +00:00
pub fn set_initialized(&self) {
self.state.set(NeovimClientState::Initialized);
2017-10-15 11:34:48 +00:00
}
2017-11-10 15:36:54 +00:00
pub fn set_error(&self) {
self.state.set(NeovimClientState::Error);
2017-10-15 11:34:48 +00:00
}
2017-11-10 15:36:54 +00:00
pub fn set_in_progress(&self) {
self.state.set(NeovimClientState::InitInProgress);
2017-10-15 11:34:48 +00:00
}
2017-11-10 15:36:54 +00:00
pub fn is_initialized(&self) -> bool {
self.state.get() == NeovimClientState::Initialized
}
2017-10-15 11:34:48 +00:00
2017-11-10 15:36:54 +00:00
pub fn is_uninitialized(&self) -> bool {
self.state.get() == NeovimClientState::Uninitialized
2017-10-15 11:34:48 +00:00
}
2017-11-10 15:36:54 +00:00
pub fn is_initializing(&self) -> bool {
self.state.get() == NeovimClientState::InitInProgress
}
pub fn nvim(&self) -> Option<NeovimRef> {
let nvim = self.nvim.borrow_mut();
if nvim.is_some() {
Some(NeovimRef::from_nvim(
RefMut::map(nvim, |n| n.as_mut().unwrap()),
))
} else {
self.nvim_async.borrow()
2017-11-10 15:36:54 +00:00
}
2017-10-15 11:34:48 +00:00
}
}