nvim_api/types/
cmd_infos.rs

1use derive_builder::Builder;
2use nvim_types::{
3    conversion::{self, FromObject, ToObject},
4    serde::Deserializer,
5    Array,
6    Object,
7};
8use serde::Deserialize;
9
10use super::{CmdMagic, CmdRange, CommandAddr, CommandModifiers, CommandNArgs};
11use crate::serde_utils as utils;
12
13#[non_exhaustive]
14#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, Builder, Deserialize)]
15#[builder(default, build_fn(private, name = "fallible_build"))]
16pub struct CmdInfos {
17    /// Value of `:command-addr`. Uses short name.
18    #[builder(setter(strip_option))]
19    #[serde(default, deserialize_with = "utils::none_literal_is_none")]
20    // Setter doesn't exist bc `addr` is ignored when passed to `nvim_cmd`.
21    pub addr: Option<CommandAddr>,
22
23    /// Command arguments.
24    #[builder(setter(custom))]
25    #[serde(default)]
26    pub args: Vec<String>,
27
28    /// Whether the command contains a `<bang>` (`!`) modifier.
29    #[builder(setter(strip_option))]
30    #[serde(default)]
31    pub bang: Option<bool>,
32
33    /// Command name.
34    #[builder(setter(into, strip_option))]
35    #[serde(default)]
36    pub cmd: Option<String>,
37
38    /// Any count that was supplied to the command. `None` if command cannot
39    /// take a count.
40    #[builder(setter(strip_option))]
41    #[serde(default, deserialize_with = "utils::minus_one_is_none")]
42    pub count: Option<u32>,
43
44    #[builder(setter(strip_option))]
45    #[serde(default)]
46    pub magic: Option<CmdMagic>,
47
48    #[builder(setter(strip_option))]
49    #[serde(default)]
50    pub mods: Option<CommandModifiers>,
51
52    // Setter doesn't exist bc `nargs` is ignored when passed to `nvim_cmd`.
53    /// Value of `:command-nargs`
54    #[builder(setter(skip))]
55    #[serde(default)]
56    pub nargs: Option<CommandNArgs>,
57
58    // Setter doesn't exist bc `nextcmd` is ignored when passed to `nvim_cmd`.
59    /// Next command if there are multiple commands separated by a `:bar`.
60    /// `None` if there isn't a next command.
61    #[builder(setter(skip))]
62    #[serde(default, deserialize_with = "utils::empty_string_is_none")]
63    pub nextcmd: Option<String>,
64
65    /// Command range.
66    #[builder(setter(strip_option))]
67    #[serde(default)]
68    pub range: Option<CmdRange>,
69
70    /// The optional command `<register>`. `None` if not specified or if
71    /// command cannot take a register.
72    #[builder(setter(strip_option))]
73    #[serde(default, deserialize_with = "utils::char_from_string")]
74    pub reg: Option<char>,
75}
76
77impl CmdInfos {
78    #[inline(always)]
79    pub fn builder() -> CmdInfosBuilder {
80        CmdInfosBuilder::default()
81    }
82}
83
84impl CmdInfosBuilder {
85    pub fn args<S, I>(&mut self, iter: I) -> &mut Self
86    where
87        S: Into<String>,
88        I: IntoIterator<Item = S>,
89    {
90        self.args = Some(iter.into_iter().map(Into::into).collect::<Vec<_>>());
91        self
92    }
93
94    pub fn build(&mut self) -> CmdInfos {
95        self.fallible_build().expect("never fails, all fields have defaults")
96    }
97}
98
99impl FromObject for CmdInfos {
100    fn from_object(obj: Object) -> Result<Self, conversion::Error> {
101        Self::deserialize(Deserializer::new(obj)).map_err(Into::into)
102    }
103}
104
105#[derive(Default, Debug)]
106#[allow(non_camel_case_types)]
107#[repr(C)]
108pub(crate) struct KeyDict_cmd {
109    cmd: Object,
110    reg: Object,
111    bang: Object,
112    addr: Object,
113    mods: Object,
114    args: Object,
115    count: Object,
116    magic: Object,
117    nargs: Object,
118    range: Object,
119    nextcmd: Object,
120}
121
122impl From<&CmdInfos> for KeyDict_cmd {
123    fn from(infos: &CmdInfos) -> Self {
124        Self {
125            cmd: infos.cmd.clone().into(),
126            reg: infos.reg.into(),
127            bang: infos.bang.into(),
128            addr: infos
129                .addr
130                .map(|v| v.to_object().unwrap())
131                .unwrap_or_default(),
132            mods: infos
133                .mods
134                .map(|v| v.to_object().unwrap())
135                .unwrap_or_default(),
136            args: Array::from_iter(infos.args.clone()).into(),
137            count: infos.count.into(),
138            magic: infos
139                .magic
140                .map(|v| v.to_object().unwrap())
141                .unwrap_or_default(),
142            nargs: infos
143                .nargs
144                .map(|v| v.to_object().unwrap())
145                .unwrap_or_default(),
146            range: infos.range.into(),
147            nextcmd: infos.nextcmd.clone().into(),
148        }
149    }
150}