1 #![doc(html_root_url = "https://dtolnay.github.io/syn")]
2 
3 #![cfg_attr(feature = "cargo-clippy", allow(large_enum_variant))]
4 
5 #[cfg(feature = "printing")]
6 extern crate quote;
7 
8 #[cfg(feature = "parsing")]
9 extern crate unicode_xid;
10 
11 #[cfg(feature = "parsing")]
12 #[macro_use]
13 extern crate synom;
14 
15 #[cfg(feature = "aster")]
16 pub mod aster;
17 
18 mod attr;
19 pub use attr::{Attribute, AttrStyle, MetaItem, NestedMetaItem};
20 
21 mod constant;
22 pub use constant::ConstExpr;
23 
24 mod data;
25 pub use data::{Field, Variant, VariantData, Visibility};
26 
27 #[cfg(feature = "parsing")]
28 mod escape;
29 
30 #[cfg(feature = "full")]
31 mod expr;
32 #[cfg(feature = "full")]
33 pub use expr::{Arm, BindingMode, Block, CaptureBy, Expr, ExprKind, FieldPat, FieldValue, Local,
34                MacStmtStyle, Pat, RangeLimits, Stmt};
35 
36 mod generics;
37 pub use generics::{Generics, Lifetime, LifetimeDef, TraitBoundModifier, TyParam, TyParamBound,
38                    WhereBoundPredicate, WhereClause, WhereEqPredicate, WherePredicate,
39                    WhereRegionPredicate};
40 #[cfg(feature = "printing")]
41 pub use generics::{ImplGenerics, Turbofish, TyGenerics};
42 
43 mod ident;
44 pub use ident::Ident;
45 
46 #[cfg(feature = "full")]
47 mod item;
48 #[cfg(feature = "full")]
49 pub use item::{Constness, Defaultness, FnArg, FnDecl, ForeignItemKind, ForeignItem, ForeignMod,
50                ImplItem, ImplItemKind, ImplPolarity, Item, ItemKind, MethodSig, PathListItem,
51                TraitItem, TraitItemKind, ViewPath};
52 
53 #[cfg(feature = "full")]
54 mod krate;
55 #[cfg(feature = "full")]
56 pub use krate::Crate;
57 
58 mod lit;
59 pub use lit::{FloatTy, IntTy, Lit, StrStyle};
60 #[cfg(feature = "parsing")]
61 pub use lit::{ByteStrLit, FloatLit, IntLit, StrLit};
62 
63 mod mac;
64 pub use mac::{BinOpToken, DelimToken, Delimited, Mac, Token, TokenTree};
65 
66 mod derive;
67 pub use derive::{Body, DeriveInput};
68 // Deprecated. Use `DeriveInput` instead.
69 #[doc(hidden)]
70 pub type MacroInput = DeriveInput;
71 
72 mod op;
73 pub use op::{BinOp, UnOp};
74 
75 mod ty;
76 pub use ty::{Abi, AngleBracketedParameterData, BareFnArg, BareFnTy, FunctionRetTy, MutTy,
77              Mutability, ParenthesizedParameterData, Path, PathParameters, PathSegment,
78              PolyTraitRef, QSelf, Ty, TypeBinding, Unsafety};
79 
80 #[cfg(feature = "visit")]
81 pub mod visit;
82 
83 #[cfg(feature = "fold")]
84 pub mod fold;
85 
86 #[cfg(feature = "parsing")]
87 pub use parsing::*;
88 
89 #[cfg(feature = "parsing")]
90 mod parsing {
91     use super::*;
92     use {derive, generics, ident, mac, ty, attr};
93     use synom::{space, IResult};
94 
95     #[cfg(feature = "full")]
96     use {expr, item, krate};
97 
parse_derive_input(input: &str) -> Result<DeriveInput, String>98     pub fn parse_derive_input(input: &str) -> Result<DeriveInput, String> {
99         unwrap("derive input", derive::parsing::derive_input, input)
100     }
101 
102     #[cfg(feature = "full")]
parse_crate(input: &str) -> Result<Crate, String>103     pub fn parse_crate(input: &str) -> Result<Crate, String> {
104         unwrap("crate", krate::parsing::krate, input)
105     }
106 
107     #[cfg(feature = "full")]
parse_item(input: &str) -> Result<Item, String>108     pub fn parse_item(input: &str) -> Result<Item, String> {
109         unwrap("item", item::parsing::item, input)
110     }
111 
112     #[cfg(feature = "full")]
parse_items(input: &str) -> Result<Vec<Item>, String>113     pub fn parse_items(input: &str) -> Result<Vec<Item>, String> {
114         unwrap("items", item::parsing::items, input)
115     }
116 
117     #[cfg(feature = "full")]
parse_expr(input: &str) -> Result<Expr, String>118     pub fn parse_expr(input: &str) -> Result<Expr, String> {
119         unwrap("expression", expr::parsing::expr, input)
120     }
121 
parse_type(input: &str) -> Result<Ty, String>122     pub fn parse_type(input: &str) -> Result<Ty, String> {
123         unwrap("type", ty::parsing::ty, input)
124     }
125 
parse_path(input: &str) -> Result<Path, String>126     pub fn parse_path(input: &str) -> Result<Path, String> {
127         unwrap("path", ty::parsing::path, input)
128     }
129 
parse_where_clause(input: &str) -> Result<WhereClause, String>130     pub fn parse_where_clause(input: &str) -> Result<WhereClause, String> {
131         unwrap("where clause", generics::parsing::where_clause, input)
132     }
133 
parse_token_trees(input: &str) -> Result<Vec<TokenTree>, String>134     pub fn parse_token_trees(input: &str) -> Result<Vec<TokenTree>, String> {
135         unwrap("token trees", mac::parsing::token_trees, input)
136     }
137 
parse_ident(input: &str) -> Result<Ident, String>138     pub fn parse_ident(input: &str) -> Result<Ident, String> {
139         unwrap("identifier", ident::parsing::ident, input)
140     }
141 
parse_ty_param_bound(input: &str) -> Result<TyParamBound, String>142     pub fn parse_ty_param_bound(input: &str) -> Result<TyParamBound, String> {
143         unwrap("type parameter bound",
144                generics::parsing::ty_param_bound,
145                input)
146     }
147 
parse_outer_attr(input: &str) -> Result<Attribute, String>148     pub fn parse_outer_attr(input: &str) -> Result<Attribute, String> {
149         unwrap("outer attribute", attr::parsing::outer_attr, input)
150     }
151 
152     #[cfg(feature = "full")]
parse_inner_attr(input: &str) -> Result<Attribute, String>153     pub fn parse_inner_attr(input: &str) -> Result<Attribute, String> {
154         unwrap("inner attribute", attr::parsing::inner_attr, input)
155     }
156 
157     // Deprecated. Use `parse_derive_input` instead.
158     #[doc(hidden)]
parse_macro_input(input: &str) -> Result<MacroInput, String>159     pub fn parse_macro_input(input: &str) -> Result<MacroInput, String> {
160         parse_derive_input(input)
161     }
162 
unwrap<T>(name: &'static str, f: fn(&str) -> IResult<&str, T>, input: &str) -> Result<T, String>163     fn unwrap<T>(name: &'static str,
164                  f: fn(&str) -> IResult<&str, T>,
165                  input: &str)
166                  -> Result<T, String> {
167         match f(input) {
168             IResult::Done(mut rest, t) => {
169                 rest = space::skip_whitespace(rest);
170                 if rest.is_empty() {
171                     Ok(t)
172                 } else if rest.len() == input.len() {
173                     // parsed nothing
174                     Err(format!("failed to parse {}: {:?}", name, rest))
175                 } else {
176                     Err(format!("unparsed tokens after {}: {:?}", name, rest))
177                 }
178             }
179             IResult::Error => Err(format!("failed to parse {}: {:?}", name, input)),
180         }
181     }
182 }
183 
184 #[cfg(feature = "parsing")]
185 pub mod parse {
186     //! This module contains a set of exported nom parsers which can be used to
187     //! parse custom grammars when used alongside the `synom` crate.
188     //!
189     //! Internally, `syn` uses a fork of `nom` called `synom` which resolves a
190     //! persistent pitfall of using `nom` to parse Rust by eliminating the
191     //! `IResult::Incomplete` variant. The `synom` crate should be used instead
192     //! of `nom` when working with the parsers in this module.
193 
194     pub use synom::IResult;
195 
196     #[cfg(feature = "full")]
197     pub use item::parsing::item;
198 
199     #[cfg(feature = "full")]
200     pub use expr::parsing::{expr, pat, block, stmt};
201 
202     pub use lit::parsing::{lit, string, byte_string, byte, character, float, int, boolean};
203 
204     pub use ty::parsing::{ty, path};
205 
206     pub use mac::parsing::token_tree as tt;
207 
208     pub use ident::parsing::ident;
209 
210     pub use generics::parsing::lifetime;
211 }
212