tower_lsp_server/
lib.rs

1//! Language Server Protocol (LSP) server abstraction for [Tower].
2//!
3//! [Tower]: https://github.com/tower-rs/tower
4//!
5//! # Example
6//!
7//! ```rust
8//! use tower_lsp_server::jsonrpc::Result;
9//! use tower_lsp_server::lsp_types::*;
10//! use tower_lsp_server::{Client, LanguageServer, LspService, Server};
11//!
12//! #[derive(Debug)]
13//! struct Backend {
14//!     client: Client,
15//! }
16//!
17//! impl LanguageServer for Backend {
18//!     async fn initialize(&self, _: InitializeParams) -> Result<InitializeResult> {
19//!         Ok(InitializeResult {
20//!             capabilities: ServerCapabilities {
21//!                 hover_provider: Some(HoverProviderCapability::Simple(true)),
22//!                 completion_provider: Some(CompletionOptions::default()),
23//!                 ..Default::default()
24//!             },
25//!             ..Default::default()
26//!         })
27//!     }
28//!
29//!     async fn initialized(&self, _: InitializedParams) {
30//!         self.client
31//!             .log_message(MessageType::INFO, "server initialized!")
32//!             .await;
33//!     }
34//!
35//!     async fn shutdown(&self) -> Result<()> {
36//!         Ok(())
37//!     }
38//!
39//!     async fn completion(&self, _: CompletionParams) -> Result<Option<CompletionResponse>> {
40//!         Ok(Some(CompletionResponse::Array(vec![
41//!             CompletionItem::new_simple("Hello".to_string(), "Some detail".to_string()),
42//!             CompletionItem::new_simple("Bye".to_string(), "More detail".to_string())
43//!         ])))
44//!     }
45//!
46//!     async fn hover(&self, _: HoverParams) -> Result<Option<Hover>> {
47//!         Ok(Some(Hover {
48//!             contents: HoverContents::Scalar(
49//!                 MarkedString::String("You're hovering!".to_string())
50//!             ),
51//!             range: None
52//!         }))
53//!     }
54//! }
55//!
56//! #[tokio::main]
57//! async fn main() {
58//! #   tracing_subscriber::fmt().init();
59//! #
60//! #   #[cfg(feature = "runtime-agnostic")]
61//! #   use tokio_util::compat::{TokioAsyncReadCompatExt, TokioAsyncWriteCompatExt};
62//! #   use std::io::Cursor;
63//!     let stdin = tokio::io::stdin();
64//!     let stdout = tokio::io::stdout();
65//! #   let message = r#"{"jsonrpc":"2.0","method":"exit"}"#;
66//! #   let (stdin, stdout) = (Cursor::new(format!("Content-Length: {}\r\n\r\n{}", message.len(), message).into_bytes()), Cursor::new(Vec::new()));
67//! #   #[cfg(feature = "runtime-agnostic")]
68//! #   let (stdin, stdout) = (stdin.compat(), stdout.compat_write());
69//!
70//!     let (service, socket) = LspService::new(|client| Backend { client });
71//!     Server::new(stdin, stdout, socket).serve(service).await;
72//! }
73//! ```
74
75#![deny(missing_debug_implementations)]
76#![deny(missing_docs)]
77#![forbid(unsafe_code)]
78
79/// A re-export of [`lsp-types`](https://docs.rs/lsp-types) for convenience.
80pub use lsp_types;
81
82pub use self::server::LanguageServer;
83pub use self::service::progress::{
84    Bounded, Cancellable, NotCancellable, OngoingProgress, Progress, Unbounded,
85};
86pub use self::service::{Client, ClientSocket, ExitedError, LspService, LspServiceBuilder};
87pub use self::transport::{Loopback, Server};
88pub use self::uri_ext::UriExt;
89
90pub mod jsonrpc;
91
92mod codec;
93mod server;
94mod service;
95mod transport;
96mod uri_ext;