1use std::{
49 iter,
50 ops::{Range, RangeInclusive},
51};
52
53use proc_macro2::{Literal, TokenStream, TokenTree};
54
55use quote::ToTokens;
56
57use syn::{
58 Token,
59 parse::{Parse, ParseStream},
60};
61
62use tokel_engine::prelude::{Pass, Registry, Transformer};
63
64#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
74pub struct Reverse;
75
76impl Pass for Reverse {
77 type Argument = syn::parse::Nothing;
78
79 fn through(&mut self, input: TokenStream, _: Self::Argument) -> syn::Result<TokenStream> {
80 Ok(input
81 .into_iter()
82 .collect::<Vec<TokenTree>>()
83 .into_iter()
84 .rev()
85 .collect::<TokenStream>())
86 }
87}
88
89#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
101pub struct Intersperse;
102
103impl Pass for Intersperse {
104 type Argument = TokenTree;
105
106 fn through(
107 &mut self,
108 input: TokenStream,
109 intersperse_tree: Self::Argument,
110 ) -> syn::Result<TokenStream> {
111 let mut target_output = TokenStream::new();
112
113 let mut target_iter = input.into_iter().into_iter().peekable();
114
115 while let Some(target_tree) = target_iter.next() {
116 let target_list = [
117 Some(target_tree),
118 if let Some(..) = target_iter.peek() {
119 let intersperse_tree = intersperse_tree.clone();
120
121 Some(intersperse_tree)
122 } else {
123 None
124 },
125 ];
126
127 target_output.extend(target_list.into_iter().flatten());
128 }
129
130 Ok(target_output)
131 }
132}
133
134#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
144pub struct PushLeft;
145
146impl Pass for PushLeft {
147 type Argument = TokenStream;
148
149 fn through(&mut self, input: TokenStream, left: Self::Argument) -> syn::Result<TokenStream> {
150 Ok(iter::chain(left, input).collect::<TokenStream>())
151 }
152}
153
154#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
164pub struct PopRight;
165
166impl Pass for PopRight {
167 type Argument = syn::parse::Nothing;
168
169 fn through(&mut self, input: TokenStream, _: Self::Argument) -> syn::Result<TokenStream> {
170 let mut target_list = input.into_iter().collect::<Vec<TokenTree>>();
171
172 let _ = target_list.pop();
173
174 Ok(target_list.into_iter().collect::<TokenStream>())
175 }
176}
177
178#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
188pub struct PushRight;
189
190impl Pass for PushRight {
191 type Argument = TokenStream;
192
193 fn through(&mut self, input: TokenStream, right: Self::Argument) -> syn::Result<TokenStream> {
194 Ok(iter::chain(input, right).collect::<TokenStream>())
195 }
196}
197
198#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
208pub struct PopLeft;
209
210impl Pass for PopLeft {
211 type Argument = syn::parse::Nothing;
212
213 fn through(&mut self, input: TokenStream, _: Self::Argument) -> syn::Result<TokenStream> {
214 Ok(input.into_iter().skip(1).collect::<TokenStream>())
215 }
216}
217
218#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
228pub struct Take;
229
230impl Pass for Take {
231 type Argument = syn::LitInt;
232
233 fn through(&mut self, input: TokenStream, count: Self::Argument) -> syn::Result<TokenStream> {
234 let take_count = count.base10_parse()?;
235
236 Ok(input.into_iter().take(take_count).collect())
237 }
238}
239
240#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
250pub struct Skip;
251
252impl Pass for Skip {
253 type Argument = syn::LitInt;
254
255 fn through(&mut self, input: TokenStream, count: Self::Argument) -> syn::Result<TokenStream> {
256 let skip_count = count.base10_parse()?;
257
258 Ok(input.into_iter().skip(skip_count).collect())
259 }
260}
261
262#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
272pub struct Repeat;
273
274impl Pass for Repeat {
275 type Argument = syn::LitInt;
276
277 fn through(
278 &mut self,
279 input: TokenStream,
280 target_count: Self::Argument,
281 ) -> syn::Result<TokenStream> {
282 let target_list = input.into_iter().collect::<Vec<TokenTree>>();
283
284 let take_count = target_list.len() * target_count.base10_parse::<usize>()?;
285
286 Ok(target_list
287 .iter()
288 .cycle()
289 .take(take_count)
290 .cloned()
291 .collect::<TokenStream>())
292 }
293}
294
295#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
305pub struct Count;
306
307impl Pass for Count {
308 type Argument = syn::parse::Nothing;
309
310 fn through(&mut self, input: TokenStream, _: Self::Argument) -> syn::Result<TokenStream> {
311 Ok(Literal::usize_unsuffixed(input.into_iter().count()).to_token_stream())
312 }
313}
314
315#[derive(Debug, Clone, PartialEq, Eq, Hash)]
317pub enum SequenceRange {
318 Inclusive(RangeInclusive<i32>),
320
321 NonInclusive(Range<i32>),
323}
324
325impl Parse for SequenceRange {
326 fn parse(input: ParseStream) -> syn::Result<Self> {
327 let start: syn::LitInt = input.parse()?;
328
329 if input.peek(Token![..=]) {
330 let _: Token![..=] = input.parse()?;
331
332 let end: syn::LitInt = input.parse()?;
333
334 Ok(Self::Inclusive(start.base10_parse()?..=end.base10_parse()?))
335 } else {
336 let _: Token![..] = input.parse()?;
337
338 let end: syn::LitInt = input.parse()?;
339
340 Ok(Self::NonInclusive(
341 start.base10_parse()?..end.base10_parse()?,
342 ))
343 }
344 }
345}
346
347#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
360pub struct Sequence;
361
362impl Pass for Sequence {
363 type Argument = SequenceRange;
364
365 fn through(
366 &mut self,
367 input: TokenStream,
368 target_range: Self::Argument,
369 ) -> syn::Result<TokenStream> {
370 let _: syn::parse::Nothing = syn::parse2(input)?;
371
372 fn fold_fn(mut target_output: TokenStream, target_literal: Literal) -> TokenStream {
373 target_output.extend(target_literal.into_token_stream());
374
375 target_output
376 }
377
378 Ok(match target_range {
379 SequenceRange::Inclusive(range_inclusive) => range_inclusive
380 .into_iter()
381 .map(Literal::i32_unsuffixed)
382 .fold(TokenStream::new(), fold_fn),
383 SequenceRange::NonInclusive(range) => range
384 .into_iter()
385 .map(Literal::i32_unsuffixed)
386 .fold(TokenStream::new(), fold_fn),
387 })
388 }
389}
390
391#[inline]
399pub fn register(registry: &mut Registry) -> Result<(), Box<dyn Transformer>> {
400 registry
401 .try_insert("reverse", Reverse)
402 .map_err(Box::new)
403 .map_err(|t| t as Box<dyn Transformer>)?;
404
405 registry
406 .try_insert("intersperse", Intersperse)
407 .map_err(Box::new)
408 .map_err(|t| t as Box<dyn Transformer>)?;
409
410 registry
411 .try_insert("push_left", PushLeft)
412 .map_err(Box::new)
413 .map_err(|t| t as Box<dyn Transformer>)?;
414
415 registry
416 .try_insert("push_right", PushRight)
417 .map_err(Box::new)
418 .map_err(|t| t as Box<dyn Transformer>)?;
419
420 registry
421 .try_insert("pop_left", PopLeft)
422 .map_err(Box::new)
423 .map_err(|t| t as Box<dyn Transformer>)?;
424
425 registry
426 .try_insert("pop_right", PopRight)
427 .map_err(Box::new)
428 .map_err(|t| t as Box<dyn Transformer>)?;
429
430 registry
431 .try_insert("take", Take)
432 .map_err(Box::new)
433 .map_err(|t| t as Box<dyn Transformer>)?;
434
435 registry
436 .try_insert("skip", Skip)
437 .map_err(Box::new)
438 .map_err(|t| t as Box<dyn Transformer>)?;
439
440 registry
441 .try_insert("repeat", Repeat)
442 .map_err(Box::new)
443 .map_err(|t| t as Box<dyn Transformer>)?;
444
445 registry
446 .try_insert("count", Count)
447 .map_err(Box::new)
448 .map_err(|t| t as Box<dyn Transformer>)?;
449
450 registry
451 .try_insert("sequence", Sequence)
452 .map_err(Box::new)
453 .map_err(|t| t as Box<dyn Transformer>)?;
454
455 Ok(())
456}