Extension methods to help with Rust FFI strings and vecs

This commit is contained in:
2025-11-28 04:24:34 -07:00
parent c97c5763ae
commit 4ac2e6408f
4 changed files with 74 additions and 1 deletions

View File

@@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Text;
using StationeersIC10Editor;
namespace Slang
{
public static unsafe class SlangExtensions
{
// 1. Convert the Rust Byte Vector (Vec_uint8_t) to a C# String
public static string AsString(this Vec_uint8_t vec)
{
if (vec.ptr == null || vec.len == UIntPtr.Zero)
{
return string.Empty;
}
// Rust strings are UTF-8. Read bytes from raw pointer.
var toReturn = Encoding.UTF8.GetString(vec.ptr, (int)vec.len);
return toReturn;
}
public static void Drop(this Vec_uint8_t vec)
{
Ffi.free_string(vec);
}
// 2. Convert Rust Token Vector to C# List
public static List<Token> AsList(this Vec_FfiToken_t vec)
{
var list = new List<Token>((int)vec.len);
var currentPtr = vec.ptr;
// Iterate through the raw memory array
for (int i = 0; i < (int)vec.len; i++)
{
// Dereference pointer to get the struct at index i
FfiToken_t token = currentPtr[i];
var newToken = new Token(token.text.AsString(), token.column);
newToken.Error = token.error.AsString();
list.Add(newToken);
}
Ffi.free_ffi_token_vec(vec);
return list;
}
}
}

View File

@@ -70,6 +70,18 @@ public unsafe struct Vec_FfiToken_t {
public UIntPtr cap; public UIntPtr cap;
} }
public unsafe partial class Ffi {
[DllImport(RustLib, ExactSpelling = true)] public static unsafe extern
void free_ffi_token_vec (
Vec_FfiToken_t v);
}
public unsafe partial class Ffi {
[DllImport(RustLib, ExactSpelling = true)] public static unsafe extern
void free_string (
Vec_uint8_t s);
}
public unsafe partial class Ffi { public unsafe partial class Ffi {
[DllImport(RustLib, ExactSpelling = true)] public static unsafe extern [DllImport(RustLib, ExactSpelling = true)] public static unsafe extern
Vec_FfiToken_t tokenize_line ( Vec_FfiToken_t tokenize_line (

View File

@@ -155,4 +155,3 @@ fn test_spilled_variable_update_in_branch() -> anyhow::Result<()> {
Ok(()) Ok(())
} }

View File

@@ -69,6 +69,16 @@ pub fn tokenize_line(input: safer_ffi::char_p::char_p_ref<'_>) -> safer_ffi::Vec
tokens.into() tokens.into()
} }
#[ffi_export]
pub fn free_ffi_token_vec(v: safer_ffi::Vec<FfiToken>) {
drop(v)
}
#[ffi_export]
pub fn free_string(s: safer_ffi::String) {
drop(s)
}
#[cfg(feature = "headers")] #[cfg(feature = "headers")]
pub fn generate_headers() -> std::io::Result<()> { pub fn generate_headers() -> std::io::Result<()> {
::safer_ffi::headers::builder() ::safer_ffi::headers::builder()