diff --git a/crates/rsonpath-benchmarks b/crates/rsonpath-benchmarks index dd8c50be..30b23820 160000 --- a/crates/rsonpath-benchmarks +++ b/crates/rsonpath-benchmarks @@ -1 +1 @@ -Subproject commit dd8c50be8086977689cc3fd6dc8b1a4a58f09133 +Subproject commit 30b238203ff4cf34a58ed9dbf5cbc19d9ee0d208 diff --git a/crates/rsonpath-lib/build.rs b/crates/rsonpath-lib/build.rs index 2bfd47b3..5e577c5f 100644 --- a/crates/rsonpath-lib/build.rs +++ b/crates/rsonpath-lib/build.rs @@ -12,7 +12,9 @@ fn main() -> eyre::Result<()> { } } - Err(eyre::eyre!("Target architecture is not supported by SIMD features of this crate. Disable the default `simd` feature.")) + Err(eyre::eyre!( + "Target architecture is not supported by SIMD features of this crate. Disable the default `simd` feature." + )) } #[cfg(not(feature = "simd"))] { diff --git a/crates/rsonpath-lib/src/classification.rs b/crates/rsonpath-lib/src/classification.rs index 5fdfc681..56376442 100644 --- a/crates/rsonpath-lib/src/classification.rs +++ b/crates/rsonpath-lib/src/classification.rs @@ -85,9 +85,7 @@ pub struct ResumeClassifierBlockState<'a, I: Input + 'a, const N: usize> { pub idx: usize, } -impl<'a, I: Input, Q: QuoteClassifiedIterator<'a, I, N>, const N: usize> - ResumeClassifierState<'a, I, Q, N> -{ +impl<'a, I: Input, Q: QuoteClassifiedIterator<'a, I, N>, const N: usize> ResumeClassifierState<'a, I, Q, N> { /// Get the index in the original bytes input at which classification has stopped. #[inline(always)] pub fn get_idx(&self) -> usize { @@ -118,8 +116,7 @@ impl<'a, I: Input, Q: QuoteClassifiedIterator<'a, I, N>, const N: usize> _ => { let blocks_to_advance = (count - remaining_in_block) / N; - let remainder = - (self.block.as_ref().map_or(0, |b| b.idx) + count - blocks_to_advance * N) % N; + let remainder = (self.block.as_ref().map_or(0, |b| b.idx) + count - blocks_to_advance * N) % N; self.iter.offset(blocks_to_advance as isize); let next_block = self.iter.next(); @@ -131,9 +128,6 @@ impl<'a, I: Input, Q: QuoteClassifiedIterator<'a, I, N>, const N: usize> } } - debug!( - "offset_bytes({count}) results in idx moved to {}", - self.get_idx() - ); + debug!("offset_bytes({count}) results in idx moved to {}", self.get_idx()); } } diff --git a/crates/rsonpath-lib/src/classification/depth.rs b/crates/rsonpath-lib/src/classification/depth.rs index 43e34e2e..8f9a078e 100644 --- a/crates/rsonpath-lib/src/classification/depth.rs +++ b/crates/rsonpath-lib/src/classification/depth.rs @@ -125,18 +125,13 @@ pub trait DepthBlock<'a>: Sized { /// Trait for depth iterators, i.e. finite iterators returning depth information /// about JSON documents. -pub trait DepthIterator<'a, I: Input, Q, const N: usize>: - Iterator + 'a -{ +pub trait DepthIterator<'a, I: Input, Q, const N: usize>: Iterator + 'a { /// Type of the [`DepthBlock`] implementation used by this iterator. type Block: DepthBlock<'a>; /// Resume classification from a state retrieved by a previous /// [`DepthIterator::stop`] or [`StructuralIterator::stop`](`crate::classification::structural::StructuralIterator::stop`) invocation. - fn resume( - state: ResumeClassifierState<'a, I, Q, N>, - opening: BracketType, - ) -> (Option, Self); + fn resume(state: ResumeClassifierState<'a, I, Q, N>, opening: BracketType) -> (Option, Self); /// Stop classification and return a state object that can be used to resume /// a classifier from the place in which the current one was stopped. @@ -165,10 +160,7 @@ cfg_if! { /// Enrich quote classified blocks with depth information. #[inline(always)] -pub fn classify_depth<'a, I, Q>( - iter: Q, - opening: BracketType, -) -> impl DepthIterator<'a, I, Q, BLOCK_SIZE> +pub fn classify_depth<'a, I, Q>(iter: Q, opening: BracketType) -> impl DepthIterator<'a, I, Q, BLOCK_SIZE> where I: Input + 'a, Q: QuoteClassifiedIterator<'a, I, BLOCK_SIZE>, diff --git a/crates/rsonpath-lib/src/classification/depth/avx2.rs b/crates/rsonpath-lib/src/classification/depth/avx2.rs index 761efe35..4d174c50 100644 --- a/crates/rsonpath-lib/src/classification/depth/avx2.rs +++ b/crates/rsonpath-lib/src/classification/depth/avx2.rs @@ -53,9 +53,7 @@ impl<'a, I: Input, Q: QuoteClassifiedIterator<'a, I, 64>> Iterator for VectorIte } } -impl<'a, I: Input, Q: QuoteClassifiedIterator<'a, I, 64>> DepthIterator<'a, I, Q, 64> - for VectorIterator<'a, I, Q> -{ +impl<'a, I: Input, Q: QuoteClassifiedIterator<'a, I, 64>> DepthIterator<'a, I, Q, 64> for VectorIterator<'a, I, Q> { type Block = Vector<'a, I>; fn stop(self, block: Option) -> ResumeClassifierState<'a, I, Q, 64> { @@ -80,10 +78,7 @@ impl<'a, I: Input, Q: QuoteClassifiedIterator<'a, I, 64>> DepthIterator<'a, I, Q } } - fn resume( - state: ResumeClassifierState<'a, I, Q, 64>, - opening: BracketType, - ) -> (Option, Self) { + fn resume(state: ResumeClassifierState<'a, I, Q, 64>, opening: BracketType) -> (Option, Self) { let classifier = DelimiterClassifierImpl::new(opening); let first_block = state.block.and_then(|b| { if b.idx == 64 { @@ -116,10 +111,7 @@ impl<'a, I: Input, Q: QuoteClassifiedIterator<'a, I, 64>> DepthIterator<'a, I, Q /// more quickly than precise depth calculation. #[cfg_attr( docsrs, - doc(cfg(all( - target_feature = "avx2", - any(target_arch = "x86", target_arch = "x86_64") - ))) + doc(cfg(all(target_feature = "avx2", any(target_arch = "x86", target_arch = "x86_64")))) )] pub(crate) struct Vector<'a, I: Input + 'a> { @@ -133,10 +125,7 @@ pub(crate) struct Vector<'a, I: Input + 'a> { impl<'a, I: Input> Vector<'a, I> { #[inline] - fn new( - bytes: QuoteClassifiedBlock, 64>, - classifier: &DelimiterClassifierImpl, - ) -> Self { + fn new(bytes: QuoteClassifiedBlock, 64>, classifier: &DelimiterClassifierImpl) -> Self { Self::new_from(bytes, classifier, 0) } @@ -159,20 +148,16 @@ impl<'a, I: Input> Vector<'a, I> { ) -> Self { let idx_mask = 0xFFFF_FFFF_FFFF_FFFF_u64 << start_idx; let (first_block, second_block) = bytes.block.halves(); - let (first_opening_vector, first_closing_vector) = - classifier.get_opening_and_closing_vectors(first_block); - let (second_opening_vector, second_closing_vector) = - classifier.get_opening_and_closing_vectors(second_block); + let (first_opening_vector, first_closing_vector) = classifier.get_opening_and_closing_vectors(first_block); + let (second_opening_vector, second_closing_vector) = classifier.get_opening_and_closing_vectors(second_block); let first_opening_mask = _mm256_movemask_epi8(first_opening_vector) as u32; let first_closing_mask = _mm256_movemask_epi8(first_closing_vector) as u32; let second_opening_mask = _mm256_movemask_epi8(second_opening_vector) as u32; let second_closing_mask = _mm256_movemask_epi8(second_closing_vector) as u32; - let combined_opening_mask = - u64::from(first_opening_mask) | (u64::from(second_opening_mask) << 32); - let combined_closing_mask = - u64::from(first_closing_mask) | (u64::from(second_closing_mask) << 32); + let combined_opening_mask = u64::from(first_opening_mask) | (u64::from(second_opening_mask) << 32); + let combined_closing_mask = u64::from(first_closing_mask) | (u64::from(second_closing_mask) << 32); let opening_mask = combined_opening_mask & (!bytes.within_quotes_mask) & idx_mask; let closing_mask = combined_closing_mask & (!bytes.within_quotes_mask) & idx_mask; @@ -229,8 +214,7 @@ impl<'a, I: Input> DepthBlock<'a> for Vector<'a, I> { #[inline(always)] fn depth_at_end(&self) -> isize { - (((self.opening_count as i32) - (self.closing_mask.count_ones() as i32)) + self.depth) - as isize + (((self.opening_count as i32) - (self.closing_mask.count_ones() as i32)) + self.depth) as isize } #[inline(always)] diff --git a/crates/rsonpath-lib/src/classification/depth/nosimd.rs b/crates/rsonpath-lib/src/classification/depth/nosimd.rs index 7d8d5c36..d7a19688 100644 --- a/crates/rsonpath-lib/src/classification/depth/nosimd.rs +++ b/crates/rsonpath-lib/src/classification/depth/nosimd.rs @@ -24,9 +24,7 @@ impl<'a, I: Input, Q, const N: usize> VectorIterator<'a, I, Q, N> { } } -impl<'a, I: Input, Q: QuoteClassifiedIterator<'a, I, N>, const N: usize> Iterator - for VectorIterator<'a, I, Q, N> -{ +impl<'a, I: Input, Q: QuoteClassifiedIterator<'a, I, N>, const N: usize> Iterator for VectorIterator<'a, I, Q, N> { type Item = Vector<'a, I, N>; fn next(&mut self) -> Option { @@ -61,13 +59,8 @@ impl<'a, I: Input, Q: QuoteClassifiedIterator<'a, I, N>, const N: usize> DepthIt } } - fn resume( - state: ResumeClassifierState<'a, I, Q, N>, - opening: BracketType, - ) -> (Option, Self) { - let first_block = state - .block - .map(|b| Vector::new_from(b.block, opening, b.idx)); + fn resume(state: ResumeClassifierState<'a, I, Q, N>, opening: BracketType) -> (Option, Self) { + let first_block = state.block.map(|b| Vector::new_from(b.block, opening, b.idx)); ( first_block, @@ -91,19 +84,12 @@ pub(crate) struct Vector<'a, I: Input + 'a, const N: usize> { impl<'a, I: Input, const N: usize> Vector<'a, I, N> { #[inline] - pub(crate) fn new( - bytes: QuoteClassifiedBlock, N>, - opening: BracketType, - ) -> Self { + pub(crate) fn new(bytes: QuoteClassifiedBlock, N>, opening: BracketType) -> Self { Self::new_from(bytes, opening, 0) } #[inline] - fn new_from( - bytes: QuoteClassifiedBlock, N>, - opening: BracketType, - idx: usize, - ) -> Self { + fn new_from(bytes: QuoteClassifiedBlock, N>, opening: BracketType, idx: usize) -> Self { Self { quote_classified: bytes, depth: 0, diff --git a/crates/rsonpath-lib/src/classification/quotes.rs b/crates/rsonpath-lib/src/classification/quotes.rs index 2a128ce9..49c97b78 100644 --- a/crates/rsonpath-lib/src/classification/quotes.rs +++ b/crates/rsonpath-lib/src/classification/quotes.rs @@ -105,8 +105,6 @@ cfg_if! { /// and classify quoted sequences. #[must_use] #[inline(always)] -pub fn classify_quoted_sequences( - bytes: &I, -) -> impl QuoteClassifiedIterator { +pub fn classify_quoted_sequences(bytes: &I) -> impl QuoteClassifiedIterator { ClassifierImpl::new(bytes) } diff --git a/crates/rsonpath-lib/src/classification/quotes/avx2.rs b/crates/rsonpath-lib/src/classification/quotes/avx2.rs index 182c8ad9..8e235392 100644 --- a/crates/rsonpath-lib/src/classification/quotes/avx2.rs +++ b/crates/rsonpath-lib/src/classification/quotes/avx2.rs @@ -45,10 +45,7 @@ impl<'a, I: Input> Avx2QuoteClassifier<'a, I> { } impl<'a, I: Input> Iterator for Avx2QuoteClassifier<'a, I> { - type Item = QuoteClassifiedBlock< - <::BlockIterator<'a, 64> as InputBlockIterator<'a, 64>>::Block, - 64, - >; + type Item = QuoteClassifiedBlock<<::BlockIterator<'a, 64> as InputBlockIterator<'a, 64>>::Block, 64>; #[inline(always)] fn next(&mut self) -> Option { @@ -122,11 +119,9 @@ struct BlockClassification { impl BlockAvx2Classifier { /// Bitmask selecting bits on even positions when indexing from zero. - const ODD: u64 = - 0b0101_0101_0101_0101_0101_0101_0101_0101_0101_0101_0101_0101_0101_0101_0101_0101_u64; + const ODD: u64 = 0b0101_0101_0101_0101_0101_0101_0101_0101_0101_0101_0101_0101_0101_0101_0101_0101_u64; /// Bitmask selecting bits on odd positions when indexing from zero. - const EVEN: u64 = - 0b1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_u64; + const EVEN: u64 = 0b1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_1010_u64; /// Set the inter-block state based on slash overflow and the quotes mask. fn update_prev_block_mask(&mut self, set_slash_mask: bool, quotes: u64) { @@ -191,8 +186,7 @@ impl BlockAvx2Classifier { // Masks are combined by shifting the latter block's 32-bit masks left by 32 bits. // From now on when we refer to a "block" we mean the combined 64 bytes of the input. - let slashes = - u64::from(classification1.slashes) | (u64::from(classification2.slashes) << 32); + let slashes = u64::from(classification1.slashes) | (u64::from(classification2.slashes) << 32); let quotes = u64::from(classification1.quotes) | (u64::from(classification2.quotes) << 32); let (escaped, set_prev_slash_mask) = if slashes == 0 { @@ -273,9 +267,8 @@ impl BlockAvx2Classifier { * prev_slash | 00000000 10000000 | * escaped | 01000000 10000100 | */ - let escaped = (ends_of_odd_starts & Self::EVEN) - | (ends_of_even_starts & Self::ODD) - | self.get_prev_slash_mask(); + let escaped = + (ends_of_odd_starts & Self::EVEN) | (ends_of_even_starts & Self::ODD) | self.get_prev_slash_mask(); (escaped, set_prev_slash_mask) }; diff --git a/crates/rsonpath-lib/src/classification/quotes/nosimd.rs b/crates/rsonpath-lib/src/classification/quotes/nosimd.rs index b6cf0606..e5b0f0b0 100644 --- a/crates/rsonpath-lib/src/classification/quotes/nosimd.rs +++ b/crates/rsonpath-lib/src/classification/quotes/nosimd.rs @@ -64,14 +64,9 @@ impl<'a, I: Input, const N: usize> Iterator for SequentialQuoteClassifier<'a, I, } } -impl<'a, I: Input, const N: usize> std::iter::FusedIterator - for SequentialQuoteClassifier<'a, I, N> -{ -} +impl<'a, I: Input, const N: usize> std::iter::FusedIterator for SequentialQuoteClassifier<'a, I, N> {} -impl<'a, I: Input, const N: usize> QuoteClassifiedIterator<'a, I, N> - for SequentialQuoteClassifier<'a, I, N> -{ +impl<'a, I: Input, const N: usize> QuoteClassifiedIterator<'a, I, N> for SequentialQuoteClassifier<'a, I, N> { fn get_offset(&self) -> usize { self.offset.unwrap_or(0) } diff --git a/crates/rsonpath-lib/src/classification/structural.rs b/crates/rsonpath-lib/src/classification/structural.rs index 5f19d4c6..a29f3168 100644 --- a/crates/rsonpath-lib/src/classification/structural.rs +++ b/crates/rsonpath-lib/src/classification/structural.rs @@ -158,9 +158,7 @@ impl Structural { /// Trait for classifier iterators, i.e. finite iterators of [`Structural`] characters /// that hold a reference to the JSON document valid for `'a`. -pub trait StructuralIterator<'a, I: Input, Q, const N: usize>: - Iterator + 'a -{ +pub trait StructuralIterator<'a, I: Input, Q, const N: usize>: Iterator + 'a { /// Stop classification and return a state object that can be used to resume /// a classifier from the place in which the current one was stopped. fn stop(self) -> ResumeClassifierState<'a, I, Q, N>; @@ -208,11 +206,7 @@ cfg_if! { /// Walk through the JSON document represented by `bytes` and iterate over all /// occurrences of structural characters in it. #[inline(always)] -pub fn classify_structural_characters< - 'a, - I: Input + 'a, - Q: QuoteClassifiedIterator<'a, I, BLOCK_SIZE>, ->( +pub fn classify_structural_characters<'a, I: Input + 'a, Q: QuoteClassifiedIterator<'a, I, BLOCK_SIZE>>( iter: Q, ) -> impl StructuralIterator<'a, I, Q, BLOCK_SIZE> { ClassifierImpl::new(iter) @@ -221,11 +215,7 @@ pub fn classify_structural_characters< /// Resume classification using a state retrieved from a previously /// used classifier via the `stop` function. #[inline(always)] -pub fn resume_structural_classification< - 'a, - I: Input, - Q: QuoteClassifiedIterator<'a, I, BLOCK_SIZE>, ->( +pub fn resume_structural_classification<'a, I: Input, Q: QuoteClassifiedIterator<'a, I, BLOCK_SIZE>>( state: ResumeClassifierState<'a, I, Q, BLOCK_SIZE>, ) -> impl StructuralIterator<'a, I, Q, BLOCK_SIZE> { ClassifierImpl::resume(state) diff --git a/crates/rsonpath-lib/src/classification/structural/avx2.rs b/crates/rsonpath-lib/src/classification/structural/avx2.rs index b66591d8..edd88c14 100644 --- a/crates/rsonpath-lib/src/classification/structural/avx2.rs +++ b/crates/rsonpath-lib/src/classification/structural/avx2.rs @@ -12,12 +12,8 @@ cfg_if::cfg_if! { } } -use crate::classification::structural::{ - BracketType, QuoteClassifiedIterator, Structural, StructuralIterator, -}; -use crate::classification::{ - QuoteClassifiedBlock, ResumeClassifierBlockState, ResumeClassifierState, -}; +use crate::classification::structural::{BracketType, QuoteClassifiedIterator, Structural, StructuralIterator}; +use crate::classification::{QuoteClassifiedBlock, ResumeClassifierBlockState, ResumeClassifierState}; use crate::input::{IBlock, Input, InputBlock}; use crate::{bin, debug}; @@ -139,10 +135,7 @@ impl<'a, I: Input, Q: QuoteClassifiedIterator<'a, I, 64>> Iterator for Avx2Class } } -impl<'a, I: Input, Q: QuoteClassifiedIterator<'a, I, 64>> std::iter::FusedIterator - for Avx2Classifier<'a, I, Q> -{ -} +impl<'a, I: Input, Q: QuoteClassifiedIterator<'a, I, 64>> std::iter::FusedIterator for Avx2Classifier<'a, I, Q> {} impl<'a, I: Input, Q: QuoteClassifiedIterator<'a, I, 64>> StructuralIterator<'a, I, Q, 64> for Avx2Classifier<'a, I, Q> @@ -270,43 +263,31 @@ struct BlockClassification { impl BlockAvx2Classifier { const LOWER_NIBBLE_MASK_ARRAY: [u8; 32] = [ - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x01, 0x02, 0x01, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x01, 0x02, 0x01, - 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x01, 0x02, 0x01, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03, 0x01, 0x02, 0x01, 0xff, 0xff, ]; const UPPER_NIBBLE_MASK_ARRAY: [u8; 32] = [ - 0xfe, 0xfe, 0x10, 0x10, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, - 0xfe, 0xfe, 0xfe, 0x10, 0x10, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, - 0xfe, 0xfe, + 0xfe, 0xfe, 0x10, 0x10, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, + 0x10, 0x10, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, ]; const COMMAS_TOGGLE_MASK_ARRAY: [u8; 32] = [ - 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, + 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]; const COLON_TOGGLE_MASK_ARRAY: [u8; 32] = [ - 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, + 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]; #[target_feature(enable = "avx2")] #[inline] unsafe fn new() -> Self { Self { - lower_nibble_mask: _mm256_loadu_si256( - Self::LOWER_NIBBLE_MASK_ARRAY.as_ptr().cast::<__m256i>(), - ), - upper_nibble_mask: _mm256_loadu_si256( - Self::UPPER_NIBBLE_MASK_ARRAY.as_ptr().cast::<__m256i>(), - ), + lower_nibble_mask: _mm256_loadu_si256(Self::LOWER_NIBBLE_MASK_ARRAY.as_ptr().cast::<__m256i>()), + upper_nibble_mask: _mm256_loadu_si256(Self::UPPER_NIBBLE_MASK_ARRAY.as_ptr().cast::<__m256i>()), upper_nibble_zeroing_mask: _mm256_set1_epi8(0x0F), - commas_toggle_mask: _mm256_loadu_si256( - Self::COMMAS_TOGGLE_MASK_ARRAY.as_ptr().cast::<__m256i>(), - ), - colons_toggle_mask: _mm256_loadu_si256( - Self::COLON_TOGGLE_MASK_ARRAY.as_ptr().cast::<__m256i>(), - ), + commas_toggle_mask: _mm256_loadu_si256(Self::COMMAS_TOGGLE_MASK_ARRAY.as_ptr().cast::<__m256i>()), + colons_toggle_mask: _mm256_loadu_si256(Self::COLON_TOGGLE_MASK_ARRAY.as_ptr().cast::<__m256i>()), } } @@ -332,8 +313,7 @@ impl BlockAvx2Classifier { let classification1 = self.classify_block(block1); let classification2 = self.classify_block(block2); - let structural = - u64::from(classification1.structural) | (u64::from(classification2.structural) << 32); + let structural = u64::from(classification1.structural) | (u64::from(classification2.structural) << 32); let nonquoted_structural = structural & !quote_classified_block.within_quotes_mask; @@ -348,11 +328,9 @@ impl BlockAvx2Classifier { unsafe fn classify_block(&self, block: &[u8]) -> BlockClassification { let byte_vector = _mm256_loadu_si256(block.as_ptr().cast::<__m256i>()); let shifted_byte_vector = _mm256_srli_epi16::<4>(byte_vector); - let upper_nibble_byte_vector = - _mm256_and_si256(shifted_byte_vector, self.upper_nibble_zeroing_mask); + let upper_nibble_byte_vector = _mm256_and_si256(shifted_byte_vector, self.upper_nibble_zeroing_mask); let lower_nibble_lookup = _mm256_shuffle_epi8(self.lower_nibble_mask, byte_vector); - let upper_nibble_lookup = - _mm256_shuffle_epi8(self.upper_nibble_mask, upper_nibble_byte_vector); + let upper_nibble_lookup = _mm256_shuffle_epi8(self.upper_nibble_mask, upper_nibble_byte_vector); let structural_vector = _mm256_cmpeq_epi8(lower_nibble_lookup, upper_nibble_lookup); let structural = _mm256_movemask_epi8(structural_vector) as u32; diff --git a/crates/rsonpath-lib/src/classification/structural/nosimd.rs b/crates/rsonpath-lib/src/classification/structural/nosimd.rs index c62175ea..375eec21 100644 --- a/crates/rsonpath-lib/src/classification/structural/nosimd.rs +++ b/crates/rsonpath-lib/src/classification/structural/nosimd.rs @@ -1,7 +1,5 @@ use super::*; -use crate::classification::{ - quotes::QuoteClassifiedBlock, ResumeClassifierBlockState, ResumeClassifierState, -}; +use crate::classification::{quotes::QuoteClassifiedBlock, ResumeClassifierBlockState, ResumeClassifierState}; use crate::debug; use crate::input::IBlock; @@ -79,9 +77,7 @@ pub(crate) struct SequentialClassifier<'a, I: Input, Q, const N: usize> { are_commas_on: bool, } -impl<'a, I: Input, Q: QuoteClassifiedIterator<'a, I, N>, const N: usize> - SequentialClassifier<'a, I, Q, N> -{ +impl<'a, I: Input, Q: QuoteClassifiedIterator<'a, I, N>, const N: usize> SequentialClassifier<'a, I, Q, N> { #[inline(always)] pub(crate) fn new(iter: Q) -> Self { Self { @@ -122,8 +118,8 @@ impl<'a, I: Input, Q: QuoteClassifiedIterator<'a, I, N>, const N: usize> std::it { } -impl<'a, I: Input, Q: QuoteClassifiedIterator<'a, I, N>, const N: usize> - StructuralIterator<'a, I, Q, N> for SequentialClassifier<'a, I, Q, N> +impl<'a, I: Input, Q: QuoteClassifiedIterator<'a, I, N>, const N: usize> StructuralIterator<'a, I, Q, N> + for SequentialClassifier<'a, I, Q, N> { fn turn_commas_on(&mut self, idx: usize) { if !self.are_commas_on { @@ -135,12 +131,7 @@ impl<'a, I: Input, Q: QuoteClassifiedIterator<'a, I, N>, const N: usize> let block_idx = (idx + 1) % N; if block_idx != 0 { - let new_block = Block::from_idx( - quote_classified_block, - block_idx, - self.are_colons_on, - true, - ); + let new_block = Block::from_idx(quote_classified_block, block_idx, self.are_colons_on, true); self.block = Some(new_block); } } @@ -162,12 +153,7 @@ impl<'a, I: Input, Q: QuoteClassifiedIterator<'a, I, N>, const N: usize> let block_idx = (idx + 1) % N; if block_idx != 0 { - let new_block = Block::from_idx( - quote_classified_block, - block_idx, - true, - self.are_commas_on, - ); + let new_block = Block::from_idx(quote_classified_block, block_idx, true, self.are_commas_on); self.block = Some(new_block); } } diff --git a/crates/rsonpath-lib/src/engine/main.rs b/crates/rsonpath-lib/src/engine/main.rs index 48d5c95a..8837dc74 100644 --- a/crates/rsonpath-lib/src/engine/main.rs +++ b/crates/rsonpath-lib/src/engine/main.rs @@ -110,10 +110,7 @@ struct Executor<'q, 'b, I: Input> { has_any_array_item_transition_to_accepting: bool, } -fn query_executor<'q, 'b, I: Input>( - automaton: &'b Automaton<'q>, - bytes: &'b I, -) -> Executor<'q, 'b, I> { +fn query_executor<'q, 'b, I: Input>(automaton: &'b Automaton<'q>, bytes: &'b I) -> Executor<'q, 'b, I> { Executor { depth: Depth::ZERO, state: automaton.initial_state(), @@ -257,9 +254,7 @@ impl<'q, 'b, I: Input> Executor<'q, 'b, I> { let is_next_opening = self.next_event.map_or(false, |s| s.is_opening()); - let is_fallback_accepting = self - .automaton - .is_accepting(self.automaton[self.state].fallback_state()); + let is_fallback_accepting = self.automaton.is_accepting(self.automaton[self.state].fallback_state()); if !is_next_opening && self.is_list && is_fallback_accepting { debug!("Accepting on comma."); @@ -351,11 +346,9 @@ impl<'q, 'b, I: Input> Executor<'q, 'b, I> { if bracket_type == BracketType::Square { self.is_list = true; - self.has_any_array_item_transition = - self.automaton.has_any_array_item_transition(self.state); - self.has_any_array_item_transition_to_accepting = self - .automaton - .has_any_array_item_transition_to_accepting(self.state); + self.has_any_array_item_transition = self.automaton.has_any_array_item_transition(self.state); + self.has_any_array_item_transition_to_accepting = + self.automaton.has_any_array_item_transition_to_accepting(self.state); let fallback = self.automaton[self.state].fallback_state(); let is_fallback_accepting = self.automaton.is_accepting(fallback); @@ -367,19 +360,15 @@ impl<'q, 'b, I: Input> Executor<'q, 'b, I> { self.array_count = NonNegativeArrayIndex::ZERO; debug!("Initialized array count to {}", self.array_count); - let wants_first_item = is_fallback_accepting - || self - .automaton - .has_first_array_index_transition_to_accepting(self.state); + let wants_first_item = + is_fallback_accepting || self.automaton.has_first_array_index_transition_to_accepting(self.state); if wants_first_item { self.next_event = classifier.next(); match self.next_event { Some(Structural::Closing(_, close_idx)) => { - if let Some((next_idx, _)) = - self.bytes.seek_non_whitespace_forward(idx + 1) - { + if let Some((next_idx, _)) = self.bytes.seek_non_whitespace_forward(idx + 1) { if next_idx < close_idx { result.report(next_idx); } @@ -411,11 +400,7 @@ impl<'q, 'b, I: Input> Executor<'q, 'b, I> { Ok(()) } - fn handle_closing( - &mut self, - classifier: &mut Classifier!(), - idx: usize, - ) -> Result<(), EngineError> + fn handle_closing(&mut self, classifier: &mut Classifier!(), idx: usize) -> Result<(), EngineError> where Q: QuoteClassifiedIterator<'b, I, BLOCK_SIZE>, S: StructuralIterator<'b, I, Q, BLOCK_SIZE>, @@ -467,9 +452,7 @@ impl<'q, 'b, I: Input> Executor<'q, 'b, I> { } if self.is_list - && (self - .automaton - .is_accepting(self.automaton[self.state].fallback_state()) + && (self.automaton.is_accepting(self.automaton[self.state].fallback_state()) || self.has_any_array_item_transition) { classifier.turn_commas_on(idx); @@ -505,8 +488,7 @@ impl<'q, 'b, I: Input> Executor<'q, 'b, I> { is_list: self.is_list, array_count: self.array_count, has_any_array_item_transition: self.has_any_array_item_transition, - has_any_array_item_transition_to_accepting: self - .has_any_array_item_transition_to_accepting, + has_any_array_item_transition_to_accepting: self.has_any_array_item_transition_to_accepting, }); self.state = target; } @@ -535,9 +517,7 @@ impl<'q, 'b, I: Input> Executor<'q, 'b, I> { } let start_idx = closing_quote_idx + 1 - len; - Ok(self - .bytes - .is_label_match(start_idx, closing_quote_idx + 1, label)) + Ok(self.bytes.is_label_match(start_idx, closing_quote_idx + 1, label)) } fn verify_subtree_closed(&self) -> Result<(), EngineError> { @@ -575,9 +555,7 @@ struct SmallStack { impl SmallStack { fn new() -> Self { - Self { - contents: smallvec![], - } + Self { contents: smallvec![] } } #[inline] diff --git a/crates/rsonpath-lib/src/engine/recursive.rs b/crates/rsonpath-lib/src/engine/recursive.rs index 264a465c..71c6a979 100644 --- a/crates/rsonpath-lib/src/engine/recursive.rs +++ b/crates/rsonpath-lib/src/engine/recursive.rs @@ -63,13 +63,7 @@ impl Engine for RecursiveEngine<'_> { Some(Structural::Opening(b, idx)) => { let mut result = R::default(); let mut execution_ctx = ExecutionContext::new(&self.automaton, input); - execution_ctx.run( - &mut classifier, - self.automaton.initial_state(), - idx, - b, - &mut result, - )?; + execution_ctx.run(&mut classifier, self.automaton.initial_state(), idx, b, &mut result)?; Ok(result) } _ => Ok(R::default()), @@ -176,10 +170,7 @@ impl<'q, 'b, I: Input> ExecutionContext<'q, 'b, I> { let searching_list = self.automaton.has_any_array_item_transition(state); - let is_accepting_list_item = is_list - && self - .automaton - .has_any_array_item_transition_to_accepting(state); + let is_accepting_list_item = is_list && self.automaton.has_any_array_item_transition_to_accepting(state); let needs_commas = is_list && (is_fallback_accepting || searching_list); let needs_colons = !is_list && self.automaton.has_transition_to_accepting(state); @@ -245,9 +236,7 @@ impl<'q, 'b, I: Input> ExecutionContext<'q, 'b, I> { // Once we are in comma search, we have already considered the option that the first item in the list is a match. Iterate on the remaining items. - if let Err(ArrayIndexError::ExceedsUpperLimitError(_)) = - array_count.try_increment() - { + if let Err(ArrayIndexError::ExceedsUpperLimitError(_)) = array_count.try_increment() { debug!("Exceeded possible array match in content."); continue; } @@ -274,8 +263,7 @@ impl<'q, 'b, I: Input> ExecutionContext<'q, 'b, I> { for &(label, target) in self.automaton[state].transitions() { match label { TransitionLabel::ObjectMember(label) - if self.automaton.is_accepting(target) - && self.is_match(idx, label)? => + if self.automaton.is_accepting(target) && self.is_match(idx, label)? => { debug!("Accept {idx}"); result.report(idx); @@ -292,8 +280,7 @@ impl<'q, 'b, I: Input> ExecutionContext<'q, 'b, I> { } #[cfg(feature = "unique-labels")] { - let is_next_closing = - matches!(next_event, Some(Structural::Closing(_, _))); + let is_next_closing = matches!(next_event, Some(Structural::Closing(_, _))); if any_matched && !is_next_closing && self.automaton.is_unitary(state) { let bracket_type = if is_list { BracketType::Square @@ -413,9 +400,7 @@ impl<'q, 'b, I: Input> ExecutionContext<'q, 'b, I> { } let start_idx = closing_quote_idx + 1 - len; - Ok(self - .bytes - .is_label_match(start_idx, closing_quote_idx + 1, label)) + Ok(self.bytes.is_label_match(start_idx, closing_quote_idx + 1, label)) } } @@ -443,13 +428,7 @@ impl<'q, 'b, I: Input> CanHeadSkip<'b, I, BLOCK_SIZE> for ExecutionContext<'q, ' _ => Err(InternalRsonpathError::from_expectation("")), }?; - self.run_on_subtree( - &mut classifier, - state, - next_event.idx(), - bracket_type, - result, - )?; + self.run_on_subtree(&mut classifier, state, next_event.idx(), bracket_type, result)?; Ok(classifier.stop()) } diff --git a/crates/rsonpath-lib/src/error.rs b/crates/rsonpath-lib/src/error.rs index 2ca85d49..9993c931 100644 --- a/crates/rsonpath-lib/src/error.rs +++ b/crates/rsonpath-lib/src/error.rs @@ -4,8 +4,7 @@ use thiserror::Error; pub(crate) const FEATURE_REQUEST_URL: &str = "https://github.com/V0ldek/rsonpath/issues/new?template=feature_request.md"; -pub(crate) const BUG_REPORT_URL: &str = - "https://github.com/V0ldek/rsonpath/issues/new?template=bug_report.md"; +pub(crate) const BUG_REPORT_URL: &str = "https://github.com/V0ldek/rsonpath/issues/new?template=bug_report.md"; /// Internal irrecoverable error. These are caused solely /// by bugs – broken invariants or assertions in internal logic – @@ -43,17 +42,11 @@ impl std::error::Error for InternalErrorSource { impl InternalRsonpathError { #[allow(unused)] pub(crate) fn from_expectation(details: &'static str) -> Self { - Self { - details, - source: None, - } + Self { details, source: None } } #[allow(unused)] - pub(crate) fn from_error( - err: E, - details: &'static str, - ) -> Self { + pub(crate) fn from_error(err: E, details: &'static str) -> Self { Self { details, source: Some(InternalErrorSource(Box::new(err))), @@ -105,10 +98,7 @@ impl UnsupportedFeatureError { #[must_use] #[inline(always)] fn untracked(feature: &'static str) -> Self { - Self { - issue: None, - feature, - } + Self { issue: None, feature } } /// Large JSON Depths feature – supporting JSON documents diff --git a/crates/rsonpath-lib/src/input.rs b/crates/rsonpath-lib/src/input.rs index 589d2da7..962bf1bf 100644 --- a/crates/rsonpath-lib/src/input.rs +++ b/crates/rsonpath-lib/src/input.rs @@ -53,8 +53,7 @@ use std::ops::Deref; /// /// Typing `IBlock<'a, I, N>` is a bit more ergonomic than /// `<::BlockIterator<'a, N> as InputBlockIterator<'a, N>>::Block`. -pub type IBlock<'a, I, const N: usize> = - <::BlockIterator<'a, N> as InputBlockIterator<'a, N>>::Block; +pub type IBlock<'a, I, const N: usize> = <::BlockIterator<'a, N> as InputBlockIterator<'a, N>>::Block; /// Global padding guarantee for all [`Input`] implementations. /// Iterating over blocks of at most this size is guaranteed diff --git a/crates/rsonpath-lib/src/input/borrowed.rs b/crates/rsonpath-lib/src/input/borrowed.rs index 4b7770d7..5ace14d1 100644 --- a/crates/rsonpath-lib/src/input/borrowed.rs +++ b/crates/rsonpath-lib/src/input/borrowed.rs @@ -61,10 +61,7 @@ impl<'a, const N: usize> BorrowedBytesBlockIterator<'a, N> { #[must_use] #[inline(always)] pub(super) fn new(bytes: &'a [u8]) -> Self { - Self { - input: bytes, - idx: 0, - } + Self { input: bytes, idx: 0 } } } diff --git a/crates/rsonpath-lib/src/input/owned.rs b/crates/rsonpath-lib/src/input/owned.rs index 550774ab..0e60410b 100644 --- a/crates/rsonpath-lib/src/input/owned.rs +++ b/crates/rsonpath-lib/src/input/owned.rs @@ -140,8 +140,7 @@ impl OwnedBytes { #[inline(always)] fn get_layout(size: usize) -> Result { - alloc::Layout::from_size_align(size, MAX_BLOCK_SIZE) - .map_err(|_err| InputError::AllocationSizeExceeded) + alloc::Layout::from_size_align(size, MAX_BLOCK_SIZE).map_err(|_err| InputError::AllocationSizeExceeded) } } @@ -198,8 +197,7 @@ impl Drop for OwnedBytes { // This should never happen and if it did it would cause a memory leak. #[allow(clippy::expect_used)] - let layout = Self::get_layout(self.capacity) - .expect("layout for existing OwnedBytes must never change"); + let layout = Self::get_layout(self.capacity).expect("layout for existing OwnedBytes must never change"); // SAFETY: // `ptr` is allocated in `new` and layout is constructed using the same function diff --git a/crates/rsonpath-lib/src/lib.rs b/crates/rsonpath-lib/src/lib.rs index a4742910..2573ddd6 100644 --- a/crates/rsonpath-lib/src/lib.rs +++ b/crates/rsonpath-lib/src/lib.rs @@ -187,12 +187,7 @@ // Panic-free lints (disabled for tests). #![cfg_attr( not(test), - warn( - clippy::expect_used, - clippy::panic, - clippy::panic_in_result_fn, - clippy::unwrap_used - ) + warn(clippy::expect_used, clippy::panic, clippy::panic_in_result_fn, clippy::unwrap_used) )] // IO hygiene, only on --release. #![cfg_attr( diff --git a/crates/rsonpath-lib/src/query.rs b/crates/rsonpath-lib/src/query.rs index 5e5624f5..d6e71670 100644 --- a/crates/rsonpath-lib/src/query.rs +++ b/crates/rsonpath-lib/src/query.rs @@ -244,11 +244,7 @@ impl JsonPathQueryNodeType for JsonPathQueryNode { fn label(&self) -> Option<&Label> { match self { Child(label, _) | Descendant(label, _) => Some(label), - Root(_) - | AnyChild(_) - | AnyDescendant(_) - | ArrayIndexChild(_, _) - | ArrayIndexDescendant(_, _) => None, + Root(_) | AnyChild(_) | AnyDescendant(_) | ArrayIndexChild(_, _) | ArrayIndexDescendant(_, _) => None, } } diff --git a/crates/rsonpath-lib/src/query/automaton.rs b/crates/rsonpath-lib/src/query/automaton.rs index 771e82a0..f54dc2b8 100644 --- a/crates/rsonpath-lib/src/query/automaton.rs +++ b/crates/rsonpath-lib/src/query/automaton.rs @@ -119,14 +119,8 @@ impl<'q> PartialEq for StateTable<'q> { fn eq(&self, other: &Self) -> bool { self.fallback_state == other.fallback_state && self.transitions.len() == other.transitions.len() - && self - .transitions - .iter() - .all(|x| other.transitions.contains(x)) - && other - .transitions - .iter() - .all(|x| self.transitions.contains(x)) + && self.transitions.iter().all(|x| other.transitions.contains(x)) + && other.transitions.iter().all(|x| self.transitions.contains(x)) && self.attributes == other.attributes } } @@ -313,11 +307,7 @@ impl<'q> Automaton<'q> { /// ``` #[must_use] #[inline(always)] - pub fn has_array_index_transition_to_accepting( - &self, - state: State, - match_index: &NonNegativeArrayIndex, - ) -> bool { + pub fn has_array_index_transition_to_accepting(&self, state: State, match_index: &NonNegativeArrayIndex) -> bool { self[state].transitions().iter().any(|t| match t { (TransitionLabel::ArrayIndex(i), s) => i.eq(match_index) && self.is_accepting(*s), _ => false, @@ -433,14 +423,7 @@ impl<'q> Display for Automaton<'q> { color_two = ""; } - let attrs = vec![ - shape, - "style=filled", - "gradientangle=45", - color_one, - color_two, - ] - .join(" "); + let attrs = vec![shape, "style=filled", "gradientangle=45", color_one, color_two].join(" "); writeln!(f, "node [{attrs}]; {i}")?; } diff --git a/crates/rsonpath-lib/src/query/automaton/minimizer.rs b/crates/rsonpath-lib/src/query/automaton/minimizer.rs index e9602d91..9790284f 100644 --- a/crates/rsonpath-lib/src/query/automaton/minimizer.rs +++ b/crates/rsonpath-lib/src/query/automaton/minimizer.rs @@ -5,10 +5,7 @@ use super::nfa::{self, NfaState, NfaStateId}; use super::small_set::{SmallSet, SmallSet256}; use super::state::StateAttributesBuilder; -use super::{ - Automaton, NondeterministicAutomaton, State as DfaStateId, StateAttributes, StateTable, - TransitionLabel, -}; +use super::{Automaton, NondeterministicAutomaton, State as DfaStateId, StateAttributes, StateTable, TransitionLabel}; use crate::debug; use crate::query::error::CompilerError; use smallvec::{smallvec, SmallVec}; @@ -85,8 +82,7 @@ impl<'q> Minimizer<'q> { fallback_state: Self::rejecting_state(), attributes: StateAttributesBuilder::new().rejecting().into(), }); - self.superstates - .insert(SmallSet256::default(), Self::rejecting_state()); + self.superstates.insert(SmallSet256::default(), Self::rejecting_state()); // Initial superstate is {0}. let initial_superstate = [0].into(); @@ -131,12 +127,9 @@ impl<'q> Minimizer<'q> { /// of NFA states within the superstate. fn process_superstate(&mut self, current_superstate: SmallSet256) -> Result<(), CompilerError> { let current_checkpoint = self.determine_checkpoint(current_superstate); - debug!( - "Expanding superstate: {current_superstate:?}, last checkpoint is {current_checkpoint:?}" - ); + debug!("Expanding superstate: {current_superstate:?}, last checkpoint is {current_checkpoint:?}"); - let mut transitions = - self.process_nfa_transitions(current_superstate, current_checkpoint)?; + let mut transitions = self.process_nfa_transitions(current_superstate, current_checkpoint)?; debug!("Raw transitions: {:?}", transitions); self.normalize_superstate_transitions(&mut transitions, current_checkpoint)?; @@ -185,11 +178,7 @@ impl<'q> Minimizer<'q> { debug!("{id} is unitary"); attrs = attrs.unitary(); } - if self.accepting.contains(fallback.0) - || transitions - .iter() - .any(|(_, s)| self.accepting.contains(s.0)) - { + if self.accepting.contains(fallback.0) || transitions.iter().any(|(_, s)| self.accepting.contains(s.0)) { debug!("{id} has transitions to accepting"); attrs = attrs.transitions_to_accepting(); } @@ -232,8 +221,9 @@ impl<'q> Minimizer<'q> { .iter() .map(NfaStateId) .filter_map(|id| match self.nfa[id] { - NfaState::Recursive(nfa::Transition::Wildcard) - | NfaState::Direct(nfa::Transition::Wildcard) => Some(id.next().map(|x| x.0)), + NfaState::Recursive(nfa::Transition::Wildcard) | NfaState::Direct(nfa::Transition::Wildcard) => { + Some(id.next().map(|x| x.0)) + } _ => None, }) .collect::>()?; @@ -255,11 +245,7 @@ impl<'q> Minimizer<'q> { // checkpoints mechanism - here we only handle the forward transition. NfaState::Direct(nfa::Transition::Labelled(label)) | NfaState::Recursive(nfa::Transition::Labelled(label)) => { - debug!( - "Considering transition {nfa_state} --{}-> {}", - label, - nfa_state.next()?, - ); + debug!("Considering transition {nfa_state} --{}-> {}", label, nfa_state.next()?,); // Add the target NFA state to the target superstate, or create a singleton // set if this is the first transition via this label encountered in the loop. if let Some(target) = transitions.labelled.get_mut(&label) { @@ -367,10 +353,7 @@ mod tests { fn simple_wildcard_test() { // Query = $.* let nfa = NondeterministicAutomaton { - ordered_states: vec![ - NfaState::Direct(nfa::Transition::Wildcard), - NfaState::Accepting, - ], + ordered_states: vec![NfaState::Direct(nfa::Transition::Wildcard), NfaState::Accepting], }; let result = minimize(nfa).unwrap(); @@ -403,10 +386,7 @@ mod tests { let label = TransitionLabel::ArrayIndex(0.try_into().unwrap()); let nfa = NondeterministicAutomaton { - ordered_states: vec![ - NfaState::Direct(nfa::Transition::Labelled(label)), - NfaState::Accepting, - ], + ordered_states: vec![NfaState::Direct(nfa::Transition::Labelled(label)), NfaState::Accepting], }; let result = minimize(nfa).unwrap(); @@ -420,8 +400,7 @@ mod tests { StateTable { transitions: smallvec![(label, State(2))], fallback_state: State(0), - attributes: StateAttributes::UNITARY - | StateAttributes::TRANSITIONS_TO_ACCEPTING, + attributes: StateAttributes::UNITARY | StateAttributes::TRANSITIONS_TO_ACCEPTING, }, StateTable { transitions: smallvec![], @@ -438,10 +417,7 @@ mod tests { fn simple_descendant_wildcard_test() { // Query = $..* let nfa = NondeterministicAutomaton { - ordered_states: vec![ - NfaState::Recursive(nfa::Transition::Wildcard), - NfaState::Accepting, - ], + ordered_states: vec![NfaState::Recursive(nfa::Transition::Wildcard), NfaState::Accepting], }; let result = minimize(nfa).unwrap(); @@ -460,8 +436,7 @@ mod tests { StateTable { transitions: smallvec![], fallback_state: State(2), - attributes: StateAttributes::ACCEPTING - | StateAttributes::TRANSITIONS_TO_ACCEPTING, + attributes: StateAttributes::ACCEPTING | StateAttributes::TRANSITIONS_TO_ACCEPTING, }, ], }; @@ -525,8 +500,7 @@ mod tests { StateTable { transitions: smallvec![(label_b, State(6))], fallback_state: State(5), - attributes: StateAttributes::ACCEPTING - | StateAttributes::TRANSITIONS_TO_ACCEPTING, + attributes: StateAttributes::ACCEPTING | StateAttributes::TRANSITIONS_TO_ACCEPTING, }, ], }; @@ -595,8 +569,7 @@ mod tests { StateTable { transitions: smallvec![(label_b, State(7))], fallback_state: State(6), - attributes: StateAttributes::ACCEPTING - | StateAttributes::TRANSITIONS_TO_ACCEPTING, + attributes: StateAttributes::ACCEPTING | StateAttributes::TRANSITIONS_TO_ACCEPTING, }, ], }; @@ -644,8 +617,7 @@ mod tests { StateTable { transitions: smallvec![(label, State(4))], fallback_state: State(3), - attributes: StateAttributes::ACCEPTING - | StateAttributes::TRANSITIONS_TO_ACCEPTING, + attributes: StateAttributes::ACCEPTING | StateAttributes::TRANSITIONS_TO_ACCEPTING, }, ], }; @@ -681,8 +653,7 @@ mod tests { StateTable { transitions: smallvec![(label, State(2))], fallback_state: State(1), - attributes: StateAttributes::TRANSITIONS_TO_ACCEPTING - | StateAttributes::ACCEPTING, + attributes: StateAttributes::TRANSITIONS_TO_ACCEPTING | StateAttributes::ACCEPTING, }, ], }; @@ -791,14 +762,12 @@ mod tests { StateTable { transitions: smallvec![(label, State(8))], fallback_state: State(7), - attributes: StateAttributes::ACCEPTING - | StateAttributes::TRANSITIONS_TO_ACCEPTING, + attributes: StateAttributes::ACCEPTING | StateAttributes::TRANSITIONS_TO_ACCEPTING, }, StateTable { transitions: smallvec![(label, State(6))], fallback_state: State(5), - attributes: StateAttributes::ACCEPTING - | StateAttributes::TRANSITIONS_TO_ACCEPTING, + attributes: StateAttributes::ACCEPTING | StateAttributes::TRANSITIONS_TO_ACCEPTING, }, StateTable { transitions: smallvec![(label, State(2))], @@ -893,8 +862,7 @@ mod tests { StateTable { transitions: smallvec![(label_d, State(8))], fallback_state: State(7), - attributes: StateAttributes::ACCEPTING - | StateAttributes::TRANSITIONS_TO_ACCEPTING, + attributes: StateAttributes::ACCEPTING | StateAttributes::TRANSITIONS_TO_ACCEPTING, }, ], }; @@ -966,8 +934,7 @@ mod tests { StateTable { transitions: smallvec![(label_a, State(4)), (label_b, State(8))], fallback_state: State(3), - attributes: StateAttributes::ACCEPTING - | StateAttributes::TRANSITIONS_TO_ACCEPTING, + attributes: StateAttributes::ACCEPTING | StateAttributes::TRANSITIONS_TO_ACCEPTING, }, StateTable { transitions: smallvec![(label_a, State(4))], diff --git a/crates/rsonpath-lib/src/query/automaton/nfa.rs b/crates/rsonpath-lib/src/query/automaton/nfa.rs index 721112d9..92750560 100644 --- a/crates/rsonpath-lib/src/query/automaton/nfa.rs +++ b/crates/rsonpath-lib/src/query/automaton/nfa.rs @@ -68,17 +68,11 @@ impl<'q> NondeterministicAutomaton<'q> { .iter() .filter_map(|node| match node { JsonPathQueryNode::Root(_) => None, - JsonPathQueryNode::Descendant(label, _) => { - Some(Ok(Recursive(Transition::Labelled(label.into())))) - } - JsonPathQueryNode::Child(label, _) => { - Some(Ok(Direct(Transition::Labelled(label.into())))) - } + JsonPathQueryNode::Descendant(label, _) => Some(Ok(Recursive(Transition::Labelled(label.into())))), + JsonPathQueryNode::Child(label, _) => Some(Ok(Direct(Transition::Labelled(label.into())))), JsonPathQueryNode::AnyChild(_) => Some(Ok(Direct(Transition::Wildcard))), JsonPathQueryNode::AnyDescendant(_) => Some(Ok(Recursive(Transition::Wildcard))), - JsonPathQueryNode::ArrayIndexChild(index, _) => { - Some(Ok(Direct(Transition::Labelled((*index).into())))) - } + JsonPathQueryNode::ArrayIndexChild(index, _) => Some(Ok(Direct(Transition::Labelled((*index).into())))), JsonPathQueryNode::ArrayIndexDescendant(index, _) => { Some(Ok(Recursive(Transition::Labelled((*index).into())))) } @@ -92,9 +86,7 @@ impl<'q> NondeterministicAutomaton<'q> { if let Err(err) = accepting_state { Err(CompilerError::QueryTooComplex(Some(err))) } else { - Ok(NondeterministicAutomaton { - ordered_states: states, - }) + Ok(NondeterministicAutomaton { ordered_states: states }) } } @@ -122,15 +114,14 @@ impl<'q> Display for NondeterministicAutomaton<'q> { // This is the format for https://paperman.name/semigroup/ // for easy debugging of minimization. fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let all_labels: Vec<_> = - self.ordered_states - .iter() - .filter_map(|s| match s { - Direct(Transition::Labelled(label)) - | Recursive(Transition::Labelled(label)) => Some(*label), - _ => None, - }) - .collect(); + let all_labels: Vec<_> = self + .ordered_states + .iter() + .filter_map(|s| match s { + Direct(Transition::Labelled(label)) | Recursive(Transition::Labelled(label)) => Some(*label), + _ => None, + }) + .collect(); for (i, state) in self.ordered_states.iter().enumerate() { match state { diff --git a/crates/rsonpath-lib/src/query/automaton/small_set.rs b/crates/rsonpath-lib/src/query/automaton/small_set.rs index 164ba388..ade91ede 100644 --- a/crates/rsonpath-lib/src/query/automaton/small_set.rs +++ b/crates/rsonpath-lib/src/query/automaton/small_set.rs @@ -120,9 +120,7 @@ impl SmallSet for SmallSet128 { } fn iter(&self) -> SmallSet128Iter { - SmallSet128Iter { - bitmask: self.bitmask, - } + SmallSet128Iter { bitmask: self.bitmask } } fn singleton(&self) -> Option { @@ -213,9 +211,7 @@ impl Iterator for SmallSet256Iter { type Item = u8; fn next(&mut self) -> Option { - self.half_1 - .next() - .or_else(|| self.half_2.next().map(|x| x + 128)) + self.half_1.next().or_else(|| self.half_2.next().map(|x| x + 128)) } } diff --git a/crates/rsonpath-lib/src/query/builder.rs b/crates/rsonpath-lib/src/query/builder.rs index c440b8d1..6add4443 100644 --- a/crates/rsonpath-lib/src/query/builder.rs +++ b/crates/rsonpath-lib/src/query/builder.rs @@ -96,20 +96,14 @@ impl JsonPathQueryBuilder { for node in self.nodes.into_iter().rev() { last = match node { - NodeTemplate::ArrayIndexChild(i) => { - Some(Box::new(JsonPathQueryNode::ArrayIndexChild(i, last))) - } + NodeTemplate::ArrayIndexChild(i) => Some(Box::new(JsonPathQueryNode::ArrayIndexChild(i, last))), NodeTemplate::ArrayIndexDescendant(i) => { Some(Box::new(JsonPathQueryNode::ArrayIndexDescendant(i, last))) } NodeTemplate::Child(label) => Some(Box::new(JsonPathQueryNode::Child(label, last))), NodeTemplate::AnyChild => Some(Box::new(JsonPathQueryNode::AnyChild(last))), - NodeTemplate::Descendant(label) => { - Some(Box::new(JsonPathQueryNode::Descendant(label, last))) - } - NodeTemplate::AnyDescendant => { - Some(Box::new(JsonPathQueryNode::AnyDescendant(last))) - } + NodeTemplate::Descendant(label) => Some(Box::new(JsonPathQueryNode::Descendant(label, last))), + NodeTemplate::AnyDescendant => Some(Box::new(JsonPathQueryNode::AnyDescendant(last))), }; } diff --git a/crates/rsonpath-lib/src/query/error.rs b/crates/rsonpath-lib/src/query/error.rs index 5c6b8a2e..9e991868 100644 --- a/crates/rsonpath-lib/src/query/error.rs +++ b/crates/rsonpath-lib/src/query/error.rs @@ -147,10 +147,7 @@ impl ParseErrorReport { } fn add_new(&mut self, idx: usize) { - self.errors.push(ParseError { - start_idx: idx, - len: 1, - }) + self.errors.push(ParseError { start_idx: idx, len: 1 }) } } diff --git a/crates/rsonpath-lib/src/query/nonnegative_array_index.rs b/crates/rsonpath-lib/src/query/nonnegative_array_index.rs index 32c2c5c5..949b1f7c 100644 --- a/crates/rsonpath-lib/src/query/nonnegative_array_index.rs +++ b/crates/rsonpath-lib/src/query/nonnegative_array_index.rs @@ -56,9 +56,7 @@ impl NonNegativeArrayIndex { self.0 = new_index; Ok(()) } else { - Err(ArrayIndexError::ExceedsUpperLimitError( - new_index.to_string(), - )) + Err(ArrayIndexError::ExceedsUpperLimitError(new_index.to_string())) } } @@ -95,8 +93,7 @@ mod tests { #[test] fn index_ulimit_parse_check() { - NonNegativeArrayIndex::try_from(ARRAY_INDEX_ULIMIT) - .expect("Array index ulimit should be convertible."); + NonNegativeArrayIndex::try_from(ARRAY_INDEX_ULIMIT).expect("Array index ulimit should be convertible."); NonNegativeArrayIndex::try_from(ARRAY_INDEX_ULIMIT + 1) .expect_err("Values in excess of array index ulimit should not be convertible."); diff --git a/crates/rsonpath-lib/src/query/parser.rs b/crates/rsonpath-lib/src/query/parser.rs index 5d027de7..0e8d44e2 100644 --- a/crates/rsonpath-lib/src/query/parser.rs +++ b/crates/rsonpath-lib/src/query/parser.rs @@ -1,11 +1,7 @@ use super::error::{ArrayIndexError, ParseErrorReport, ParserError}; use crate::debug; -use crate::query::{ - JsonPathQuery, JsonPathQueryNode, JsonPathQueryNodeType, Label, NonNegativeArrayIndex, -}; -use nom::{ - branch::*, bytes::complete::*, character::complete::*, combinator::*, multi::*, sequence::*, *, -}; +use crate::query::{JsonPathQuery, JsonPathQueryNode, JsonPathQueryNodeType, Label, NonNegativeArrayIndex}; +use nom::{branch::*, bytes::complete::*, character::complete::*, combinator::*, multi::*, sequence::*, *}; use std::borrow::Borrow; use std::fmt::{self, Display}; @@ -78,18 +74,13 @@ pub(crate) fn parse_json_path_query(query_string: &str) -> Result() + + &tokens.iter().map(|x| format!("({x:?})")).collect::() ); let node = tokens_to_node(&mut tokens.into_iter())?; Ok(match node { None => JsonPathQuery::new(Box::new(JsonPathQueryNode::Root(None))), Some(node) if node.is_root() => JsonPathQuery::new(Box::new(node)), - Some(node) => { - JsonPathQuery::new(Box::new(JsonPathQueryNode::Root(Some(Box::new(node))))) - } + Some(node) => JsonPathQuery::new(Box::new(JsonPathQueryNode::Root(Some(Box::new(node))))), }) } _ => { @@ -97,51 +88,34 @@ pub(crate) fn parse_json_path_query(query_string: &str) -> Result { - return Err(ParserError::SyntaxError { - report: parse_errors, - }) - } + Ok("") => return Err(ParserError::SyntaxError { report: parse_errors }), Ok(remaining) => { let error_character_index = query_string.len() - remaining.len(); parse_errors.record_at(error_character_index); continuation = non_root()(&remaining[1..]).finish().map(|x| x.0); } - Err(e) => { - return Err(nom::error::Error::new(query_string.to_owned(), e.code).into()) - } + Err(e) => return Err(nom::error::Error::new(query_string.to_owned(), e.code).into()), } } } } } -fn tokens_to_node<'a, I: Iterator>>( - tokens: &mut I, -) -> Result, ParserError> { +fn tokens_to_node<'a, I: Iterator>>(tokens: &mut I) -> Result, ParserError> { match tokens.next() { Some(token) => { let child_node = tokens_to_node(tokens)?.map(Box::new); match token { Token::Root => Ok(Some(JsonPathQueryNode::Root(child_node))), - Token::Child(label) => Ok(Some(JsonPathQueryNode::Child( - Label::new(label.borrow()), - child_node, - ))), - Token::ArrayIndexChild(i) => { - Ok(Some(JsonPathQueryNode::ArrayIndexChild(i, child_node))) - } + Token::Child(label) => Ok(Some(JsonPathQueryNode::Child(Label::new(label.borrow()), child_node))), + Token::ArrayIndexChild(i) => Ok(Some(JsonPathQueryNode::ArrayIndexChild(i, child_node))), Token::WildcardChild() => Ok(Some(JsonPathQueryNode::AnyChild(child_node))), Token::Descendant(label) => Ok(Some(JsonPathQueryNode::Descendant( Label::new(label.borrow()), child_node, ))), - Token::ArrayIndexDescendant(i) => { - Ok(Some(JsonPathQueryNode::ArrayIndexDescendant(i, child_node))) - } - Token::WildcardDescendant() => { - Ok(Some(JsonPathQueryNode::AnyDescendant(child_node))) - } + Token::ArrayIndexDescendant(i) => Ok(Some(JsonPathQueryNode::ArrayIndexDescendant(i, child_node))), + Token::WildcardDescendant() => Ok(Some(JsonPathQueryNode::AnyDescendant(child_node))), } } _ => Ok(None), @@ -181,10 +155,9 @@ fn non_root<'a>() -> impl Parser<'a, Vec>> { } fn wildcard_child_selector<'a>() -> impl Parser<'a, Token<'a>> { - map( - alt((dot_wildcard_selector(), index_wildcard_selector())), - |_| Token::WildcardChild(), - ) + map(alt((dot_wildcard_selector(), index_wildcard_selector())), |_| { + Token::WildcardChild() + }) } fn child_selector<'a>() -> impl Parser<'a, Token<'a>> { @@ -210,10 +183,9 @@ fn descendant_selector<'a>() -> impl Parser<'a, Token<'a>> { } fn wildcard_descendant_selector<'a>() -> impl Parser<'a, Token<'a>> { - map( - preceded(tag(".."), alt((char('*'), index_wildcard_selector()))), - |_| Token::WildcardDescendant(), - ) + map(preceded(tag(".."), alt((char('*'), index_wildcard_selector()))), |_| { + Token::WildcardDescendant() + }) } fn index_selector<'a>() -> impl Parser<'a, LabelString<'a>> { @@ -236,9 +208,7 @@ fn label_first<'a>() -> impl Parser<'a, char> { } fn label_character<'a>() -> impl Parser<'a, char> { - verify(anychar, |&x| { - x.is_alphanumeric() || x == '_' || !x.is_ascii() - }) + verify(anychar, |&x| x.is_alphanumeric() || x == '_' || !x.is_ascii()) } fn array_index_child_selector<'a>() -> impl Parser<'a, Token<'a>> { @@ -261,8 +231,7 @@ fn parsed_array_index<'a>() -> impl Parser<'a, u64> { map_res(length_limited_array_index(), str::parse) } -const ARRAY_INDEX_ULIMIT_BASE_10_DIGIT_COUNT: usize = - NonNegativeArrayIndex::MAX.get_index().ilog10() as usize; +const ARRAY_INDEX_ULIMIT_BASE_10_DIGIT_COUNT: usize = NonNegativeArrayIndex::MAX.get_index().ilog10() as usize; fn length_limited_array_index<'a>() -> impl Parser<'a, &'a str> { map_res(digit1, |cs: &str| { if cs.len() > (ARRAY_INDEX_ULIMIT_BASE_10_DIGIT_COUNT + 1) { @@ -280,11 +249,7 @@ fn quoted_label<'a>() -> impl Parser<'a, LabelString<'a>> { map(opt(single_quoted_label()), LabelString::from), char('\''), ), - delimited( - char('"'), - map(opt(double_quoted_label()), LabelString::from), - char('"'), - ), + delimited(char('"'), map(opt(double_quoted_label()), LabelString::from), char('"')), )) } @@ -481,8 +446,7 @@ mod tests { #[test] fn should_infer_root_from_empty_string() { let input = ""; - let expected_query = - JsonPathQuery::new(Box::new(crate::query::JsonPathQueryNode::Root(None))); + let expected_query = JsonPathQuery::new(Box::new(crate::query::JsonPathQueryNode::Root(None))); let result = parse_json_path_query(input).expect("expected Ok"); @@ -492,8 +456,7 @@ mod tests { #[test] fn root() { let input = "$"; - let expected_query = - JsonPathQuery::new(Box::new(crate::query::JsonPathQueryNode::Root(None))); + let expected_query = JsonPathQuery::new(Box::new(crate::query::JsonPathQueryNode::Root(None))); let result = parse_json_path_query(input).expect("expected Ok"); diff --git a/crates/rsonpath-lib/tests/query_parser_tests.rs b/crates/rsonpath-lib/tests/query_parser_tests.rs index 40e9da34..600ea55f 100644 --- a/crates/rsonpath-lib/tests/query_parser_tests.rs +++ b/crates/rsonpath-lib/tests/query_parser_tests.rs @@ -139,9 +139,7 @@ fn escaped_single_quote_in_single_quote_label() { #[test] fn unescaped_double_quote_in_single_quote_label() { let input = r#"['"']"#; - let expected_query = JsonPathQueryBuilder::new() - .child(Label::new(r#"\""#)) - .into(); + let expected_query = JsonPathQueryBuilder::new().child(Label::new(r#"\""#)).into(); let result = JsonPathQuery::parse(input).expect("expected Ok"); @@ -255,21 +253,17 @@ mod proptests { // .label or ['label'] fn any_child() -> impl Strategy { - prop_oneof![any_label().prop_map(|x| (format!(".{x}"), x)), any_index(),].prop_map( - |(s, l)| Selector { - string: s, - tag: SelectorTag::Child(l), - }, - ) + prop_oneof![any_label().prop_map(|x| (format!(".{x}"), x)), any_index(),].prop_map(|(s, l)| Selector { + string: s, + tag: SelectorTag::Child(l), + }) } // ..label or ..['label'] fn any_descendant() -> impl Strategy { - prop_oneof![any_label().prop_map(|x| (x.clone(), x)), any_index(),].prop_map(|(x, l)| { - Selector { - string: format!("..{x}"), - tag: SelectorTag::Descendant(l), - } + prop_oneof![any_label().prop_map(|x| (x.clone(), x)), any_index(),].prop_map(|(x, l)| Selector { + string: format!("..{x}"), + tag: SelectorTag::Descendant(l), }) } diff --git a/crates/rsonpath/src/lib.rs b/crates/rsonpath/src/lib.rs index 07967a5f..5036c57e 100644 --- a/crates/rsonpath/src/lib.rs +++ b/crates/rsonpath/src/lib.rs @@ -11,8 +11,7 @@ use rsonpath_lib::{ }, }; -const FEATURE_REQUEST_URL: &str = - "https://github.com/V0ldek/rsonpath/issues/new?template=feature_request.md"; +const FEATURE_REQUEST_URL: &str = "https://github.com/V0ldek/rsonpath/issues/new?template=feature_request.md"; /// Turn a [`ParserError`] into a user-friendly eyre Report. pub fn report_parser_error(query_string: &str, error: ParserError) -> eyre::Report { @@ -36,7 +35,7 @@ pub fn report_compiler_error(query: &JsonPathQuery, error: CompilerError) -> eyr { report = report.suggestion( "Wildcard selectors are a common source of query complexity.\n \ - Consider reformulating the query using descendant selectors to replace sequences of wildcards." + Consider reformulating the query using descendant selectors to replace sequences of wildcards.", ); } add_unsupported_context(report, UnsupportedFeatureError::large_automaton_queries()) @@ -48,10 +47,9 @@ pub fn report_compiler_error(query: &JsonPathQuery, error: CompilerError) -> eyr pub fn report_engine_error(error: EngineError) -> eyre::Report { match error { EngineError::DepthBelowZero(_, _) => eyre::Report::new(error), - EngineError::DepthAboveLimit(_, _) => add_unsupported_context( - eyre::Report::new(error), - UnsupportedFeatureError::large_json_depths(), - ), + EngineError::DepthAboveLimit(_, _) => { + add_unsupported_context(eyre::Report::new(error), UnsupportedFeatureError::large_json_depths()) + } EngineError::MissingClosingCharacter() => eyre::Report::new(error), EngineError::MalformedLabelQuotes(_) => eyre::Report::new(error), EngineError::NotSupported(unsupported) => report_unsupported_error(unsupported), @@ -72,10 +70,7 @@ fn report_query_syntax_error(query_string: &str, report: ParseErrorReport) -> ey } else { 0 }; - let display_length = cmp::min( - error.len + MAX_DISPLAY_LENGTH, - query_string.len() - display_start_idx, - ); + let display_length = cmp::min(error.len + MAX_DISPLAY_LENGTH, query_string.len() - display_start_idx); let error_slice = &query_string[error.start_idx..error.start_idx + error.len]; let slice = &query_string[display_start_idx..display_start_idx + display_length]; let error_idx = error.start_idx - display_start_idx; @@ -84,11 +79,7 @@ fn report_query_syntax_error(query_string: &str, report: ParseErrorReport) -> ey .take(error_idx) .chain(iter::repeat('^').take(error.len)) .collect(); - let display_string = format!( - "{}\n{}", - slice, - (underline + " invalid tokens").bright_red() - ); + let display_string = format!("{}\n{}", slice, (underline + " invalid tokens").bright_red()); eyre = eyre.section(display_string.header("Parse error:")); @@ -100,7 +91,10 @@ fn report_query_syntax_error(query_string: &str, report: ParseErrorReport) -> ey } if error_slice.contains('$') { - eyre = eyre.suggestion(format!("The '{}' character is reserved for the root selector and may appear only at the start.", "$".dimmed())); + eyre = eyre.suggestion(format!( + "The '{}' character is reserved for the root selector and may appear only at the start.", + "$".dimmed() + )); } } @@ -112,10 +106,7 @@ fn report_unsupported_error(unsupported: UnsupportedFeatureError) -> eyre::Repor let feature = unsupported.feature(); let base_report = if unsupported.is_planned() { let feature = feature.blue(); - eyre!( - "The feature {feature} {}", - "is not supported yet.".bright_red() - ) + eyre!("The feature {feature} {}", "is not supported yet.".bright_red()) } else { let feature = feature.red(); eyre!("The feature {feature} {}", "is not supported.".bright_red()) @@ -123,10 +114,7 @@ fn report_unsupported_error(unsupported: UnsupportedFeatureError) -> eyre::Repor add_unsupported_context(base_report, unsupported) } -fn add_unsupported_context( - report: eyre::Report, - unsupported: UnsupportedFeatureError, -) -> eyre::Report { +fn add_unsupported_context(report: eyre::Report, unsupported: UnsupportedFeatureError) -> eyre::Report { use color_eyre::owo_colors::OwoColorize; let feature = unsupported.feature(); if let Some(issue) = unsupported.issue() { diff --git a/crates/rsonpath/src/main.rs b/crates/rsonpath/src/main.rs index 59845dda..35f10dbf 100644 --- a/crates/rsonpath/src/main.rs +++ b/crates/rsonpath/src/main.rs @@ -68,8 +68,7 @@ fn main() -> Result<()> { configure_logger(args.verbose)?; - run_with_args(&args) - .map_err(|err| err.with_note(|| format!("Query string: '{}'.", args.query.dimmed()))) + run_with_args(&args).map_err(|err| err.with_note(|| format!("Query string: '{}'.", args.query.dimmed()))) } fn run_with_args(args: &Args) -> Result<()> { @@ -100,20 +99,18 @@ fn compile(query: &JsonPathQuery) -> Result<()> { fn run(query: &JsonPathQuery, input: &OwnedBytes, engine: EngineArg) -> Result<()> { match engine { EngineArg::Main => { - let result = run_engine::(query, input) - .wrap_err("Error running the main engine.")?; + let result = run_engine::(query, input).wrap_err("Error running the main engine.")?; println!("{result}"); } EngineArg::Recursive => { - let result = run_engine::(query, input) - .wrap_err("Error running the recursive engine.")?; + let result = + run_engine::(query, input).wrap_err("Error running the recursive engine.")?; println!("{result}"); } EngineArg::VerifyBoth => { - let main_result = run_engine::(query, input) - .wrap_err("Error running the main engine.")?; - let recursive_result = run_engine::(query, input) - .wrap_err("Error running the recursive engine.")?; + let main_result = run_engine::(query, input).wrap_err("Error running the main engine.")?; + let recursive_result = + run_engine::(query, input).wrap_err("Error running the recursive engine.")?; if recursive_result != main_result { return Err(eyre!("Result mismatch!")); @@ -140,9 +137,8 @@ fn run_engine(query: &JsonPathQuery, input: &OwnedB } fn parse_query(query_string: &str) -> Result { - JsonPathQuery::parse(query_string).map_err(|err| { - report_parser_error(query_string, err).wrap_err("Could not parse JSONPath query.") - }) + JsonPathQuery::parse(query_string) + .map_err(|err| report_parser_error(query_string, err).wrap_err("Could not parse JSONPath query.")) } fn get_contents(file_path: Option<&str>) -> Result { @@ -162,11 +158,7 @@ fn get_contents(file_path: Option<&str>) -> Result { fn configure_logger(verbose: bool) -> Result<()> { SimpleLogger::new() - .with_level(if verbose { - LevelFilter::Trace - } else { - LevelFilter::Warn - }) + .with_level(if verbose { LevelFilter::Trace } else { LevelFilter::Warn }) .init() .wrap_err("Logger configuration error.") } diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 00000000..95fefa43 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,5 @@ +edition = "2021" +max_width = 120 +newline_style = "Unix" +use_field_init_shorthand = true +use_try_shorthand = true \ No newline at end of file