From a692b0fe371ee2fb182c952278653323062af367 Mon Sep 17 00:00:00 2001 From: Riccardo Mazzarini Date: Tue, 3 Oct 2023 00:52:58 +0200 Subject: [PATCH] api: add `OneOrMore` enum for deserializing either singletons or strings --- crates/oxi-api/src/types/extmark_infos.rs | 4 +-- crates/oxi-api/src/types/mod.rs | 2 ++ crates/oxi-api/src/types/one_or_more.rs | 26 ++++++++++++++ tests/src/api/extmark.rs | 42 ++++++++++++++++------- 4 files changed, 60 insertions(+), 14 deletions(-) create mode 100644 crates/oxi-api/src/types/one_or_more.rs diff --git a/crates/oxi-api/src/types/extmark_infos.rs b/crates/oxi-api/src/types/extmark_infos.rs index 851795da..ed0dd3d1 100644 --- a/crates/oxi-api/src/types/extmark_infos.rs +++ b/crates/oxi-api/src/types/extmark_infos.rs @@ -5,7 +5,7 @@ use oxi_types::{ }; use serde::Deserialize; -use super::{ExtmarkHlMode, ExtmarkVirtTextPosition}; +use super::{ExtmarkHlMode, ExtmarkVirtTextPosition, OneOrMore}; /// Extmark infos returned by `Buffer::get_extmark_by_id`. #[non_exhaustive] @@ -47,7 +47,7 @@ pub struct ExtmarkInfos { pub virt_lines_leftcol: Option, #[serde(default)] - pub virt_text: Option>, + pub virt_text: Option)>>, #[serde(default)] pub virt_text_hide: Option, diff --git a/crates/oxi-api/src/types/mod.rs b/crates/oxi-api/src/types/mod.rs index 18cbe15a..0eecd13e 100644 --- a/crates/oxi-api/src/types/mod.rs +++ b/crates/oxi-api/src/types/mod.rs @@ -27,6 +27,7 @@ mod log_level; mod mode; mod mouse_action; mod mouse_button; +mod one_or_more; mod option_infos; mod parsed_viml_expression; mod paste_phase; @@ -73,6 +74,7 @@ pub use log_level::*; pub use mode::*; pub use mouse_action::*; pub use mouse_button::*; +pub use one_or_more::*; pub use option_infos::*; pub use parsed_viml_expression::*; pub use paste_phase::*; diff --git a/crates/oxi-api/src/types/one_or_more.rs b/crates/oxi-api/src/types/one_or_more.rs new file mode 100644 index 00000000..0f8cd008 --- /dev/null +++ b/crates/oxi-api/src/types/one_or_more.rs @@ -0,0 +1,26 @@ +use serde::Deserialize; + +#[derive(Clone, Debug, Eq, PartialEq, Hash, Deserialize)] +#[serde(untagged)] +pub enum OneOrMore { + One(T), + List(Vec), +} + +impl From for OneOrMore { + fn from(one: T) -> Self { + OneOrMore::One(one) + } +} + +impl From> for OneOrMore { + fn from(vec: Vec) -> Self { + OneOrMore::List(vec) + } +} + +impl From<&str> for OneOrMore { + fn from(s: &str) -> Self { + OneOrMore::One(s.to_owned()) + } +} diff --git a/tests/src/api/extmark.rs b/tests/src/api/extmark.rs index 8752e038..f74db3e8 100644 --- a/tests/src/api/extmark.rs +++ b/tests/src/api/extmark.rs @@ -52,6 +52,7 @@ fn get_extmarks() { let (id, row, col, infos) = extmarks.into_iter().next().unwrap(); assert!(infos.is_some(), "no informations were returned"); + let infos = infos.unwrap(); assert_eq!(extmark_id, id); @@ -60,10 +61,19 @@ fn get_extmarks() { assert_eq!(Some(0), infos.end_row); assert_eq!(Some(String::from("Bar")), infos.hl_group); assert_eq!(Some(ExtmarkHlMode::Combine), infos.hl_mode); - assert_eq!( - Some(vec![("".into(), "Foo".into()), ("foo".into(), "Bar".into())]), - infos.virt_text - ); + + #[cfg(feature = "neovim-nightly")] + let virt_text = vec![( + "foo".to_owned(), + vec!["Foo".to_owned(), "Bar".to_owned()].into(), + )]; + + #[cfg(not(feature = "neovim-nightly"))] + let virt_text = + vec![("".into(), "Foo".into()), ("foo".into(), "Bar".into())]; + + assert_eq!(Some(virt_text), infos.virt_text); + assert_eq!(Some(ExtmarkVirtTextPosition::Overlay), infos.virt_text_pos); } @@ -154,14 +164,22 @@ fn set_get_del_extmark() { assert_eq!(Some(0), infos.end_row); assert_eq!(Some(String::from("Bar")), infos.hl_group); assert_eq!(Some(ExtmarkHlMode::Combine), infos.hl_mode); - assert_eq!( - Some(vec![ - ("foo".into(), "Foo".into()), - ("".into(), "Bar".into()), - ("bar".into(), "Baz".into()) - ]), - infos.virt_text - ); + + #[cfg(feature = "neovim-nightly")] + let virt_text = vec![ + ("foo".to_owned(), "Foo".into()), + ("bar".to_owned(), vec!["Bar".to_owned(), "Baz".to_owned()].into()), + ]; + + #[cfg(not(feature = "neovim-nightly"))] + let virt_text = vec![ + ("foo".into(), "Foo".into()), + ("".into(), "Bar".into()), + ("bar".into(), "Baz".into()), + ]; + + assert_eq!(Some(virt_text), infos.virt_text); + assert_eq!(Some(ExtmarkVirtTextPosition::Overlay), infos.virt_text_pos); let res = buf.del_extmark(ns_id, extmark_id);