nvim_api/
trait_utils.rs

1use luajit_bindings::{Poppable, Pushable};
2use nvim_types::{Array, Function, Object};
3
4macro_rules! impl_into {
5    ($trait:ident, $type:ty) => {
6        impl $trait for $type {
7            fn to_object(self) -> Object {
8                self.into()
9            }
10        }
11    };
12}
13
14/// A string or an integer.
15pub trait StringOrInt {
16    fn to_object(self) -> Object;
17}
18
19impl_into!(StringOrInt, &str);
20impl_into!(StringOrInt, String);
21impl_into!(StringOrInt, i8);
22impl_into!(StringOrInt, u8);
23impl_into!(StringOrInt, i16);
24impl_into!(StringOrInt, u16);
25impl_into!(StringOrInt, i32);
26impl_into!(StringOrInt, u32);
27impl_into!(StringOrInt, i64);
28
29/// A string or a list of strings.
30pub trait StringOrListOfStrings {
31    fn to_object(self) -> Object;
32}
33
34impl_into!(StringOrListOfStrings, &str);
35impl_into!(StringOrListOfStrings, String);
36
37// Here I'd like to use `IntoIterator` instead of `Vec`, but without
38// specilization that'd cause conflicting impls.
39impl<S: Into<String>> StringOrListOfStrings for Vec<S> {
40    #[inline]
41    fn to_object(self) -> Object {
42        Array::from_iter(self.into_iter().map(Into::into)).into()
43    }
44}
45
46/// A Rust closure or a [`Function`].
47pub trait ToFunction<A, R> {
48    fn to_object(self) -> Object;
49}
50
51impl<A, R, F> ToFunction<A, R> for F
52where
53    A: Poppable,
54    R: Pushable,
55    F: FnMut(A) -> crate::Result<R> + 'static,
56{
57    #[inline]
58    fn to_object(self) -> Object {
59        Function::from_fn_mut(self).into()
60    }
61}
62
63impl<A, R> ToFunction<A, R> for Function<A, R> {
64    #[inline]
65    fn to_object(self) -> Object {
66        self.into()
67    }
68}
69
70/// A Rust closure, a [`Function`] or a string.
71pub trait StringOrFunction<A, R> {
72    fn to_object(self) -> Object;
73}
74
75impl<A, R> StringOrFunction<A, R> for &str {
76    #[inline]
77    fn to_object(self) -> Object {
78        self.into()
79    }
80}
81
82impl<A, R> StringOrFunction<A, R> for String {
83    #[inline]
84    fn to_object(self) -> Object {
85        self.into()
86    }
87}
88
89impl<A, R, F> StringOrFunction<A, R> for F
90where
91    A: Poppable,
92    R: Pushable,
93    F: FnMut(A) -> crate::Result<R> + 'static,
94{
95    #[inline]
96    fn to_object(self) -> Object {
97        Function::from_fn_mut(self).into()
98    }
99}
100
101impl<A, R> StringOrFunction<A, R> for Function<A, R> {
102    #[inline]
103    fn to_object(self) -> Object {
104        self.into()
105    }
106}