nvim_api/types/
client_infos.rs

1use std::collections::HashMap;
2use std::fmt;
3use std::ops::RangeInclusive;
4
5use serde::{de, Deserialize, Serialize};
6
7#[non_exhaustive]
8#[derive(Clone, Debug, Eq, PartialEq, Deserialize)]
9/// Informations about a remote RPC client.
10pub struct ClientInfos {
11    /// Arbitrary map of informal client properties. Suggested keys:
12    ///  - "website": client homepage URL (e.g. GitHub repository);
13    ///  - "license": license description ("Apache 2", "GPLv3", "MIT", …);
14    ///  - "logo": URI or path to image.
15    pub attributes: HashMap<String, String>,
16
17    /// Builtin methods in the client, where map keys represent method names.
18    pub methods: HashMap<String, ClientMethod>,
19
20    /// Short name for the connected client.
21    pub name: String,
22
23    /// Advertised type of remote client.
24    pub r#type: ClientType,
25
26    /// Describes the client version.
27    pub version: ClientVersion,
28}
29
30#[non_exhaustive]
31#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
32pub struct ClientVersion {
33    /// Major version
34    pub major: Option<u32>,
35
36    /// Minor version
37    pub minor: Option<u32>,
38
39    /// Patch number
40    pub patch: Option<u32>,
41
42    /// String describing a prerelease, like `"dev"` or `"beta1"`.
43    pub prerelease: Option<String>,
44
45    /// Commit hash or similar identifier of commit.
46    pub commit: Option<String>,
47}
48
49#[non_exhaustive]
50#[derive(Clone, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)]
51#[serde(rename_all = "lowercase")]
52pub enum ClientType {
53    /// Remote client connected to Neovim.
54    Remote,
55
56    /// GUI frontend.
57    Ui,
58
59    /// Application using Neovim as a component (for example, IDE/editor
60    /// implementing a vim mode).
61    Embedder,
62
63    /// Plugin host, typically started by Neovim.
64    Host,
65
66    /// Single plugin, started by Neovim.
67    Plugin,
68}
69
70#[non_exhaustive]
71#[derive(Clone, Debug, Eq, PartialEq, Hash, Deserialize)]
72pub struct ClientMethod {
73    /// Whether the method is called as a notification. If `false` or
74    /// unspecified a blocking request will be used.
75    pub r#async: Option<bool>,
76
77    /// Number of arguments. Can either be a single integer or an inclusive
78    /// range representive the minimum and maximum number of arguments
79    /// accepted.
80    pub nargs: Option<ClientMethodNArgs>,
81}
82
83#[non_exhaustive]
84#[derive(Clone, Debug, Eq, PartialEq, Hash)]
85/// Number of arguments accepted by a client method.
86pub enum ClientMethodNArgs {
87    Exact(u32),
88    Range(RangeInclusive<u32>),
89}
90
91impl<'de> de::Deserialize<'de> for ClientMethodNArgs {
92    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
93    where
94        D: de::Deserializer<'de>,
95    {
96        struct ClientMethodNArgsVisitor;
97
98        impl<'de> de::Visitor<'de> for ClientMethodNArgsVisitor {
99            type Value = ClientMethodNArgs;
100
101            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
102                f.write_str(
103                    "either a single integer or an array of two integers",
104                )
105            }
106
107            fn visit_i64<E>(self, n: i64) -> Result<Self::Value, E>
108            where
109                E: de::Error,
110            {
111                Ok(Self::Value::Exact(n as u32))
112            }
113
114            fn visit_seq<S>(
115                self,
116                mut visitor: S,
117            ) -> Result<Self::Value, S::Error>
118            where
119                S: de::SeqAccess<'de>,
120            {
121                let len = visitor
122                    .size_hint()
123                    .expect("couldn't determine number of arguments");
124
125                if len != 2 {
126                    return Err(de::Error::invalid_length(
127                        len,
128                        &"was expecting two integers, a minimum and a maximum",
129                    ));
130                }
131
132                let min = visitor.next_element::<u32>()?.unwrap();
133                let max = visitor.next_element::<u32>()?.unwrap();
134
135                Ok(Self::Value::Range(RangeInclusive::new(min, max)))
136            }
137        }
138
139        deserializer.deserialize_str(ClientMethodNArgsVisitor)
140    }
141}