From 284041e9ba04a3d7260b8eaccd7b73241e9aa6a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B5=D0=BD=D0=B8=D1=81=20=D0=9A=D0=BE=D1=82=D0=BB?= =?UTF-8?q?=D1=8F=D1=80=D0=BE=D0=B2?= Date: Mon, 8 Apr 2024 01:33:58 +0300 Subject: [PATCH] 1. Update, clarification of Cargo.toml items. 2. Removing unnecessary code marker when generating code. 3. Test code improvement 4. Improved documentation --- Cargo.toml | 4 +- src/core.rs | 109 -------------------------------------------------- src/lib.rs | 86 +++++++++++++++++++++++++++++---------- tests/easy.rs | 10 ----- 4 files changed, 67 insertions(+), 142 deletions(-) delete mode 100644 src/core.rs diff --git a/Cargo.toml b/Cargo.toml index 9d45df7..7b438ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "drop_code" -version = "0.1.1" +version = "1.0.0" edition = "2021" authors = ["Denis Kotlyarov (Денис Котляров) "] repository = "https://github.com/clucompany/drop_code.git" @@ -8,7 +8,7 @@ homepage = "https://github.com/clucompany/drop_code.git" license = "Apache-2.0" readme = "README.md" -description = " Macro for ensuring critical code execution on function return or panics in Rust, making it easy to include essential code for reliable operation." +description = "Macro for ensuring critical code execution on function return or panics in Rust, making it easy to include essential code for reliable operation." keywords = ["drop_code", "macro", "code-transformation", "no_std", "clucompany"] categories = ["development-tools"] diff --git a/src/core.rs b/src/core.rs deleted file mode 100644 index c1f8ab0..0000000 --- a/src/core.rs +++ /dev/null @@ -1,109 +0,0 @@ - -/// A marker that defines automatically generated structures -/// that participate only in the drop. -pub trait DropCodeMarker {} - -/* -use core::fmt::Debug; -use core::fmt::Display; -use core::ops::DerefMut; -use core::ops::Deref; -*/ - -/* -!!! -!!! Not supported in rust code -!!! -#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct DropCodeCapturedArg<'a, T>(&'a mut T); - -impl<'a, T> Debug for DropCodeCapturedArg<'a, T> where T: Debug { - #[inline(always)] - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { - Debug::fmt(self.as_data(), f) - } -} - -impl<'a, T> Display for DropCodeCapturedArg<'a, T> where T: Display { - #[inline(always)] - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { - Display::fmt(self.as_data(), f) - } -} - -impl<'a, T> DropCodeCapturedArg<'a, T> { - #[inline(always)] - pub /*const*/ fn new(a: &'a mut T) -> Self { - Self(a) - } - - #[inline(always)] - pub fn as_data(&self) -> &T { - &self.0 - } - - #[inline(always)] - pub fn as_mut_data(&mut self) -> &mut T { - &mut self.0 - } -} - -default impl<'a, T> Deref for DropCodeCapturedArg<'a, T> { - type Target = T; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - self.as_data() - } -} - -default impl<'a, T> DerefMut for DropCodeCapturedArg<'a, T> { - #[inline(always)] - fn deref_mut(&mut self) -> &mut Self::Target { - self.as_mut_data() - } -} - -impl<'a, 'b, T> Deref for DropCodeCapturedArg<'a, - DropCodeCapturedArg<'b, T> -> { - type Target = T; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - self.deref() - } -} - -impl<'a, 'b, T> DerefMut for DropCodeCapturedArg<'a, - DropCodeCapturedArg<'b, T> -> { - #[inline(always)] - fn deref_mut(&mut self) -> &mut Self::Target { - self.deref_mut() - } -} - -impl<'a, 'b, 'c, T> Deref for DropCodeCapturedArg<'a, - DropCodeCapturedArg<'b, - DropCodeCapturedArg<'c, T> - > -> { - type Target = T; - - #[inline(always)] - fn deref(&self) -> &Self::Target { - self.deref().deref() - } -} - -impl<'a, 'b, 'c, T> DerefMut for DropCodeCapturedArg<'a, - DropCodeCapturedArg<'b, - DropCodeCapturedArg<'c, T> - > -> { - #[inline(always)] - fn deref_mut(&mut self) -> &mut Self::Target { - self.as_data() - } -}*/ \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index e43ec21..2422a49 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -//Copyright 2022 #UlinProject Denis Kotlyarov (Денис Котляров) +//Copyright 2022-2024 #UlinProject Denis Kotlyarov (Денис Котляров) //Licensed under the Apache License, Version 2.0 (the "License"); //you may not use this file except in compliance with the License. @@ -12,56 +12,100 @@ //See the License for the specific language governing permissions and // limitations under the License. -// #Ulin Project 2022 +// #Ulin Project 2022-2024 // // *_--- -#![no_std] +/*! Macro for ensuring critical code execution on function return or panics in Rust, making it easy to include essential code for reliable operation. + +## Short example: + +```rust +use drop_code::drop_code; + +#[allow(unreachable_code)] +fn main() { + drop_code! { + println!("Code that must be executed in any situation."); // 3 + } + + println!("your code"); // 1 + panic!("panic info"); // 2 +} +``` -pub mod core; +## Full syntax example: -/// A handy macro for quickly implementing code that will be executed on deletion. -/// Replaces the tedious work of creating a hidden struct with data types inside a -/// function and implementing the `Drop` hidden trait for that struct. +```rust +use drop_code::drop_code; + +struct AlwaysDropLogic {} + +impl AlwaysDropLogic { + fn drop_logic(&mut self) { + println!("#[] drop_logic!"); + } + + fn valid_logic(&mut self) { + println!("#[] valid_logic!"); + } +} + +fn main() { + let mut adl = AlwaysDropLogic {}; + drop_code!(#[inline(always)]: (mut adl: AlwaysDropLogic) { + adl.drop_logic(); + }); + + adl.valid_logic(); + // out: + // #[] valid_logic! + // #[] drop_logic! +} +``` + +## Technical concept: +The drop_code macro generates the drop function code for the Drop trait in Rust, +creating a hidden structure that encapsulates user-supplied arguments from the macro +and ensuring their transfer. This mechanism guarantees the execution of critical +operations when the object is destroyed, facilitating reliable handling of essential +code within Rust applications, with the order of code execution dictated by Rust's +rules and conventions. + + + +*/ + +#![no_std] + +/// Macro for ensuring critical code execution on function return or panics in Rust, +/// making it easy to include essential code for reliable operation. #[macro_export] macro_rules! drop_code { [ @raw $(#[ $meta:meta ]:)* $name_struct:ident ( $($($args_in:tt)+)? ) { $($drop_code:tt)* - } + } ] => { #[allow(unused_mut)] #[allow(unused_variables)] #[allow(non_snake_case)] let mut $name_struct = { - use $crate::core::DropCodeMarker; $crate::__drop_code_compareimpls! ( #[allow(non_snake_case)] struct $name_struct { $($($args_in)*)? } - impl[$($($args_in)*)?] DropCodeMarker for $name_struct {} - impl[$($($args_in)*)?] Drop for $name_struct { #[allow(unused_attributes)] $(#[$meta])* fn drop(&mut self) { - /*$( - #[allow(unused_variables)] - #[allow(unused_mut)] - let ref mut $args_in = self.$args_in; - )*/ $( $crate::__drop_code_init_automut_refslet! { let ref automut self.( $($args_in)* ) } )? - /*$( - let ( $($args_in),* ) = ( $(self.$args_in),* ); - )?*/ - - $($drop_code)* } diff --git a/tests/easy.rs b/tests/easy.rs index f7cbd7f..f026140 100644 --- a/tests/easy.rs +++ b/tests/easy.rs @@ -26,16 +26,6 @@ fn auto_test_syntax() { assert_eq!(CHECK.get(), Some(&true)); } - { // EmptyBlock + meta for drop_trait - static CHECK: OnceLock = OnceLock::new(); - { - drop_code!(#[inline(always)]: #[inline(always)]: () { - CHECK.set(true).unwrap(); - }); - } - assert_eq!(CHECK.get(), Some(&true)); - } - { // EmptyBlock + meta for drop_trait static CHECK: OnceLock = OnceLock::new(); {