Struct proc_macro2::Punct
source · pub struct Punct { /* private fields */ }
Expand description
A Punct
is a single punctuation character like +
, -
or #
.
Multicharacter operators like +=
are represented as two instances of
Punct
with different forms of Spacing
returned.
Implementations§
source§impl Punct
impl Punct
sourcepub fn new(ch: char, spacing: Spacing) -> Self
pub fn new(ch: char, spacing: Spacing) -> Self
Creates a new Punct
from the given character and spacing.
The ch
argument must be a valid punctuation character permitted by the
language, otherwise the function will panic.
The returned Punct
will have the default span of Span::call_site()
which can be further configured with the set_span
method below.
Examples found in repository?
More examples
752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835
fn punct(input: Cursor) -> PResult<Punct> {
let (rest, ch) = punct_char(input)?;
if ch == '\'' {
if ident_any(rest)?.0.starts_with("'") {
Err(Reject)
} else {
Ok((rest, Punct::new('\'', Spacing::Joint)))
}
} else {
let kind = match punct_char(rest) {
Ok(_) => Spacing::Joint,
Err(Reject) => Spacing::Alone,
};
Ok((rest, Punct::new(ch, kind)))
}
}
fn punct_char(input: Cursor) -> PResult<char> {
if input.starts_with("//") || input.starts_with("/*") {
// Do not accept `/` of a comment as a punct.
return Err(Reject);
}
let mut chars = input.chars();
let first = match chars.next() {
Some(ch) => ch,
None => {
return Err(Reject);
}
};
let recognized = "~!@#$%^&*-=+|;:,<.>/?'";
if recognized.contains(first) {
Ok((input.advance(first.len_utf8()), first))
} else {
Err(Reject)
}
}
fn doc_comment<'a>(input: Cursor<'a>, trees: &mut TokenStreamBuilder) -> PResult<'a, ()> {
#[cfg(span_locations)]
let lo = input.off;
let (rest, (comment, inner)) = doc_comment_contents(input)?;
let span = crate::Span::_new_stable(Span {
#[cfg(span_locations)]
lo,
#[cfg(span_locations)]
hi: rest.off,
});
let mut scan_for_bare_cr = comment;
while let Some(cr) = scan_for_bare_cr.find('\r') {
let rest = &scan_for_bare_cr[cr + 1..];
if !rest.starts_with('\n') {
return Err(Reject);
}
scan_for_bare_cr = rest;
}
let mut pound = Punct::new('#', Spacing::Alone);
pound.set_span(span);
trees.push_token_from_parser(TokenTree::Punct(pound));
if inner {
let mut bang = Punct::new('!', Spacing::Alone);
bang.set_span(span);
trees.push_token_from_parser(TokenTree::Punct(bang));
}
let doc_ident = crate::Ident::new("doc", span);
let mut equal = Punct::new('=', Spacing::Alone);
equal.set_span(span);
let mut literal = crate::Literal::string(comment);
literal.set_span(span);
let mut bracketed = TokenStreamBuilder::with_capacity(3);
bracketed.push_token_from_parser(TokenTree::Ident(doc_ident));
bracketed.push_token_from_parser(TokenTree::Punct(equal));
bracketed.push_token_from_parser(TokenTree::Literal(literal));
let group = Group::new(Delimiter::Bracket, bracketed.build());
let mut group = crate::Group::_new_stable(group);
group.set_span(span);
trees.push_token_from_parser(TokenTree::Group(group));
Ok((rest, ()))
}
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
fn next(&mut self) -> Option<TokenTree> {
let token = match self {
TokenTreeIter::Compiler(iter) => iter.next()?,
TokenTreeIter::Fallback(iter) => return iter.next(),
};
Some(match token {
proc_macro::TokenTree::Group(tt) => crate::Group::_new(Group::Compiler(tt)).into(),
proc_macro::TokenTree::Punct(tt) => {
let spacing = match tt.spacing() {
proc_macro::Spacing::Joint => Spacing::Joint,
proc_macro::Spacing::Alone => Spacing::Alone,
};
let mut o = Punct::new(tt.as_char(), spacing);
o.set_span(crate::Span::_new(Span::Compiler(tt.span())));
o.into()
}
proc_macro::TokenTree::Ident(s) => crate::Ident::_new(Ident::Compiler(s)).into(),
proc_macro::TokenTree::Literal(l) => crate::Literal::_new(Literal::Compiler(l)).into(),
})
}
sourcepub fn as_char(&self) -> char
pub fn as_char(&self) -> char
Returns the value of this punctuation character as char
.
Examples found in repository?
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
fn into_compiler_token(token: TokenTree) -> proc_macro::TokenTree {
match token {
TokenTree::Group(tt) => tt.inner.unwrap_nightly().into(),
TokenTree::Punct(tt) => {
let spacing = match tt.spacing() {
Spacing::Joint => proc_macro::Spacing::Joint,
Spacing::Alone => proc_macro::Spacing::Alone,
};
let mut punct = proc_macro::Punct::new(tt.as_char(), spacing);
punct.set_span(tt.span().inner.unwrap_nightly());
punct.into()
}
TokenTree::Ident(tt) => tt.inner.unwrap_nightly().into(),
TokenTree::Literal(tt) => tt.inner.unwrap_nightly().into(),
}
}
sourcepub fn spacing(&self) -> Spacing
pub fn spacing(&self) -> Spacing
Returns the spacing of this punctuation character, indicating whether
it’s immediately followed by another Punct
in the token stream, so
they can potentially be combined into a multicharacter operator
(Joint
), or it’s followed by some other token or whitespace (Alone
)
so the operator has certainly ended.
Examples found in repository?
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut joint = false;
for (i, tt) in self.inner.iter().enumerate() {
if i != 0 && !joint {
write!(f, " ")?;
}
joint = false;
match tt {
TokenTree::Group(tt) => Display::fmt(tt, f),
TokenTree::Ident(tt) => Display::fmt(tt, f),
TokenTree::Punct(tt) => {
joint = tt.spacing() == Spacing::Joint;
Display::fmt(tt, f)
}
TokenTree::Literal(tt) => Display::fmt(tt, f),
}?;
}
Ok(())
}
More examples
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
fn into_compiler_token(token: TokenTree) -> proc_macro::TokenTree {
match token {
TokenTree::Group(tt) => tt.inner.unwrap_nightly().into(),
TokenTree::Punct(tt) => {
let spacing = match tt.spacing() {
Spacing::Joint => proc_macro::Spacing::Joint,
Spacing::Alone => proc_macro::Spacing::Alone,
};
let mut punct = proc_macro::Punct::new(tt.as_char(), spacing);
punct.set_span(tt.span().inner.unwrap_nightly());
punct.into()
}
TokenTree::Ident(tt) => tt.inner.unwrap_nightly().into(),
TokenTree::Literal(tt) => tt.inner.unwrap_nightly().into(),
}
}
sourcepub fn span(&self) -> Span
pub fn span(&self) -> Span
Returns the span for this punctuation character.
Examples found in repository?
More examples
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
fn into_compiler_token(token: TokenTree) -> proc_macro::TokenTree {
match token {
TokenTree::Group(tt) => tt.inner.unwrap_nightly().into(),
TokenTree::Punct(tt) => {
let spacing = match tt.spacing() {
Spacing::Joint => proc_macro::Spacing::Joint,
Spacing::Alone => proc_macro::Spacing::Alone,
};
let mut punct = proc_macro::Punct::new(tt.as_char(), spacing);
punct.set_span(tt.span().inner.unwrap_nightly());
punct.into()
}
TokenTree::Ident(tt) => tt.inner.unwrap_nightly().into(),
TokenTree::Literal(tt) => tt.inner.unwrap_nightly().into(),
}
}
sourcepub fn set_span(&mut self, span: Span)
pub fn set_span(&mut self, span: Span)
Configure the span for this punctuation character.
Examples found in repository?
More examples
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
fn next(&mut self) -> Option<TokenTree> {
let token = match self {
TokenTreeIter::Compiler(iter) => iter.next()?,
TokenTreeIter::Fallback(iter) => return iter.next(),
};
Some(match token {
proc_macro::TokenTree::Group(tt) => crate::Group::_new(Group::Compiler(tt)).into(),
proc_macro::TokenTree::Punct(tt) => {
let spacing = match tt.spacing() {
proc_macro::Spacing::Joint => Spacing::Joint,
proc_macro::Spacing::Alone => Spacing::Alone,
};
let mut o = Punct::new(tt.as_char(), spacing);
o.set_span(crate::Span::_new(Span::Compiler(tt.span())));
o.into()
}
proc_macro::TokenTree::Ident(s) => crate::Ident::_new(Ident::Compiler(s)).into(),
proc_macro::TokenTree::Literal(l) => crate::Literal::_new(Literal::Compiler(l)).into(),
})
}
790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835
fn doc_comment<'a>(input: Cursor<'a>, trees: &mut TokenStreamBuilder) -> PResult<'a, ()> {
#[cfg(span_locations)]
let lo = input.off;
let (rest, (comment, inner)) = doc_comment_contents(input)?;
let span = crate::Span::_new_stable(Span {
#[cfg(span_locations)]
lo,
#[cfg(span_locations)]
hi: rest.off,
});
let mut scan_for_bare_cr = comment;
while let Some(cr) = scan_for_bare_cr.find('\r') {
let rest = &scan_for_bare_cr[cr + 1..];
if !rest.starts_with('\n') {
return Err(Reject);
}
scan_for_bare_cr = rest;
}
let mut pound = Punct::new('#', Spacing::Alone);
pound.set_span(span);
trees.push_token_from_parser(TokenTree::Punct(pound));
if inner {
let mut bang = Punct::new('!', Spacing::Alone);
bang.set_span(span);
trees.push_token_from_parser(TokenTree::Punct(bang));
}
let doc_ident = crate::Ident::new("doc", span);
let mut equal = Punct::new('=', Spacing::Alone);
equal.set_span(span);
let mut literal = crate::Literal::string(comment);
literal.set_span(span);
let mut bracketed = TokenStreamBuilder::with_capacity(3);
bracketed.push_token_from_parser(TokenTree::Ident(doc_ident));
bracketed.push_token_from_parser(TokenTree::Punct(equal));
bracketed.push_token_from_parser(TokenTree::Literal(literal));
let group = Group::new(Delimiter::Bracket, bracketed.build());
let mut group = crate::Group::_new_stable(group);
group.set_span(span);
trees.push_token_from_parser(TokenTree::Group(group));
Ok((rest, ()))
}