#![allow(non_upper_case_globals)]
#[macro_use]
extern crate enum_primitive;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate url;
extern crate url_serde;
use url::Url;
use std::collections::HashMap;
use serde::de;
use serde::de::Error as Error_;
use serde_json::Value;
pub mod notification;
pub mod request;
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum NumberOrString {
Number(u64),
String(String),
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct CancelParams {
pub id: NumberOrString,
}
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Copy, Clone, Default, Deserialize, Serialize)]
pub struct Position {
pub line: u64,
pub character: u64,
}
impl Position {
pub fn new(line: u64, character: u64) -> Position {
Position {
line: line,
character: character,
}
}
}
#[derive(Debug, Eq, PartialEq, Copy, Clone, Default, Deserialize, Serialize)]
pub struct Range {
pub start: Position,
pub end: Position,
}
impl Range {
pub fn new(start: Position, end: Position) -> Range {
Range {
start: start,
end: end,
}
}
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
pub struct Location {
#[serde(with = "url_serde")] pub uri: Url,
pub range: Range,
}
impl Location {
pub fn new(uri: Url, range: Range) -> Location {
Location {
uri: uri,
range: range,
}
}
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
pub struct Diagnostic {
pub range: Range,
pub severity: Option<DiagnosticSeverity>,
pub code: Option<NumberOrString>,
pub source: Option<String>,
pub message: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub group: Option<u64>,
}
impl Diagnostic {
pub fn new(
range: Range,
severity: Option<DiagnosticSeverity>,
code: Option<NumberOrString>,
source: Option<String>,
message: String,
group: Option<u64>
) -> Diagnostic {
Diagnostic {
range: range,
severity: severity,
code: code,
source: source,
message: message,
group: group,
}
}
pub fn new_simple(range: Range, message: String) -> Diagnostic {
Self::new(range, None, None, None, message, None)
}
pub fn new_with_code_number(
range: Range,
severity: DiagnosticSeverity,
code_number: u64,
source: Option<String>,
message: String,
) -> Diagnostic {
let code = Some(NumberOrString::Number(code_number));
Self::new(range, Some(severity), code, source, message, None)
}
}
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
pub enum DiagnosticSeverity {
Error = 1,
Warning = 2,
Information = 3,
Hint = 4,
}
impl<'de> serde::Deserialize<'de> for DiagnosticSeverity {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Ok(match try!(u8::deserialize(deserializer)) {
1 => DiagnosticSeverity::Error,
2 => DiagnosticSeverity::Warning,
3 => DiagnosticSeverity::Information,
4 => DiagnosticSeverity::Hint,
i => {
return Err(D::Error::invalid_value(
de::Unexpected::Unsigned(i as u64),
&"value of 1, 2, 3 or 4",
));
}
})
}
}
impl serde::Serialize for DiagnosticSeverity {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_u8(*self as u8)
}
}
#[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)]
pub struct Command {
pub title: String,
pub command: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub arguments: Option<Vec<Value>>,
}
impl Command {
pub fn new(title: String, command: String, arguments: Option<Vec<Value>>) -> Command {
Command {
title: title,
command: command,
arguments: arguments,
}
}
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TextEdit {
pub range: Range,
pub new_text: String,
}
impl TextEdit {
pub fn new(range: Range, new_text: String) -> TextEdit {
TextEdit {
range: range,
new_text: new_text,
}
}
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TextDocumentEdit {
pub text_document: VersionedTextDocumentIdentifier,
pub edits: Vec<TextEdit>,
}
#[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct WorkspaceEdit {
#[serde(with = "url_map")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(default)]
pub changes: Option<HashMap<Url, Vec<TextEdit>>>,
pub document_changes: Option<Vec<TextDocumentEdit>>,
}
mod url_map {
use super::*;
use std::fmt;
pub fn deserialize<'de, D>(
deserializer: D,
) -> Result<Option<HashMap<Url, Vec<TextEdit>>>, D::Error>
where
D: serde::Deserializer<'de>,
{
struct UrlMapVisitor;
impl<'de> de::Visitor<'de> for UrlMapVisitor {
type Value = HashMap<Url, Vec<TextEdit>>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("map")
}
fn visit_map<M>(self, mut visitor: M) -> Result<Self::Value, M::Error>
where
M: de::MapAccess<'de>,
{
let mut values = HashMap::with_capacity(visitor.size_hint().unwrap_or(0));
while let Some((key, value)) = visitor.next_entry::<url_serde::De<Url>, _>()? {
values.insert(key.into_inner(), value);
}
Ok(values)
}
}
struct OptionUrlMapVisitor;
impl<'de> de::Visitor<'de> for OptionUrlMapVisitor {
type Value = Option<HashMap<Url, Vec<TextEdit>>>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("option")
}
#[inline]
fn visit_unit<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(None)
}
#[inline]
fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: serde::de::Error,
{
Ok(None)
}
#[inline]
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: serde::Deserializer<'de>,
{
deserializer.deserialize_map(UrlMapVisitor).map(Some)
}
}
deserializer.deserialize_option(OptionUrlMapVisitor)
}
pub fn serialize<S>(
changes: &Option<HashMap<Url, Vec<TextEdit>>>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::SerializeMap;
match *changes {
Some(ref changes) => {
let mut map = serializer.serialize_map(Some(changes.len()))?;
for (k, v) in changes {
map.serialize_entry(k.as_str(), v)?;
}
map.end()
}
None => serializer.serialize_none(),
}
}
}
impl WorkspaceEdit {
pub fn new(changes: HashMap<Url, Vec<TextEdit>>) -> WorkspaceEdit {
WorkspaceEdit {
changes: Some(changes),
document_changes: None,
}
}
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
pub struct TextDocumentIdentifier {
#[serde(with = "url_serde")]
pub uri: Url,
}
impl TextDocumentIdentifier {
pub fn new(uri: Url) -> TextDocumentIdentifier {
TextDocumentIdentifier { uri: uri }
}
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TextDocumentItem {
#[serde(with = "url_serde")]
pub uri: Url,
pub language_id: String,
pub version: u64,
pub text: String,
}
impl TextDocumentItem {
pub fn new(uri: Url, language_id: String, version: u64, text: String) -> TextDocumentItem {
TextDocumentItem {
uri: uri,
language_id: language_id,
version: version,
text: text,
}
}
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
pub struct VersionedTextDocumentIdentifier {
#[serde(with = "url_serde")]
pub uri: Url,
pub version: Option<u64>,
}
impl VersionedTextDocumentIdentifier {
pub fn new(uri: Url, version: u64) -> VersionedTextDocumentIdentifier {
VersionedTextDocumentIdentifier {
uri: uri,
version: Some(version),
}
}
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TextDocumentPositionParams {
pub text_document: TextDocumentIdentifier,
pub position: Position,
}
impl TextDocumentPositionParams {
pub fn new(
text_document: TextDocumentIdentifier,
position: Position,
) -> TextDocumentPositionParams {
TextDocumentPositionParams {
text_document: text_document,
position: position,
}
}
}
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
pub struct DocumentFilter {
pub language: Option<String>,
pub scheme: Option<String>,
pub pattern: Option<String>,
}
pub type DocumentSelector = Vec<DocumentFilter>;
#[derive(Debug, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct InitializeParams {
pub process_id: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub root_path: Option<String>,
#[serde(with = "option_url")]
#[serde(default)]
pub root_uri: Option<Url>,
pub initialization_options: Option<Value>,
pub capabilities: ClientCapabilities,
#[serde(default)]
pub trace: Option<TraceOption>,
}
#[derive(Debug, PartialEq, Deserialize, Serialize)]
pub struct InitializedParams { }
#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
pub enum TraceOption {
#[serde(rename = "off")] Off,
#[serde(rename = "messages")] Messages,
#[serde(rename = "verbose")] Verbose,
}
impl Default for TraceOption {
fn default() -> TraceOption {
TraceOption::Off
}
}
mod option_url {
use serde::{self, Serialize};
use url_serde::{De, Ser};
use url::Url;
pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Url>, D::Error>
where
D: serde::Deserializer<'de>,
{
serde::Deserialize::deserialize(deserializer)
.map(|x: Option<De<Url>>| x.map(|url| url.into_inner()))
}
pub fn serialize<S>(self_: &Option<Url>, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self_.as_ref().map(Ser::new).serialize(serializer)
}
}
#[derive(Debug, Eq, PartialEq, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GenericCapability {
pub dynamic_registration: Option<bool>,
}
#[derive(Debug, Eq, PartialEq, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct WorkspaceEditCapability {
pub document_changes: Option<bool>,
}
#[derive(Debug, Eq, PartialEq, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct WorkspaceClientCapabilites {
pub apply_edit: Option<bool>,
pub workspace_edit: Option<WorkspaceEditCapability>,
pub did_change_configuration: Option<GenericCapability>,
pub did_change_watched_files: Option<GenericCapability>,
pub symbol: Option<GenericCapability>,
pub execute_command: Option<GenericCapability>,
}
#[derive(Debug, Eq, PartialEq, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SynchronizationCapability {
pub dynamic_registration: Option<bool>,
pub will_save: Option<bool>,
pub will_save_wait_until: Option<bool>,
pub did_save: Option<bool>,
}
#[derive(Debug, Eq, PartialEq, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CompletionItemCapability {
pub snippet_support: Option<bool>,
pub commit_characters_support: Option<bool>,
pub documentation_format: Option<Vec<MarkupKind>>,
}
#[derive(Debug, Eq, PartialEq, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CompletionItemKindCapability {
pub value_set: Option<Vec<CompletionItemKind>>,
}
#[derive(Debug, Eq, PartialEq, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct HoverCapability {
pub dynamic_registration: Option<bool>,
pub content_format: Option<Vec<MarkupKind>>,
pub completion_item: Option<CompletionItemKindCapability>,
pub context_support: Option<bool>,
}
#[derive(Debug, Eq, PartialEq, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CompletionCapability {
pub dynamic_registration: Option<bool>,
pub completion_item: Option<CompletionItemCapability>,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SignatureInformationSettings {
documentation_format: Option<Vec<MarkupKind>>,
}
#[derive(Debug, Eq, PartialEq, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SignatureHelpCapability {
pub dynamic_registration: Option<bool>,
pub signature_information: Option<SignatureInformationSettings>,
}
#[derive(Debug, Eq, PartialEq, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TextDocumentClientCapabilities {
#[serde(skip_serializing_if = "Option::is_none")]
pub synchronization: Option<SynchronizationCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub completion: Option<CompletionCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hover: Option<HoverCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub signature_help: Option<SignatureHelpCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub references: Option<GenericCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub document_highlight: Option<GenericCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub document_symbol: Option<GenericCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub formatting: Option<GenericCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub range_formatting: Option<GenericCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub on_type_formatting: Option<GenericCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub definition: Option<GenericCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub code_action: Option<GenericCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub code_lens: Option<GenericCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub document_link: Option<GenericCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub rename: Option<GenericCapability>,
}
#[derive(Debug, PartialEq, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ClientCapabilities {
#[serde(skip_serializing_if = "Option::is_none")]
pub workspace: Option<WorkspaceClientCapabilites>,
#[serde(skip_serializing_if = "Option::is_none")]
pub text_document: Option<TextDocumentClientCapabilities>,
#[serde(skip_serializing_if = "Option::is_none")]
pub experimental: Option<Value>,
}
#[derive(Debug, Eq, PartialEq, Default, Deserialize, Serialize)]
pub struct InitializeResult {
pub capabilities: ServerCapabilities,
}
#[derive(Debug, Eq, PartialEq, Default, Deserialize, Serialize)]
pub struct InitializeError {
pub retry: bool,
}
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
pub enum TextDocumentSyncKind {
None = 0,
Full = 1,
Incremental = 2,
}
impl<'de> serde::Deserialize<'de> for TextDocumentSyncKind {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Ok(match try!(u8::deserialize(deserializer)) {
0 => TextDocumentSyncKind::None,
1 => TextDocumentSyncKind::Full,
2 => TextDocumentSyncKind::Incremental,
i => {
return Err(D::Error::invalid_value(
de::Unexpected::Unsigned(i as u64),
&"value between 0 and 2 (inclusive)",
));
}
})
}
}
impl serde::Serialize for TextDocumentSyncKind {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_u8(*self as u8)
}
}
#[derive(Debug, Eq, PartialEq, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CompletionOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub resolve_provider: Option<bool>,
pub trigger_characters: Option<Vec<String>>,
}
#[derive(Debug, Eq, PartialEq, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SignatureHelpOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub trigger_characters: Option<Vec<String>>,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CodeLensOptions {
pub resolve_provider: Option<bool>,
}
#[derive(Debug, Eq, PartialEq, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DocumentOnTypeFormattingOptions {
pub first_trigger_character: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub more_trigger_character: Option<Vec<String>>,
}
#[derive(Debug, Eq, PartialEq, Default, Deserialize, Serialize)]
pub struct ExecuteCommandOptions {
pub commands: Vec<String>,
}
#[derive(Debug, Eq, PartialEq, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SaveOptions {
pub include_text: Option<bool>,
}
#[derive(Debug, Eq, PartialEq, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TextDocumentSyncOptions {
pub open_close: Option<bool>,
pub change: Option<TextDocumentSyncKind>,
pub will_save: Option<bool>,
pub will_save_wait_until: Option<bool>,
pub save: Option<SaveOptions>,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(untagged)]
pub enum TextDocumentSyncCapability {
Kind(TextDocumentSyncKind),
Options(TextDocumentSyncOptions),
}
#[derive(Debug, Eq, PartialEq, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ServerCapabilities {
#[serde(skip_serializing_if = "Option::is_none")]
pub text_document_sync: Option<TextDocumentSyncCapability>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hover_provider: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub completion_provider: Option<CompletionOptions>,
#[serde(skip_serializing_if = "Option::is_none")]
pub signature_help_provider: Option<SignatureHelpOptions>,
#[serde(skip_serializing_if = "Option::is_none")]
pub definition_provider: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub references_provider: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub document_highlight_provider: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub document_symbol_provider: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub workspace_symbol_provider: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub code_action_provider: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub code_lens_provider: Option<CodeLensOptions>,
#[serde(skip_serializing_if = "Option::is_none")]
pub document_formatting_provider: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub document_range_formatting_provider: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub document_on_type_formatting_provider: Option<DocumentOnTypeFormattingOptions>,
#[serde(skip_serializing_if = "Option::is_none")]
pub rename_provider: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub execute_command_provider: Option<ExecuteCommandOptions>,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct ShowMessageParams {
#[serde(rename = "type")]
pub typ: MessageType,
pub message: String,
}
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
pub enum MessageType {
Error = 1,
Warning = 2,
Info = 3,
Log = 4,
}
impl<'de> serde::Deserialize<'de> for MessageType {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Ok(match try!(u8::deserialize(deserializer)) {
1 => MessageType::Error,
2 => MessageType::Warning,
3 => MessageType::Info,
4 => MessageType::Log,
i => {
return Err(D::Error::invalid_value(
de::Unexpected::Unsigned(i as u64),
&"value of 1, 2, 3 or 4",
));
}
})
}
}
impl serde::Serialize for MessageType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_u8(*self as u8)
}
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct ShowMessageRequestParams {
#[serde(rename = "type")]
pub typ: MessageType,
pub message: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub actions: Option<Vec<MessageActionItem>>,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct MessageActionItem {
pub title: String,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct LogMessageParams {
#[serde(rename = "type")]
pub typ: MessageType,
pub message: String,
}
#[derive(Debug, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct Registration {
pub id: String,
pub method: String,
pub register_options: Value,
}
#[derive(Debug, PartialEq, Deserialize, Serialize)]
pub struct RegistrationParams {
pub registrations: Vec<Registration>,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TextDocumentRegistrationOptions {
pub document_selector: Option<DocumentSelector>,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct Unregistration {
pub id: String,
pub method: String,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct UnregistrationParams {
pub unregisterations: Vec<Unregistration>,
}
#[derive(Debug, PartialEq, Deserialize, Serialize)]
pub struct DidChangeConfigurationParams {
pub settings: Value,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DidOpenTextDocumentParams {
pub text_document: TextDocumentItem,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DidChangeTextDocumentParams {
pub text_document: VersionedTextDocumentIdentifier,
pub content_changes: Vec<TextDocumentContentChangeEvent>,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TextDocumentContentChangeEvent {
pub range: Option<Range>,
pub range_length: Option<u64>,
pub text: String,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TextDocumentChangeRegistrationOptions {
pub document_selector: Option<DocumentSelector>,
pub sync_kind: i32,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct WillSaveTextDocumentParams {
pub text_document: TextDocumentIdentifier,
pub reason: TextDocumentSaveReason,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum TextDocumentSaveReason {
Manual = 1,
AfterDelay = 2,
FocusOut = 3,
}
impl<'de> serde::Deserialize<'de> for TextDocumentSaveReason {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Ok(match try!(u8::deserialize(deserializer)) {
1 => TextDocumentSaveReason::Manual,
2 => TextDocumentSaveReason::AfterDelay,
3 => TextDocumentSaveReason::FocusOut,
i => {
return Err(D::Error::invalid_value(
de::Unexpected::Unsigned(i as u64),
&"value of 1, 2 or 3",
))
}
})
}
}
impl serde::Serialize for TextDocumentSaveReason {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_u8(*self as u8)
}
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DidCloseTextDocumentParams {
pub text_document: TextDocumentIdentifier,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DidSaveTextDocumentParams {
pub text_document: TextDocumentIdentifier,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct DidChangeWatchedFilesParams {
pub changes: Vec<FileEvent>,
}
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub enum FileChangeType {
Created = 1,
Changed = 2,
Deleted = 3,
}
impl<'de> serde::Deserialize<'de> for FileChangeType {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Ok(match try!(u8::deserialize(deserializer)) {
1 => FileChangeType::Created,
2 => FileChangeType::Changed,
3 => FileChangeType::Deleted,
i => {
return Err(D::Error::invalid_value(
de::Unexpected::Unsigned(i as u64),
&"value of 1, 2 or 3",
))
}
})
}
}
impl serde::Serialize for FileChangeType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_u8(*self as u8)
}
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct FileEvent {
#[serde(with = "url_serde")]
pub uri: Url,
#[serde(rename = "type")]
pub typ: FileChangeType,
}
impl FileEvent {
pub fn new(uri: Url, typ: FileChangeType) -> FileEvent {
FileEvent { uri: uri, typ: typ }
}
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct PublishDiagnosticsParams {
#[serde(with = "url_serde")]
pub uri: Url,
pub diagnostics: Vec<Diagnostic>,
}
impl PublishDiagnosticsParams {
pub fn new(uri: Url, diagnostics: Vec<Diagnostic>) -> PublishDiagnosticsParams {
PublishDiagnosticsParams {
uri: uri,
diagnostics: diagnostics,
}
}
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum CompletionResponse {
Array(Vec<CompletionItem>),
List(CompletionList),
}
#[derive(Debug, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CompletionParams {
pub text_document: TextDocumentIdentifier,
pub position: Position,
#[serde(skip_serializing_if = "Option::is_none")]
pub context: Option<CompletionContext>,
}
#[derive(Debug, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CompletionContext {
pub trigger_kind: CompletionTriggerKind,
#[serde(skip_serializing_if = "Option::is_none")]
pub trigger_character: Option<String>,
}
enum_from_primitive!{
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum CompletionTriggerKind {
Invoked = 1,
TriggerCharacter = 2,
}
}
impl<'de> serde::Deserialize<'de> for CompletionTriggerKind {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
use enum_primitive::FromPrimitive;
let i = try!(u8::deserialize(deserializer));
CompletionTriggerKind::from_u8(i).ok_or_else(|| {
D::Error::invalid_value(
de::Unexpected::Unsigned(i as u64),
&"value between 1 and 2 (inclusive)",
)
})
}
}
impl serde::Serialize for CompletionTriggerKind {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_u8(*self as u8)
}
}
#[derive(Debug, PartialEq, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CompletionList {
pub is_incomplete: bool,
pub items: Vec<CompletionItem>,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(untagged)]
pub enum Documentation {
String(String),
MarkupContent(MarkupContent),
}
#[derive(Debug, PartialEq, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CompletionItem {
pub label: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<CompletionItemKind>,
#[serde(skip_serializing_if = "Option::is_none")]
pub detail: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub documentation: Option<Documentation>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sort_text: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub filter_text: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub insert_text: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub insert_text_format: Option<InsertTextFormat>,
#[serde(skip_serializing_if = "Option::is_none")]
pub text_edit: Option<TextEdit>,
#[serde(skip_serializing_if = "Option::is_none")]
pub additional_text_edits: Option<Vec<TextEdit>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub command: Option<Command>,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<Value>,
}
impl CompletionItem {
pub fn new_simple(label: String, detail: String) -> CompletionItem {
CompletionItem {
label: label,
detail: Some(detail),
..Self::default()
}
}
}
enum_from_primitive!{
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
pub enum CompletionItemKind {
Text = 1,
Method = 2,
Function = 3,
Constructor = 4,
Field = 5,
Variable = 6,
Class = 7,
Interface = 8,
Module = 9,
Property = 10,
Unit = 11,
Value = 12,
Enum = 13,
Keyword = 14,
Snippet = 15,
Color = 16,
File = 17,
Reference = 18,
Folder = 19,
EnumMember = 20,
Constant = 21,
Struct = 22,
Event = 23,
Operator = 24,
TypeParameter = 25,
}
}
impl<'de> serde::Deserialize<'de> for CompletionItemKind {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
use enum_primitive::FromPrimitive;
let i = try!(u8::deserialize(deserializer));
CompletionItemKind::from_u8(i).ok_or_else(|| {
D::Error::invalid_value(
de::Unexpected::Unsigned(i as u64),
&"value between 1 and 18 (inclusive)",
)
})
}
}
impl serde::Serialize for CompletionItemKind {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_u8(*self as u8)
}
}
enum_from_primitive!{
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
pub enum InsertTextFormat {
PlainText = 1,
Snippet = 2,
}
}
impl<'de> serde::Deserialize<'de> for InsertTextFormat {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
use enum_primitive::FromPrimitive;
let i = try!(u8::deserialize(deserializer));
InsertTextFormat::from_u8(i).ok_or_else(|| {
D::Error::invalid_value(
de::Unexpected::Unsigned(i as u64),
&"value between 1 and 2 (inclusive)",
)
})
}
}
impl serde::Serialize for InsertTextFormat {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_u8(*self as u8)
}
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct Hover {
pub contents: HoverContents,
pub range: Option<Range>,
}
#[derive(Debug, Eq, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum HoverContents {
Scalar(MarkedString),
Array(Vec<MarkedString>),
Markup(MarkupContent),
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(untagged)]
pub enum MarkedString {
String(String),
LanguageString(LanguageString),
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct LanguageString {
pub language: String,
pub value: String,
}
impl MarkedString {
pub fn from_markdown(markdown: String) -> MarkedString {
MarkedString::String(markdown)
}
pub fn from_language_code(language: String, code_block: String) -> MarkedString {
MarkedString::LanguageString(LanguageString {
language: language,
value: code_block,
})
}
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SignatureHelp {
pub signatures: Vec<SignatureInformation>,
pub active_signature: Option<u64>,
pub active_parameter: Option<u64>,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct SignatureInformation {
pub label: String,
pub documentation: Option<Documentation>,
#[serde(skip_serializing_if = "Option::is_none")]
pub parameters: Option<Vec<ParameterInformation>>,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct ParameterInformation {
pub label: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub documentation: Option<Documentation>,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ReferenceParams {
pub text_document: TextDocumentIdentifier,
pub position: Position,
pub context: ReferenceContext,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ReferenceContext {
pub include_declaration: bool,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct DocumentHighlight {
pub range: Range,
pub kind: Option<DocumentHighlightKind>,
}
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub enum DocumentHighlightKind {
Text = 1,
Read = 2,
Write = 3,
}
impl<'de> serde::Deserialize<'de> for DocumentHighlightKind {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Ok(match try!(u8::deserialize(deserializer)) {
1 => DocumentHighlightKind::Text,
2 => DocumentHighlightKind::Read,
3 => DocumentHighlightKind::Write,
i => {
return Err(D::Error::invalid_value(
de::Unexpected::Unsigned(i as u64),
&"1, 2, or 3",
))
}
})
}
}
impl serde::Serialize for DocumentHighlightKind {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_u8(*self as u8)
}
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DocumentSymbolParams {
pub text_document: TextDocumentIdentifier,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SymbolInformation {
pub name: String,
pub kind: SymbolKind,
pub location: Location,
pub container_name: Option<String>,
}
enum_from_primitive!{
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub enum SymbolKind {
File = 1,
Module = 2,
Namespace = 3,
Package = 4,
Class = 5,
Method = 6,
Property = 7,
Field = 8,
Constructor = 9,
Enum = 10,
Interface = 11,
Function = 12,
Variable = 13,
Constant = 14,
String = 15,
Number = 16,
Boolean = 17,
Array = 18,
Object = 19,
Key = 20,
Null = 21,
EnumMember = 22,
Struct = 23,
Event = 24,
Operator = 25,
TypeParameter = 26,
Unknown = 255,
}
}
impl<'de> serde::Deserialize<'de> for SymbolKind {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
use enum_primitive::FromPrimitive;
let i = try!(u8::deserialize(deserializer));
Ok(SymbolKind::from_u8(i).unwrap_or(SymbolKind::Unknown))
}
}
impl serde::Serialize for SymbolKind {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_u8(*self as u8)
}
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct WorkspaceSymbolParams {
pub query: String,
}
#[derive(Debug, PartialEq, Deserialize, Serialize)]
pub struct ExecuteCommandParams {
pub command: String,
#[serde(default)]
pub arguments: Vec<Value>,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct ExecuteCommandRegistrationOptions {
pub commands: Vec<String>,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct ApplyWorkspaceEditParams {
pub edit: WorkspaceEdit,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct ApplyWorkspaceEditResponse {
pub applied: bool,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CodeActionParams {
pub text_document: TextDocumentIdentifier,
pub range: Range,
pub context: CodeActionContext,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct CodeActionContext {
pub diagnostics: Vec<Diagnostic>,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CodeLensParams {
pub text_document: TextDocumentIdentifier,
}
#[derive(Debug, PartialEq, Deserialize, Serialize)]
pub struct CodeLens {
pub range: Range,
pub command: Option<Command>,
pub data: Option<Value>,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DocumentLinkParams {
pub text_document: TextDocumentIdentifier,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct DocumentLink {
pub range: Range,
#[serde(with = "url_serde")]
pub target: Url,
}
#[derive(Debug, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DocumentFormattingParams {
pub text_document: TextDocumentIdentifier,
pub options: FormattingOptions,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct FormattingOptions {
pub tab_size: u64,
pub insert_spaces: bool,
#[serde(flatten)]
pub properties: HashMap<String, FormattingProperty>,
}
#[derive(Debug, PartialEq, Deserialize, Serialize)]
#[serde(untagged)]
pub enum FormattingProperty {
Bool(bool),
Number(f64),
String(String),
}
#[derive(Debug, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DocumentRangeFormattingParams {
pub text_document: TextDocumentIdentifier,
pub range: Range,
pub options: FormattingOptions,
}
#[derive(Debug, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DocumentOnTypeFormattingParams {
pub text_document: TextDocumentIdentifier,
pub position: Position,
pub ch: String,
pub options: FormattingOptions,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DocumentOnTypeFormattingRegistrationOptions {
pub document_selector: Option<DocumentSelector>,
pub first_trigger_character: String,
pub more_trigger_character: Option<Vec<String>>,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RenameParams {
pub text_document: TextDocumentIdentifier,
pub position: Position,
pub new_name: String,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum MarkupKind {
PlainText,
Markdown,
}
#[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct MarkupContent {
pub kind: MarkupKind,
pub value: String,
}
#[cfg(test)]
mod tests {
use super::*;
use serde::{Deserialize, Serialize};
fn test_serialization<SER>(ms: &SER, expected: &str)
where
SER: Serialize + for<'de> Deserialize<'de> + PartialEq + std::fmt::Debug,
{
let json_str = serde_json::to_string(ms).unwrap();
assert_eq!(&json_str, expected);
let deserialized: SER = serde_json::from_str(&json_str).unwrap();
assert_eq!(&deserialized, ms);
}
#[test]
fn number_or_string() {
test_serialization(&NumberOrString::Number(123), r#"123"#);
test_serialization(&NumberOrString::String("abcd".into()), r#""abcd""#);
}
#[test]
fn marked_string() {
test_serialization(&MarkedString::from_markdown("xxx".into()), r#""xxx""#);
test_serialization(
&MarkedString::from_language_code("lang".into(), "code".into()),
r#"{"language":"lang","value":"code"}"#,
);
}
#[test]
fn language_string() {
test_serialization(
&LanguageString {
language: "LL".into(),
value: "VV".into(),
},
r#"{"language":"LL","value":"VV"}"#,
);
}
#[test]
fn workspace_edit() {
test_serialization(
&WorkspaceEdit {
changes: Some(vec![].into_iter().collect()),
document_changes: None,
},
r#"{"changes":{},"documentChanges":null}"#,
);
test_serialization(
&WorkspaceEdit {
changes: None,
document_changes: None,
},
r#"{"documentChanges":null}"#,
);
test_serialization(&WorkspaceEdit {
changes: Some(vec![(Url::parse("file://test").unwrap(), vec![])]
.into_iter()
.collect()),
document_changes: None,
},
r#"{"changes":{"file://test/":[]},"documentChanges":null}"#);
}
#[test]
fn formatting_options() {
test_serialization(
&FormattingOptions {
tab_size: 123,
insert_spaces: true,
properties: HashMap::new(),
},
r#"{"tabSize":123,"insertSpaces":true}"#,
);
test_serialization(
&FormattingOptions {
tab_size: 123,
insert_spaces: true,
properties: vec![("prop".to_string(), FormattingProperty::Number(1.0))]
.into_iter()
.collect(),
},
r#"{"tabSize":123,"insertSpaces":true,"prop":1.0}"#,
);
}
#[test]
fn root_uri_can_be_missing() {
serde_json::from_str::<InitializeParams>(r#"{ "capabilities": {} }"#).unwrap();
}
}