use std::mem::ManuallyDrop; use std::str; use napi::{ noop_finalize, CallContext, ContextlessResult, Env, Error, JsBuffer, JsNumber, JsObject, JsString, JsUndefined, Result, Status, }; #[js_function(1)] pub fn get_buffer_length(ctx: CallContext) -> Result { let buffer = ctx.get::(0)?.into_value()?; ctx.env.create_uint32((&buffer).len() as u32) } #[js_function(1)] pub fn buffer_to_string(ctx: CallContext) -> Result { let buffer = ctx.get::(0)?.into_value()?; ctx.env.create_string( str::from_utf8(&buffer).map_err(|e| Error::new(Status::StringExpected, format!("{}", e)))?, ) } #[js_function(1)] pub fn copy_buffer(ctx: CallContext) -> Result { let buffer = ctx.get::(0)?.into_value()?; ctx.env.create_buffer_copy(buffer).map(|b| b.into_raw()) } #[contextless_function] pub fn create_borrowed_buffer_with_noop_finalize(env: Env) -> ContextlessResult { let data = vec![1, 2, 3]; let data_ptr = data.as_ptr(); let length = data.len(); let manually_drop = ManuallyDrop::new(data); unsafe { env.create_buffer_with_borrowed_data(data_ptr, length, manually_drop, noop_finalize) } .map(|b| Some(b.into_raw())) } #[contextless_function] pub fn create_borrowed_buffer_with_finalize(env: Env) -> ContextlessResult { let data = vec![1, 2, 3]; let data_ptr = data.as_ptr(); let length = data.len(); let manually_drop = ManuallyDrop::new(data); unsafe { env.create_buffer_with_borrowed_data( data_ptr, length, manually_drop, |mut hint: ManuallyDrop>, _| { ManuallyDrop::drop(&mut hint); }, ) } .map(|b| Some(b.into_raw())) } #[js_function(1)] fn mutate_buffer(ctx: CallContext) -> Result { let buffer = &mut ctx.get::(0)?.into_value()?; buffer[1] = 42; ctx.env.get_undefined() } pub fn register_js(exports: &mut JsObject) -> Result<()> { exports.create_named_method("getBufferLength", get_buffer_length)?; exports.create_named_method("bufferToString", buffer_to_string)?; exports.create_named_method("copyBuffer", copy_buffer)?; exports.create_named_method( "createBorrowedBufferWithNoopFinalize", create_borrowed_buffer_with_noop_finalize, )?; exports.create_named_method( "createBorrowedBufferWithFinalize", create_borrowed_buffer_with_finalize, )?; exports.create_named_method("mutateBuffer", mutate_buffer)?; Ok(()) }