group.rs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. // SPDX-License-Identifier: Apache-2.0 OR MIT
  2. use crate::error::Result;
  3. use crate::parse::ParseBuffer;
  4. use crate::token;
  5. use proc_macro2::extra::DelimSpan;
  6. use proc_macro2::Delimiter;
  7. // Not public API.
  8. #[doc(hidden)]
  9. pub struct Parens<'a> {
  10. #[doc(hidden)]
  11. pub token: token::Paren,
  12. #[doc(hidden)]
  13. pub content: ParseBuffer<'a>,
  14. }
  15. // Not public API.
  16. #[doc(hidden)]
  17. pub struct Braces<'a> {
  18. #[doc(hidden)]
  19. pub token: token::Brace,
  20. #[doc(hidden)]
  21. pub content: ParseBuffer<'a>,
  22. }
  23. // Not public API.
  24. #[doc(hidden)]
  25. pub struct Brackets<'a> {
  26. #[doc(hidden)]
  27. pub token: token::Bracket,
  28. #[doc(hidden)]
  29. pub content: ParseBuffer<'a>,
  30. }
  31. // Not public API.
  32. #[cfg(any(feature = "full", feature = "derive"))]
  33. #[doc(hidden)]
  34. pub struct Group<'a> {
  35. #[doc(hidden)]
  36. pub token: token::Group,
  37. #[doc(hidden)]
  38. pub content: ParseBuffer<'a>,
  39. }
  40. // Not public API.
  41. #[doc(hidden)]
  42. pub fn parse_parens<'a>(input: &ParseBuffer<'a>) -> Result<Parens<'a>> {
  43. parse_delimited(input, Delimiter::Parenthesis).map(|(span, content)| Parens {
  44. token: token::Paren(span),
  45. content,
  46. })
  47. }
  48. // Not public API.
  49. #[doc(hidden)]
  50. pub fn parse_braces<'a>(input: &ParseBuffer<'a>) -> Result<Braces<'a>> {
  51. parse_delimited(input, Delimiter::Brace).map(|(span, content)| Braces {
  52. token: token::Brace(span),
  53. content,
  54. })
  55. }
  56. // Not public API.
  57. #[doc(hidden)]
  58. pub fn parse_brackets<'a>(input: &ParseBuffer<'a>) -> Result<Brackets<'a>> {
  59. parse_delimited(input, Delimiter::Bracket).map(|(span, content)| Brackets {
  60. token: token::Bracket(span),
  61. content,
  62. })
  63. }
  64. #[cfg(any(feature = "full", feature = "derive"))]
  65. pub(crate) fn parse_group<'a>(input: &ParseBuffer<'a>) -> Result<Group<'a>> {
  66. parse_delimited(input, Delimiter::None).map(|(span, content)| Group {
  67. token: token::Group(span.join()),
  68. content,
  69. })
  70. }
  71. fn parse_delimited<'a>(
  72. input: &ParseBuffer<'a>,
  73. delimiter: Delimiter,
  74. ) -> Result<(DelimSpan, ParseBuffer<'a>)> {
  75. input.step(|cursor| {
  76. if let Some((content, span, rest)) = cursor.group(delimiter) {
  77. let scope = span.close();
  78. let nested = crate::parse::advance_step_cursor(cursor, content);
  79. let unexpected = crate::parse::get_unexpected(input);
  80. let content = crate::parse::new_parse_buffer(scope, nested, unexpected);
  81. Ok(((span, content), rest))
  82. } else {
  83. let message = match delimiter {
  84. Delimiter::Parenthesis => "expected parentheses",
  85. Delimiter::Brace => "expected curly braces",
  86. Delimiter::Bracket => "expected square brackets",
  87. Delimiter::None => "expected invisible group",
  88. };
  89. Err(cursor.error(message))
  90. }
  91. })
  92. }
  93. /// Parse a set of parentheses and expose their content to subsequent parsers.
  94. ///
  95. /// # Example
  96. ///
  97. /// ```
  98. /// # use quote::quote;
  99. /// #
  100. /// use syn::{parenthesized, token, Ident, Result, Token, Type};
  101. /// use syn::parse::{Parse, ParseStream};
  102. /// use syn::punctuated::Punctuated;
  103. ///
  104. /// // Parse a simplified tuple struct syntax like:
  105. /// //
  106. /// // struct S(A, B);
  107. /// struct TupleStruct {
  108. /// struct_token: Token![struct],
  109. /// ident: Ident,
  110. /// paren_token: token::Paren,
  111. /// fields: Punctuated<Type, Token![,]>,
  112. /// semi_token: Token![;],
  113. /// }
  114. ///
  115. /// impl Parse for TupleStruct {
  116. /// fn parse(input: ParseStream) -> Result<Self> {
  117. /// let content;
  118. /// Ok(TupleStruct {
  119. /// struct_token: input.parse()?,
  120. /// ident: input.parse()?,
  121. /// paren_token: parenthesized!(content in input),
  122. /// fields: content.parse_terminated(Type::parse, Token![,])?,
  123. /// semi_token: input.parse()?,
  124. /// })
  125. /// }
  126. /// }
  127. /// #
  128. /// # fn main() {
  129. /// # let input = quote! {
  130. /// # struct S(A, B);
  131. /// # };
  132. /// # syn::parse2::<TupleStruct>(input).unwrap();
  133. /// # }
  134. /// ```
  135. #[macro_export]
  136. #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
  137. macro_rules! parenthesized {
  138. ($content:ident in $cursor:expr) => {
  139. match $crate::__private::parse_parens(&$cursor) {
  140. $crate::__private::Ok(parens) => {
  141. $content = parens.content;
  142. parens.token
  143. }
  144. $crate::__private::Err(error) => {
  145. return $crate::__private::Err(error);
  146. }
  147. }
  148. };
  149. }
  150. /// Parse a set of curly braces and expose their content to subsequent parsers.
  151. ///
  152. /// # Example
  153. ///
  154. /// ```
  155. /// # use quote::quote;
  156. /// #
  157. /// use syn::{braced, token, Ident, Result, Token, Type};
  158. /// use syn::parse::{Parse, ParseStream};
  159. /// use syn::punctuated::Punctuated;
  160. ///
  161. /// // Parse a simplified struct syntax like:
  162. /// //
  163. /// // struct S {
  164. /// // a: A,
  165. /// // b: B,
  166. /// // }
  167. /// struct Struct {
  168. /// struct_token: Token![struct],
  169. /// ident: Ident,
  170. /// brace_token: token::Brace,
  171. /// fields: Punctuated<Field, Token![,]>,
  172. /// }
  173. ///
  174. /// struct Field {
  175. /// name: Ident,
  176. /// colon_token: Token![:],
  177. /// ty: Type,
  178. /// }
  179. ///
  180. /// impl Parse for Struct {
  181. /// fn parse(input: ParseStream) -> Result<Self> {
  182. /// let content;
  183. /// Ok(Struct {
  184. /// struct_token: input.parse()?,
  185. /// ident: input.parse()?,
  186. /// brace_token: braced!(content in input),
  187. /// fields: content.parse_terminated(Field::parse, Token![,])?,
  188. /// })
  189. /// }
  190. /// }
  191. ///
  192. /// impl Parse for Field {
  193. /// fn parse(input: ParseStream) -> Result<Self> {
  194. /// Ok(Field {
  195. /// name: input.parse()?,
  196. /// colon_token: input.parse()?,
  197. /// ty: input.parse()?,
  198. /// })
  199. /// }
  200. /// }
  201. /// #
  202. /// # fn main() {
  203. /// # let input = quote! {
  204. /// # struct S {
  205. /// # a: A,
  206. /// # b: B,
  207. /// # }
  208. /// # };
  209. /// # syn::parse2::<Struct>(input).unwrap();
  210. /// # }
  211. /// ```
  212. #[macro_export]
  213. #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
  214. macro_rules! braced {
  215. ($content:ident in $cursor:expr) => {
  216. match $crate::__private::parse_braces(&$cursor) {
  217. $crate::__private::Ok(braces) => {
  218. $content = braces.content;
  219. braces.token
  220. }
  221. $crate::__private::Err(error) => {
  222. return $crate::__private::Err(error);
  223. }
  224. }
  225. };
  226. }
  227. /// Parse a set of square brackets and expose their content to subsequent
  228. /// parsers.
  229. ///
  230. /// # Example
  231. ///
  232. /// ```
  233. /// # use quote::quote;
  234. /// #
  235. /// use proc_macro2::TokenStream;
  236. /// use syn::{bracketed, token, Result, Token};
  237. /// use syn::parse::{Parse, ParseStream};
  238. ///
  239. /// // Parse an outer attribute like:
  240. /// //
  241. /// // #[repr(C, packed)]
  242. /// struct OuterAttribute {
  243. /// pound_token: Token![#],
  244. /// bracket_token: token::Bracket,
  245. /// content: TokenStream,
  246. /// }
  247. ///
  248. /// impl Parse for OuterAttribute {
  249. /// fn parse(input: ParseStream) -> Result<Self> {
  250. /// let content;
  251. /// Ok(OuterAttribute {
  252. /// pound_token: input.parse()?,
  253. /// bracket_token: bracketed!(content in input),
  254. /// content: content.parse()?,
  255. /// })
  256. /// }
  257. /// }
  258. /// #
  259. /// # fn main() {
  260. /// # let input = quote! {
  261. /// # #[repr(C, packed)]
  262. /// # };
  263. /// # syn::parse2::<OuterAttribute>(input).unwrap();
  264. /// # }
  265. /// ```
  266. #[macro_export]
  267. #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
  268. macro_rules! bracketed {
  269. ($content:ident in $cursor:expr) => {
  270. match $crate::__private::parse_brackets(&$cursor) {
  271. $crate::__private::Ok(brackets) => {
  272. $content = brackets.content;
  273. brackets.token
  274. }
  275. $crate::__private::Err(error) => {
  276. return $crate::__private::Err(error);
  277. }
  278. }
  279. };
  280. }