11include ! ( concat!( env!( "OUT_DIR" ) , "/bindings.rs" ) ) ;
2+ use rbs_encoding_type_t:: RBS_ENCODING_UTF_8 ;
23use ruby_rbs_sys:: bindings:: * ;
4+ use std:: sync:: Once ;
5+
6+ static INIT : Once = Once :: new ( ) ;
7+
8+ /// Parse RBS code into an AST.
9+ ///
10+ /// ```rust
11+ /// use ruby_rbs::parse;
12+ /// let rbs_code = r#"type foo = "hello""#;
13+ /// let signature = parse(rbs_code.as_bytes());
14+ /// assert!(signature.is_ok(), "Failed to parse RBS signature");
15+ /// ```
16+ pub fn parse ( rbs_code : & [ u8 ] ) -> Result < * mut rbs_signature_t , String > {
17+ unsafe {
18+ INIT . call_once ( || {
19+ rbs_constant_pool_init ( RBS_GLOBAL_CONSTANT_POOL , 26 ) ;
20+ } ) ;
21+
22+ let start_ptr = rbs_code. as_ptr ( ) as * const i8 ;
23+ let end_ptr = start_ptr. add ( rbs_code. len ( ) ) ;
24+
25+ let raw_rbs_string_value = rbs_string_new ( start_ptr, end_ptr) ;
26+
27+ let encoding_ptr = & rbs_encodings[ RBS_ENCODING_UTF_8 as usize ] as * const rbs_encoding_t ;
28+ let parser = rbs_parser_new ( raw_rbs_string_value, encoding_ptr, 0 , rbs_code. len ( ) as i32 ) ;
29+
30+ let mut signature: * mut rbs_signature_t = std:: ptr:: null_mut ( ) ;
31+ let result = rbs_parse_signature ( parser, & mut signature) ;
32+
33+ rbs_parser_free ( parser) ;
34+
35+ if result {
36+ Ok ( signature)
37+ } else {
38+ Err ( String :: from ( "Failed to parse RBS signature" ) )
39+ }
40+ }
41+ }
342
443pub struct RBSString {
544 pointer : * const rbs_string_t ,
@@ -17,3 +56,19 @@ impl RBSString {
1756 }
1857 }
1958}
59+
60+ #[ cfg( test) ]
61+ mod tests {
62+ use super :: * ;
63+
64+ #[ test]
65+ fn test_parse ( ) {
66+ let rbs_code = r#"type foo = "hello""# ;
67+ let signature = parse ( rbs_code. as_bytes ( ) ) ;
68+ assert ! ( signature. is_ok( ) , "Failed to parse RBS signature" ) ;
69+
70+ let rbs_code2 = r#"class Foo end"# ;
71+ let signature2 = parse ( rbs_code2. as_bytes ( ) ) ;
72+ assert ! ( signature2. is_ok( ) , "Failed to parse RBS signature" ) ;
73+ }
74+ }
0 commit comments