devela/lang/ffi/js/
namespace.rs1use devela::{JsConsole, Str, js_int32, js_uint32};
7#[cfg(all(feature = "alloc", unsafe··))]
8use devela::{String, Vec};
9
10#[doc = crate::TAG_NAMESPACE!()]
11#[derive(Debug)]
15pub struct Js;
16
17#[rustfmt::skip]
18impl Js {
19 pub fn console() -> JsConsole { JsConsole }
21}
22
23impl Js {
25 #[inline(always)]
31 pub fn read_str(
32 buffer: &mut [u8],
33 mut write_fn: impl FnMut(*mut u8, js_uint32) -> js_int32,
34 ) -> &str {
35 let ptr = buffer.as_mut_ptr();
36 let cap = buffer.len() as js_uint32;
37 let len = write_fn(ptr, cap) as usize;
38 Str::from_utf8(&buffer[..len]).expect("Valid UTF-8") }
40
41 #[inline(always)]
47 #[cfg(not(feature = "safe_lang"))]
48 #[cfg(all(feature = "alloc", unsafe··))]
49 #[cfg_attr(nightly_doc, doc(cfg(all(feature = "alloc", unsafe··))))]
50 pub fn read_string(write_fn: impl FnMut(*mut u8, js_uint32) -> js_int32) -> String {
51 Js::read_string_capped(128, false, write_fn)
52 }
53
54 #[cfg(not(feature = "safe_lang"))]
60 #[cfg(all(feature = "alloc", unsafe··))]
61 #[cfg_attr(nightly_doc, doc(cfg(all(feature = "alloc", unsafe··))))]
62 pub fn read_string_capped(
63 mut cap: js_uint32,
64 truncate: bool,
65 mut write_fn: impl FnMut(*mut u8, js_uint32) -> js_int32,
66 ) -> String {
67 loop {
68 let mut vec = Vec::with_capacity(cap as usize);
69 let ptr = vec.as_mut_ptr();
70 let result = write_fn(ptr, cap);
71 if !truncate && result < 0 {
72 cap = (-result) as js_uint32;
73 continue;
74 }
75 unsafe {
76 vec.set_len(result as usize);
77 return String::from_utf8_unchecked(vec);
78 }
79 }
80 }
81}