Skip to content

Commit b0271a1

Browse files
committed
refactor(rust): unify parse API with located errors
Drop the separate parse_commonjs_with_location entrypoint and make parse_commonjs return LocatedLexerError, so callers always get kind plus optional line/column.
1 parent 611a8db commit b0271a1

2 files changed

Lines changed: 19 additions & 76 deletions

File tree

rust/README.md

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,24 +51,13 @@ merve = { version = "...", features = ["libcpp"] }
5151
### `parse_commonjs`
5252

5353
```rust
54-
pub fn parse_commonjs(source: &str) -> Result<Analysis<'_>, LexerError>
54+
pub fn parse_commonjs(source: &str) -> Result<Analysis<'_>, LocatedLexerError>
5555
```
5656

5757
Parse CommonJS source code and extract export information. The returned
5858
`Analysis` borrows from `source` because export names may point directly into
5959
the source buffer (zero-copy).
6060

61-
### `parse_commonjs_with_location`
62-
63-
```rust
64-
pub fn parse_commonjs_with_location(
65-
source: &str,
66-
) -> Result<Analysis<'_>, LocatedLexerError>
67-
```
68-
69-
Like `parse_commonjs`, but returns a `LocatedLexerError` that includes
70-
`kind: LexerError` plus optional location (`line`, `column`).
71-
7261
### `Analysis<'a>`
7362

7463
| Method | Returns | Description |

rust/src/lib.rs

Lines changed: 18 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -377,11 +377,9 @@ impl ExactSizeIterator for ExportIter<'_, '_> {}
377377
///
378378
/// # Errors
379379
///
380-
/// Returns a [`LexerError`] if the input contains ESM syntax or other
380+
/// Returns a [`LocatedLexerError`] if the input contains ESM syntax or other
381381
/// unsupported constructs.
382382
///
383-
/// Use [`parse_commonjs_with_location`] for location-aware errors.
384-
///
385383
/// # Examples
386384
///
387385
/// ```
@@ -408,44 +406,7 @@ impl ExactSizeIterator for ExportIter<'_, '_> {}
408406
/// let _ = leaked;
409407
/// }
410408
/// ```
411-
pub fn parse_commonjs(source: &str) -> Result<Analysis<'_>, LexerError> {
412-
if source.is_empty() {
413-
return Err(LexerError::EmptySource);
414-
}
415-
let handle = unsafe {
416-
ffi::merve_parse_commonjs(source.as_ptr().cast(), source.len(), core::ptr::null_mut())
417-
};
418-
if handle.is_null() {
419-
// NULL means allocation failure; map to a generic error
420-
let code = unsafe { ffi::merve_get_last_error() };
421-
return Err(if code >= 0 {
422-
LexerError::from_code(code)
423-
} else {
424-
LexerError::Unknown(code)
425-
});
426-
}
427-
if !unsafe { ffi::merve_is_valid(handle) } {
428-
let code = unsafe { ffi::merve_get_last_error() };
429-
let err = if code >= 0 {
430-
LexerError::from_code(code)
431-
} else {
432-
LexerError::Unknown(code)
433-
};
434-
unsafe { ffi::merve_free(handle) };
435-
return Err(err);
436-
}
437-
Ok(Analysis {
438-
handle,
439-
_source: PhantomData,
440-
})
441-
}
442-
443-
/// Parse CommonJS source and return location-aware errors.
444-
///
445-
/// # Errors
446-
///
447-
/// Returns [`LocatedLexerError`] on parse failure. Location data is optional.
448-
pub fn parse_commonjs_with_location(source: &str) -> Result<Analysis<'_>, LocatedLexerError> {
409+
pub fn parse_commonjs(source: &str) -> Result<Analysis<'_>, LocatedLexerError> {
449410
if source.is_empty() {
450411
return Err(LocatedLexerError {
451412
kind: LexerError::EmptySource,
@@ -557,7 +518,7 @@ mod tests {
557518
let result = parse_commonjs(source);
558519
assert!(result.is_err());
559520
let err = result.unwrap_err();
560-
assert_eq!(err, LexerError::UnexpectedEsmImport);
521+
assert_eq!(err.kind, LexerError::UnexpectedEsmImport);
561522
}
562523

563524
#[test]
@@ -566,20 +527,26 @@ mod tests {
566527
let result = parse_commonjs(source);
567528
assert!(result.is_err());
568529
let err = result.unwrap_err();
569-
assert_eq!(err, LexerError::UnexpectedEsmExport);
530+
assert_eq!(err.kind, LexerError::UnexpectedEsmExport);
570531
}
571532

572533
#[test]
573534
fn empty_input() {
574535
let result = parse_commonjs("");
575536
assert!(result.is_err());
576-
assert_eq!(result.unwrap_err(), LexerError::EmptySource);
537+
let err = result.unwrap_err();
538+
assert_eq!(err.kind, LexerError::EmptySource);
539+
let loc = err
540+
.location
541+
.expect("empty source location should be present");
542+
assert_eq!(loc.line, NonZeroU32::new(1).unwrap());
543+
assert_eq!(loc.column, NonZeroU32::new(1).unwrap());
577544
}
578545

579546
#[test]
580-
fn parse_with_location_reports_error_position() {
547+
fn parse_reports_error_position() {
581548
let source = "\n import 'x';";
582-
let result = parse_commonjs_with_location(source);
549+
let result = parse_commonjs(source);
583550
assert!(result.is_err());
584551

585552
let err = result.unwrap_err();
@@ -590,22 +557,9 @@ mod tests {
590557
}
591558

592559
#[test]
593-
fn parse_with_location_empty_source() {
594-
let result = parse_commonjs_with_location("");
595-
assert!(result.is_err());
596-
let err = result.unwrap_err();
597-
assert_eq!(err.kind, LexerError::EmptySource);
598-
let loc = err
599-
.location
600-
.expect("empty source location should be present");
601-
assert_eq!(loc.line, NonZeroU32::new(1).unwrap());
602-
assert_eq!(loc.column, NonZeroU32::new(1).unwrap());
603-
}
604-
605-
#[test]
606-
fn parse_with_location_crlf_position() {
560+
fn parse_crlf_position() {
607561
let source = "\r\n import 'x';";
608-
let result = parse_commonjs_with_location(source);
562+
let result = parse_commonjs(source);
609563
assert!(result.is_err());
610564

611565
let err = result.unwrap_err();
@@ -616,8 +570,8 @@ mod tests {
616570
}
617571

618572
#[test]
619-
fn parse_with_location_import_meta_and_eof() {
620-
let import_meta = parse_commonjs_with_location("\n import.meta.url");
573+
fn parse_import_meta_and_eof() {
574+
let import_meta = parse_commonjs("\n import.meta.url");
621575
assert!(import_meta.is_err());
622576
let import_meta_err = import_meta.unwrap_err();
623577
assert_eq!(import_meta_err.kind, LexerError::UnexpectedEsmImportMeta);
@@ -627,7 +581,7 @@ mod tests {
627581
assert_eq!(import_meta_loc.line, NonZeroU32::new(2).unwrap());
628582
assert_eq!(import_meta_loc.column, NonZeroU32::new(3).unwrap());
629583

630-
let eof = parse_commonjs_with_location("(a + b");
584+
let eof = parse_commonjs("(a + b");
631585
assert!(eof.is_err());
632586
let eof_err = eof.unwrap_err();
633587
assert_eq!(eof_err.kind, LexerError::UnterminatedParen);

0 commit comments

Comments
 (0)