#![doc = concat!("**", include_str!("lsp_version.txt"), "**.")]
#![allow(rustdoc::redundant_explicit_links)] #![allow(deprecated)]
pub mod notification;
pub mod request;
mod types;
pub use types::*;
mod uri;
pub use uri::Uri;
#[cfg(not(feature = "raw_value"))]
type Value = serde_json::Value;
#[cfg(feature = "raw_value")]
type Value = Box<serde_json::value::RawValue>;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(not(feature = "raw_value"), derive(Deserialize))]
#[serde(untagged)]
pub enum Or2<A, B> {
A(A),
B(B),
}
#[derive(Debug, Clone, Serialize)]
#[cfg_attr(not(feature = "raw_value"), derive(Deserialize))]
#[serde(untagged)]
pub enum Or3<A, B, C> {
A(A),
B(B),
C(C),
}
#[cfg(feature = "raw_value")]
impl<'de, A: serde::de::DeserializeOwned, B: serde::de::DeserializeOwned> Deserialize<'de>
for Or2<A, B>
{
fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
let raw = Box::<serde_json::value::RawValue>::deserialize(d)?;
let res_a = serde_json::from_str::<A>(raw.get());
let err_a = match res_a {
Ok(a) => return Ok(Or2::A(a)),
Err(e) => e,
};
let res_b = serde_json::from_str::<B>(raw.get());
let err_b = match res_b {
Ok(b) => return Ok(Or2::B(b)),
Err(e) => e,
};
Err(serde::de::Error::custom(format!(
"Failed to deserialize as both {}: {} and {}: {}",
std::any::type_name::<A>(),
err_a,
std::any::type_name::<B>(),
err_b,
)))
}
}
#[cfg(feature = "raw_value")]
impl<
'de,
A: serde::de::DeserializeOwned,
B: serde::de::DeserializeOwned,
C: serde::de::DeserializeOwned,
> Deserialize<'de> for Or3<A, B, C>
{
fn deserialize<D: serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
let raw = Box::<serde_json::value::RawValue>::deserialize(d)?;
let res_a = serde_json::from_str::<A>(raw.get());
let err_a = match res_a {
Ok(a) => return Ok(Or3::A(a)),
Err(e) => e,
};
let res_b = serde_json::from_str::<B>(raw.get());
let err_b = match res_b {
Ok(b) => return Ok(Or3::B(b)),
Err(e) => e,
};
let res_c = serde_json::from_str::<C>(raw.get());
let err_c = match res_c {
Ok(c) => return Ok(Or3::C(c)),
Err(e) => e,
};
Err(serde::de::Error::custom(format!(
"Failed to deserialize as any of {}: {}, {}: {}, and {}: {}",
std::any::type_name::<A>(),
err_a,
std::any::type_name::<B>(),
err_b,
std::any::type_name::<C>(),
err_c,
)))
}
}
impl<A: Default, B> Default for Or2<A, B> {
fn default() -> Self { Or2::A(A::default()) }
}
impl<A: Default, B, C> Default for Or3<A, B, C> {
fn default() -> Self { Or3::A(A::default()) }
}
#[derive(serde::Deserialize)]
#[serde(tag = "kind")]
#[serde(rename_all = "camelCase")]
pub enum WorkDoneProgress {
Begin(WorkDoneProgressBegin),
Report(WorkDoneProgressReport),
End(WorkDoneProgressEnd),
}
#[cfg(test)]
mod tests {
use serde::de::DeserializeOwned;
use super::*;
macro_rules! assert_serde {
($value:expr, $expected:literal as $ty:ty) => {
assert_eq!(ser($value), $expected);
assert_eq!(format!("{:?}", de::<$ty>($expected)), format!("{:?}", $value));
};
}
fn ser<T: Serialize>(t: &T) -> String { serde_json::to_string(t).unwrap() }
fn de<T: DeserializeOwned>(t: &str) -> T { serde_json::from_str(t).unwrap() }
#[test]
fn string_enums_work() {
assert_serde!(
&[
PositionEncodingKind::Utf8,
PositionEncodingKind::Utf16,
PositionEncodingKind::Custom("foo".into())
],
r#"["utf-8","utf-16","foo"]"# as Vec<PositionEncodingKind>
);
}
#[test]
fn empty_caps_works() {
assert_serde!(&ClientCapabilities::default(), r#"{}"# as ClientCapabilities);
assert_serde!(&ServerCapabilities::default(), r#"{}"# as ServerCapabilities);
}
#[test]
fn or2_works() {
assert_serde!(
&TextDocumentSyncOptions { save: Some(Or2::A(true)), ..Default::default() },
r#"{"save":true}"# as TextDocumentSyncOptions
);
assert_serde!(
&TextDocumentSyncOptions { save: Some(Or2::B(SaveOptions::default())), ..Default::default() },
r#"{"save":{}}"# as TextDocumentSyncOptions
);
assert_serde!(
&TextDocumentSyncOptions {
save: Some(Or2::B(SaveOptions { include_text: Some(true), ..Default::default() })),
..Default::default()
},
r#"{"save":{"includeText":true}}"# as TextDocumentSyncOptions
);
}
#[test]
fn double_untagged() {
type DoubleUntagged = Or2<u32, DoubleObj>;
#[derive(Debug, Serialize, Deserialize)]
struct DoubleObj {
outer: Or2<u32, SingleObj>,
}
#[derive(Debug, Serialize, Deserialize)]
struct SingleObj {
inner: Value,
}
assert_serde!(
&DoubleUntagged::B(DoubleObj {
outer: Or2::B(SingleObj {
#[cfg(not(feature = "raw_value"))]
inner: Value::Number(3.into()),
#[cfg(feature = "raw_value")]
inner: serde_json::value::RawValue::from_string(
"3".into()
)
.unwrap(),
}),
}),
r#"{"outer":{"inner":3}}"# as DoubleUntagged
);
}
}