From e7b1d84a8362c029351e3733b82b285185f77ac3 Mon Sep 17 00:00:00 2001 From: Andrew Hlynskyi Date: Sun, 18 Apr 2021 14:01:02 +0300 Subject: [PATCH 1/2] binding_rust: implement Display and Error traits for TS errors to be convertible --- lib/binding_rust/lib.rs | 55 ++++++++++++++++++++++++++++++++--------- 1 file changed, 43 insertions(+), 12 deletions(-) diff --git a/lib/binding_rust/lib.rs b/lib/binding_rust/lib.rs index a0b757d5..7138d8bc 100644 --- a/lib/binding_rust/lib.rs +++ b/lib/binding_rust/lib.rs @@ -13,7 +13,7 @@ use std::mem::MaybeUninit; use std::os::raw::{c_char, c_void}; use std::ptr::NonNull; use std::sync::atomic::AtomicUsize; -use std::{char, fmt, hash, iter, ptr, slice, str, u16}; +use std::{char, error, fmt, hash, iter, ptr, slice, str, u16}; /// The latest ABI version that is supported by the current version of the /// library. @@ -271,16 +271,6 @@ impl Language { } } -impl fmt::Display for LanguageError { - fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - write!( - f, - "Incompatible language version {}. Expected minimum {}, maximum {}", - self.version, MIN_COMPATIBLE_LANGUAGE_VERSION, LANGUAGE_VERSION, - ) - } -} - impl Parser { /// Create a new parser. pub fn new() -> Parser { @@ -573,7 +563,8 @@ impl Parser { /// ```text /// ranges[i].end_byte <= ranges[i + 1].start_byte /// ``` - /// If this requirement is not satisfied, method will panic. + /// If this requirement is not satisfied, method will return IncludedRangesError + /// error with an offset in the passed ranges slice pointing to a first incorrect range. pub fn set_included_ranges<'a>( &mut self, ranges: &'a [Range], @@ -1908,6 +1899,46 @@ fn predicate_error(row: usize, message: String) -> QueryError { } } +impl fmt::Display for IncludedRangesError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Incorrect range by index: {}", self.0) + } +} + +impl fmt::Display for LanguageError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "Incompatible language version {}. Expected minimum {}, maximum {}", + self.version, MIN_COMPATIBLE_LANGUAGE_VERSION, LANGUAGE_VERSION, + ) + } +} + +impl fmt::Display for QueryError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let msg = match self.kind { + QueryErrorKind::Capture => format!("Invalid capture name {}", self.message), + QueryErrorKind::Field => format!("Invalid field name {}", self.message), + QueryErrorKind::NodeType => format!("Invalid node type {}", self.message), + QueryErrorKind::Syntax => format!("Invalid syntax:\n{}", self.message), + QueryErrorKind::Structure => format!("Impossible pattern:\n{}", self.message), + QueryErrorKind::Predicate => format!("Invalid predicate: {}", self.message), + }; + write!( + f, + "Query error at {}:{}. {}", + self.row + 1, + self.column + 1, + msg + ) + } +} + +impl error::Error for IncludedRangesError {} +impl error::Error for LanguageError {} +impl error::Error for QueryError {} + unsafe impl Send for Language {} unsafe impl Send for Parser {} unsafe impl Send for Query {} From 3c0a49289cb5916ad4f3f55e0cb7e364724fe1d4 Mon Sep 17 00:00:00 2001 From: Andrew Hlynskyi Date: Fri, 23 Apr 2021 06:44:16 +0300 Subject: [PATCH 2/2] binding_rust: Improve implementation of fmt::Display for QueryError trait, avoid multiple format!() calls --- lib/binding_rust/lib.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/binding_rust/lib.rs b/lib/binding_rust/lib.rs index 7138d8bc..73c310fc 100644 --- a/lib/binding_rust/lib.rs +++ b/lib/binding_rust/lib.rs @@ -1917,20 +1917,20 @@ impl fmt::Display for LanguageError { impl fmt::Display for QueryError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let msg = match self.kind { - QueryErrorKind::Capture => format!("Invalid capture name {}", self.message), - QueryErrorKind::Field => format!("Invalid field name {}", self.message), - QueryErrorKind::NodeType => format!("Invalid node type {}", self.message), - QueryErrorKind::Syntax => format!("Invalid syntax:\n{}", self.message), - QueryErrorKind::Structure => format!("Impossible pattern:\n{}", self.message), - QueryErrorKind::Predicate => format!("Invalid predicate: {}", self.message), - }; write!( f, - "Query error at {}:{}. {}", + "Query error at {}:{}. {}{}", self.row + 1, self.column + 1, - msg + match self.kind { + QueryErrorKind::Field => "Invalid field name ", + QueryErrorKind::NodeType => "Invalid node type ", + QueryErrorKind::Capture => "Invalid capture name ", + QueryErrorKind::Predicate => "Invalid predicate: ", + QueryErrorKind::Structure => "Impossible pattern:\n", + QueryErrorKind::Syntax => "Invalid syntax:\n", + }, + self.message ) } }