mirror of
https://github.com/noib3/nvim-oxi.git
synced 2025-07-07 13:25:18 +00:00
✨ implement (De)Serialize
for LuaFn
, LuaFnMut
and LuaFnOnce
This commit is contained in:
parent
13bd0552f7
commit
9f7a95aa6c
11 changed files with 105 additions and 26 deletions
|
@ -0,0 +1 @@
|
|||
|
|
@ -22,12 +22,18 @@ use crate::lua::{LuaFnOnce, LUA_INTERNAL_CALL};
|
|||
use crate::object::{FromObject, ToObject};
|
||||
use crate::Result;
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct Buffer(BufHandle);
|
||||
|
||||
impl fmt::Debug for Buffer {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_tuple("Buffer").field(&self.0).finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Buffer {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Buffer({})", self.0)
|
||||
write!(f, "{self:?}")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
use std::marker::PhantomData;
|
||||
use std::result::Result as StdResult;
|
||||
use std::{fmt, mem, ptr};
|
||||
|
||||
use libc::c_int;
|
||||
use nvim_types::{object, LuaRef};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::{de, ser};
|
||||
|
||||
use super::ffi::*;
|
||||
use crate::Result;
|
||||
|
||||
macro_rules! define {
|
||||
($name:ident) => {
|
||||
// TODO: custom impls for serialize & deserialize
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct $name<A, R>(
|
||||
pub(crate) LuaRef,
|
||||
PhantomData<A>,
|
||||
|
@ -66,6 +66,78 @@ from_fn_for_object!(LuaFn);
|
|||
from_fn_for_object!(LuaFnMut);
|
||||
from_fn_for_object!(LuaFnOnce);
|
||||
|
||||
macro_rules! deserialize {
|
||||
($name:ident, $visitor:ident) => {
|
||||
impl<'de, A, R> de::Deserialize<'de> for $name<A, R>
|
||||
where
|
||||
A: super::LuaPoppable,
|
||||
R: super::LuaPushable,
|
||||
{
|
||||
fn deserialize<D>(
|
||||
deserializer: D,
|
||||
) -> StdResult<$name<A, R>, D::Error>
|
||||
where
|
||||
D: de::Deserializer<'de>,
|
||||
{
|
||||
struct $visitor<A, R>(PhantomData<A>, PhantomData<R>);
|
||||
|
||||
impl<'de, A, R> de::Visitor<'de> for $visitor<A, R>
|
||||
where
|
||||
A: super::LuaPoppable,
|
||||
R: super::LuaPushable,
|
||||
{
|
||||
type Value = $name<A, R>;
|
||||
|
||||
fn expecting(
|
||||
&self,
|
||||
f: &mut fmt::Formatter,
|
||||
) -> fmt::Result {
|
||||
f.write_str("an f32 representing a Lua reference")
|
||||
}
|
||||
|
||||
fn visit_f32<E>(
|
||||
self,
|
||||
value: f32,
|
||||
) -> StdResult<Self::Value, E>
|
||||
where
|
||||
E: de::Error,
|
||||
{
|
||||
Ok($name(value as i32, PhantomData, PhantomData))
|
||||
}
|
||||
}
|
||||
|
||||
deserializer
|
||||
.deserialize_f32($visitor(PhantomData, PhantomData))
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
deserialize!(LuaFn, LuaFnVisitor);
|
||||
deserialize!(LuaFnMut, LuaFnMutVisitor);
|
||||
deserialize!(LuaFnOnce, LuaFnOnceVisitor);
|
||||
|
||||
macro_rules! serialize {
|
||||
($name:ident) => {
|
||||
impl<A, R> ser::Serialize for $name<A, R>
|
||||
where
|
||||
A: super::LuaPoppable,
|
||||
R: super::LuaPushable,
|
||||
{
|
||||
fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
|
||||
where
|
||||
S: ser::Serializer,
|
||||
{
|
||||
serializer.serialize_f32(self.0 as f32)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
serialize!(LuaFn);
|
||||
serialize!(LuaFnMut);
|
||||
serialize!(LuaFnOnce);
|
||||
|
||||
macro_rules! create_ref {
|
||||
($lstate:ident, $fun:ident, $cb:ident) => {
|
||||
super::with_state(move |$lstate| unsafe {
|
||||
|
@ -154,18 +226,6 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
macro_rules! unref {
|
||||
() => {
|
||||
/// Removes the stored reference from the Lua registry.
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn unref(self) {
|
||||
super::with_state(move |lstate| unsafe {
|
||||
luaL_unref(lstate, LUA_REGISTRYINDEX, self.0);
|
||||
})
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! call_body {
|
||||
($self:ident, $args:ident) => {
|
||||
todo!()
|
||||
|
@ -177,8 +237,6 @@ where
|
|||
A: super::LuaPoppable,
|
||||
R: super::LuaPushable,
|
||||
{
|
||||
unref!();
|
||||
|
||||
pub fn _call(&self, _args: A) -> crate::Result<R> {
|
||||
call_body!(self, _args)
|
||||
}
|
||||
|
@ -189,8 +247,6 @@ where
|
|||
A: super::LuaPoppable,
|
||||
R: super::LuaPushable,
|
||||
{
|
||||
unref!();
|
||||
|
||||
pub fn _call(&mut self, _args: A) -> crate::Result<R> {
|
||||
call_body!(self, _args)
|
||||
}
|
||||
|
@ -201,9 +257,14 @@ where
|
|||
A: super::LuaPoppable,
|
||||
R: super::LuaPushable,
|
||||
{
|
||||
unref!();
|
||||
|
||||
pub fn _call(self, _args: A) -> crate::Result<R> {
|
||||
call_body!(self, _args)
|
||||
}
|
||||
|
||||
/// Removes the stored reference from the Lua registry.
|
||||
pub(crate) fn unref(self) {
|
||||
super::with_state(move |lstate| unsafe {
|
||||
luaL_unref(lstate, LUA_REGISTRYINDEX, self.0);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,8 +42,14 @@ impl<'de> de::Deserializer<'de> for Deserializer {
|
|||
},
|
||||
kObjectTypeArray => self.deserialize_seq(visitor),
|
||||
kObjectTypeDictionary => self.deserialize_map(visitor),
|
||||
// TODO: map Lua functions to i32 for now.
|
||||
kObjectTypeLuaRef => visitor.visit_i32(unsafe { data.luaref }),
|
||||
|
||||
// We map the ref representing the index of the lua function in the
|
||||
// Lua registry to `f32`. It's definitely a hack, but Neovim rarely
|
||||
// returns a float so it should a good place to store it to avoid
|
||||
// collisions.
|
||||
kObjectTypeLuaRef => {
|
||||
visitor.visit_f32(unsafe { data.luaref } as f32)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ group_imports = "StdExternalCrate"
|
|||
imports_layout = "HorizontalVertical"
|
||||
match_block_trailing_comma = true
|
||||
max_width = 79
|
||||
reorder_impl_items = true
|
||||
unstable_features = true
|
||||
use_field_init_shorthand = true
|
||||
use_small_heuristics = "Max"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue