use std::ffi::CStr;
use std::iter;
use proc_macro2::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
mod sealed {
pub trait Sealed {}
}
use sealed::Sealed;
pub trait TokenStreamExt: Sealed + Sized {
fn token(token: impl Into<TokenTree>) -> Self;
fn equals(&self, other: &Self) -> bool;
fn append<T>(&mut self, token: T)
where
T: Into<TokenTree>;
}
impl TokenStreamExt for TokenStream {
fn token(token: impl Into<TokenTree>) -> Self {
Self::from(token.into())
}
fn equals(&self, other: &Self) -> bool {
let mut this = self.clone().into_iter();
let mut other = other.clone().into_iter();
loop {
match (this.next(), other.next()) {
(Some(this), Some(other)) if this.equals(&other) => {}
(None, None) => return true,
_ => return false,
}
}
}
fn append<T>(&mut self, token: T)
where
T: Into<TokenTree>,
{
self.extend(iter::once(token.into()));
}
}
impl Sealed for TokenStream {}
pub trait TokenTreeExt: Sealed + Sized {
fn equals(&self, other: &Self) -> bool;
fn is_group(&self) -> bool;
fn is_ident(&self) -> bool;
fn is_punct(&self) -> bool;
fn is_literal(&self) -> bool;
fn is_group_and<P>(&self, predicate: P) -> bool
where
P: FnOnce(&Group) -> bool;
fn is_ident_and<P>(&self, predicate: P) -> bool
where
P: FnOnce(&Ident) -> bool;
fn is_punct_and<P>(&self, predicate: P) -> bool
where
P: FnOnce(&Punct) -> bool;
fn is_literal_and<P>(&self, predicate: P) -> bool
where
P: FnOnce(&Literal) -> bool;
fn into_group(self) -> Result<Group, Self>;
fn into_ident(self) -> Result<Ident, Self>;
fn into_punct(self) -> Result<Punct, Self>;
fn into_literal(self) -> Result<Literal, Self>;
fn into_group_if<P>(self, predicate: P) -> Result<Group, Self>
where
P: FnOnce(&Group) -> bool;
fn into_ident_if<P>(self, predicate: P) -> Result<Ident, Self>
where
P: FnOnce(&Ident) -> bool;
fn into_punct_if<P>(self, predicate: P) -> Result<Punct, Self>
where
P: FnOnce(&Punct) -> bool;
fn into_literal_if<P>(self, predicate: P) -> Result<Literal, Self>
where
P: FnOnce(&Literal) -> bool;
fn as_group(&self) -> Option<&Group>;
fn as_ident(&self) -> Option<&Ident>;
fn as_punct(&self) -> Option<&Punct>;
fn as_literal(&self) -> Option<&Literal>;
fn as_group_mut(&mut self) -> Option<&mut Group>;
fn as_ident_mut(&mut self) -> Option<&mut Ident>;
fn as_punct_mut(&mut self) -> Option<&mut Punct>;
fn as_literal_mut(&mut self) -> Option<&mut Literal>;
}
impl TokenTreeExt for TokenTree {
fn is_group(&self) -> bool {
matches!(self, Self::Group(_))
}
fn is_ident(&self) -> bool {
matches!(self, Self::Ident(_))
}
fn is_punct(&self) -> bool {
matches!(self, Self::Punct(_))
}
fn is_literal(&self) -> bool {
matches!(self, Self::Literal(_))
}
fn is_group_and<P>(&self, predicate: P) -> bool
where
P: FnOnce(&Group) -> bool,
{
matches!(self, Self::Group(group) if predicate(group))
}
fn is_ident_and<P>(&self, predicate: P) -> bool
where
P: FnOnce(&Ident) -> bool,
{
matches!(self, Self::Ident(ident) if predicate(ident))
}
fn is_punct_and<P>(&self, predicate: P) -> bool
where
P: FnOnce(&Punct) -> bool,
{
matches!(self, Self::Punct(punct) if predicate(punct))
}
fn is_literal_and<P>(&self, predicate: P) -> bool
where
P: FnOnce(&Literal) -> bool,
{
matches!(self, Self::Literal(literal) if predicate(literal))
}
fn equals(&self, other: &Self) -> bool {
match (self, other) {
(Self::Group(this), Self::Group(other)) => this.equals(other),
(Self::Ident(this), Self::Ident(other)) => this.equals(other),
(Self::Punct(this), Self::Punct(other)) => this.equals(other),
(Self::Literal(this), Self::Literal(other)) => this.equals(other),
_ => false,
}
}
fn into_group(self) -> Result<Group, Self> {
match self {
Self::Group(group) => Ok(group),
_ => Err(self),
}
}
fn into_ident(self) -> Result<Ident, Self> {
match self {
Self::Ident(ident) => Ok(ident),
_ => Err(self),
}
}
fn into_punct(self) -> Result<Punct, Self> {
match self {
Self::Punct(punct) => Ok(punct),
_ => Err(self),
}
}
fn into_literal(self) -> Result<Literal, Self> {
match self {
Self::Literal(literal) => Ok(literal),
_ => Err(self),
}
}
fn into_group_if<P>(self, predicate: P) -> Result<Group, Self>
where
P: FnOnce(&Group) -> bool,
{
match self {
Self::Group(group) if predicate(&group) => Ok(group),
_ => Err(self),
}
}
fn into_ident_if<P>(self, predicate: P) -> Result<Ident, Self>
where
P: FnOnce(&Ident) -> bool,
{
match self {
Self::Ident(ident) if predicate(&ident) => Ok(ident),
_ => Err(self),
}
}
fn into_punct_if<P>(self, predicate: P) -> Result<Punct, Self>
where
P: FnOnce(&Punct) -> bool,
{
match self {
Self::Punct(punct) if predicate(&punct) => Ok(punct),
_ => Err(self),
}
}
fn into_literal_if<P>(self, predicate: P) -> Result<Literal, Self>
where
P: FnOnce(&Literal) -> bool,
{
match self {
Self::Literal(literal) if predicate(&literal) => Ok(literal),
_ => Err(self),
}
}
fn as_group(&self) -> Option<&Group> {
match self {
Self::Group(group) => Some(group),
_ => None,
}
}
fn as_ident(&self) -> Option<&Ident> {
match self {
Self::Ident(ident) => Some(ident),
_ => None,
}
}
fn as_punct(&self) -> Option<&Punct> {
match self {
Self::Punct(punct) => Some(punct),
_ => None,
}
}
fn as_literal(&self) -> Option<&Literal> {
match self {
Self::Literal(literal) => Some(literal),
_ => None,
}
}
fn as_group_mut(&mut self) -> Option<&mut Group> {
match self {
Self::Group(group) => Some(group),
_ => None,
}
}
fn as_ident_mut(&mut self) -> Option<&mut Ident> {
match self {
Self::Ident(ident) => Some(ident),
_ => None,
}
}
fn as_punct_mut(&mut self) -> Option<&mut Punct> {
match self {
Self::Punct(punct) => Some(punct),
_ => None,
}
}
fn as_literal_mut(&mut self) -> Option<&mut Literal> {
match self {
Self::Literal(literal) => Some(literal),
_ => None,
}
}
}
impl Sealed for TokenTree {}
pub trait GroupExt: Sealed + Sized {
fn new_spanned(span: Span, delimiter: Delimiter, stream: TokenStream) -> Self;
fn equals(&self, other: &Self) -> bool;
fn is_delimiter(&self, delimiter: Delimiter) -> bool;
fn is_parenthesized(&self) -> bool;
fn is_braced(&self) -> bool;
fn is_bracketed(&self) -> bool;
fn is_undelimited(&self) -> bool;
fn is_empty(&self) -> bool;
}
impl GroupExt for Group {
fn new_spanned(span: Span, delimiter: Delimiter, stream: TokenStream) -> Self {
let mut group = Group::new(delimiter, stream);
group.set_span(span);
group
}
fn equals(&self, other: &Self) -> bool {
self.delimiter() == other.delimiter() && self.stream().equals(&other.stream())
}
fn is_delimiter(&self, delimiter: Delimiter) -> bool {
self.delimiter() == delimiter
}
fn is_parenthesized(&self) -> bool {
self.is_delimiter(Delimiter::Parenthesis)
}
fn is_braced(&self) -> bool {
self.is_delimiter(Delimiter::Brace)
}
fn is_bracketed(&self) -> bool {
self.is_delimiter(Delimiter::Bracket)
}
fn is_undelimited(&self) -> bool {
self.is_delimiter(Delimiter::None)
}
fn is_empty(&self) -> bool {
self.stream().is_empty()
}
}
impl Sealed for Group {}
pub trait IdentExt: Sealed + Sized {
fn equals(&self, other: &Self) -> bool;
fn is_raw(&self) -> bool;
fn unraw(&self) -> Self;
}
impl IdentExt for Ident {
fn equals(&self, other: &Self) -> bool {
self == other
}
fn is_raw(&self) -> bool {
self.to_string().starts_with("r#")
}
fn unraw(&self) -> Self {
self.to_string()
.strip_prefix("r#")
.map_or_else(|| self.clone(), |stripped| Self::new(stripped, self.span()))
}
}
impl Sealed for Ident {}
pub trait PunctExt: Sealed + Sized {
fn new_spanned(span: Span, character: char, spacing: Spacing) -> Self;
fn equals(&self, other: &Self) -> bool;
fn is_char(&self, character: char) -> bool;
fn is_spacing(&self, spacing: Spacing) -> bool;
fn is_alone(&self) -> bool;
fn is_joint(&self) -> bool;
}
impl PunctExt for Punct {
fn new_spanned(span: Span, character: char, spacing: Spacing) -> Self {
let mut punct = Punct::new(character, spacing);
punct.set_span(span);
punct
}
fn equals(&self, other: &Self) -> bool {
self.as_char() == other.as_char() && self.spacing() == other.spacing()
}
fn is_char(&self, character: char) -> bool {
self.as_char() == character
}
fn is_spacing(&self, spacing: Spacing) -> bool {
self.spacing() == spacing
}
fn is_alone(&self) -> bool {
self.is_spacing(Spacing::Alone)
}
fn is_joint(&self) -> bool {
self.is_spacing(Spacing::Joint)
}
}
impl Sealed for Punct {}
pub trait LiteralExt: Sealed + Sized {
fn i8_suffixed_spanned(span: Span, integer: i8) -> Self;
fn i8_unsuffixed_spanned(span: Span, integer: i8) -> Self;
fn i16_suffixed_spanned(span: Span, integer: i16) -> Self;
fn i16_unsuffixed_spanned(span: Span, integer: i16) -> Self;
fn i32_suffixed_spanned(span: Span, integer: i32) -> Self;
fn i32_unsuffixed_spanned(span: Span, integer: i32) -> Self;
fn i64_suffixed_spanned(span: Span, integer: i64) -> Self;
fn i64_unsuffixed_spanned(span: Span, integer: i64) -> Self;
fn i128_suffixed_spanned(span: Span, integer: i128) -> Self;
fn i128_unsuffixed_spanned(span: Span, integer: i128) -> Self;
fn isize_suffixed_spanned(span: Span, integer: isize) -> Self;
fn isize_unsuffixed_spanned(span: Span, integer: isize) -> Self;
fn u8_suffixed_spanned(span: Span, integer: u8) -> Self;
fn u8_unsuffixed_spanned(span: Span, integer: u8) -> Self;
fn u16_suffixed_spanned(span: Span, integer: u16) -> Self;
fn u16_unsuffixed_spanned(span: Span, integer: u16) -> Self;
fn u32_suffixed_spanned(span: Span, integer: u32) -> Self;
fn u32_unsuffixed_spanned(span: Span, integer: u32) -> Self;
fn u64_suffixed_spanned(span: Span, integer: u64) -> Self;
fn u64_unsuffixed_spanned(span: Span, integer: u64) -> Self;
fn u128_suffixed_spanned(span: Span, integer: u128) -> Self;
fn u128_unsuffixed_spanned(span: Span, integer: u128) -> Self;
fn usize_suffixed_spanned(span: Span, integer: usize) -> Self;
fn usize_unsuffixed_spanned(span: Span, integer: usize) -> Self;
fn f32_suffixed_spanned(span: Span, float: f32) -> Self;
fn f32_unsuffixed_spanned(span: Span, float: f32) -> Self;
fn f64_suffixed_spanned(span: Span, float: f64) -> Self;
fn f64_unsuffixed_spanned(span: Span, float: f64) -> Self;
fn string_spanned(span: Span, string: &str) -> Self;
fn byte_string_spanned(span: Span, bytes: &[u8]) -> Self;
fn c_string_spanned(span: Span, string: &CStr) -> Self;
fn character_spanned(span: Span, character: char) -> Self;
fn byte_character_spanned(span: Span, byte: u8) -> Self;
fn equals(&self, other: &Self) -> bool;
}
impl LiteralExt for Literal {
fn i8_suffixed_spanned(span: Span, integer: i8) -> Self {
let mut literal = Self::i8_suffixed(integer);
literal.set_span(span);
literal
}
fn i8_unsuffixed_spanned(span: Span, integer: i8) -> Self {
let mut literal = Self::i8_unsuffixed(integer);
literal.set_span(span);
literal
}
fn i16_suffixed_spanned(span: Span, integer: i16) -> Self {
let mut literal = Self::i16_suffixed(integer);
literal.set_span(span);
literal
}
fn i16_unsuffixed_spanned(span: Span, integer: i16) -> Self {
let mut literal = Self::i16_unsuffixed(integer);
literal.set_span(span);
literal
}
fn i32_suffixed_spanned(span: Span, integer: i32) -> Self {
let mut literal = Self::i32_suffixed(integer);
literal.set_span(span);
literal
}
fn i32_unsuffixed_spanned(span: Span, integer: i32) -> Self {
let mut literal = Self::i32_unsuffixed(integer);
literal.set_span(span);
literal
}
fn i64_suffixed_spanned(span: Span, integer: i64) -> Self {
let mut literal = Self::i64_suffixed(integer);
literal.set_span(span);
literal
}
fn i64_unsuffixed_spanned(span: Span, integer: i64) -> Self {
let mut literal = Self::i64_unsuffixed(integer);
literal.set_span(span);
literal
}
fn i128_suffixed_spanned(span: Span, integer: i128) -> Self {
let mut literal = Self::i128_suffixed(integer);
literal.set_span(span);
literal
}
fn i128_unsuffixed_spanned(span: Span, integer: i128) -> Self {
let mut literal = Self::i128_unsuffixed(integer);
literal.set_span(span);
literal
}
fn isize_suffixed_spanned(span: Span, integer: isize) -> Self {
let mut literal = Self::isize_suffixed(integer);
literal.set_span(span);
literal
}
fn isize_unsuffixed_spanned(span: Span, integer: isize) -> Self {
let mut literal = Self::isize_unsuffixed(integer);
literal.set_span(span);
literal
}
fn u8_suffixed_spanned(span: Span, integer: u8) -> Self {
let mut literal = Self::u8_suffixed(integer);
literal.set_span(span);
literal
}
fn u8_unsuffixed_spanned(span: Span, integer: u8) -> Self {
let mut literal = Self::u8_unsuffixed(integer);
literal.set_span(span);
literal
}
fn u16_suffixed_spanned(span: Span, integer: u16) -> Self {
let mut literal = Self::u16_suffixed(integer);
literal.set_span(span);
literal
}
fn u16_unsuffixed_spanned(span: Span, integer: u16) -> Self {
let mut literal = Self::u16_unsuffixed(integer);
literal.set_span(span);
literal
}
fn u32_suffixed_spanned(span: Span, integer: u32) -> Self {
let mut literal = Self::u32_suffixed(integer);
literal.set_span(span);
literal
}
fn u32_unsuffixed_spanned(span: Span, integer: u32) -> Self {
let mut literal = Self::u32_unsuffixed(integer);
literal.set_span(span);
literal
}
fn u64_suffixed_spanned(span: Span, integer: u64) -> Self {
let mut literal = Self::u64_suffixed(integer);
literal.set_span(span);
literal
}
fn u64_unsuffixed_spanned(span: Span, integer: u64) -> Self {
let mut literal = Self::u64_unsuffixed(integer);
literal.set_span(span);
literal
}
fn u128_suffixed_spanned(span: Span, integer: u128) -> Self {
let mut literal = Self::u128_suffixed(integer);
literal.set_span(span);
literal
}
fn u128_unsuffixed_spanned(span: Span, integer: u128) -> Self {
let mut literal = Self::u128_unsuffixed(integer);
literal.set_span(span);
literal
}
fn usize_suffixed_spanned(span: Span, integer: usize) -> Self {
let mut literal = Self::usize_suffixed(integer);
literal.set_span(span);
literal
}
fn usize_unsuffixed_spanned(span: Span, integer: usize) -> Self {
let mut literal = Self::usize_unsuffixed(integer);
literal.set_span(span);
literal
}
fn f32_suffixed_spanned(span: Span, float: f32) -> Self {
let mut literal = Self::f32_suffixed(float);
literal.set_span(span);
literal
}
fn f32_unsuffixed_spanned(span: Span, float: f32) -> Self {
let mut literal = Self::f32_unsuffixed(float);
literal.set_span(span);
literal
}
fn f64_suffixed_spanned(span: Span, float: f64) -> Self {
let mut literal = Self::f64_suffixed(float);
literal.set_span(span);
literal
}
fn f64_unsuffixed_spanned(span: Span, float: f64) -> Self {
let mut literal = Self::f64_unsuffixed(float);
literal.set_span(span);
literal
}
fn string_spanned(span: Span, string: &str) -> Self {
let mut literal = Self::string(string);
literal.set_span(span);
literal
}
fn byte_string_spanned(span: Span, bytes: &[u8]) -> Self {
let mut literal = Self::byte_string(bytes);
literal.set_span(span);
literal
}
fn c_string_spanned(span: Span, string: &CStr) -> Self {
let mut literal = Self::c_string(string);
literal.set_span(span);
literal
}
fn character_spanned(span: Span, character: char) -> Self {
let mut literal = Self::character(character);
literal.set_span(span);
literal
}
fn byte_character_spanned(span: Span, byte: u8) -> Self {
let mut literal = Self::byte_character(byte);
literal.set_span(span);
literal
}
fn equals(&self, other: &Self) -> bool {
self.to_string() == other.to_string()
}
}
impl Sealed for Literal {}