konst/slice/
bytes_pattern.rs1use crate::{
2 chr,
3 polymorphism::{HasTypeWitness, MakeTypeWitness, TypeEq, TypeWitnessTypeArg},
4};
5
6pub trait BytesPattern<const N: usize>: HasTypeWitness<BytesPatternInput<N, Self>> {
13 #[doc(hidden)]
14 type __Normalized: ?Sized;
15}
16
17#[non_exhaustive]
18pub enum BytesPatternInput<const N: usize, P: ?Sized + BytesPattern<N>> {
19 Str(TypeEq<P, str>, TypeEq<*const P::__Normalized, *const [u8]>),
20 Bytes(TypeEq<P, [u8]>, TypeEq<*const P::__Normalized, *const [u8]>),
21 Array(
22 TypeEq<P, [u8; N]>,
23 TypeEq<*const P::__Normalized, *const [u8]>,
24 ),
25 Char(
26 TypeEq<P, char>,
27 TypeEq<*const P::__Normalized, *const chr::Utf8Encoded>,
28 ),
29}
30
31impl<const N: usize, Arg> TypeWitnessTypeArg for BytesPatternInput<N, Arg>
32where
33 Arg: ?Sized + BytesPattern<N>,
34{
35 type Arg = Arg;
36}
37
38impl MakeTypeWitness for BytesPatternInput<0, str> {
39 const MAKE: Self = BytesPatternInput::Str(TypeEq::NEW, TypeEq::NEW);
40}
41impl BytesPattern<0> for str {
42 #[doc(hidden)]
43 type __Normalized = [u8];
44}
45
46impl MakeTypeWitness for BytesPatternInput<0, [u8]> {
47 const MAKE: Self = BytesPatternInput::Bytes(TypeEq::NEW, TypeEq::NEW);
48}
49impl BytesPattern<0> for [u8] {
50 #[doc(hidden)]
51 type __Normalized = [u8];
52}
53
54impl<const N: usize> MakeTypeWitness for BytesPatternInput<N, [u8; N]> {
55 const MAKE: Self = BytesPatternInput::Array(TypeEq::NEW, TypeEq::NEW);
56}
57impl<const N: usize> BytesPattern<N> for [u8; N] {
58 #[doc(hidden)]
59 type __Normalized = [u8];
60}
61
62impl MakeTypeWitness for BytesPatternInput<0, char> {
63 const MAKE: Self = BytesPatternInput::Char(TypeEq::NEW, TypeEq::NEW);
64}
65impl BytesPattern<0> for char {
66 #[doc(hidden)]
67 type __Normalized = chr::Utf8Encoded;
68}
69
70#[derive(Copy, Clone)]
71pub(crate) enum PatternNorm<'a, const N: usize, P>
72where
73 P: ?Sized + BytesPattern<N>,
74{
75 Bytes {
76 val: &'a [u8],
77 ten: TypeEq<*const P::__Normalized, *const [u8]>,
78 },
79 Char {
80 val: chr::Utf8Encoded,
81 ten: TypeEq<*const P::__Normalized, *const chr::Utf8Encoded>,
82 },
83}
84
85impl<'a, const N: usize, P> PatternNorm<'a, N, P>
86where
87 P: ?Sized + BytesPattern<N>,
88{
89 pub(crate) const fn new(pattern: &'a P) -> Self {
90 match P::WITNESS {
91 BytesPatternInput::Str(te, ten) => {
92 let val: &'a [u8] = te.in_ref().to_right(pattern).as_bytes();
93 PatternNorm::Bytes { val, ten }
94 }
95 BytesPatternInput::Bytes(te, ten) => {
96 let val: &'a [u8] = te.in_ref().to_right(pattern);
97 PatternNorm::Bytes { val, ten }
98 }
99 BytesPatternInput::Array(te, ten) => {
100 let val: &'a [u8] = te.in_ref().to_right(pattern);
101 PatternNorm::Bytes { val, ten }
102 }
103 BytesPatternInput::Char(te, ten) => {
104 let val: &'a char = te.in_ref().to_right(pattern);
105 let val = chr::encode_utf8(*val);
106 PatternNorm::Char { val, ten }
107 }
108 }
109 }
110
111 pub(crate) const fn as_bytes(&self) -> &[u8] {
112 match self {
113 PatternNorm::Bytes { val, ten } => ten.reachability_hint(val),
114 PatternNorm::Char { val, ten } => ten.reachability_hint(val.as_bytes()),
115 }
116 }
117}