Skip to main content

grafix_toolbox/kit/policies/func/
vec.rs

1use crate::{lib::*, math::*};
2use std::hash::Hash;
3
4pub trait Utf8Len {
5	fn utf8_len_at<T>(&self, idx: T) -> usize
6	where
7		usize: Cast<T>;
8	fn utf8_count(&self) -> usize;
9	fn utf8_slice(&self, r: impl uRange) -> &str;
10	fn slice(&self, r: impl uRange) -> &str;
11}
12impl Utf8Len for str {
13	fn utf8_len_at<T>(&self, char_idx: T) -> usize
14	where
15		usize: Cast<T>,
16	{
17		let char_idx = usize(char_idx);
18		self.char_indices()
19			.enumerate()
20			.take(char_idx + 1)
21			.last()
22			.map_or(0, |(n, (i, _))| if n == char_idx { i } else { self.len() })
23	}
24	fn utf8_count(&self) -> usize {
25		self.chars().count()
26	}
27	fn utf8_slice(&self, r: impl uRange) -> &str {
28		let (b, e) = r.get_range();
29		let beg = self.utf8_len_at(b);
30		if e == usize::MAX {
31			return &self[beg..];
32		}
33
34		let end = self[beg..].utf8_len_at(e - b);
35		&self[beg..beg + end]
36	}
37	fn slice(&self, r: impl uRange) -> &str {
38		let (b, e) = r.get_range().fmin(self.len());
39		&self[b..e]
40	}
41}
42
43pub trait CountItems<T: Eq + Hash>: Sized + Iterator<Item = T> {
44	fn map_count(self) -> HashMap<T, usize> {
45		let mut map = HashMap::new();
46		for i in self {
47			*map.entry(i).or_default() += 1;
48		}
49		map
50	}
51}
52impl<T: Eq + Hash, V: Sized + Iterator<Item = T>> CountItems<T> for V {}
53
54pub trait CollectVec<T>: Sized + Iterator<Item = T> {
55	fn collect_vec(self) -> Vec<T> {
56		self.collect()
57	}
58	fn collect_box(self) -> Box<[T]> {
59		self.collect()
60	}
61	fn collect_arr<const N: usize>(self) -> [T; N] {
62		let vec = self.collect_vec();
63		vec.try_into()
64			.map_err(|v: Vec<_>| format!("Cannot collect [_][..{}] into [{}; {N}]", v.len(), type_name::<T>()))
65			.fail()
66	}
67}
68impl<V: Sized + Iterator<Item = T>, T> CollectVec<T> for V {}