1use crate::attr::Attribute;
2use crate::item::Item;
3use alloc::string::String;
4use alloc::vec::Vec;
5
6#[doc = r" A complete file of Rust source code."]
#[doc = r""]
#[doc = r" Typically `File` objects are created with [`parse_file`]."]
#[doc = r""]
#[doc = r" [`parse_file`]: crate::parse_file"]
#[doc = r""]
#[doc = r" # Example"]
#[doc = r""]
#[doc = r" Parse a Rust source file into a `syn::File` and print out a debug"]
#[doc = r" representation of the syntax tree."]
#[doc = r""]
#[doc = r" ```"]
#[doc = r" use std::env;"]
#[doc = r" use std::fs;"]
#[doc = r" use std::process;"]
#[doc = r""]
#[doc = r" fn main() {"]
#[doc = r" # }"]
#[doc = r" #"]
#[doc = r" # fn fake_main() {"]
#[doc = r" let mut args = env::args();"]
#[doc = r" let _ = args.next(); // executable name"]
#[doc = r""]
#[doc = r" let filename = match (args.next(), args.next()) {"]
#[doc = r" (Some(filename), None) => filename,"]
#[doc = r" _ => {"]
#[doc =
r#" eprintln!("Usage: dump-syntax path/to/filename.rs");"#]
#[doc = r" process::exit(1);"]
#[doc = r" }"]
#[doc = r" };"]
#[doc = r""]
#[doc =
r#" let src = fs::read_to_string(&filename).expect("unable to read file");"#]
#[doc =
r#" let syntax = syn::parse_file(&src).expect("unable to parse file");"#]
#[doc = r""]
#[doc =
r#" // Debug impl is available if Syn is built with "extra-traits" feature."#]
#[doc = r#" println!("{:#?}", syntax);"#]
#[doc = r" }"]
#[doc = r" ```"]
#[doc = r""]
#[doc =
r" Running with its own source code as input, this program prints output"]
#[doc = r" that begins with:"]
#[doc = r""]
#[doc = r" ```text"]
#[doc = r" File {"]
#[doc = r" shebang: None,"]
#[doc = r" frontmatter: None,"]
#[doc = r" attrs: [],"]
#[doc = r" items: ["]
#[doc = r" Item::Use {"]
#[doc = r" attrs: [],"]
#[doc = r" vis: Visibility::Inherited,"]
#[doc = r" use_token: Token![use],"]
#[doc = r" leading_colon: None,"]
#[doc = r" tree: UseTree::Path("]
#[doc = r" UsePath {"]
#[doc = r" ident: Ident("]
#[doc = r" std,"]
#[doc = r" ),"]
#[doc = r" colon2_token: Token![::],"]
#[doc = r" tree: UseTree::Name("]
#[doc = r" UseName {"]
#[doc = r" ident: Ident("]
#[doc = r" env,"]
#[doc = r" ),"]
#[doc = r" },"]
#[doc = r" ),"]
#[doc = r" },"]
#[doc = r" ),"]
#[doc = r" semi_token: Token![;],"]
#[doc = r" },"]
#[doc = r" ..."]
#[doc = r" ```"]
pub struct File {
pub shebang: Option<String>,
pub frontmatter: Option<Frontmatter>,
pub attrs: Vec<Attribute>,
pub items: Vec<Item>,
}ast_struct! {
7 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
80 pub struct File {
81 pub shebang: Option<String>,
82 pub frontmatter: Option<Frontmatter>,
83 pub attrs: Vec<Attribute>,
84 pub items: Vec<Item>,
85 }
86}
87
88#[doc = r" A frontmatter section fenced by `---`."]
#[non_exhaustive]
pub struct Frontmatter {}ast_struct! {
89 #[cfg_attr(docsrs, doc(cfg(feature = "full")))]
91 #[non_exhaustive]
92 pub struct Frontmatter {}
93}
94
95#[cfg(feature = "parsing")]
96pub(crate) mod parsing {
97 use crate::attr::Attribute;
98 use crate::error::Result;
99 use crate::file::File;
100 use crate::parse::{Parse, ParseStream};
101 use alloc::vec::Vec;
102
103 #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
104 impl Parse for File {
105 fn parse(input: ParseStream) -> Result<Self> {
106 Ok(File {
107 shebang: None,
108 frontmatter: None,
109 attrs: input.call(Attribute::parse_inner)?,
110 items: {
111 let mut items = Vec::new();
112 while !input.is_empty() {
113 items.push(input.parse()?);
114 }
115 items
116 },
117 })
118 }
119 }
120}
121
122#[cfg(feature = "printing")]
123mod printing {
124 use crate::attr::FilterAttrs;
125 use crate::file::File;
126 use proc_macro2::TokenStream;
127 use quote::{ToTokens, TokenStreamExt as _};
128
129 #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
130 impl ToTokens for File {
131 fn to_tokens(&self, tokens: &mut TokenStream) {
132 tokens.append_all(self.attrs.inner());
133 tokens.append_all(&self.items);
134 }
135 }
136}