From 8e8fe3244ae9f8557f1265fc4bb75f41c613758b Mon Sep 17 00:00:00 2001 From: Ed Morley <501702+edmorley@users.noreply.github.com> Date: Mon, 21 Feb 2022 12:18:46 +0000 Subject: [PATCH] Prevent unnecessary runtime validation for newtype generated macros Adjusts the newtype generated compile-time validation macros so that they don't perform redundant validation at runtime, given that the value was already validated at compile time. In cases where only compile-time validation is being performed (for example `exec.d` scripts), this results in significant reduction in binary size (1.7MB -> 0.4MB in a release+stripped binary), due to no longer needing the `fancy-regex` dependency at runtime.. A `new_unchecked()` method was added, so that the types (whose backing string is intentionally private) can be constructed by the code generated by the macro (which will exist outside of the module). The name was based on: https://doc.rust-lang.org/std/index.html?search=new_unchecked Fixes #330. GUS-W-10727850. --- libcnb-data/CHANGELOG.md | 1 + libcnb-data/src/newtypes.rs | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/libcnb-data/CHANGELOG.md b/libcnb-data/CHANGELOG.md index b9d627bb..1a2fd132 100644 --- a/libcnb-data/CHANGELOG.md +++ b/libcnb-data/CHANGELOG.md @@ -5,6 +5,7 @@ - Add `#[must_use]` to `BuildPlan` and `BuildPlanBuilder` ([#288](https://github.com/Malax/libcnb.rs/pull/288)). - Add `exec_d` module with types representing the output of an `exec.d` program ([#324](https://github.com/Malax/libcnb.rs/pull/324)). - Increase minimum supported Rust version from 1.56 to 1.58 ([#318](https://github.com/Malax/libcnb.rs/pull/318)). +- Adjust newtype generated compile-time validation macros so that they don't also perform redundant validation at runtime. In cases where only compile-time validation is being performed (for example `exec.d` scripts), this results in a significant reduction in binary size. ([#331](https://github.com/Malax/libcnb.rs/pull/331)) ## [0.4.0] 2022-01-14 diff --git a/libcnb-data/src/newtypes.rs b/libcnb-data/src/newtypes.rs index c0bed75a..b53dcdd8 100644 --- a/libcnb-data/src/newtypes.rs +++ b/libcnb-data/src/newtypes.rs @@ -5,6 +5,7 @@ /// - [`Debug`] /// - [`Display`](std::fmt::Display) /// - [`Eq`] +/// - [`Hash`] /// - [`PartialEq`] /// - [`serde::Deserialize`] /// - [`serde::Serialize`] @@ -130,6 +131,18 @@ macro_rules! libcnb_newtype { } } + impl $name { + /// Construct an instance of this type without performing validation. + /// + /// This should not be used directly, and is only public so that it + /// can be used by the compile-time validation macro. + #[must_use] + #[doc(hidden)] + pub fn new_unchecked(value: &str) -> Self { + Self(String::from(value)) + } + } + #[macro_export] $(#[$macro_attributes])* macro_rules! $macro_name { @@ -139,7 +152,7 @@ macro_rules! libcnb_newtype { $value, { use $crate::$path as base; - $value.parse::().unwrap() + base::$name::new_unchecked($value) }, compile_error!(concat!( stringify!($value),