nvim_rs/rpc/
handler.rs

1//! Handling notifications and request received from neovim
2//!
3//! The core of a plugin is defining and implementing the
4//! [`handler`](crate::rpc::handler::Handler).
5use std::{marker::PhantomData, sync::Arc};
6
7use async_trait::async_trait;
8use futures::io::AsyncWrite;
9use rmpv::Value;
10
11use crate::Neovim;
12
13/// The central functionality of a plugin. The trait bounds asure that each
14/// asynchronous task can receive a copy of the handler, so some state can be
15/// shared.
16#[async_trait]
17pub trait Handler: Send + Sync + Clone + 'static {
18  /// The type where we write our responses to requests. Handling of incoming
19  /// requests/notifications is done on the io loop, which passes the parsed
20  /// messages to the handler.
21  type Writer: AsyncWrite + Send + Unpin + 'static;
22
23  /// Handling an rpc request. The ID's of requests are handled by the
24  /// [`neovim`](crate::neovim::Neovim) instance.
25  async fn handle_request(
26    &self,
27    _name: String,
28    _args: Vec<Value>,
29    _neovim: Neovim<Self::Writer>,
30  ) -> Result<Value, Value> {
31    Err(Value::from("Not implemented"))
32  }
33
34  /// Handling an rpc notification. Notifications are handled one at a time in
35  /// the order in which they were received, and will block new requests from
36  /// being received until handle_notify returns.
37  async fn handle_notify(
38    &self,
39    _name: String,
40    _args: Vec<Value>,
41    _neovim: Neovim<<Self as Handler>::Writer>,
42  ) {
43  }
44}
45
46/// The dummy handler defaults to doing nothing with a notification, and
47/// returning a generic error for a request. It can be used if a plugin only
48/// wants to send requests to neovim and get responses, but not handle any
49/// notifications or requests.
50#[derive(Default)]
51pub struct Dummy<Q>
52where
53  Q: AsyncWrite + Send + Sync + Unpin + 'static,
54{
55  q: Arc<PhantomData<Q>>,
56}
57
58impl<Q> Clone for Dummy<Q>
59where
60  Q: AsyncWrite + Send + Sync + Unpin + 'static,
61{
62  fn clone(&self) -> Self {
63    Dummy { q: self.q.clone() }
64  }
65}
66
67impl<Q> Handler for Dummy<Q>
68where
69  Q: AsyncWrite + Send + Sync + Unpin + 'static,
70{
71  type Writer = Q;
72}
73
74impl<Q> Dummy<Q>
75where
76  Q: AsyncWrite + Send + Sync + Unpin + 'static,
77{
78  #[must_use]
79  pub fn new() -> Dummy<Q> {
80    Dummy {
81      q: Arc::new(PhantomData),
82    }
83  }
84}