#expand #source-code #inline-modules #rust


Library to load full source code of multi-file crates

4 releases (2 breaking)

0.3.0 Jul 12, 2023
0.2.0 May 28, 2022
0.1.1 Mar 28, 2022
0.1.0 Mar 26, 2022

#170 in Procedural macros

Download history 314/week @ 2023-12-11 60/week @ 2023-12-18 24/week @ 2023-12-25 250/week @ 2024-01-01 296/week @ 2024-01-08 212/week @ 2024-01-15 192/week @ 2024-01-22 119/week @ 2024-01-29 226/week @ 2024-02-05 206/week @ 2024-02-12 92/week @ 2024-02-19 148/week @ 2024-02-26 290/week @ 2024-03-04 182/week @ 2024-03-11 342/week @ 2024-03-18 421/week @ 2024-03-25

1,244 downloads per month
Used in 14 crates (3 directly)


602 lines


This library allows you to load full source code of multi-file crates into a single syn::File.


  • Based on syn crate.
  • Handling #[path] attributes
  • Handling #[cfg] where it affects modules to filesystem mapping
  • There is both a lower-level IO-less function and a simpler one that just loads crate from a std::fs::Path.


Start exploring the library from the read_crate function.

Bonus: CLI tool

syn-file-expand-cli tool expands Rust sources, like cargo expand, but without macro expansion, only for modules. rustc is not involved. Filtering through rustfmt is adviced for debugging use case.

$ syn-file-expand-cli -fTp src/lib.rs
#![doc = include_str!("../README.md")]
mod attrs {
    use proc_macro2;
mod expand_impl {
    use std::path::PathBuf;

$ syn-file-expand-cli --help
Usage: syn-file-expand-cli [OPTIONS]

Use `syn-file-expand-cli -fTp src/lib.rs` as a starting point.

Reads rust source file, including referred modules and expands them into a single source with all modules inline
Apart from respective dedicated command line arguments, conditional paths like
`#[cfg_attr(feature="qqq"),path=...)` are resolved using
environment variables like SYN_FILE_EXPAND_FEATURE_QQQ=1

Positional arguments:
  input_file                 Input Rust source file to start crawling from

Optional arguments:
  -h, --help
  -l, --loopify              Convert all blocks and expressions to `loop{}`s.
                      Note that inner items within blocks get lost in the process.
  -D, --undoc                Strip all documentation attributes. Note that inner items within blocks are not processed and may retain their attributes.
  -T, --cfg-true-by-default  Assume all `#[cfg]`s and `#[cfg_attr]`s are true. May lead to errors unless `-f` is also used.
  -f, --full-crate-tree      Allow duplicate modules, also preserve/transform some `cfg` attributes.
  -c, --cfg CFG              Set this cfg check result to true.
                                Note that `all` or `any` are not handled.
                                You need to set all needed expression results one by one.
                                Strings required for --cfg are not the same as for environment variables-
                                -based version of this feature.
  -u, --unset-cfg UNSET-CFG  In `--cfg-true-by-default` mode, explicitly unset given cfg expression outcome.
  -d, --debug-cfg            Print each encountered cfg check to stderr, in form suitable for `--cfg` parameter
                   Note that the format is different from the one used by `SYN_FILE_EXPAND_DEBUGVARS=1` environment variable.
  -o, --output OUTPUT        Use given file for output instead of stdout
  -p, --pretty               Use `prettyplease` to format the output

There is a Github release with the tool pre-built for various platforms.
You can also install the tool using cargo install syn-file-expand-cli.


~51K SLoC