Skip to main content

ytil_noxi/
extract.rs

1//! Primitive extraction trait implementations for Nvim `Object` kinds.
2
3use nvim_oxi::Dictionary;
4use nvim_oxi::Object;
5use nvim_oxi::ObjectKind;
6use rootcause::prelude::ResultExt;
7
8/// Trait for extracting typed values from Nvim objects.
9pub trait OxiExtract {
10    type Out;
11
12    /// Extracts a typed value from an Nvim [`Object`] by key from a [`Dictionary`] with error context.
13    ///
14    /// # Errors
15    /// - The value has a different kind than expected for the target type.
16    fn extract_from_dict(key: &str, value: &Object, dict: &Dictionary) -> rootcause::Result<Self::Out>;
17}
18
19/// Implementation for extracting [`String`] values from Nvim objects.
20impl OxiExtract for nvim_oxi::String {
21    type Out = String;
22
23    /// Extract from dict.
24    fn extract_from_dict(key: &str, value: &Object, dict: &Dictionary) -> rootcause::Result<Self::Out> {
25        let out = Self::try_from(value.clone())
26            .context("unexpected object kind")
27            .attach_with(|| unexpected_kind_error_msg(value, key, dict, ObjectKind::String))?;
28        Ok(out.to_string())
29    }
30}
31
32/// Implementation for extracting [`i64`] values from Nvim objects.
33impl OxiExtract for nvim_oxi::Integer {
34    type Out = Self;
35
36    /// Extract from dict.
37    fn extract_from_dict(key: &str, value: &Object, dict: &Dictionary) -> rootcause::Result<Self::Out> {
38        let out = Self::try_from(value.clone())
39            .context("unexpected object kind")
40            .attach_with(|| unexpected_kind_error_msg(value, key, dict, ObjectKind::Integer))?;
41        Ok(out)
42    }
43}
44
45/// Generates an error message for unexpected [`Object`] kind.
46pub fn unexpected_kind_error_msg(obj: &Object, key: &str, dict: &Dictionary, expected_kind: ObjectKind) -> String {
47    format!(
48        "value {obj:#?} of key {key:?} in dict {dict:#?} is {0:#?} but {expected_kind:?} was expected",
49        obj.kind()
50    )
51}