include_file/
lib.rs

1// Copyright 2025 Heath Stewart.
2// Licensed under the MIT License. See LICENSE.txt in the project root for license information.
3
4#![doc = include_str!("../README.md")]
5
6extern crate proc_macro;
7mod code;
8
9use proc_macro::TokenStream;
10
11/// Include code from within a code fence in a markdown file.
12///
13/// Two arguments are required: a file path relative to the current source file,
14/// and a name defined within the code fence as shown below.
15///
16/// All CommonMark [code fences](https://spec.commonmark.org/current/#fenced-code-blocks) are supported.
17///
18/// # Examples
19///
20/// Consider the following code fence in a crate `README.md` markdown file:
21///
22/// ````markdown
23/// ```rust example
24/// let m = example()?;
25/// assert_eq!(format!("{m:?}"), r#"Model { name: "example" }"#);
26/// ```
27/// ````
28///
29/// In Rust documentation comments, we can use `# line` to hide setup code.
30/// That's not possible in markdown, so we can include only the code we want to demonstrate;
31/// however, we can still compile and even run it in Rust tests:
32///
33/// ```no_run
34/// struct Model {
35///     name: String,
36/// }
37///
38/// fn example() -> Result<Model, Box<dyn std::error::Error>> {
39///     Ok(Model { name: "example".into() })
40/// }
41///
42/// #[test]
43/// fn test_example() -> Result<(), Box<dyn std::error::Error>> {
44///     include_code!("../README.md", "example");
45///     Ok(())
46/// }
47/// ```
48#[proc_macro]
49pub fn include_code(item: TokenStream) -> TokenStream {
50    code::include_code(item.into())
51        .unwrap_or_else(syn::Error::into_compile_error)
52        .into()
53}