@@ -16,11 +16,12 @@ pub fn parse(rbs_code: &[u8]) -> Result<SignatureNode<'_>, String> {
1616 unsafe {
1717 let start_ptr = rbs_code. as_ptr ( ) as * const i8 ;
1818 let end_ptr = start_ptr. add ( rbs_code. len ( ) ) ;
19+ let bytes = rbs_code. len ( ) as i32 ;
1920
2021 let raw_rbs_string_value = rbs_string_new ( start_ptr, end_ptr) ;
2122
2223 let encoding_ptr = & rbs_encodings[ RBS_ENCODING_UTF_8 as usize ] as * const rbs_encoding_t ;
23- let parser = rbs_parser_new ( raw_rbs_string_value, encoding_ptr, 0 , rbs_code . len ( ) as i32 ) ;
24+ let parser = rbs_parser_new ( raw_rbs_string_value, encoding_ptr, 0 , bytes ) ;
2425
2526 let mut signature: * mut rbs_signature_t = std:: ptr:: null_mut ( ) ;
2627 let result = rbs_parse_signature ( parser, & mut signature) ;
@@ -34,7 +35,18 @@ pub fn parse(rbs_code: &[u8]) -> Result<SignatureNode<'_>, String> {
3435 if result {
3536 Ok ( signature_node)
3637 } else {
37- Err ( String :: from ( "Failed to parse RBS signature" ) )
38+ let error_message = ( * parser)
39+ . error
40+ . as_ref ( )
41+ . filter ( |error| !error. message . is_null ( ) )
42+ . map ( |error| {
43+ std:: ffi:: CStr :: from_ptr ( error. message )
44+ . to_string_lossy ( )
45+ . into_owned ( )
46+ } )
47+ . unwrap_or_else ( || String :: from ( "Failed to parse RBS signature" ) ) ;
48+
49+ Err ( error_message)
3850 }
3951 }
4052}
@@ -267,6 +279,14 @@ impl SymbolNode<'_> {
267279mod tests {
268280 use super :: * ;
269281
282+ #[ test]
283+ fn test_parse_error_contains_actual_message ( ) {
284+ let rbs_code = "class { end" ;
285+ let result = parse ( rbs_code. as_bytes ( ) ) ;
286+ let error_message = result. unwrap_err ( ) ;
287+ assert_eq ! ( error_message, "expected one of class/module/constant name" ) ;
288+ }
289+
270290 #[ test]
271291 fn test_parse ( ) {
272292 let rbs_code = r#"type foo = "hello""# ;
0 commit comments