diff --git a/crates/api/src/ffi/command.rs b/crates/api/src/ffi/command.rs index d03546ff..b94ecefd 100644 --- a/crates/api/src/ffi/command.rs +++ b/crates/api/src/ffi/command.rs @@ -6,7 +6,7 @@ use crate::opts::*; pub(crate) type ParseCmdOutput = Dictionary; #[cfg(feature = "neovim-0-10")] // On 0.10 and nightly. -pub(crate) type ParseCmdOutput = crate::types::KeyDict_cmd; +pub(crate) type ParseCmdOutput = crate::types::ParseCmdOutput; #[cfg_attr( all(target_os = "windows", target_env = "msvc"), @@ -42,7 +42,7 @@ extern "C" { // https://github.com/neovim/neovim/blob/v0.10.0/src/nvim/api/command.c#L308 pub(crate) fn nvim_cmd( channel_id: u64, - cmd: *const crate::types::KeyDict_cmd, + cmd: *const crate::types::ParseCmdOutput, opts: *const CmdOpts, #[cfg(feature = "neovim-0-10")] // On 0.10 and nightly. arena: *mut Arena, diff --git a/crates/api/src/types/cmd_infos.rs b/crates/api/src/types/cmd_infos.rs index 19be4da3..0103d93d 100644 --- a/crates/api/src/types/cmd_infos.rs +++ b/crates/api/src/types/cmd_infos.rs @@ -168,7 +168,7 @@ impl FromObject for CmdInfos { #[derive(Default, Debug)] #[allow(non_camel_case_types)] #[repr(C)] -pub(crate) struct KeyDict_cmd { +pub(crate) struct ParseCmdOutput { cmd: Object, reg: Object, bang: Object, @@ -183,47 +183,39 @@ pub(crate) struct KeyDict_cmd { } #[cfg(feature = "neovim-0-10")] // On 0.10 and nightly. -#[derive(Default, Debug)] -#[allow(non_camel_case_types)] +#[derive(Default, Debug, Clone, macros::OptsBuilder)] #[repr(C)] -pub(crate) struct KeyDict_cmd { +pub(crate) struct ParseCmdOutput { + #[builder(mask)] mask: u64, - - /// 1st in the mask. cmd: NvimString, - - /// 10th in the mask. range: Array, - - /// 7th in the mask. count: Integer, - - /// 2nd in the mask. reg: NvimString, - - /// 3rd in the mask. bang: Boolean, - - /// 6th in the mask. args: Array, - - /// 8th in the mask. magic: Dictionary, - - /// 5th in the mask. mods: Dictionary, - - /// 9th in the mask. nargs: Object, - /// 4th in the mask. + // Only on 0.10. + #[cfg(all(feature = "neovim-0-10", not(feature = "neovim-nightly")))] addr: Object, - /// 11th in the mask. + // Only on Nightly. + #[cfg(feature = "neovim-nightly")] + addr: NvimString, + + // Only on Nightly. + #[cfg(all(feature = "neovim-0-10", not(feature = "neovim-nightly")))] nextcmd: Object, + + // Only on 0.10. + #[cfg(feature = "neovim-nightly")] + nextcmd: NvimString, } -impl From<&CmdInfos> for KeyDict_cmd { +impl From<&CmdInfos> for ParseCmdOutput { #[inline] fn from(infos: &CmdInfos) -> Self { #[cfg(not(feature = "neovim-0-10"))] // 0nly on 0.9. @@ -256,110 +248,64 @@ impl From<&CmdInfos> for KeyDict_cmd { } #[cfg(feature = "neovim-0-10")] // On 0.10 and nightly. { - let mut mask = 0; + let mut builder = Self::builder(); - let cmd = if let Some(cmd) = infos.cmd.as_deref() { - mask |= 0b11; - NvimString::from(cmd) - } else { - NvimString::default() - }; + if let Some(cmd) = infos.cmd.as_deref() { + builder.cmd(cmd.into()); + } - let range = if let Some(range) = infos.range { - mask |= 0b10000000001; - Array::from(range) - } else { - Array::default() - }; + if let Some(range) = infos.range { + builder.range(Array::from(range)); + } - let count = if let Some(count) = infos.count { - mask |= 0b10000001; - count as Integer - } else { - Integer::default() - }; + if let Some(count) = infos.count { + builder.count(count as Integer); + } - let reg = if let Some(reg) = infos.reg { - mask |= 0b101; - reg.into() - } else { - NvimString::default() - }; + if let Some(reg) = infos.reg { + builder.reg(reg.into()); + } - let bang = if let Some(bang) = infos.bang { - mask |= 0b1001; - bang - } else { - Boolean::default() - }; + if let Some(bang) = infos.bang { + builder.bang(bang); + } - let args = if !infos.args.is_empty() { - mask |= 0b1000001; - Array::from_iter(infos.args.clone()) - } else { - Array::default() - }; + if !infos.args.is_empty() { + builder.args(Array::from_iter(infos.args.clone())); + } - let magic = if let Some(magic) = infos.magic { - mask |= 0b100000001; - Dictionary::from(magic) - } else { - Dictionary::default() - }; + if let Some(magic) = infos.magic { + builder.magic(Dictionary::from(magic)); + } - let mods = if let Some(mods) = infos.mods { - mask |= 0b100001; - Dictionary::from(mods) - } else { - Dictionary::default() - }; + if let Some(mods) = infos.mods { + builder.mods(Dictionary::from(mods)); + } - let nargs = if let Some(nargs) = infos.nargs { - mask |= 0b1000000001; - nargs.to_object().unwrap() - } else { - Object::default() - }; + if let Some(nargs) = infos.nargs { + builder.nargs(nargs.to_object().unwrap()); + } - let addr = if let Some(addr) = infos.addr { - mask |= 0b10001; - addr.to_object().unwrap() - } else { - Object::default() - }; + if let Some(addr) = infos.addr { + builder.addr(addr.as_str().into()); + } - let nextcmd = if let Some(nextcmd) = infos.nextcmd.as_deref() { - mask |= 0b100000000001; - NvimString::from(nextcmd).into() - } else { - Object::default() + if let Some(nextcmd) = infos.nextcmd.as_deref() { + builder.nextcmd(nextcmd.into()); }; - Self { - mask, - cmd, - reg, - bang, - addr, - mods, - args, - count, - magic, - nargs, - range, - nextcmd, - } + builder.build() } } } #[cfg(feature = "neovim-0-10")] // On 0.10 and nightly. -impl TryFrom for CmdInfos { +impl TryFrom for CmdInfos { type Error = conversion::Error; #[inline] - fn try_from(cmd: KeyDict_cmd) -> Result { - let KeyDict_cmd { + fn try_from(cmd: ParseCmdOutput) -> Result { + let ParseCmdOutput { addr, args, bang, @@ -385,7 +331,7 @@ impl TryFrom for CmdInfos { } Ok(Self { - addr: utils::none_literal_is_none(Deserializer::new(addr))?, + addr: utils::none_literal_is_none(Deserializer::new(addr.into()))?, args: deserialize(args)?, bang: deserialize(bang)?, cmd: deserialize(cmd)?, @@ -393,7 +339,9 @@ impl TryFrom for CmdInfos { magic: deserialize(magic)?, mods: deserialize(mods)?, nargs: deserialize(nargs)?, - nextcmd: utils::empty_string_is_none(Deserializer::new(nextcmd))?, + nextcmd: utils::empty_string_is_none(Deserializer::new( + nextcmd.into(), + ))?, range: deserialize(range)?, reg: utils::char_from_string(Deserializer::new(reg.into()))?, }) diff --git a/crates/api/src/types/command_addr.rs b/crates/api/src/types/command_addr.rs index 7ed2417c..d84d608e 100644 --- a/crates/api/src/types/command_addr.rs +++ b/crates/api/src/types/command_addr.rs @@ -20,6 +20,22 @@ pub enum CommandAddr { Other, } +impl CommandAddr { + #[cfg(feature = "neovim-0-10")] // On 0.10 and Nightly. + pub(crate) const fn as_str(&self) -> &'static str { + match self { + Self::Lines => "lines", + Self::Arguments => "arguments", + Self::Buffers => "buffers", + Self::LoadedBuffers => "loaded_buffers", + Self::Windows => "windows", + Self::Tabs => "tabs", + Self::Quickfix => "quickfix", + Self::Other => "other", + } + } +} + impl ToObject for CommandAddr { fn to_object(self) -> Result { self.serialize(Serializer::new()).map_err(Into::into)