use std::iter::FusedIterator;
use oxi_luajit::{Poppable, Pushable};
#[cfg(feature = "neovim-nightly")]
use oxi_types::{self as types, HlGroupId, Integer};
use oxi_types::{Array, Function, LuaRef, Object};
pub trait SuperIterator<I>:
Iterator<Item = I> + ExactSizeIterator + DoubleEndedIterator + FusedIterator
{
}
impl<I, T> SuperIterator<I> for T where
T: Iterator<Item = I>
+ ExactSizeIterator
+ DoubleEndedIterator
+ FusedIterator
{
}
macro_rules! impl_into {
($trait:ident, $type:ty) => {
impl $trait for $type {
fn to_object(self) -> Object {
self.into()
}
}
};
}
pub trait StringOrInt {
fn to_object(self) -> Object;
}
impl_into!(StringOrInt, &str);
impl_into!(StringOrInt, String);
impl_into!(StringOrInt, i8);
impl_into!(StringOrInt, u8);
impl_into!(StringOrInt, i16);
impl_into!(StringOrInt, u16);
impl_into!(StringOrInt, i32);
impl_into!(StringOrInt, u32);
impl_into!(StringOrInt, i64);
pub trait StringOrListOfStrings {
fn to_object(self) -> Object;
}
impl_into!(StringOrListOfStrings, &str);
impl_into!(StringOrListOfStrings, String);
impl<S: Into<String>> StringOrListOfStrings for Vec<S> {
#[inline]
fn to_object(self) -> Object {
Array::from_iter(self.into_iter().map(Into::into)).into()
}
}
pub trait ToFunction<A, R> {
fn into_luaref(self) -> LuaRef;
}
impl<A, R, F> ToFunction<A, R> for F
where
A: Poppable,
R: Pushable,
F: FnMut(A) -> crate::Result<R> + 'static,
{
#[inline]
fn into_luaref(self) -> LuaRef {
Function::from_fn_mut(self).lua_ref()
}
}
impl<A, R> ToFunction<A, R> for Function<A, R> {
#[inline]
fn into_luaref(self) -> LuaRef {
self.lua_ref()
}
}
pub trait StringOrFunction<A, R> {
fn to_object(self) -> Object;
}
impl<A, R> StringOrFunction<A, R> for &str {
#[inline]
fn to_object(self) -> Object {
self.into()
}
}
impl<A, R> StringOrFunction<A, R> for String {
#[inline]
fn to_object(self) -> Object {
self.into()
}
}
impl<A, R, F> StringOrFunction<A, R> for F
where
A: Poppable,
R: Pushable,
F: FnMut(A) -> crate::Result<R> + 'static,
{
#[inline]
fn to_object(self) -> Object {
Function::from_fn_mut(self).into()
}
}
impl<A, R> StringOrFunction<A, R> for Function<A, R> {
#[inline]
fn to_object(self) -> Object {
self.into()
}
}
#[cfg(feature = "neovim-nightly")]
#[cfg_attr(docsrs, doc(cfg(feature = "neovim-nightly")))]
pub trait HlGroup: sealed::Sealed {
type Error;
fn to_hl_id(&self) -> Result<HlGroupId, Self::Error>;
}
#[cfg(feature = "neovim-nightly")]
impl HlGroup for Integer {
type Error = core::convert::Infallible;
#[inline(always)]
fn to_hl_id(&self) -> Result<HlGroupId, Self::Error> {
Ok(*self)
}
}
#[cfg(feature = "neovim-nightly")]
impl HlGroup for &str {
type Error = crate::Error;
#[inline]
fn to_hl_id(&self) -> Result<HlGroupId, Self::Error> {
let obj = oxi_types::String::from(*self).into();
let mut err = types::Error::default();
let hl_id = unsafe {
crate::ffi::helpers::object_to_hl_id(
obj,
b"hl_group\0".as_ptr() as *const _,
&mut err,
)
};
if err.is_err() {
Err(err.into())
} else {
Ok(hl_id)
}
}
}
mod sealed {
pub trait Sealed {}
impl Sealed for oxi_types::Integer {}
impl Sealed for &str {}
}