| 1 | use std::ops::RangeBounds; |
| 2 | |
| 3 | use proc_macro2::{Ident, Span}; |
| 4 | use syn::LitStr; |
| 5 | |
| 6 | /// Joins the arguments with `&&` operators. |
| 7 | macro_rules! and { |
| 8 | ($($expr:expr),* $(,)?) => { |
| 9 | $($expr)&&* |
| 10 | }; |
| 11 | } |
| 12 | |
| 13 | /// Joins the arguments with `||` operators. |
| 14 | #[cfg (feature = "terminfo" )] |
| 15 | macro_rules! or { |
| 16 | ($($expr:expr),* $(,)?) => { |
| 17 | $($expr)||* |
| 18 | }; |
| 19 | } |
| 20 | |
| 21 | /// Creates a new [`Ident`] which can be tokenized. |
| 22 | pub fn ident(s: &str) -> Ident { |
| 23 | Ident::new(string:s, Span::call_site()) |
| 24 | } |
| 25 | |
| 26 | /// Creates a new [`struct@LitStr`] which can be tokenized. |
| 27 | pub fn literal_string(s: &str) -> LitStr { |
| 28 | LitStr::new(value:s, Span::call_site()) |
| 29 | } |
| 30 | |
| 31 | /// Unfortunately, unless a nightly compiler is used, this function will actually only return the |
| 32 | /// original input span. |
| 33 | /// |
| 34 | /// Returns the subspan corresponding to the range of `inside` inside `input`, considering that: |
| 35 | /// - `input` is exactly `&input_lit_str.value()`, |
| 36 | /// - `inside` is a subslice of `input`, |
| 37 | /// |
| 38 | /// Warning: may panic if the conditions are not met. |
| 39 | /// TODO: improve safety |
| 40 | pub fn inner_span<'a>(input: &'a str, input_lit_str: &LitStr, inside: &'a str) -> Span { |
| 41 | let input_offset: usize = (inside.as_ptr() as usize) - (input.as_ptr() as usize); |
| 42 | let range: Range = input_offset + 1..input_offset + inside.len() + 1; |
| 43 | subspan(input_lit_str.span(), range).unwrap_or_else(|| input_lit_str.span()) |
| 44 | } |
| 45 | |
| 46 | /// Returns a subspan of the given span. |
| 47 | /// |
| 48 | /// TODO: the implementation is really... wtf! But i didn't find a better way to do it. |
| 49 | fn subspan<R: RangeBounds<usize>>(span: Span, range: R) -> Option<Span> { |
| 50 | let mut lit: Literal = proc_macro2::Literal::i8_suffixed(0); // wtf... |
| 51 | lit.set_span(span); |
| 52 | lit.subspan(range) |
| 53 | } |
| 54 | |