From c0cf31da50c4bb18174604265813fc8c65884f41 Mon Sep 17 00:00:00 2001 From: Alex Rocha Date: Wed, 22 Oct 2025 19:12:20 +0100 Subject: [PATCH] Handle RBSString types --- rust/ruby-rbs/build.rs | 33 ++++++++++++++++++++++++++++++++- rust/ruby-rbs/src/lib.rs | 18 ++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/rust/ruby-rbs/build.rs b/rust/ruby-rbs/build.rs index 299145f81..7f39c29e1 100644 --- a/rust/ruby-rbs/build.rs +++ b/rust/ruby-rbs/build.rs @@ -6,10 +6,17 @@ struct Config { nodes: Vec, } +#[derive(Debug, Deserialize)] +struct NodeField { + name: String, + c_type: String, +} + #[derive(Debug, Deserialize)] struct Node { name: String, rust_name: String, + fields: Option>, } fn main() -> Result<(), Box> { @@ -40,7 +47,31 @@ fn generate(config: &Config) -> Result<(), Box> { // TODO: Go through all of the nodes and generate the structs to back them up for node in &config.nodes { - writeln!(file, "pub struct {} {{}}\n", node.rust_name)?; + writeln!(file, "pub struct {} {{", node.rust_name)?; + if let Some(fields) = &node.fields { + for field in fields { + match field.c_type.as_str() { + "rbs_string" => writeln!(file, " {}: *const rbs_string_t,", field.name)?, + _ => eprintln!("Unknown field type: {}", field.c_type), + } + } + } + writeln!(file, "}}\n")?; + + writeln!(file, "impl {} {{", node.rust_name)?; + if let Some(fields) = &node.fields { + for field in fields { + match field.c_type.as_str() { + "rbs_string" => { + writeln!(file, " pub fn {}(&self) -> RBSString {{", field.name)?; + writeln!(file, " RBSString::new(self.{})", field.name)?; + writeln!(file, " }}")?; + } + _ => eprintln!("Unknown field type: {}", field.c_type), + } + } + } + writeln!(file, "}}\n")?; } // Generate the Node enum to wrap all of the structs diff --git a/rust/ruby-rbs/src/lib.rs b/rust/ruby-rbs/src/lib.rs index 44ae78fca..909a616f2 100644 --- a/rust/ruby-rbs/src/lib.rs +++ b/rust/ruby-rbs/src/lib.rs @@ -1 +1,19 @@ include!(concat!(env!("OUT_DIR"), "/bindings.rs")); +use ruby_rbs_sys::bindings::*; + +pub struct RBSString { + pointer: *const rbs_string_t, +} + +impl RBSString { + pub fn new(pointer: *const rbs_string_t) -> Self { + Self { pointer } + } + + pub fn as_bytes(&self) -> &[u8] { + unsafe { + let s = *self.pointer; + std::slice::from_raw_parts(s.start as *const u8, s.end.offset_from(s.start) as usize) + } + } +}