use super::types::*;
use std::collections::HashMap;
pub const JSONRPC_VERSION: &str = "2.0";
#[derive(Debug, Clone)]
pub enum Message {
Request(RequestMessage),
Response(ResponseMessage),
Notification(NotificationMessage),
}
#[derive(Debug, Clone)]
pub struct RequestMessage {
pub jsonrpc: String,
pub id: RequestId,
pub method: String,
pub params: Option<Params>,
}
impl RequestMessage {
pub fn new(id: impl Into<RequestId>, method: impl Into<String>) -> Self {
Self {
jsonrpc: JSONRPC_VERSION.to_string(),
id: id.into(),
method: method.into(),
params: None,
}
}
pub fn with_params(mut self, params: Params) -> Self {
self.params = Some(params);
self
}
}
#[derive(Debug, Clone)]
pub struct ResponseMessage {
pub jsonrpc: String,
pub id: RequestId,
pub result: Option<ResponseResult>,
pub error: Option<ResponseError>,
}
impl ResponseMessage {
pub fn success(id: RequestId, result: ResponseResult) -> Self {
Self {
jsonrpc: JSONRPC_VERSION.to_string(),
id,
result: Some(result),
error: None,
}
}
pub fn error(id: RequestId, error: ResponseError) -> Self {
Self {
jsonrpc: JSONRPC_VERSION.to_string(),
id,
result: None,
error: Some(error),
}
}
}
#[derive(Debug, Clone)]
pub struct NotificationMessage {
pub jsonrpc: String,
pub method: String,
pub params: Option<Params>,
}
impl NotificationMessage {
pub fn new(method: impl Into<String>) -> Self {
Self {
jsonrpc: JSONRPC_VERSION.to_string(),
method: method.into(),
params: None,
}
}
pub fn with_params(mut self, params: Params) -> Self {
self.params = Some(params);
self
}
}
#[derive(Debug, Clone)]
pub enum Params {
None,
Bool(bool),
Integer(i64),
Float(f64),
String(String),
Array(Vec<Params>),
Object(HashMap<String, Params>),
}
impl Params {
pub fn as_bool(&self) -> Option<bool> {
match self {
Params::Bool(b) => Some(*b),
_ => None,
}
}
pub fn as_i64(&self) -> Option<i64> {
match self {
Params::Integer(n) => Some(*n),
_ => None,
}
}
pub fn as_str(&self) -> Option<&str> {
match self {
Params::String(s) => Some(s),
_ => None,
}
}
pub fn as_array(&self) -> Option<&[Params]> {
match self {
Params::Array(arr) => Some(arr),
_ => None,
}
}
pub fn as_object(&self) -> Option<&HashMap<String, Params>> {
match self {
Params::Object(obj) => Some(obj),
_ => None,
}
}
pub fn get(&self, key: &str) -> Option<&Params> {
self.as_object().and_then(|obj| obj.get(key))
}
}
impl Default for Params {
fn default() -> Self {
Params::None
}
}
#[derive(Debug, Clone)]
pub enum ResponseResult {
Null,
Bool(bool),
Number(f64),
String(String),
Array(Vec<ResponseResult>),
Object(HashMap<String, ResponseResult>),
Initialize(InitializeResult),
Completion(CompletionList),
Hover(Option<Hover>),
Definition(Vec<Location>),
References(Vec<Location>),
DocumentSymbols(Vec<DocumentSymbol>),
CodeActions(Vec<CodeAction>),
TextEdits(Vec<TextEdit>),
WorkspaceEdit(WorkspaceEdit),
SignatureHelp(Option<SignatureHelp>),
FoldingRanges(Vec<FoldingRange>),
}
#[derive(Debug, Clone)]
pub struct ResponseError {
pub code: ErrorCode,
pub message: String,
pub data: Option<String>,
}
impl ResponseError {
pub fn new(code: ErrorCode, message: impl Into<String>) -> Self {
Self {
code,
message: message.into(),
data: None,
}
}
pub fn parse_error(message: impl Into<String>) -> Self {
Self::new(ErrorCode::ParseError, message)
}
pub fn invalid_request(message: impl Into<String>) -> Self {
Self::new(ErrorCode::InvalidRequest, message)
}
pub fn method_not_found(message: impl Into<String>) -> Self {
Self::new(ErrorCode::MethodNotFound, message)
}
pub fn invalid_params(message: impl Into<String>) -> Self {
Self::new(ErrorCode::InvalidParams, message)
}
pub fn internal_error(message: impl Into<String>) -> Self {
Self::new(ErrorCode::InternalError, message)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ErrorCode {
ParseError = -32700,
InvalidRequest = -32600,
MethodNotFound = -32601,
InvalidParams = -32602,
InternalError = -32603,
ServerNotInitialized = -32002,
UnknownErrorCode = -32001,
RequestCancelled = -32800,
ContentModified = -32801,
ServerCancelled = -32802,
RequestFailed = -32803,
}
#[derive(Debug, Clone)]
pub struct InitializeParams {
pub process_id: Option<i32>,
pub root_path: Option<String>,
pub root_uri: Option<DocumentUri>,
pub capabilities: ClientCapabilities,
pub initialization_options: Option<Params>,
pub trace: Option<TraceValue>,
pub workspace_folders: Option<Vec<WorkspaceFolder>>,
}
#[derive(Debug, Clone)]
pub struct InitializeResult {
pub capabilities: ServerCapabilities,
pub server_info: Option<ServerInfo>,
}
#[derive(Debug, Clone)]
pub struct ServerInfo {
pub name: String,
pub version: Option<String>,
}
#[derive(Debug, Clone, Default)]
pub struct ClientCapabilities {
pub text_document: Option<TextDocumentClientCapabilities>,
pub workspace: Option<WorkspaceClientCapabilities>,
pub window: Option<WindowClientCapabilities>,
pub general: Option<GeneralClientCapabilities>,
}
#[derive(Debug, Clone, Default)]
pub struct TextDocumentClientCapabilities {
pub synchronization: Option<SynchronizationCapabilities>,
pub completion: Option<CompletionClientCapabilities>,
pub hover: Option<HoverClientCapabilities>,
}
#[derive(Debug, Clone, Default)]
pub struct SynchronizationCapabilities {
pub dynamic_registration: bool,
pub will_save: bool,
pub will_save_wait_until: bool,
pub did_save: bool,
}
#[derive(Debug, Clone, Default)]
pub struct CompletionClientCapabilities {
pub dynamic_registration: bool,
pub snippet_support: bool,
pub commit_characters_support: bool,
pub documentation_format: Vec<MarkupKind>,
pub preselect_support: bool,
}
#[derive(Debug, Clone, Default)]
pub struct HoverClientCapabilities {
pub dynamic_registration: bool,
pub content_format: Vec<MarkupKind>,
}
#[derive(Debug, Clone, Default)]
pub struct WorkspaceClientCapabilities {
pub apply_edit: bool,
pub workspace_edit: Option<WorkspaceEditClientCapabilities>,
pub did_change_configuration: Option<DidChangeConfigurationCapabilities>,
}
#[derive(Debug, Clone, Default)]
pub struct WorkspaceEditClientCapabilities {
pub document_changes: bool,
}
#[derive(Debug, Clone, Default)]
pub struct DidChangeConfigurationCapabilities {
pub dynamic_registration: bool,
}
#[derive(Debug, Clone, Default)]
pub struct WindowClientCapabilities {
pub work_done_progress: bool,
pub show_message: Option<ShowMessageRequestCapabilities>,
}
#[derive(Debug, Clone, Default)]
pub struct ShowMessageRequestCapabilities {
pub message_action_item: Option<MessageActionItemCapabilities>,
}
#[derive(Debug, Clone, Default)]
pub struct MessageActionItemCapabilities {
pub additional_properties_support: bool,
}
#[derive(Debug, Clone, Default)]
pub struct GeneralClientCapabilities {
pub stale_request_support: Option<StaleRequestSupportCapabilities>,
pub regular_expressions: Option<RegularExpressionsCapabilities>,
pub markdown: Option<MarkdownClientCapabilities>,
}
#[derive(Debug, Clone, Default)]
pub struct StaleRequestSupportCapabilities {
pub cancel: bool,
pub retry_on_content_modified: Vec<String>,
}
#[derive(Debug, Clone, Default)]
pub struct RegularExpressionsCapabilities {
pub engine: String,
pub version: Option<String>,
}
#[derive(Debug, Clone, Default)]
pub struct MarkdownClientCapabilities {
pub parser: String,
pub version: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TraceValue {
Off,
Messages,
Verbose,
}
#[derive(Debug, Clone)]
pub struct WorkspaceFolder {
pub uri: DocumentUri,
pub name: String,
}
#[derive(Debug, Clone)]
pub struct DidOpenTextDocumentParams {
pub text_document: TextDocumentItem,
}
#[derive(Debug, Clone)]
pub struct DidChangeTextDocumentParams {
pub text_document: VersionedTextDocumentIdentifier,
pub content_changes: Vec<TextDocumentContentChangeEvent>,
}
#[derive(Debug, Clone)]
pub struct DidSaveTextDocumentParams {
pub text_document: TextDocumentIdentifier,
pub text: Option<String>,
}
#[derive(Debug, Clone)]
pub struct DidCloseTextDocumentParams {
pub text_document: TextDocumentIdentifier,
}
#[derive(Debug, Clone)]
pub struct PublishDiagnosticsParams {
pub uri: DocumentUri,
pub version: Option<i32>,
pub diagnostics: Vec<Diagnostic>,
}
impl PublishDiagnosticsParams {
pub fn new(uri: DocumentUri, diagnostics: Vec<Diagnostic>) -> Self {
Self {
uri,
version: None,
diagnostics,
}
}
}
#[derive(Debug, Clone)]
pub struct CompletionParams {
pub text_document_position: TextDocumentPositionParams,
pub context: Option<CompletionContext>,
}
#[derive(Debug, Clone)]
pub struct CompletionContext {
pub trigger_kind: CompletionTriggerKind,
pub trigger_character: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum CompletionTriggerKind {
Invoked = 1,
TriggerCharacter = 2,
TriggerForIncompleteCompletions = 3,
}
#[derive(Debug, Clone)]
pub struct CodeActionParams {
pub text_document: TextDocumentIdentifier,
pub range: Range,
pub context: CodeActionContext,
}
#[derive(Debug, Clone)]
pub struct CodeActionContext {
pub diagnostics: Vec<Diagnostic>,
pub only: Option<Vec<String>>,
pub trigger_kind: Option<CodeActionTriggerKind>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum CodeActionTriggerKind {
Invoked = 1,
Automatic = 2,
}
#[derive(Debug, Clone)]
pub struct DocumentFormattingParams {
pub text_document: TextDocumentIdentifier,
pub options: FormattingOptions,
}
#[derive(Debug, Clone)]
pub struct DocumentRangeFormattingParams {
pub text_document: TextDocumentIdentifier,
pub range: Range,
pub options: FormattingOptions,
}
#[derive(Debug, Clone)]
pub struct FormattingOptions {
pub tab_size: u32,
pub insert_spaces: bool,
pub trim_trailing_whitespace: bool,
pub insert_final_newline: bool,
pub trim_final_newlines: bool,
}
impl Default for FormattingOptions {
fn default() -> Self {
Self {
tab_size: 4,
insert_spaces: true,
trim_trailing_whitespace: true,
insert_final_newline: true,
trim_final_newlines: true,
}
}
}
#[derive(Debug, Clone)]
pub struct RenameParams {
pub text_document_position: TextDocumentPositionParams,
pub new_name: String,
}
#[derive(Debug, Clone)]
pub struct PrepareRenameParams {
pub text_document: TextDocumentIdentifier,
pub position: Position,
}
#[derive(Debug, Clone)]
pub struct PrepareRenameResult {
pub range: Range,
pub placeholder: String,
}
pub mod methods {
pub const INITIALIZE: &str = "initialize";
pub const INITIALIZED: &str = "initialized";
pub const SHUTDOWN: &str = "shutdown";
pub const EXIT: &str = "exit";
pub const DID_OPEN: &str = "textDocument/didOpen";
pub const DID_CHANGE: &str = "textDocument/didChange";
pub const DID_SAVE: &str = "textDocument/didSave";
pub const DID_CLOSE: &str = "textDocument/didClose";
pub const COMPLETION: &str = "textDocument/completion";
pub const COMPLETION_RESOLVE: &str = "completionItem/resolve";
pub const HOVER: &str = "textDocument/hover";
pub const SIGNATURE_HELP: &str = "textDocument/signatureHelp";
pub const DEFINITION: &str = "textDocument/definition";
pub const TYPE_DEFINITION: &str = "textDocument/typeDefinition";
pub const IMPLEMENTATION: &str = "textDocument/implementation";
pub const REFERENCES: &str = "textDocument/references";
pub const DOCUMENT_HIGHLIGHT: &str = "textDocument/documentHighlight";
pub const DOCUMENT_SYMBOL: &str = "textDocument/documentSymbol";
pub const CODE_ACTION: &str = "textDocument/codeAction";
pub const CODE_LENS: &str = "textDocument/codeLens";
pub const CODE_LENS_RESOLVE: &str = "codeLens/resolve";
pub const FORMATTING: &str = "textDocument/formatting";
pub const RANGE_FORMATTING: &str = "textDocument/rangeFormatting";
pub const RENAME: &str = "textDocument/rename";
pub const PREPARE_RENAME: &str = "textDocument/prepareRename";
pub const FOLDING_RANGE: &str = "textDocument/foldingRange";
pub const SEMANTIC_TOKENS_FULL: &str = "textDocument/semanticTokens/full";
pub const WORKSPACE_SYMBOL: &str = "workspace/symbol";
pub const EXECUTE_COMMAND: &str = "workspace/executeCommand";
pub const APPLY_EDIT: &str = "workspace/applyEdit";
pub const PUBLISH_DIAGNOSTICS: &str = "textDocument/publishDiagnostics";
pub const SHOW_MESSAGE: &str = "window/showMessage";
pub const LOG_MESSAGE: &str = "window/logMessage";
pub const WORK_DONE_PROGRESS_CREATE: &str = "window/workDoneProgress/create";
pub const PROGRESS: &str = "$/progress";
pub const CANCEL_REQUEST: &str = "$/cancelRequest";
}