1pub mod ffi;
14pub mod format;
15pub mod module;
16pub mod struct_doc;
17pub(crate) mod utils;
18
19#[cfg(test)]
20pub mod fmt {
21 use proc_macro2::TokenStream;
22 use similar::{ChangeTag, TextDiff};
23 use std::fmt::Write; pub fn format_tokens(tokens: &TokenStream) -> String {
26 match syn::parse_file(&tokens.to_string()) {
27 Ok(file) => prettyplease::unparse(&file),
28 Err(err) => {
29 println!("Parsing Error {err:?}");
30 tokens.to_string()
31 }
32 }
33 }
34
35 pub fn assert_code_eq_token(tokens: &TokenStream, expected: &TokenStream) {
36 let actual_file: syn::File = match syn::parse2(tokens.clone()) {
37 Ok(actual_file) => actual_file,
38 Err(err) => {
39 println!("=== Bad Code: ===");
40 println!("{tokens}");
41 println!("=================");
42 println!("Error: {err}");
43 panic!("Actual string is not valid Rust code (syn::File)")
44 }
45 };
46 let expected_file: syn::File = match syn::parse2(expected.clone()) {
47 Ok(actual_file) => actual_file,
48 Err(err) => {
49 println!("=== Bad Code: ===");
50 println!("{expected}");
51 println!("=================");
52 println!("Error: {err}");
53 panic!("Expected string is not valid Rust code (syn::File)")
54 }
55 };
56
57 let actual_str = prettyplease::unparse(&actual_file);
58 let expected_str = prettyplease::unparse(&expected_file);
59
60 if actual_str != expected_str {
61 let diff = TextDiff::from_lines(&expected_str, &actual_str);
63 let mut diff_output = String::new();
64
65 for change in diff.iter_all_changes() {
66 let sign = match change.tag() {
67 ChangeTag::Delete => "-", ChangeTag::Insert => "+", ChangeTag::Equal => " ",
70 };
71
72 let _ = write!(&mut diff_output, "{}{}", sign, change);
74 }
75
76 panic!(
77 "Code mismatch!\n\nDIFF ((- expected) (+ actual)):\n\n{}\n",
78 diff_output
79 );
80 }
81 }
82}