1use std::{
7 borrow::Borrow,
8 convert::TryFrom,
9 fmt::{Debug, Display},
10 marker::PhantomData,
11 ops::{Add, Range},
12};
13
14use as_derive_utils::{return_syn_err, to_stream};
15
16use proc_macro2::{Span, TokenStream as TokenStream2};
17use quote::ToTokens;
18
19use crate::common_tokens::StartLenTokens;
20
21pub type SmallStartLen = StartLen<u16>;
23
24#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd)]
26pub struct StartLen<N> {
27 pub start: N,
28 pub len: N,
29}
30
31impl StartLen<u16> {
32 abi_stable_shared::declare_start_len_bit_methods! {}
33}
34
35impl<N> StartLen<N> {
36 #[inline]
37 pub(crate) fn from_start_len(start: usize, len: usize) -> Self
38 where
39 N: TryFrom<usize>,
40 N::Error: Debug,
41 {
42 Self {
43 start: N::try_from(start).unwrap(),
44 len: N::try_from(len).unwrap(),
45 }
46 }
47
48 #[inline]
49 pub const fn new(start: N, len: N) -> Self {
50 Self { start, len }
51 }
52
53 #[allow(dead_code)]
54 pub(crate) fn into_range(self) -> Range<N>
55 where
56 N: Copy + Add<N, Output = N>,
57 {
58 self.start..(self.start + self.len)
59 }
60
61 #[inline]
62 pub(crate) fn tokenizer(self, ctokens: &StartLenTokens) -> StartLenTokenizer<'_, N> {
63 StartLenTokenizer {
64 start: self.start,
65 len: self.len,
66 ctokens,
67 }
68 }
69}
70
71impl StartLen<u16> {
72 pub const DUMMY: Self = Self {
73 start: (1u16 << 15) + 1,
74 len: (1u16 << 15) + 1,
75 };
76
77 pub const EMPTY: Self = Self { start: 0, len: 0 };
78
79 #[inline]
81 pub const fn start(self) -> usize {
82 self.start as usize
83 }
84
85 #[inline]
86 pub const fn len(self) -> usize {
87 self.len as usize
88 }
89
90 pub const fn to_u32(self) -> u32 {
92 self.start as u32 | ((self.len as u32) << 16)
93 }
94
95 pub fn check_ident_length(&self, span: Span) -> Result<(), syn::Error> {
96 if self.len > Self::IDENT_MAX_LEN {
97 return_syn_err!(
98 span,
99 "Identifier is too long,it must be at most {} bytes.",
100 Self::IDENT_MAX_LEN,
101 );
102 }
103 Ok(())
104 }
105}
106
107pub struct StartLenTokenizer<'a, N> {
108 start: N,
109 len: N,
110 ctokens: &'a StartLenTokens,
111}
112
113impl<'a, N> ToTokens for StartLenTokenizer<'a, N>
114where
115 N: ToTokens,
116{
117 fn to_tokens(&self, ts: &mut TokenStream2) {
118 use syn::token::{Colon2, Comma, Paren};
119
120 let ct = self.ctokens;
121 to_stream!(ts; ct.start_len,Colon2::default(),ct.new );
122 Paren::default().surround(ts, |ts| {
123 to_stream!(ts; self.start,Comma::default(),self.len );
124 });
125 }
126}
127
128#[allow(dead_code)]
131pub type SmallCompositeString = CompositeString<u16>;
132
133pub struct CompositeString<N> {
136 buffer: String,
137 _integer: PhantomData<N>,
138}
139
140#[allow(dead_code)]
141impl<N> CompositeString<N>
142where
143 N: TryFrom<usize>,
144 N::Error: Debug,
145{
146 pub fn new() -> Self {
147 Self {
148 buffer: String::with_capacity(128),
149 _integer: PhantomData,
150 }
151 }
152
153 fn len(&self) -> usize {
154 self.buffer.len()
155 }
156
157 pub fn push_str(&mut self, s: &str) -> StartLen<N> {
158 let start = self.len();
159 self.buffer.push_str(s);
160 StartLen::from_start_len(start, s.len())
161 }
162
163 pub fn push_display<D>(&mut self, s: &D) -> StartLen<N>
164 where
165 D: Display,
166 {
167 use std::fmt::Write;
168 let start = self.len();
169 let _ = write!(self.buffer, "{}", s);
170 StartLen::from_start_len(start, self.len() - start)
171 }
172
173 #[allow(dead_code)]
174 pub fn extend_with_str<I>(&mut self, separator: &str, iter: I) -> StartLen<N>
175 where
176 I: IntoIterator,
177 I::Item: Borrow<str>,
178 {
179 let start = self.len();
180 for s in iter {
181 self.buffer.push_str(s.borrow());
182 self.buffer.push_str(separator);
183 }
184 StartLen::from_start_len(start, self.len() - start)
185 }
186
187 pub fn extend_with_display<I>(&mut self, separator: &str, iter: I) -> StartLen<N>
188 where
189 I: IntoIterator,
190 I::Item: Display,
191 {
192 use std::fmt::Write;
193 let start = self.len();
194 for elem in iter {
195 let _ = write!(self.buffer, "{}", elem);
196 self.buffer.push_str(separator);
197 }
198 StartLen::from_start_len(start, self.len() - start)
199 }
200
201 pub fn into_inner(self) -> String {
202 self.buffer
203 }
204 pub fn as_inner(&self) -> &str {
205 &self.buffer
206 }
207}
208
209pub type SmallCompositeVec<T> = CompositeVec<T, u16>;
212
213pub struct CompositeVec<T, N> {
216 list: Vec<T>,
217 _integer: PhantomData<N>,
218}
219
220#[allow(dead_code)]
221impl<T, N> CompositeVec<T, N>
222where
223 N: TryFrom<usize>,
224 N::Error: Debug,
225{
226 pub fn new() -> Self {
227 Self {
228 list: Vec::new(),
229 _integer: PhantomData,
230 }
231 }
232
233 pub fn with_capacity(capacity: usize) -> Self {
234 Self {
235 list: Vec::with_capacity(capacity),
236 _integer: PhantomData,
237 }
238 }
239
240 fn len(&self) -> usize {
241 self.list.len()
242 }
243
244 pub fn push(&mut self, elem: T) -> u16 {
245 let ind = self.len();
246 self.list.push(elem);
247 ind as u16
248 }
249
250 pub fn extend<I>(&mut self, iter: I) -> StartLen<N>
251 where
252 I: IntoIterator<Item = T>,
253 {
254 let start = self.len();
255 self.list.extend(iter);
256 StartLen::from_start_len(start, self.len() - start)
257 }
258
259 pub fn into_inner(self) -> Vec<T> {
260 self.list
261 }
262 pub fn as_inner(&self) -> &[T] {
263 &self.list
264 }
265}