1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
#![doc(html_root_url = "https://docs.rs/call2-for-syn/1.0.2")] #![forbid(unsafe_code)] #![warn(clippy::pedantic)] use proc_macro2::TokenStream; use syn::parse::{ParseStream, Parser}; #[cfg(doctest)] pub mod readme { doc_comment::doctest!("../README.md"); } /// Analogous to [`syn::parse2`] and [`syn::parse::ParseBuffer::call`]. /// /// # Panics /// /// Iff `parser` doesn't consume all of `input`. /// /// > This was originally [a bug](https://github.com/Tamschi/call2-for-syn/issues/1). /// > /// > I recommend using version 2 or later of this crate instead, once available. /// /// # Example /// /// ```rust /// use { /// call2_for_syn::call2, /// quote::quote, /// syn::{Ident, Token}, /// }; /// /// # (|| { /// let (hello, world) = call2::<syn::Result<_>, _>(quote!(Hello world!), |input| { /// let hello: Ident = input.parse()?; /// let world: Ident = input.parse()?; /// input.parse::<Token![!]>()?; /// Ok((hello, world)) /// })?; /// /// assert_eq!(format!("{}", hello), "Hello"); /// assert_eq!(format!("{}", world), "world"); /// # syn::Result::Ok(()) /// # })().unwrap(); /// ``` /// /// [`syn::parse2`]: https://docs.rs/syn/1.0.14/syn/fn.parse2.html /// [`syn::parse::ParseBuffer::call`]: https://docs.rs/syn/1.0.14/syn/parse/struct.ParseBuffer.html#method.call #[rustversion::attr(since(1.46), track_caller)] pub fn call2<T, P: FnOnce(ParseStream) -> T>(input: TokenStream, parser: P) -> T { let mut result: Option<T> = None; Parser::parse2( |input: ParseStream| { result = Some(parser(input)); Ok(()) }, input, ) .unwrap(); result.unwrap() }