1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
use std::marker::PhantomData;

use rmpv::Value;

use session::ClientConnection;
use neovim;
use rpc::model::FromVal;

pub struct AsyncCall<'a, R: FromVal<Value>> {
    method: String,
    args: Vec<Value>,
    client: &'a mut ClientConnection,
    cb: Option<Box<FnMut(Result<Value, Value>) + Send + 'static>>,
    marker: PhantomData<R>,
}

impl<'a, R: FromVal<Value>> AsyncCall<'a, R> {
    pub fn new(client: &'a mut ClientConnection, method: String, args: Vec<Value>) -> Self {
        AsyncCall {
            method,
            args,
            client,
            cb: None,
            marker: PhantomData,
        }
    }

    pub fn cb<F>(mut self, cb: F) -> Self
    where
        F: FnOnce(Result<R, neovim::CallError>) + Send + 'static,
    {
        let mut cb = Some(cb);

        self.cb = Some(Box::new(move |res| {
            let res = res.map(|v| R::from_val(v)).map_err(
                neovim::map_generic_error,
            );
            cb.take().unwrap()(res);
        }));
        self
    }

    /// Async call. Call can be made only after event loop begin processing
    pub fn call(self) {
        match self.client {
            &mut ClientConnection::Child(ref mut client, _) => {
                client.call_async(self.method, self.args, self.cb)
            }
            &mut ClientConnection::Parent(ref mut client) => {
                client.call_async(self.method, self.args, self.cb)
            }
            &mut ClientConnection::Tcp(ref mut client) => {
                client.call_async(self.method, self.args, self.cb)
            }

            #[cfg(unix)]
            &mut ClientConnection::UnixSocket(ref mut client) => {
                client.call_async(self.method, self.args, self.cb)
            }
        };
    }
}