use proc_macro2::{Delimiter, Span};
use crate::error::Result;
use crate::parse::ParseBuffer;
use crate::token;
#[doc(hidden)]
pub struct Parens<'a> {
pub token: token::Paren,
pub content: ParseBuffer<'a>,
}
#[doc(hidden)]
pub struct Braces<'a> {
pub token: token::Brace,
pub content: ParseBuffer<'a>,
}
#[doc(hidden)]
pub struct Brackets<'a> {
pub token: token::Bracket,
pub content: ParseBuffer<'a>,
}
#[cfg(any(feature = "full", feature = "derive"))]
#[doc(hidden)]
pub struct Group<'a> {
pub token: token::Group,
pub content: ParseBuffer<'a>,
}
#[doc(hidden)]
pub fn parse_parens<'a>(input: &ParseBuffer<'a>) -> Result<Parens<'a>> {
parse_delimited(input, Delimiter::Parenthesis).map(|(span, content)| Parens {
token: token::Paren(span),
content,
})
}
#[doc(hidden)]
pub fn parse_braces<'a>(input: &ParseBuffer<'a>) -> Result<Braces<'a>> {
parse_delimited(input, Delimiter::Brace).map(|(span, content)| Braces {
token: token::Brace(span),
content,
})
}
#[doc(hidden)]
pub fn parse_brackets<'a>(input: &ParseBuffer<'a>) -> Result<Brackets<'a>> {
parse_delimited(input, Delimiter::Bracket).map(|(span, content)| Brackets {
token: token::Bracket(span),
content,
})
}
#[cfg(any(feature = "full", feature = "derive"))]
pub(crate) fn parse_group<'a>(input: &ParseBuffer<'a>) -> Result<Group<'a>> {
parse_delimited(input, Delimiter::None).map(|(span, content)| Group {
token: token::Group(span),
content,
})
}
fn parse_delimited<'a>(
input: &ParseBuffer<'a>,
delimiter: Delimiter,
) -> Result<(Span, ParseBuffer<'a>)> {
input.step(|cursor| {
if let Some((content, span, rest)) = cursor.group(delimiter) {
let scope = crate::buffer::close_span_of_group(*cursor);
let nested = crate::parse::advance_step_cursor(cursor, content);
let unexpected = crate::parse::get_unexpected(input);
let content = crate::parse::new_parse_buffer(scope, nested, unexpected);
Ok(((span, content), rest))
} else {
let message = match delimiter {
Delimiter::Parenthesis => "expected parentheses",
Delimiter::Brace => "expected curly braces",
Delimiter::Bracket => "expected square brackets",
Delimiter::None => "expected invisible group",
};
Err(cursor.error(message))
}
})
}
#[macro_export]
macro_rules! parenthesized {
($content:ident in $cursor:expr) => {
match $crate::group::parse_parens(&$cursor) {
$crate::export::Ok(parens) => {
$content = parens.content;
parens.token
}
$crate::export::Err(error) => {
return $crate::export::Err(error);
}
}
};
}
#[macro_export]
macro_rules! braced {
($content:ident in $cursor:expr) => {
match $crate::group::parse_braces(&$cursor) {
$crate::export::Ok(braces) => {
$content = braces.content;
braces.token
}
$crate::export::Err(error) => {
return $crate::export::Err(error);
}
}
};
}
#[macro_export]
macro_rules! bracketed {
($content:ident in $cursor:expr) => {
match $crate::group::parse_brackets(&$cursor) {
$crate::export::Ok(brackets) => {
$content = brackets.content;
brackets.token
}
$crate::export::Err(error) => {
return $crate::export::Err(error);
}
}
};
}