mirror of
https://github.com/noib3/nvim-oxi.git
synced 2025-07-07 21:35: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::object::{FromObject, ToObject};
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||||
pub struct Buffer(BufHandle);
|
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 {
|
impl fmt::Display for Buffer {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
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::marker::PhantomData;
|
||||||
|
use std::result::Result as StdResult;
|
||||||
use std::{fmt, mem, ptr};
|
use std::{fmt, mem, ptr};
|
||||||
|
|
||||||
use libc::c_int;
|
use libc::c_int;
|
||||||
use nvim_types::{object, LuaRef};
|
use nvim_types::{object, LuaRef};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{de, ser};
|
||||||
|
|
||||||
use super::ffi::*;
|
use super::ffi::*;
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
|
||||||
macro_rules! define {
|
macro_rules! define {
|
||||||
($name:ident) => {
|
($name:ident) => {
|
||||||
// TODO: custom impls for serialize & deserialize
|
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)]
|
|
||||||
pub struct $name<A, R>(
|
pub struct $name<A, R>(
|
||||||
pub(crate) LuaRef,
|
pub(crate) LuaRef,
|
||||||
PhantomData<A>,
|
PhantomData<A>,
|
||||||
|
@ -66,6 +66,78 @@ from_fn_for_object!(LuaFn);
|
||||||
from_fn_for_object!(LuaFnMut);
|
from_fn_for_object!(LuaFnMut);
|
||||||
from_fn_for_object!(LuaFnOnce);
|
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 {
|
macro_rules! create_ref {
|
||||||
($lstate:ident, $fun:ident, $cb:ident) => {
|
($lstate:ident, $fun:ident, $cb:ident) => {
|
||||||
super::with_state(move |$lstate| unsafe {
|
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 {
|
macro_rules! call_body {
|
||||||
($self:ident, $args:ident) => {
|
($self:ident, $args:ident) => {
|
||||||
todo!()
|
todo!()
|
||||||
|
@ -177,8 +237,6 @@ where
|
||||||
A: super::LuaPoppable,
|
A: super::LuaPoppable,
|
||||||
R: super::LuaPushable,
|
R: super::LuaPushable,
|
||||||
{
|
{
|
||||||
unref!();
|
|
||||||
|
|
||||||
pub fn _call(&self, _args: A) -> crate::Result<R> {
|
pub fn _call(&self, _args: A) -> crate::Result<R> {
|
||||||
call_body!(self, _args)
|
call_body!(self, _args)
|
||||||
}
|
}
|
||||||
|
@ -189,8 +247,6 @@ where
|
||||||
A: super::LuaPoppable,
|
A: super::LuaPoppable,
|
||||||
R: super::LuaPushable,
|
R: super::LuaPushable,
|
||||||
{
|
{
|
||||||
unref!();
|
|
||||||
|
|
||||||
pub fn _call(&mut self, _args: A) -> crate::Result<R> {
|
pub fn _call(&mut self, _args: A) -> crate::Result<R> {
|
||||||
call_body!(self, _args)
|
call_body!(self, _args)
|
||||||
}
|
}
|
||||||
|
@ -201,9 +257,14 @@ where
|
||||||
A: super::LuaPoppable,
|
A: super::LuaPoppable,
|
||||||
R: super::LuaPushable,
|
R: super::LuaPushable,
|
||||||
{
|
{
|
||||||
unref!();
|
|
||||||
|
|
||||||
pub fn _call(self, _args: A) -> crate::Result<R> {
|
pub fn _call(self, _args: A) -> crate::Result<R> {
|
||||||
call_body!(self, _args)
|
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),
|
kObjectTypeArray => self.deserialize_seq(visitor),
|
||||||
kObjectTypeDictionary => self.deserialize_map(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"
|
imports_layout = "HorizontalVertical"
|
||||||
match_block_trailing_comma = true
|
match_block_trailing_comma = true
|
||||||
max_width = 79
|
max_width = 79
|
||||||
reorder_impl_items = true
|
|
||||||
unstable_features = true
|
unstable_features = true
|
||||||
use_field_init_shorthand = true
|
use_field_init_shorthand = true
|
||||||
use_small_heuristics = "Max"
|
use_small_heuristics = "Max"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue