syn/
file.rs

1use super::*;
2
3ast_struct! {
4    /// A complete file of Rust source code.
5    ///
6    /// *This type is available if Syn is built with the `"full"` feature.*
7    ///
8    /// # Example
9    ///
10    /// Parse a Rust source file into a `syn::File` and print out a debug
11    /// representation of the syntax tree.
12    ///
13    /// ```
14    /// use std::env;
15    /// use std::fs::File;
16    /// use std::io::Read;
17    /// use std::process;
18    ///
19    /// fn main() {
20    /// # }
21    /// #
22    /// # fn fake_main() {
23    ///     let mut args = env::args();
24    ///     let _ = args.next(); // executable name
25    ///
26    ///     let filename = match (args.next(), args.next()) {
27    ///         (Some(filename), None) => filename,
28    ///         _ => {
29    ///             eprintln!("Usage: dump-syntax path/to/filename.rs");
30    ///             process::exit(1);
31    ///         }
32    ///     };
33    ///
34    ///     let mut file = File::open(&filename).expect("Unable to open file");
35    ///
36    ///     let mut src = String::new();
37    ///     file.read_to_string(&mut src).expect("Unable to read file");
38    ///
39    ///     let syntax = syn::parse_file(&src).expect("Unable to parse file");
40    ///     println!("{:#?}", syntax);
41    /// }
42    /// ```
43    ///
44    /// Running with its own source code as input, this program prints output
45    /// that begins with:
46    ///
47    /// ```text
48    /// File {
49    ///     shebang: None,
50    ///     attrs: [],
51    ///     items: [
52    ///         ExternCrate(
53    ///             ItemExternCrate {
54    ///                 attrs: [],
55    ///                 vis: Inherited,
56    ///                 extern_token: Extern,
57    ///                 crate_token: Crate,
58    ///                 ident: Ident {
59    ///                     term: Term(
60    ///                         "syn"
61    ///                     ),
62    ///                     span: Span
63    ///                 },
64    ///                 rename: None,
65    ///                 semi_token: Semi
66    ///             }
67    ///         ),
68    /// ...
69    /// ```
70    pub struct File {
71        pub shebang: Option<String>,
72        pub attrs: Vec<Attribute>,
73        pub items: Vec<Item>,
74    }
75}
76
77#[cfg(feature = "parsing")]
78pub mod parsing {
79    use super::*;
80
81    use crate::parse::{Parse, ParseStream, Result};
82
83    impl Parse for File {
84        fn parse(input: ParseStream) -> Result<Self> {
85            Ok(File {
86                shebang: None,
87                attrs: input.call(Attribute::parse_inner)?,
88                items: {
89                    let mut items = Vec::new();
90                    while !input.is_empty() {
91                        items.push(input.parse()?);
92                    }
93                    items
94                },
95            })
96        }
97    }
98}
99
100#[cfg(feature = "printing")]
101mod printing {
102    use super::*;
103    use crate::attr::FilterAttrs;
104    use proc_macro2::TokenStream;
105    use quote::{ToTokens, TokenStreamExt};
106
107    impl ToTokens for File {
108        fn to_tokens(&self, tokens: &mut TokenStream) {
109            tokens.append_all(self.attrs.inner());
110            tokens.append_all(&self.items);
111        }
112    }
113}