1use std::slice;
4
5use super::count;
6use crate::value::{self, Slot, TypeDesc};
7
8#[unsafe(no_mangle)]
13pub(crate) unsafe extern "C" fn nf_string_new(bytes: *const u8, len: usize) -> Slot {
14 let bytes = unsafe { slice::from_raw_parts(bytes, len) };
16 value::string_slot(String::from_utf8_lossy(bytes))
17}
18
19#[unsafe(no_mangle)]
21pub(crate) extern "C" fn nf_string_concat(a: Slot, b: Slot) -> Slot {
22 value::string_slot([value::as_str(a), value::as_str(b)].concat())
23}
24
25#[unsafe(no_mangle)]
27pub(crate) extern "C" fn nf_string_len(text: Slot) -> i64 {
28 count(value::as_str(text).chars().count())
29}
30
31#[unsafe(no_mangle)]
33pub(crate) extern "C" fn nf_string_compare(a: Slot, b: Slot) -> i32 {
34 match value::as_str(a).cmp(value::as_str(b)) {
35 std::cmp::Ordering::Less => -1,
36 std::cmp::Ordering::Equal => 0,
37 std::cmp::Ordering::Greater => 1,
38 }
39}
40
41#[unsafe(no_mangle)]
43pub(crate) extern "C" fn nf_text_new() -> *mut String {
44 Box::into_raw(Box::default())
45}
46
47#[unsafe(no_mangle)]
52pub(crate) unsafe extern "C" fn nf_text_push_str(text: *mut String, bytes: *const u8, len: usize) {
53 let (text, bytes) = unsafe { (&mut *text, slice::from_raw_parts(bytes, len)) };
55 text.push_str(&String::from_utf8_lossy(bytes));
56}
57
58#[unsafe(no_mangle)]
63pub(crate) unsafe extern "C" fn nf_text_push(text: *mut String, slot: Slot, ty: &TypeDesc) {
64 value::write(unsafe { &mut *text }, slot, ty);
66}
67
68#[unsafe(no_mangle)]
71pub(crate) unsafe extern "C" fn nf_text_finish(text: *mut String) -> Slot {
72 let text = unsafe { Box::from_raw(text) };
74 value::string_slot(*text)
75}