use std::{mem, ops::Deref}; use mlua::{UserData, prelude::LuaUserDataMethods}; use tokio::sync::SemaphorePermit; pub type PermitRef = mlua::UserDataRef>; pub struct Permit { inner: Option>, destruct: Option, } impl Deref for Permit { type Target = Option>; fn deref(&self) -> &Self::Target { &self.inner } } impl Permit { pub fn new(inner: SemaphorePermit<'static>, f: F) -> Self { Self { inner: Some(inner), destruct: Some(f) } } fn dropping(&mut self) { if let Some(f) = self.destruct.take() { f(); } if let Some(p) = self.inner.take() { mem::drop(p); } } } impl Drop for Permit { fn drop(&mut self) { self.dropping(); } } impl UserData for Permit { fn add_methods>(methods: &mut M) { methods.add_method_mut("drop", |_, me, ()| Ok(me.dropping())); } }