https://github.com/deathbeds/expectorate can give us a JSON schema of the LSP. See if we can use that in combination with @Marwes schemafy crate to autogenerate the LSP types.
There's now actually an official machine-readable description available:
There is also a first version of a meta model for LSP together with the corresponding schema as a JSON schema or as TypeScript type definitions. The meta model contains the following information: specified requests and notifications together with their parameter types, return types, partial return types, and registration options. It also contains all defined structures and enums.
metaModel.json unfortunately seems to be a custom format, only the schema for that json file exists as a json schema. So https://github.com/Marwes/schemafy couldn't be used to generate the types (only the types describing the custom format).
Meta model
```
#[doc = " Represents an `and`type (e.g. TextDocumentParams & WorkDoneProgressParams`)."]
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct AndType {
pub items: Vec,
pub kind: String,
}
#[doc = " Represents an array type (e.g. `TextDocument[]`)."]
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct ArrayType {
pub element: Type,
pub kind: String,
}
#[doc = " Represents a base type like `string` or `DocumentUri`."]
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct BaseType {
pub kind: String,
pub name: BaseTypes,
}
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub enum BaseTypes {
Uri,
DocumentUri,
#[serde(rename = "integer")]
Integer,
#[serde(rename = "uinteger")]
Uinteger,
#[serde(rename = "decimal")]
Decimal,
RegExp,
#[serde(rename = "string")]
String,
#[serde(rename = "boolean")]
Boolean,
#[serde(rename = "null")]
Null,
}
#[doc = " Represents a boolean literal type (e.g. `kind: true`)."]
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct BooleanLiteralType {
pub kind: String,
pub value: bool,
}
#[doc = " Defines an enumeration."]
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct Enumeration {
#[doc = " An optional documentation."]
#[serde(skip_serializing_if = "Option::is_none")]
pub documentation: Option,
#[doc = " The name of the enumeration."]
pub name: String,
#[doc = " Whether this is a proposed enumeration. If omitted, the enumeration is final."]
#[serde(skip_serializing_if = "Option::is_none")]
pub proposed: Option,
#[doc = " Since when (release number) this enumeration is available. Is undefined if not known."]
#[serde(skip_serializing_if = "Option::is_none")]
pub since: Option,
#[doc = " The type of the elements."]
#[serde(rename = "type")]
pub type_: EnumerationType,
#[doc = " The enum values."]
pub values: Vec,
}
#[doc = " Defines an enumeration entry."]
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct EnumerationEntry {
#[doc = " An optional documentation."]
#[serde(skip_serializing_if = "Option::is_none")]
pub documentation: Option,
#[doc = " The name of the enum item."]
pub name: String,
#[doc = " Whether this is a proposed enumeration entry. If omitted, the enumeration entry is final."]
#[serde(skip_serializing_if = "Option::is_none")]
pub proposed: Option,
#[doc = " Since when (release number) this enumeration entry is available. Is undefined if not known."]
#[serde(skip_serializing_if = "Option::is_none")]
pub since: Option,
#[doc = " The value."]
pub value: serde_json::Value,
}
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct EnumerationType {
pub kind: String,
pub name: String,
}
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct IntegerLiteralType {
#[doc = " Represents an integer literal type (e.g. `kind: 1`)."]
pub kind: String,
pub value: f64,
}
#[doc = " Represents a type that can be used as a key in a map type. If a reference type is used then the "]
#[doc = " type must either resolve to a `string` or `integer` type. (e.g. `type "]
#[doc = " ChangeAnnotationIdentifier === string`)."]
pub type MapKeyType = serde_json::Value;
#[doc = " Represents a JSON object map (e.g. `interface Map { [key: K] => "]
#[doc = " V; }`)."]
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct MapType {
pub key: MapKeyType,
pub kind: String,
pub value: Type,
}
#[doc = " The actual meta model."]
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct MetaModel {
#[doc = " The enumerations."]
pub enumerations: Vec,
#[doc = " The notifications."]
pub notifications: Vec,
#[doc = " The requests."]
pub requests: Vec,
#[doc = " The structures."]
pub structures: Vec,
#[doc = " The type aliases."]
#[serde(rename = "typeAliases")]
pub type_aliases: Vec,
}
#[doc = " Represents a LSP notification"]
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct Notification {
#[doc = " An optional documentation;"]
#[serde(skip_serializing_if = "Option::is_none")]
pub documentation: Option,
#[doc = " The request's method name."]
pub method: String,
#[doc = " The parameter type(s) if any."]
#[serde(default)]
#[serde(with = "::schemafy_core::one_or_many")]
pub params: Vec,
#[doc = " Whether this is a proposed notification. If omitted the notification is final."]
#[serde(skip_serializing_if = "Option::is_none")]
pub proposed: Option,
#[doc = " Optional registration options if the notification supports dynamic registration."]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "registrationOptions")]
pub registration_options: Option,
#[doc = " Since when (release number) this notification is available. Is undefined if not known."]
#[serde(skip_serializing_if = "Option::is_none")]
pub since: Option,
}
#[doc = " Represents an `or` type (e.g. `Location | LocationLink`)."]
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct OrType {
pub items: Vec,
pub kind: String,
}
#[doc = " Represents an object property."]
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct Property {
#[doc = " An optional documentation."]
#[serde(skip_serializing_if = "Option::is_none")]
pub documentation: Option,
#[doc = " The property name;"]
pub name: String,
#[doc = " Whether the property is optional. If omitted, the property is mandatory."]
#[serde(skip_serializing_if = "Option::is_none")]
pub optional: Option,
#[doc = " Whether this is a proposed property. If omitted, the structure is final."]
#[serde(skip_serializing_if = "Option::is_none")]
pub proposed: Option,
#[doc = " Since when (release number) this property is available. Is undefined if not known."]
#[serde(skip_serializing_if = "Option::is_none")]
pub since: Option,
#[doc = " The type of the property"]
#[serde(rename = "type")]
pub type_: Type,
}
#[doc = " Represents a reference to another type (e.g. `TextDocument`). This is either a `Structure`, a "]
#[doc = " `Enumeration` or a `TypeAlias` in the same meta model."]
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct ReferenceType {
pub kind: String,
pub name: String,
}
#[doc = " Represents a LSP request"]
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct Request {
#[doc = " An optional documentation;"]
#[serde(skip_serializing_if = "Option::is_none")]
pub documentation: Option,
#[doc = " An optional error data type."]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "errorData")]
pub error_data: Option,
#[doc = " The request's method name."]
pub method: String,
#[doc = " The parameter type(s) if any."]
#[serde(default)]
#[serde(with = "::schemafy_core::one_or_many")]
pub params: Vec,
#[doc = " Optional partial result type if the request supports partial result reporting."]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "partialResult")]
pub partial_result: Option,
#[doc = " Whether this is a proposed feature. If omitted the feature is final."]
#[serde(skip_serializing_if = "Option::is_none")]
pub proposed: Option,
#[doc = " Optional registration options if the request supports dynamic registration."]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "registrationOptions")]
pub registration_options: Option,
#[doc = " The result type."]
pub result: Type,
#[doc = " Since when (release number) this request is available. Is undefined if not known."]
#[serde(skip_serializing_if = "Option::is_none")]
pub since: Option,
}
#[doc = " Represents a string literal type (e.g. `kind: 'rename'`)."]
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct StringLiteralType {
pub kind: String,
pub value: String,
}
#[doc = " Defines the structure of an object literal."]
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct Structure {
#[doc = " An optional documentation;"]
#[serde(skip_serializing_if = "Option::is_none")]
pub documentation: Option,
#[doc = " Structures extended from. This structures form a polymorphic type hierarchy."]
#[serde(skip_serializing_if = "Option::is_none")]
pub extends: Option>,
#[doc = " Structures to mix in. The properties of these structures are `copied` into this structure. "]
#[doc = " Mixins don't form a polymorphic type hierarchy in LSP."]
#[serde(skip_serializing_if = "Option::is_none")]
pub mixins: Option>,
#[doc = " The name of the structure."]
pub name: String,
#[doc = " The properties."]
pub properties: Vec,
#[doc = " Whether this is a proposed structure. If omitted, the structure is final."]
#[serde(skip_serializing_if = "Option::is_none")]
pub proposed: Option,
#[doc = " Since when (release number) this structure is available. Is undefined if not known."]
#[serde(skip_serializing_if = "Option::is_none")]
pub since: Option,
}
#[doc = " Defines a unnamed structure of an object literal."]
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct StructureLiteral {
#[doc = " An optional documentation."]
#[serde(skip_serializing_if = "Option::is_none")]
pub documentation: Option,
#[doc = " The properties."]
pub properties: Vec,
#[doc = " Whether this is a proposed structure. If omitted, the structure is final."]
#[serde(skip_serializing_if = "Option::is_none")]
pub proposed: Option,
#[doc = " Since when (release number) this structure is available. Is undefined if not known."]
#[serde(skip_serializing_if = "Option::is_none")]
pub since: Option,
}
#[doc = " Represents a literal structure (e.g. `property: { start: uinteger; end: uinteger; }`)."]
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct StructureLiteralType {
pub kind: String,
pub value: StructureLiteral,
}
#[doc = " Represents a `tuple` type (e.g. `[integer, integer]`)."]
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct TupleType {
pub items: Vec,
pub kind: String,
}
pub type Type = serde_json::Value;
#[doc = " Defines a type alias. (e.g. `type Definition = Location | LocationLink`)"]
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct TypeAlias {
#[doc = " An optional documentation."]
#[serde(skip_serializing_if = "Option::is_none")]
pub documentation: Option,
#[doc = " The name of the type alias."]
pub name: String,
#[doc = " Whether this is a proposed type alias. If omitted, the type alias is final."]
#[serde(skip_serializing_if = "Option::is_none")]
pub proposed: Option,
#[doc = " Since when (release number) this structure is available. Is undefined if not known."]
#[serde(skip_serializing_if = "Option::is_none")]
pub since: Option,
#[doc = " The aliased type."]
#[serde(rename = "type")]
pub type_: Type,
}
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub enum TypeKind {
#[serde(rename = "base")]
Base,
#[serde(rename = "reference")]
Reference,
#[serde(rename = "array")]
Array,
#[serde(rename = "map")]
Map,
#[serde(rename = "and")]
And,
#[serde(rename = "or")]
Or,
#[serde(rename = "tuple")]
Tuple,
#[serde(rename = "literal")]
Literal,
#[serde(rename = "stringLiteral")]
StringLiteral,
#[serde(rename = "integerLiteral")]
IntegerLiteral,
#[serde(rename = "booleanLiteral")]
BooleanLiteral,
}
pub type Schema = serde_json::Value;
```
Yes, but that's to be expected. Maybe I should have filed a new issue instead.