Comments (6)
Could quote_attribute!
do compile-time parsing while keeping the generality of "Anything that implements ToTokens
can be used with #foo
interpolation" ?
Anyway, just to write down the idea, the traits I mentioned before could look like this:
pub trait Parse: Sized {
fn parse<I: ToSourceString>(input: I) -> Result<Self, String>;
}
// This replaces parse_expr()
impl Parse for Expr {
fn parse<I: ToSourceString>(input: I) -> Result<Self, String> {
unwrap("expression", expr::parsing::expr, &input.to_source_string())
}
}
// Other impls for various AST types…
pub trait ToSourceString {
fn to_source_string(&self) -> Cow<str>;
}
impl ToSourceString for str {
fn to_source_string(&self) -> Cow<str> {
// Remove leading and trailing whitespace.
// Nom parsing functions tend to trip on the latter particularly
self.trim().into()
}
}
impl ToSourceString for String {
fn to_source_string(&self) -> Cow<str> {
(**self).to_source_string()
}
}
impl ToSourceString for quote::Tokens {
fn to_source_string(&self) -> Cow<str> {
self.to_string().to_source_string().into_owned().into()
}
}
impl ToSourceString for [TokenTree] {
fn to_source_string(&self) -> Cow<str> {
let mut tokens = quote::Tokens::new();
tokens.append_all(self);
tokens.to_string().to_source_string().into_owned().into()
}
}
impl ToSourceString for Vec<TokenTree> {
fn to_source_string(&self) -> Cow<str> {
(**self).to_source_string()
}
}
from syn.
Rather than a large number of macros for each type, maybe a method available on each type would be a nicer API?
let attr = Attribute::parse(quote!(#[derive(Debug, Clone, #a, #b)])).unwrap();
These methods could also replace the ad-hoc top-level parse_*
functions, if they accept a generic parameter with some trait implemented by both quote::Tokens
and &str
(and maybe &[syn::TonkenTree]
/ Vec<TokenTree>
/ TokenTree
? For dealing with expression/items macros.)
from syn.
I like it but I have two concerns:
- I think
Attribute::parse
puts too much emphasis on the fact that parsing is happening, which is not what I want the user and readers of the user's code to focus on in these cases. Everyone knows parsing is something that can fail, so you need to unwrap ortry!(Attribute::parse(...))
. But if the thing you are parsing is right there inside aquote!(...)
macro, you should write it in a way that you know will parse i.e. anything that doesn't parse is a bug in your program, not an expected failure that you can handle at runtime. I thinkquote_attribute!(...)
captures this distinction better. - Once procedural macros are stable, the
quote_attribute!
approach allows us to do the parsing at compile time rather than run time in most cases. As I mentioned in another ticket I am not worried about performance here so that is not why I am excited about this. Instead, parsing at compile time would let us validate the thing you are quoting, and fail to compile your program if it looks wrong. We can't ever do this with theAttribute::parse(quote!(...))
approach.
I am not settled on the quote_attribute!
approach yet but these are some of the advantages.
I do like Attribute::parse
as an alternative to the current style of syn::parse_attribute
, will think about the tradeoffs there.
from syn.
This seems like it should be doable with an external crate, which may be desirable to keep syn small.
from syn.
I added a parse_quote!
macro in 01cc020 that can return any Synom implementation.
// Add a bound `T: HeapSize` to every type parameter T.
fn add_trait_bounds(mut generics: Generics) -> Generics {
for param in &mut generics.params {
if let GenericParam::Type(ref mut type_param) = *param {
type_param.bounds.push(parse_quote!(HeapSize));
}
}
generics
}
from syn.
@dtolnay Unfortunately this doesn't handle the case of things like Attribute which don't implement Synom
, because the have specific parse_inner
and parse_outer
methods which are distinct.
Do you have any idea how we could go about handling that case? I think Attribute
is particularly relevant (especially considering that it's the one you mention in the first comment!)
from syn.
Related Issues (20)
- Consider relaxing item types for a future syn 3 HOT 2
- `parse` should take a `&mut ParseStream` HOT 2
- `Arbitrary` support to allow for downstream fuzzing
- Add ability to strip doc / attributes info from the Span
- `Visitable` trait?
- parsing fields from `quote` fails with `"expected curly braces"`
- error[E0432]: unresolved import `syn::ItemStruct` HOT 1
- Parse generic const items
- Parse explicit tail call syntax
- Parse `c"…"` and `cr"…"` string literals HOT 1
- LitStr::parse can cause panic, "compiler/fallback mismatch"
- Clearer parsing API for Generics ? HOT 2
- `syn::parse::<ItemTrait>` fails on traits that contain `unsafe extern fn` HOT 1
- allow `custom_keyword!` to support different struct name
- Support delimiter tokens with `Token![{}]`
- Not all repr expressions in enums can be parsed with `derive` feature
- Missing `Ord` implementation for `syn::Type` HOT 1
- Should syn::parse_file require the parse feature? HOT 1
- Why not impl `Parse` for `Pat` in 2.x HOT 1
- string passed to `ParseStream::error` does not make its way to the user HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from syn.