Struct lsp_server::Connection

source ·
pub struct Connection {
    pub sender: Sender<Message>,
    pub receiver: Receiver<Message>,
}
Expand description

Connection is just a pair of channels of LSP messages.

Fields§

§sender: Sender<Message>§receiver: Receiver<Message>

Implementations§

source§

impl Connection

source

pub fn stdio() -> (Connection, IoThreads)

Create connection over standard in/standard out.

Use this to create a real language server.

source

pub fn connect<A: ToSocketAddrs>(addr: A) -> Result<(Connection, IoThreads)>

Open a connection over tcp. This call blocks until a connection is established.

Use this to create a real language server.

source

pub fn listen<A: ToSocketAddrs>(addr: A) -> Result<(Connection, IoThreads)>

Listen for a connection over tcp. This call blocks until a connection is established.

Use this to create a real language server.

source

pub fn memory() -> (Connection, Connection)

Creates a pair of connected connections.

Use this for testing.

source

pub fn initialize_start(&self) -> Result<(RequestId, Value), ProtocolError>

Starts the initialization process by waiting for an initialize request from the client. Use this for more advanced customization than initialize can provide.

Returns the request id and serialized InitializeParams from the client.

Example
use std::error::Error;
use lsp_types::{ClientCapabilities, InitializeParams, ServerCapabilities};

use lsp_server::{Connection, Message, Request, RequestId, Response};

fn main() -> Result<(), Box<dyn Error + Sync + Send>> {
   // Create the transport. Includes the stdio (stdin and stdout) versions but this could
   // also be implemented to use sockets or HTTP.
   let (connection, io_threads) = Connection::stdio();

   // Run the server
   let (id, params) = connection.initialize_start()?;

   let init_params: InitializeParams = serde_json::from_value(params).unwrap();
   let client_capabilities: ClientCapabilities = init_params.capabilities;
   let server_capabilities = ServerCapabilities::default();

   let initialize_data = serde_json::json!({
       "capabilities": server_capabilities,
       "serverInfo": {
           "name": "lsp-server-test",
           "version": "0.1"
       }
   });

   connection.initialize_finish(id, initialize_data)?;

   // ... Run main loop ...

   Ok(())
}
source

pub fn initialize_start_while<C>( &self, running: C ) -> Result<(RequestId, Value), ProtocolError>
where C: Fn() -> bool,

Starts the initialization process by waiting for an initialize as described in Self::initialize_start as long as running returns true while the return value can be changed through a sig handler such as CTRL + C.

Example
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
let running = Arc::new(AtomicBool::new(true));
let r = running.clone();

ctrlc::set_handler(move || {
    r.store(false, Ordering::SeqCst);
}).expect("Error setting Ctrl-C handler");

let (connection, io_threads) = Connection::stdio();

let res = connection.initialize_start_while(|| running.load(Ordering::SeqCst));
source

pub fn initialize_finish( &self, initialize_id: RequestId, initialize_result: Value ) -> Result<(), ProtocolError>

Finishes the initialization process by sending an InitializeResult to the client

source

pub fn initialize_finish_while<C>( &self, initialize_id: RequestId, initialize_result: Value, running: C ) -> Result<(), ProtocolError>
where C: Fn() -> bool,

Finishes the initialization process as described in Self::initialize_finish as long as running returns true while the return value can be changed through a sig handler such as CTRL + C.

source

pub fn initialize( &self, server_capabilities: Value ) -> Result<Value, ProtocolError>

Initialize the connection. Sends the server capabilities to the client and returns the serialized client capabilities on success. If more fine-grained initialization is required use initialize_start/initialize_finish.

Example
use std::error::Error;
use lsp_types::ServerCapabilities;

use lsp_server::{Connection, Message, Request, RequestId, Response};

fn main() -> Result<(), Box<dyn Error + Sync + Send>> {
   // Create the transport. Includes the stdio (stdin and stdout) versions but this could
   // also be implemented to use sockets or HTTP.
   let (connection, io_threads) = Connection::stdio();

   // Run the server
   let server_capabilities = serde_json::to_value(&ServerCapabilities::default()).unwrap();
   let initialization_params = connection.initialize(server_capabilities)?;

   // ... Run main loop ...

   Ok(())
}
source

pub fn initialize_while<C>( &self, server_capabilities: Value, running: C ) -> Result<Value, ProtocolError>
where C: Fn() -> bool,

Initialize the connection as described in Self::initialize as long as running returns true while the return value can be changed through a sig handler such as CTRL + C.

Example
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;

let running = Arc::new(AtomicBool::new(true));
let r = running.clone();

ctrlc::set_handler(move || {
    r.store(false, Ordering::SeqCst);
}).expect("Error setting Ctrl-C handler");

let (connection, io_threads) = Connection::stdio();

let server_capabilities = serde_json::to_value(&ServerCapabilities::default()).unwrap();
let initialization_params = connection.initialize_while(
    server_capabilities,
    || running.load(Ordering::SeqCst)
);
source

pub fn handle_shutdown(&self, req: &Request) -> Result<bool, ProtocolError>

If req is Shutdown, respond to it and return true, otherwise return false

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.