From e90965d8e5405727d9e59d42028f769ccf851d29 Mon Sep 17 00:00:00 2001 From: Bernhard Schuster Date: Thu, 24 Feb 2022 10:38:42 +0100 Subject: [PATCH] feat: integrate syn::Error Closes #3 --- Cargo.toml | 6 ++++ src/lib.rs | 78 ++++++++++++++++----------------------------- src/tests.rs | 82 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/baz/lib.rs | 2 +- 4 files changed, 116 insertions(+), 52 deletions(-) create mode 100644 src/tests.rs diff --git a/Cargo.toml b/Cargo.toml index e1c436e..0e28e25 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,12 @@ fs-err = "2" proc-macro2 = "1" quote = "1" blake2 = "0.10" +syn = { version = "1", optional = true, default-features = false } [dev-dependencies] baz = { path = "./tests/baz" } +syn = { version = "1", features = ["extra-traits", "full"] } + +[features] +default = ["syndicate"] +syndicate = ["syn"] \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 3facdd9..82e2d76 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -101,22 +101,34 @@ impl Expander { self } + #[cfg(feature = "syndicate")] + /// Create a file with `filename` under `env!("OUT_DIR")` if it's not an `Err(_)`. + pub fn maybe_write_to_out_dir( + self, + tokens: impl Into>, + ) -> Result { + self.maybe_write_to( + tokens.into(), + std::path::PathBuf::from(env!("OUT_DIR")).as_path(), + ) + } + /// Create a file with `filename` under `env!("OUT_DIR")`. pub fn write_to_out_dir(self, tokens: TokenStream) -> Result { - if self.dry { - Ok(tokens) - } else { - let out = env!("OUT_DIR"); - let out = std::path::PathBuf::from(out); - let path = out.join(self.filename); - expand_to_file( - tokens, - path.as_path(), - out.as_path(), - self.rustfmt, - self.comment, - self.verbose, - ) + let out = std::path::PathBuf::from(env!("OUT_DIR")); + self.write_to(tokens, out.as_path()) + } + + #[cfg(feature = "syndicate")] + /// Create a file with `filename` at `dest` if it's not an `Err(_)`. + pub fn maybe_write_to( + self, + maybe_tokens: Result, + dest_dir: &Path, + ) -> Result { + match maybe_tokens { + Ok(tokens) => self.write_to(tokens, dest_dir), + Err(err) => Ok(err.to_compile_error()), } } @@ -197,40 +209,4 @@ fn expand_to_file( } #[cfg(test)] -mod tests { - use super::*; - - #[test] - fn dry() -> Result<(), std::io::Error> { - let ts = quote! { - pub struct X { - x: [u8;32], - } - }; - let modified = Expander::new("foo") - .add_comment("This is generated code!".to_owned()) - .fmt(Edition::_2021) - .dry(true) - .write_to_out_dir(ts.clone())?; - - assert_eq!(ts.to_string(), modified.to_string()); - Ok(()) - } - - #[test] - fn basic() -> Result<(), std::io::Error> { - let ts = quote! { - pub struct X { - x: [u8;32], - } - }; - let modified = Expander::new("bar") - .add_comment("This is generated code!".to_owned()) - .fmt(Edition::_2021) - // .dry(false) - .write_to_out_dir(ts.clone())?; - - assert_ne!(ts.to_string(), modified.to_string()); - Ok(()) - } -} +mod tests; diff --git a/src/tests.rs b/src/tests.rs new file mode 100644 index 0000000..b85a038 --- /dev/null +++ b/src/tests.rs @@ -0,0 +1,82 @@ +use super::*; + +#[test] +fn dry() -> Result<(), std::io::Error> { + let ts = quote! { + pub struct X { + x: [u8;32], + } + }; + let modified = Expander::new("foo") + .add_comment("This is generated code!".to_owned()) + .fmt(Edition::_2021) + .dry(true) + .write_to_out_dir(ts.clone())?; + + assert_eq!( + ts.to_string(), + modified.to_string(), + "Dry does not alter the provided `TokenStream`. qed" + ); + Ok(()) +} + +#[test] +fn basic() -> Result<(), std::io::Error> { + let ts = quote! { + pub struct X { + x: [u8;32], + } + }; + let modified = Expander::new("bar") + .add_comment("This is generated code!".to_owned()) + .fmt(Edition::_2021) + // .dry(false) + .write_to_out_dir(ts.clone())?; + + let s = modified.to_string(); + assert_ne!(s, ts.to_string()); + assert!(s.contains("include ! (")); + Ok(()) +} + +#[cfg(feature = "syndicate")] +mod syndicate { + use super::*; + use proc_macro2::Span; + + #[test] + fn ok_is_written_to_external_file() -> Result<(), std::io::Error> { + let ts = Ok(quote! { + pub struct X { + x: [u8;32], + } + }); + let modified = Expander::new("bar") + .add_comment("This is generated code!".to_owned()) + .fmt(Edition::_2021) + // .dry(false) + .maybe_write_to_out_dir(ts.clone())?; + + let s = modified.to_string(); + assert_ne!(s, ts.unwrap().to_string()); + assert!(s.contains("include ! (")); + Ok(()) + } + + #[test] + fn errors_are_not_written_to_external_file() -> Result<(), std::io::Error> { + let ts = Err(syn::Error::new(Span::call_site(), "Hajajajaiii!")); + let modified = Expander::new("") + .add_comment("This is generated code!".to_owned()) + .fmt(Edition::_2021) + // .dry(false) + .maybe_write_to_out_dir(ts.clone())?; + + assert_eq!( + ts.unwrap_err().to_compile_error().to_string(), + modified.to_string() + ); + Ok(()) + } +} diff --git a/tests/baz/lib.rs b/tests/baz/lib.rs index a42d8f6..cd1956b 100644 --- a/tests/baz/lib.rs +++ b/tests/baz/lib.rs @@ -14,6 +14,6 @@ fn baz2(input: proc_macro2::TokenStream) -> proc_macro2::TokenStream { let expanded = Expander::new("baz") .add_comment("This is generated code!".to_owned()) .fmt(Edition::_2021) - .write_to_out_dir(modified).expect("IO error"); + .write_to_out_dir(modified).expect("No IO error"); expanded }