Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/utils.rs')
| -rw-r--r-- | crates/hir-ty/src/utils.rs | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/crates/hir-ty/src/utils.rs b/crates/hir-ty/src/utils.rs index 509109543c..ae9b2c4618 100644 --- a/crates/hir-ty/src/utils.rs +++ b/crates/hir-ty/src/utils.rs @@ -1,6 +1,8 @@ //! Helper functions for working with def, which don't need to be a separate //! query, but can't be computed directly from `*Data` (ie, which need a `db`). +use std::iter::Enumerate; + use base_db::target::{self, TargetData}; use hir_def::{ EnumId, EnumVariantId, FunctionId, Lookup, TraitId, attrs::AttrFlags, lang_item::LangItems, @@ -163,3 +165,54 @@ pub(crate) fn detect_variant_from_bytes<'a>( }; Some((var_id, var_layout)) } + +pub(crate) struct EnumerateAndAdjust<I> { + enumerate: Enumerate<I>, + gap_pos: usize, + gap_len: usize, +} + +impl<I> Iterator for EnumerateAndAdjust<I> +where + I: Iterator, +{ + type Item = (usize, <I as Iterator>::Item); + + fn next(&mut self) -> Option<(usize, <I as Iterator>::Item)> { + self.enumerate + .next() + .map(|(i, elem)| (if i < self.gap_pos { i } else { i + self.gap_len }, elem)) + } + + fn size_hint(&self) -> (usize, Option<usize>) { + self.enumerate.size_hint() + } +} + +pub(crate) trait EnumerateAndAdjustIterator { + fn enumerate_and_adjust( + self, + expected_len: usize, + gap_pos: Option<u32>, + ) -> EnumerateAndAdjust<Self> + where + Self: Sized; +} + +impl<T: ExactSizeIterator> EnumerateAndAdjustIterator for T { + fn enumerate_and_adjust( + self, + expected_len: usize, + gap_pos: Option<u32>, + ) -> EnumerateAndAdjust<Self> + where + Self: Sized, + { + let actual_len = self.len(); + EnumerateAndAdjust { + enumerate: self.enumerate(), + gap_pos: gap_pos.map(|it| it as usize).unwrap_or(expected_len), + gap_len: expected_len - actual_len, + } + } +} |