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;