include_lines_proc/
lib.rs

1/// This proc-macro crate is used by the include-lines crate to import lines from a file
2/// at compile time.
3
4use proc_macro::TokenStream;
5use quote::quote;
6use std::{
7    fs::File,
8    io::{BufRead, BufReader},
9};
10use syn::{parse_macro_input, LitStr};
11
12/// Reads in the lines of a file. Given the path to the file.
13///
14/// Returns type `&str`.
15#[proc_macro]
16pub fn include_lines(input: TokenStream) -> TokenStream {
17    let lines = get_lines(parse_macro_input!(input as LitStr).value());
18
19    TokenStream::from(quote! {
20        [#(#lines),*]
21    })
22}
23
24/// Reads in the lines of a file. Given the path to the file.
25///
26/// Returns type `String`
27#[proc_macro]
28pub fn include_lines_s(input: TokenStream) -> TokenStream {
29    let lines = get_lines(parse_macro_input!(input as LitStr).value());
30
31    TokenStream::from(quote! {
32        [#(String::from(#lines)),*]
33    })
34}
35
36/// Counts the number of lines in a file. Given the path to the file.
37///
38/// Returns type `usize`.
39#[proc_macro]
40pub fn count_lines(input: TokenStream) -> TokenStream {
41    let num_lines = get_lines(parse_macro_input!(input as LitStr).value()).count();
42
43    TokenStream::from(quote! {
44        #num_lines
45    })
46}
47
48// Get an iterator over the lines in a file
49fn get_lines(filename: String) -> impl Iterator<Item = String> {
50    let file = File::open(filename).expect("Error opening the file: ");
51    BufReader::new(file).lines().filter_map(|l| l.ok())
52}