1#![doc(html_root_url = "https://docs.rs/lazyext-slice/0.0.2")]
3#![deny(
4 missing_docs,
5 warnings,
6)]
7#![cfg_attr(docsrs, feature(doc_cfg))]
8#![cfg_attr(docsrs, allow(unused_attributes))]
9
10#[cfg(feature = "alloc")]
11extern crate alloc;
12
13#[macro_use]
14extern crate paste;
15
16macro_rules! cfg_alloc {
17 ($($item:item)*) => {
18 $(
19 #[cfg(feature = "alloc")]
20 #[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
21 $item
22 )*
23 }
24}
25
26macro_rules! has_prefix {
27 ($trait:tt::$fn:tt) => {
28 #[inline]
30 fn has_prefix(&self, prefix: impl $trait) -> bool {
31 let src = $trait::$fn(self);
32 let prefix = $trait::$fn(&prefix);
33 let pl = prefix.len();
34 if src.len() < pl {
35 return false;
36 }
37
38 src[0..pl].eq(prefix)
39 }
40 };
41}
42
43macro_rules! has_suffix {
44 ($trait:tt::$fn:tt) => {
45 #[inline]
47 fn has_suffix(&self, suffix: impl $trait) -> bool {
48 let src = $trait::$fn(self);
49 let suffix = $trait::$fn(&suffix);
50 let pl = suffix.len() - 1;
51 if src.len() <= pl {
52 return false;
53 }
54
55 src[pl..].eq(suffix)
56 }
57 };
58}
59
60macro_rules! longest_prefix {
61 ($trait:tt::$fn:tt, $ty: ty) => {
62 #[inline]
64 fn longest_prefix(&self, other: impl $trait) -> &[$ty] {
65 let k1 = $trait::$fn(self);
66 let k2 = $trait::$fn(&other);
67 let max = k1.len().min(k2.len());
68
69 let mut n = max - 1;
70 for i in 0..max {
71 if k1[i].ne(&k2[i]) {
72 n = i;
73 break;
74 }
75 }
76 &k1[..n]
77 }
78 };
79}
80
81macro_rules! longest_suffix {
82 ($trait:tt::$fn:tt, $ty: ty) => {
83 #[inline]
85 fn longest_suffix(&self, other: impl $trait) -> &[$ty] {
86 let k1 = $trait::$fn(self);
87 let k1_len = k1.len();
88 let k2 = $trait::$fn(&other);
89 let k2_len = k2.len();
90 return if k1_len < k2_len {
91 let max = k1_len;
92 let mut n = max;
93 for i in 0..max {
94 if k1[k1_len - i - 1].ne(&k2[k2_len - i - 1]) {
95 n = i;
96 break;
97 }
98 }
99 &k1[max - n..]
100 } else {
101 let max = k2_len;
102 let mut n = max;
103 for i in 0..max {
104 if k1[k1_len - i - 1].ne(&k2[k2_len - i - 1]) {
105 n = i;
106 break;
107 }
108 }
109 &k1[k1_len - k2_len + max - n..]
110 };
111 }
112 }
113}
114
115#[cfg(feature = "alloc")]
116macro_rules! longest_prefix_lossy {
117 ($trait:tt::$fn:tt, $ty: ty, $ty_literal: literal) => {
118 #[doc = concat!("Finds the longest shared prefix, return a Cow<'_, [", $ty_literal, "]>.")]
119 #[inline]
120 fn longest_prefix_lossy(&self, other: impl $trait) -> Cow<'_, [$ty]> {
121 Cow::Borrowed(self.longest_prefix(other))
122 }
123 };
124}
125
126#[cfg(feature = "alloc")]
127macro_rules! longest_suffix_lossy {
128 ($trait:tt::$fn:tt, $ty: ty, $ty_literal: literal) => {
129 #[doc = concat!("Finds the longest shared suffix, return a Cow<'_, [", $ty_literal, "]>.")]
130 #[inline]
131 fn longest_suffix_lossy(&self, other: impl $trait) -> Cow<'_, [$ty]> {
132 Cow::Borrowed(self.longest_suffix(other))
133 }
134 };
135}
136
137macro_rules! impl_psfix_suites {
138 ($trait:tt::$fn:tt, $ty: ty, $ty_literal: literal) => {
139 has_prefix!($trait::$fn);
140
141 has_suffix!($trait::$fn);
142
143 longest_prefix!($trait::$fn, $ty);
144
145 longest_suffix!($trait::$fn, $ty);
146
147 cfg_alloc!{
148 longest_prefix_lossy!($trait::$fn, $ty, $ty_literal);
149 longest_suffix_lossy!($trait::$fn, $ty, $ty_literal);
150 }
151 };
152}
153
154mod bytes_ext;
155mod slice_ext;
156
157pub use bytes_ext::*;
158pub use slice_ext::*;