Skip to content

Commit d60e030

Browse files
committed
Handle RBSString types (#52)
Handle rbs_string field types when generating Rust structs from config.yml. The RBSString struct wraps rbs_string_t pointers and provides an as_bytes() method that safely calculates string length using pointer arithmetic.
1 parent d1aa329 commit d60e030

2 files changed

Lines changed: 50 additions & 1 deletion

File tree

rust/ruby-rbs/build.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,17 @@ struct Config {
66
nodes: Vec<Node>,
77
}
88

9+
#[derive(Debug, Deserialize)]
10+
struct NodeField {
11+
name: String,
12+
c_type: String,
13+
}
14+
915
#[derive(Debug, Deserialize)]
1016
struct Node {
1117
name: String,
1218
rust_name: String,
19+
fields: Option<Vec<NodeField>>,
1320
}
1421

1522
fn main() -> Result<(), Box<dyn Error>> {
@@ -40,7 +47,31 @@ fn generate(config: &Config) -> Result<(), Box<dyn Error>> {
4047

4148
// TODO: Go through all of the nodes and generate the structs to back them up
4249
for node in &config.nodes {
43-
writeln!(file, "pub struct {} {{}}\n", node.rust_name)?;
50+
writeln!(file, "pub struct {} {{", node.rust_name)?;
51+
if let Some(fields) = &node.fields {
52+
for field in fields {
53+
match field.c_type.as_str() {
54+
"rbs_string" => writeln!(file, " {}: *const rbs_string_t,", field.name)?,
55+
_ => eprintln!("Unknown field type: {}", field.c_type),
56+
}
57+
}
58+
}
59+
writeln!(file, "}}\n")?;
60+
61+
writeln!(file, "impl {} {{", node.rust_name)?;
62+
if let Some(fields) = &node.fields {
63+
for field in fields {
64+
match field.c_type.as_str() {
65+
"rbs_string" => {
66+
writeln!(file, " pub fn {}(&self) -> RBSString {{", field.name)?;
67+
writeln!(file, " RBSString::new(self.{})", field.name)?;
68+
writeln!(file, " }}")?;
69+
}
70+
_ => eprintln!("Unknown field type: {}", field.c_type),
71+
}
72+
}
73+
}
74+
writeln!(file, "}}\n")?;
4475
}
4576

4677
// Generate the Node enum to wrap all of the structs

rust/ruby-rbs/src/lib.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,19 @@
11
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
2+
use ruby_rbs_sys::bindings::*;
3+
4+
pub struct RBSString {
5+
pointer: *const rbs_string_t,
6+
}
7+
8+
impl RBSString {
9+
pub fn new(pointer: *const rbs_string_t) -> Self {
10+
Self { pointer }
11+
}
12+
13+
pub fn as_bytes(&self) -> &[u8] {
14+
unsafe {
15+
let s = *self.pointer;
16+
std::slice::from_raw_parts(s.start as *const u8, s.end.offset_from(s.start) as usize)
17+
}
18+
}
19+
}

0 commit comments

Comments
 (0)