duchess_reflect/
lib.rs

1use std::path::PathBuf;
2
3use rust_format::Formatter as _;
4
5pub mod argument;
6pub mod check;
7pub mod class_info;
8pub mod codegen;
9pub mod parse;
10pub mod reflect;
11pub mod signature;
12pub mod substitution;
13pub mod upcasts;
14
15lazy_static::lazy_static! {
16    static ref DEBUG_DIR: PathBuf = {
17        let tmp_dir = tempfile::TempDir::new().expect("failed to create temp directory");
18        tmp_dir.into_path()
19    };
20}
21
22pub fn debug_tokens(name: impl std::fmt::Display, token_stream: &proc_macro2::TokenStream) {
23    let Ok(debug_filter) = std::env::var("DUCHESS_DEBUG") else {
24        return;
25    };
26    let name = name.to_string();
27    let debug_enabled = match debug_filter {
28        f if f.eq_ignore_ascii_case("true") || f.eq_ignore_ascii_case("1") => true,
29        filter => name.starts_with(&filter),
30    };
31    if debug_enabled {
32        let path = DEBUG_DIR.join(name.replace('.', "_")).with_extension("rs");
33        match rust_format::RustFmt::default().format_tokens(token_stream.clone()) {
34            Ok(formatted_tokens) => {
35                std::fs::write(&path, formatted_tokens).expect("failed to write to debug file");
36            }
37            Err(_) => {
38                std::fs::write(&path, format!("{token_stream:?}"))
39                    .expect("failed to write to debug file");
40            }
41        }
42        // in JetBrains terminal, links are only clickable with a `file:///` prefix. But in VsCode
43        // iTerm, and most other terminals, they are only clickable if they are absolute paths.
44        if running_in_jetbrains() {
45            eprintln!("file:///{}", path.display())
46        } else {
47            eprintln!("{}", path.display())
48        }
49    }
50}
51
52fn running_in_jetbrains() -> bool {
53    std::env::var("TERMINAL_EMULATOR")
54        .map(|var| var.contains("JetBrains"))
55        .unwrap_or_default()
56}