From 87f2ace9246a1753810a2b0ed91590e860a61b4b Mon Sep 17 00:00:00 2001 From: dmvict Date: Tue, 26 Jul 2022 10:31:48 +0300 Subject: [PATCH 01/17] Add test suite `user_type_no_default`, implement former for types with no default implementation --- rust/test/former/all/basic_only_test.rs | 8 -- rust/test/former/all/default_container.rs | 1 - rust/test/former/all/default_primitive.rs | 1 - rust/test/former/all/default_user_type.rs | 1 - rust/test/former/all/perform.rs | 1 - .../test/former/all/string_slice_only_test.rs | 1 - rust/test/former/all/user_type_no_default.rs | 84 +++++++++++++++++++ rust/test/former/common_front_test.rs | 2 + 8 files changed, 86 insertions(+), 13 deletions(-) create mode 100644 rust/test/former/all/user_type_no_default.rs diff --git a/rust/test/former/all/basic_only_test.rs b/rust/test/former/all/basic_only_test.rs index f929564b40..66ce0aa5a3 100644 --- a/rust/test/former/all/basic_only_test.rs +++ b/rust/test/former/all/basic_only_test.rs @@ -7,7 +7,6 @@ use test_tools::exposed::*; tests_impls! { - #[ test ] fn test_int() { @@ -44,7 +43,6 @@ tests_impls! // - #[ test ] fn test_string() { @@ -100,7 +98,6 @@ tests_impls! // - #[ test ] fn test_optional_string() { @@ -155,7 +152,6 @@ tests_impls! // - #[ test ] fn test_vector() { @@ -220,7 +216,6 @@ tests_impls! // - #[ test ] fn test_hashmap() { @@ -287,7 +282,6 @@ tests_impls! // - #[ test ] fn test_hashset() { @@ -354,7 +348,6 @@ tests_impls! // - #[ test ] fn test_underscored_form() { // test.case( "basic" ); @@ -377,7 +370,6 @@ tests_impls! // - #[ test ] fn test_complex() { let command = Struct1::former() diff --git a/rust/test/former/all/default_container.rs b/rust/test/former/all/default_container.rs index ee4006f9fd..6af68edd9b 100644 --- a/rust/test/former/all/default_container.rs +++ b/rust/test/former/all/default_container.rs @@ -46,7 +46,6 @@ pub struct Struct1 tests_impls! { - #[ test ] fn test_complex() { diff --git a/rust/test/former/all/default_primitive.rs b/rust/test/former/all/default_primitive.rs index 9c84076d31..e909e928f0 100644 --- a/rust/test/former/all/default_primitive.rs +++ b/rust/test/former/all/default_primitive.rs @@ -43,7 +43,6 @@ pub struct Struct1 tests_impls! { - #[ test ] fn test_complex() { let command = Struct1::former().form(); diff --git a/rust/test/former/all/default_user_type.rs b/rust/test/former/all/default_user_type.rs index 326a671565..62e0d622a7 100644 --- a/rust/test/former/all/default_user_type.rs +++ b/rust/test/former/all/default_user_type.rs @@ -23,7 +23,6 @@ only_for_local_module! tests_impls! { - #[ test ] fn test_user_type_with_default() { #[derive( Debug, PartialEq, Default )] diff --git a/rust/test/former/all/perform.rs b/rust/test/former/all/perform.rs index 8a111ef1a0..d3241ced25 100644 --- a/rust/test/former/all/perform.rs +++ b/rust/test/former/all/perform.rs @@ -41,7 +41,6 @@ impl Struct1 tests_impls! { - #[ test ] fn basic() { let got = Struct1::former().form(); diff --git a/rust/test/former/all/string_slice_only_test.rs b/rust/test/former/all/string_slice_only_test.rs index e0977612a2..133878f977 100644 --- a/rust/test/former/all/string_slice_only_test.rs +++ b/rust/test/former/all/string_slice_only_test.rs @@ -7,7 +7,6 @@ use test_tools::exposed::*; tests_impls! { - #[ test ] fn test_complex() { // test.case( "default" ); diff --git a/rust/test/former/all/user_type_no_default.rs b/rust/test/former/all/user_type_no_default.rs new file mode 100644 index 0000000000..7226bd1825 --- /dev/null +++ b/rust/test/former/all/user_type_no_default.rs @@ -0,0 +1,84 @@ +#[ allow( unused_imports ) ] +use super::*; +#[ allow( unused_imports ) ] +use test_tools::exposed::*; + +only_for_wtools! +{ + #[ allow( unused_imports ) ] + use wtools::meta::*; + #[ allow( unused_imports ) ] + use wtools::former::Former; +} + +only_for_local_module! +{ + #[ allow( unused_imports ) ] + use meta_tools::*; + #[ allow( unused_imports ) ] + use former::Former; +} + +// + +tests_impls! +{ + fn test_user_type_with_no_default() + { + // #[ derive( Debug, PartialEq ) ] + // enum State + // { + // On, + // Off, + // } + // + // #[derive( Debug, PartialEq, Former )] + // struct Device + // { + // device : String, + // state : State, + // } + // + // let device = Device::former() + // .state( State::On ) + // .form(); + // + // let expected = Device + // { + // device : "".to_string(), + // state : State::On, + // }; + // + // a_id!( device, expected ); + } + + // + + #[ ignore ] + #[ should_panic ] + fn test_user_type_with_no_default_throwing() + { + // #[ derive( Debug, PartialEq ) ] + // enum State + // { + // On, + // Off, + // } + // + // #[derive( Debug, PartialEq, Former )] + // struct Device + // { + // device : String, + // state : State, + // } + // let device = Device::former().form(); + } +} + +// + +tests_index! +{ + test_user_type_with_no_default, + test_user_type_with_no_default_throwing, +} diff --git a/rust/test/former/common_front_test.rs b/rust/test/former/common_front_test.rs index 9b35a5164f..f9c66975a1 100644 --- a/rust/test/former/common_front_test.rs +++ b/rust/test/former/common_front_test.rs @@ -17,6 +17,8 @@ mod string_slice; #[ path = "./all/default_user_type.rs" ] mod default_user_type; +#[ path = "./all/user_type_no_default.rs" ] +mod user_type_no_default; #[ path = "./all/default_primitive.rs" ] mod default_primitive; #[ path = "./all/default_container.rs" ] From 8c51bbd04e30d7f5be42b47f6d252742d5f8c35c Mon Sep 17 00:00:00 2001 From: dmvict Date: Tue, 26 Jul 2022 10:37:48 +0300 Subject: [PATCH 02/17] Add test suite `user_type_no_debug`, implement former for types with no debug implementation --- rust/test/former/all/user_type_no_debug.rs | 59 ++++++++++++++++++++++ rust/test/former/common_front_test.rs | 2 + 2 files changed, 61 insertions(+) create mode 100644 rust/test/former/all/user_type_no_debug.rs diff --git a/rust/test/former/all/user_type_no_debug.rs b/rust/test/former/all/user_type_no_debug.rs new file mode 100644 index 0000000000..88a25ffca1 --- /dev/null +++ b/rust/test/former/all/user_type_no_debug.rs @@ -0,0 +1,59 @@ +#[ allow( unused_imports ) ] +use super::*; +#[ allow( unused_imports ) ] +use test_tools::exposed::*; + +only_for_wtools! +{ + #[ allow( unused_imports ) ] + use wtools::meta::*; + #[ allow( unused_imports ) ] + use wtools::former::Former; +} + +only_for_local_module! +{ + #[ allow( unused_imports ) ] + use meta_tools::*; + #[ allow( unused_imports ) ] + use former::Former; +} + +// + +tests_impls! +{ + fn test_user_type_with_no_debug() + { + // #[ derive( Default, PartialEq ) ] + // struct State + // { + // on : bool + // } + // + // #[derive( Debug, PartialEq, Former )] + // struct Device + // { + // device : String, + // state : State, + // } + // + // let device = Device::former() + // .form(); + // + // let expected = Device + // { + // device : "".to_string(), + // state : State { on : false }, + // }; + // + // a_id!( device, expected ); + } +} + +// + +tests_index! +{ + test_user_type_with_no_debug, +} diff --git a/rust/test/former/common_front_test.rs b/rust/test/former/common_front_test.rs index f9c66975a1..914eb736b3 100644 --- a/rust/test/former/common_front_test.rs +++ b/rust/test/former/common_front_test.rs @@ -19,6 +19,8 @@ mod string_slice; mod default_user_type; #[ path = "./all/user_type_no_default.rs" ] mod user_type_no_default; +#[ path = "./all/user_type_no_debug.rs" ] +mod user_type_no_debug; #[ path = "./all/default_primitive.rs" ] mod default_primitive; #[ path = "./all/default_container.rs" ] From 21bd5b464061cf3c7cafefef00b1004d7d6183a3 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Tue, 26 Jul 2022 22:55:18 +0300 Subject: [PATCH 03/17] add `same_data` --- rust/impl/mem/mem.rs | 16 ++++++++++++++++ rust/test/mem/inc/mem_test.rs | 22 ++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/rust/impl/mem/mem.rs b/rust/impl/mem/mem.rs index a2033f451d..013ee1124c 100644 --- a/rust/impl/mem/mem.rs +++ b/rust/impl/mem/mem.rs @@ -3,6 +3,21 @@ pub( crate ) mod private { // use crate::protected::*; + /// TODO + pub fn same_data< T1 : ?Sized, T2 : ?Sized >( src1 : &T1, src2 : &T2 ) -> bool + { + extern "C" { fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32; } + + let mem1 = src1 as *const _ as *const u8; + let mem2 = src2 as *const _ as *const u8; + + if same_size( src1, src2 ) { + unsafe { memcmp( mem1, mem2, core::mem::size_of_val( src1 ) ) == 0 } + } else { + false + } + } + /* zzz : qqq : implement mem::same_data, comparing data. discuss */ /// @@ -60,6 +75,7 @@ pub mod orphan pub use super:: { exposed::*, + private::same_data, private::same_ptr, private::same_size, private::same_region, diff --git a/rust/test/mem/inc/mem_test.rs b/rust/test/mem/inc/mem_test.rs index 6e47f11780..a5ca4fd119 100644 --- a/rust/test/mem/inc/mem_test.rs +++ b/rust/test/mem/inc/mem_test.rs @@ -5,6 +5,27 @@ use super::*; tests_impls! { + fn same_data() + { + let buf = [ 0u8; 128 ]; + a_true!( TheModule::same_data( &buf, &buf ) ); + + let x = [ 0u8; 1 ]; + let y = 0u8; + + a_true!( TheModule::same_data( &x, &y ) ); + + a_false!( TheModule::same_data( &buf, &x ) ); + a_false!( TheModule::same_data( &buf, &y ) ); + + struct H1( &'static str ); + struct H2( &'static str ); + + a_true!( TheModule::same_data( &H1( "hello" ), &H2( "hello" ) ) ); + a_false!( TheModule::same_data( &H1( "qwerty" ), &H2( "hello" ) ) ); + + } + fn same_ptr() { @@ -91,6 +112,7 @@ tests_impls! tests_index! { + same_data, same_ptr, same_size, same_region, From 27f9f764e6ebd89153b02c0e962e552f612e9cd7 Mon Sep 17 00:00:00 2001 From: dmvict Date: Wed, 27 Jul 2022 07:46:49 +0300 Subject: [PATCH 04/17] Write trivial test routine `basic_rgba` for encoder `Mp4` --- rust/test/video/inc/mp4_test.rs | 39 +++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/rust/test/video/inc/mp4_test.rs b/rust/test/video/inc/mp4_test.rs index 051c98b359..ffda78effc 100644 --- a/rust/test/video/inc/mp4_test.rs +++ b/rust/test/video/inc/mp4_test.rs @@ -2,9 +2,9 @@ use super::*; tests_impls! { - fn basic() -> Result< (), Box< dyn std::error::Error > > + fn basic_rgb() -> Result< (), Box< dyn std::error::Error > > { - let mut encoder = super::encoders::Mp4::new( 100, 100, 30, None, &ColorType::Rgb, "../../../target/out.mp4" )?; + let mut encoder = super::encoders::Mp4::new( 100, 100, 30, None, &ColorType::Rgb, "../../../target/out_rgb.mp4" )?; let mut buf = [ 255u8; 30_000 ]; buf[ 0 ] = 0; buf[ 1 ] = 0; @@ -24,7 +24,37 @@ tests_impls! } encoder.flush()?; - let path = std::path::PathBuf::from( "../../../target/out.mp4" ); + let path = std::path::PathBuf::from( "../../../target/out_rgb.mp4" ); + a_id!( path.exists(), true ); + + Ok( () ) + } + + // + + fn basic_rgba() -> Result< (), Box< dyn std::error::Error > > + { + let mut encoder = super::encoders::Mp4::new( 100, 100, 30, None, &ColorType::Rgba, "../../../target/out_rgba.mp4" )?; + let mut buf = [ 255u8; 40_000 ]; + buf[ 0 ] = 0; + buf[ 1 ] = 0; + buf[ 2 ] = 0; + encoder.encode( &buf )?; + + for i in 1..100 + { + buf[ ( i - 1 ) * 4 + ( i - 1 ) * 400 ] = 255; + buf[ ( i - 1 ) * 4 + 1 + ( i - 1 ) * 400 ] = 255; + buf[ ( i - 1 ) * 4 + 2 + ( i - 1 ) * 400 ] = 255; + + buf[ i * 4 + i * 400 ] = 0; + buf[ i * 4 + 1 + i * 400 ] = 0; + buf[ i * 4 + 2 + i * 400 ] = 0; + encoder.encode( &buf )?; + } + encoder.flush()?; + + let path = std::path::PathBuf::from( "../../../target/out_rgba.mp4" ); a_id!( path.exists(), true ); Ok( () ) @@ -35,5 +65,6 @@ tests_impls! tests_index! { - basic, + basic_rgb, + basic_rgba, } From 34f7aeec8b06de5f1b718702835210303533baa4 Mon Sep 17 00:00:00 2001 From: dmvict Date: Wed, 27 Jul 2022 07:47:33 +0300 Subject: [PATCH 05/17] Extend encoder `Mp4`, implement trivial handling of color type `Rgba` --- rust/impl/video/encoders/mp4.rs | 84 ++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 38 deletions(-) diff --git a/rust/impl/video/encoders/mp4.rs b/rust/impl/video/encoders/mp4.rs index 65f107f57c..e38307a715 100644 --- a/rust/impl/video/encoders/mp4.rs +++ b/rust/impl/video/encoders/mp4.rs @@ -66,49 +66,57 @@ pub( crate ) mod private /// Encode bytes buffer to output. fn encode( &mut self, data : &[ u8 ] ) -> Result< (), Box > { - match self.color_type + let data = match self.color_type { ColorType::Rgb => { - let frame_timestamp = Timestamp::new( self.frame_idx, self.time_base ); - self.frame_idx += 1; - - let mut yuv = openh264::formats::RBGYUVConverter::new( self.width, self.height ); - yuv.convert( data ); - - /* the initialization of new instance is required for correct conversion */ - let mut encoder = Encoder::with_config( self.config.clone() ).unwrap(); - let bitstream = encoder.encode( &yuv )?; - let buf = bitstream.to_vec(); - - #[ cfg( feature = "mp4_ratio_conversion" ) ] - { - let mut frame_timestamp = frame_timestamp; - for _i in 0..self.frame_rate_ratio - { - let packet = PacketMut::from( &buf ) - .with_pts( frame_timestamp ) - .with_dts( frame_timestamp ) - .freeze(); - - frame_timestamp = Timestamp::new( self.frame_idx, self.time_base ); - self.frame_idx += 1; - self.muxer.push( packet )?; - } - } - #[ cfg( not( feature = "mp4_ratio_conversion" ) ) ] - { - let packet = PacketMut::from( &buf ) - .with_pts( frame_timestamp ) - .with_dts( frame_timestamp ) - .freeze(); - self.muxer.push( packet )?; - } - - Ok( () ) + data.to_vec() }, - _ => unimplemented!( "not implemented" ), + ColorType::Rgba => + { + /* skip alpha channel */ + data.iter().enumerate() + .filter_map( | ( i, v ) | if ( i + 1 ) % 4 == 0 { None } else { Some( *v ) } ) + .collect::>() + }, + }; + + let frame_timestamp = Timestamp::new( self.frame_idx, self.time_base ); + self.frame_idx += 1; + + let mut yuv = openh264::formats::RBGYUVConverter::new( self.width, self.height ); + yuv.convert( data.as_slice() ); + + /* the initialization of new instance is required for correct conversion */ + let mut encoder = Encoder::with_config( self.config.clone() ).unwrap(); + let bitstream = encoder.encode( &yuv )?; + let buf = bitstream.to_vec(); + + #[ cfg( feature = "mp4_ratio_conversion" ) ] + { + let mut frame_timestamp = frame_timestamp; + for _i in 0..self.frame_rate_ratio + { + let packet = PacketMut::from( &buf ) + .with_pts( frame_timestamp ) + .with_dts( frame_timestamp ) + .freeze(); + + frame_timestamp = Timestamp::new( self.frame_idx, self.time_base ); + self.frame_idx += 1; + self.muxer.push( packet )?; + } } + #[ cfg( not( feature = "mp4_ratio_conversion" ) ) ] + { + let packet = PacketMut::from( &buf ) + .with_pts( frame_timestamp ) + .with_dts( frame_timestamp ) + .freeze(); + self.muxer.push( packet )?; + } + + Ok( () ) } /// Finish encoding. From c1fa58fde0e4bcb4ac88d1cea8a124c6aa711167 Mon Sep 17 00:00:00 2001 From: dmvict Date: Wed, 27 Jul 2022 08:17:17 +0300 Subject: [PATCH 06/17] Update encoders, use struct `X2` to pass frame dimensions --- module/move/_video_experiment/Cargo.toml | 1 + rust/impl/video/encoder_strategy.rs | 30 +++++++++++------------- rust/impl/video/encoders/gif.rs | 18 +++++++------- rust/impl/video/encoders/mp4.rs | 16 ++++++------- rust/impl/video/encoders/png.rs | 26 ++++++++++---------- 5 files changed, 42 insertions(+), 49 deletions(-) diff --git a/module/move/_video_experiment/Cargo.toml b/module/move/_video_experiment/Cargo.toml index fda06c1d1a..19268c961d 100644 --- a/module/move/_video_experiment/Cargo.toml +++ b/module/move/_video_experiment/Cargo.toml @@ -52,6 +52,7 @@ path = "rust/test/video/video_experiment_tests.rs" [dependencies] wtools = { version = "~0.2", path = "../../rust/wtools" } +wmath = "~0.3" gif = "~0.11" apng = "~0.2.0" png = "~0.16.3" diff --git a/rust/impl/video/encoder_strategy.rs b/rust/impl/video/encoder_strategy.rs index 309329acb5..3570491aed 100644 --- a/rust/impl/video/encoder_strategy.rs +++ b/rust/impl/video/encoder_strategy.rs @@ -7,6 +7,7 @@ pub( crate ) mod private use wtools::error::BasicError; #[ allow( unused_imports ) ] use wtools::prelude::former::Former; + use wmath::X2; /// Encoder for the buffer. @@ -14,23 +15,21 @@ pub( crate ) mod private // #[ derive( Former ) ] pub struct Encoder { - // /// Frame width. - width : usize, - // /// Frame height. - height : usize, - // /// Frame rate. + /// Frame width and height. + dims : wmath::X2< usize >, + /// Frame rate. frame_rate : usize, - // /// Color encoding. + /// Color encoding. color_type : ColorType, - // /// Repeat animation. For animated images formats. + /// Repeat animation. For animated images formats. repeat : Option< usize >, - // /// Type of output format. + /// Type of output format. encoder_type : EncoderType, - // /// Encoder for the output format. + /// Encoder for the output format. encoder : Box< dyn EncodeData >, - // /// Output filename. + /// Output filename. output_filename : std::path::PathBuf, } @@ -39,8 +38,8 @@ pub( crate ) mod private fn fmt( &self, f : &mut Formatter< '_ > ) -> std::fmt::Result { f.debug_struct( "Encoder" ) - .field( "width", &self.width ) - .field( "height", &self.height ) + .field( "width", &self.dims.0 ) + .field( "height", &self.dims.0 ) .field( "frame_rate", &self.frame_rate ) .field( "color_type", &self.color_type ) .field( "encoder_type", &self.encoder_type ) @@ -81,8 +80,7 @@ pub( crate ) mod private let instance = Self { - width, - height, + dims : X2( width, height ), frame_rate, color_type, repeat, @@ -141,8 +139,8 @@ pub( crate ) mod private let encoder = Encoder::encoder_make ( &encoder_type, - self.width, - self.height, + self.dims.0, + self.dims.1, self.frame_rate, self.repeat, &self.color_type, diff --git a/rust/impl/video/encoders/gif.rs b/rust/impl/video/encoders/gif.rs index 99d6fa7677..58d762aa58 100644 --- a/rust/impl/video/encoders/gif.rs +++ b/rust/impl/video/encoders/gif.rs @@ -3,16 +3,15 @@ pub( crate ) mod private { use std::fmt::{ Debug, Formatter }; use crate::common::prelude::*; + use wmath::X2; use ::gif::{ Encoder, Frame, Repeat }; /// Encoder for the buffer. // #[ derive( Former ) ] pub struct Gif { - /// Frame width. - width : usize, - /// Frame height. - height : usize, + /// Frame width and height. + dims : X2< usize >, /// Frame rate. frame_rate : usize, /// Delay for frame. @@ -30,8 +29,8 @@ pub( crate ) mod private fn fmt( &self, f : &mut Formatter< '_ > ) -> std::fmt::Result { f.debug_struct( "Gif" ) - .field( "width", &self.width ) - .field( "height", &self.height ) + .field( "width", &self.dims.0 ) + .field( "height", &self.dims.1 ) .field( "frame_rate", &self.frame_rate ) .field( "color_type", &self.color_type ) .field( "output_filename", &self.output_filename ) @@ -48,13 +47,13 @@ pub( crate ) mod private { ColorType::Rgb => { - Frame::from_rgb( self.width as u16, self.height as u16, data ) + Frame::from_rgb( self.dims.0 as u16, self.dims.1 as u16, data ) }, ColorType::Rgba => { let mut cloned_data = data.to_vec(); /* routine accepts mutable slice */ - Frame::from_rgba( self.width as u16, self.height as u16, cloned_data.as_mut_slice() ) + Frame::from_rgba( self.dims.0 as u16, self.dims.1 as u16, cloned_data.as_mut_slice() ) }, }; buf.delay = self.frame_delay; @@ -102,8 +101,7 @@ pub( crate ) mod private let instance = Self { - width, - height, + dims : X2( width, height ), frame_rate, frame_delay, color_type : color_type.clone(), diff --git a/rust/impl/video/encoders/mp4.rs b/rust/impl/video/encoders/mp4.rs index e38307a715..df45af4ce3 100644 --- a/rust/impl/video/encoders/mp4.rs +++ b/rust/impl/video/encoders/mp4.rs @@ -3,6 +3,7 @@ pub( crate ) mod private { use std::fmt::{ Debug, Formatter }; use crate::common::prelude::*; + use wmath::X2; use ::ac_ffmpeg:: { packet::PacketMut, @@ -23,10 +24,8 @@ pub( crate ) mod private // #[ derive( Former ) ] pub struct Mp4 { - /// Frame width. - width : usize, - /// Frame height. - height : usize, + /// Frame width and height. + dims : X2< usize >, /// Frame rate. frame_rate : usize, #[ cfg( feature = "mp4_ratio_conversion" ) ] @@ -52,8 +51,8 @@ pub( crate ) mod private fn fmt( &self, f : &mut Formatter< '_ > ) -> std::fmt::Result { f.debug_struct( "Mp4" ) - .field( "width", &self.width ) - .field( "height", &self.height ) + .field( "width", &self.dims.0 ) + .field( "height", &self.dims.1 ) .field( "frame_rate", &self.frame_rate ) .field( "color_type", &self.color_type ) .field( "output_filename", &self.output_filename ) @@ -84,7 +83,7 @@ pub( crate ) mod private let frame_timestamp = Timestamp::new( self.frame_idx, self.time_base ); self.frame_idx += 1; - let mut yuv = openh264::formats::RBGYUVConverter::new( self.width, self.height ); + let mut yuv = openh264::formats::RBGYUVConverter::new( self.dims.0, self.dims.1 ); yuv.convert( data.as_slice() ); /* the initialization of new instance is required for correct conversion */ @@ -179,8 +178,7 @@ pub( crate ) mod private let instance = Self { - width, - height, + dims : X2( width, height ), frame_rate, #[ cfg( feature = "mp4_ratio_conversion" ) ] frame_rate_ratio : ( 30 / frame_rate ) as _, diff --git a/rust/impl/video/encoders/png.rs b/rust/impl/video/encoders/png.rs index a5599bf2d8..e997e8b854 100644 --- a/rust/impl/video/encoders/png.rs +++ b/rust/impl/video/encoders/png.rs @@ -4,6 +4,7 @@ pub( crate ) mod private use std::fmt::{ Debug, Formatter }; use crate::common::prelude::*; use wtools::error::BasicError; + use wmath::X2; use ::apng::{ Config, Encoder, Frame, PNGImage }; use ::png::{ BitDepth, FilterType }; @@ -12,10 +13,8 @@ pub( crate ) mod private // #[ derive( Former ) ] pub struct Png { - /// Frame width. - width : usize, - /// Frame height. - height : usize, + /// Frame width and height. + dims : X2< usize >, /// Frame rate. frame_rate : usize, /// Color encoding. @@ -33,8 +32,8 @@ pub( crate ) mod private fn fmt( &self, f : &mut Formatter< '_ > ) -> std::fmt::Result { f.debug_struct( "Png" ) - .field( "width", &self.width ) - .field( "height", &self.height ) + .field( "width", &self.dims.0 ) + .field( "height", &self.dims.1 ) .field( "frame_rate", &self.frame_rate ) .field( "color_type", &self.color_type ) .field( "output_filename", &self.output_filename ) @@ -53,8 +52,8 @@ pub( crate ) mod private { PNGImage { - width : self.width as _, - height : self.height as _, + width : self.dims.0 as _, + height : self.dims.1 as _, data : data.to_vec(), bit_depth : BitDepth::Eight, color_type : ::png::ColorType::RGB, @@ -64,8 +63,8 @@ pub( crate ) mod private { PNGImage { - width : self.width as _, - height : self.height as _, + width : self.dims.0 as _, + height : self.dims.1 as _, data : data.to_vec(), bit_depth : BitDepth::Eight, color_type : ::png::ColorType::RGBA, @@ -84,8 +83,8 @@ pub( crate ) mod private let config = Config { - width : self.width as _, - height : self.height as _, + width : self.dims.0 as _, + height : self.dims.1 as _, num_frames : self.images_buffer.len() as _, num_plays : self.repeat, color : self.images_buffer[ 0 ].color_type, @@ -146,8 +145,7 @@ pub( crate ) mod private let instance = Self { - width, - height, + dims : X2( width, height ), frame_rate, color_type : color_type.clone(), images_buffer : vec![], From a7d225d4c7ad9eb2e3d706347b77344a2f404c03 Mon Sep 17 00:00:00 2001 From: dmvict Date: Wed, 27 Jul 2022 08:33:21 +0300 Subject: [PATCH 07/17] Improve constructors of encoders, use type `X2` to pass frame dimensions --- rust/impl/video/encoder_strategy.rs | 23 ++++++++++---------- rust/impl/video/encoders/gif.rs | 7 +++--- rust/impl/video/encoders/mp4.rs | 11 +++++----- rust/impl/video/encoders/png.rs | 5 ++--- rust/test/video/inc/apng_test.rs | 4 ++-- rust/test/video/inc/encoder_strategy_test.rs | 14 ++++++------ rust/test/video/inc/gif_test.rs | 4 ++-- rust/test/video/inc/mp4_test.rs | 4 ++-- rust/test/video/video_experiment_tests.rs | 1 + 9 files changed, 36 insertions(+), 37 deletions(-) diff --git a/rust/impl/video/encoder_strategy.rs b/rust/impl/video/encoder_strategy.rs index 3570491aed..219556baba 100644 --- a/rust/impl/video/encoder_strategy.rs +++ b/rust/impl/video/encoder_strategy.rs @@ -68,19 +68,18 @@ pub( crate ) mod private pub fn new ( encoder_type : EncoderType, - width : usize, - height : usize, + dims : X2< usize >, frame_rate : usize, repeat : Option< usize >, color_type : ColorType, filename : impl AsRef< str > ) -> Result< Self, Box< dyn std::error::Error > > { - let encoder = Encoder::encoder_make( &encoder_type, width, height, frame_rate, repeat, &color_type, filename.as_ref() )?; + let encoder = Encoder::encoder_make( &encoder_type, &dims, frame_rate, repeat, &color_type, filename.as_ref() )?; let instance = Self { - dims : X2( width, height ), + dims, frame_rate, color_type, repeat, @@ -91,11 +90,12 @@ pub( crate ) mod private Ok( instance ) } + // + fn encoder_make ( encoder_type : &EncoderType, - width : usize, - height : usize, + dims : &X2< usize >, frame_rate : usize, repeat : Option< usize >, color_type : &ColorType, @@ -104,23 +104,25 @@ pub( crate ) mod private { if encoder_type == &EncoderType::Gif { - let encoder = Gif::new( width, height, frame_rate, repeat, color_type, filename )?; + let encoder = Gif::new( dims.clone(), frame_rate, repeat, color_type, filename )?; return Ok( Box::new( encoder ) ); } if encoder_type == &EncoderType::Png { - let encoder = Png::new( width, height, frame_rate, repeat, color_type, filename )?; + let encoder = Png::new( dims.clone(), frame_rate, repeat, color_type, filename )?; return Ok( Box::new( encoder ) ); } if encoder_type == &EncoderType::Mp4 { - let encoder = Mp4::new( width, height, frame_rate, repeat, color_type, filename )?; + let encoder = Mp4::new( dims.clone(), frame_rate, repeat, color_type, filename )?; return Ok( Box::new( encoder ) ); } Err( Box::new( BasicError::new( format!( "unknown encoder type \"{:?}\"", encoder_type ) ) ) ) } + // + /// Change type of encoder. pub fn type_change( &mut self, encoder_type : EncoderType ) -> Result< (), Box< dyn std::error::Error > > { @@ -139,8 +141,7 @@ pub( crate ) mod private let encoder = Encoder::encoder_make ( &encoder_type, - self.dims.0, - self.dims.1, + &self.dims, self.frame_rate, self.repeat, &self.color_type, diff --git a/rust/impl/video/encoders/gif.rs b/rust/impl/video/encoders/gif.rs index 58d762aa58..658e3a6647 100644 --- a/rust/impl/video/encoders/gif.rs +++ b/rust/impl/video/encoders/gif.rs @@ -73,8 +73,7 @@ pub( crate ) mod private /// Create an instance. pub fn new ( - width : usize, - height : usize, + dims : X2< usize >, frame_rate : usize, repeat : Option< usize >, color_type : &ColorType, @@ -82,7 +81,7 @@ pub( crate ) mod private ) -> Result< Self, Box< dyn std::error::Error > > { let image = std::fs::File::create( filename.as_ref() )?; - let mut encoder = Encoder::new( image, width as u16, height as u16, &[] )?; + let mut encoder = Encoder::new( image, dims.0 as u16, dims.1 as u16, &[] )?; if let Some( n ) = repeat { match n @@ -101,7 +100,7 @@ pub( crate ) mod private let instance = Self { - dims : X2( width, height ), + dims, frame_rate, frame_delay, color_type : color_type.clone(), diff --git a/rust/impl/video/encoders/mp4.rs b/rust/impl/video/encoders/mp4.rs index df45af4ce3..09a10eec69 100644 --- a/rust/impl/video/encoders/mp4.rs +++ b/rust/impl/video/encoders/mp4.rs @@ -131,8 +131,7 @@ pub( crate ) mod private /// Create an instance. pub fn new ( - width : usize, - height : usize, + dims : X2< usize >, frame_rate : usize, _repeat : Option< usize >, color_type : &ColorType, @@ -151,8 +150,8 @@ pub( crate ) mod private let codec_parameters = CodecParameters::from ( VideoCodecParameters::builder( "libx264" ).unwrap() - .width( width ) - .height( height ) + .width( dims.0 ) + .height( dims.1 ) .build() ); @@ -174,11 +173,11 @@ pub( crate ) mod private }; let time_base = TimeBase::new( 1, base_frame_rate ); - let config = EncoderConfig::new( width as _, height as _ ); + let config = EncoderConfig::new( dims.0 as _, dims.1 as _ ); let instance = Self { - dims : X2( width, height ), + dims, frame_rate, #[ cfg( feature = "mp4_ratio_conversion" ) ] frame_rate_ratio : ( 30 / frame_rate ) as _, diff --git a/rust/impl/video/encoders/png.rs b/rust/impl/video/encoders/png.rs index e997e8b854..6fd15cd629 100644 --- a/rust/impl/video/encoders/png.rs +++ b/rust/impl/video/encoders/png.rs @@ -128,8 +128,7 @@ pub( crate ) mod private /// Create an instance. pub fn new ( - width : usize, - height : usize, + dims : X2< usize >, frame_rate : usize, repeat : Option< usize >, color_type : &ColorType, @@ -145,7 +144,7 @@ pub( crate ) mod private let instance = Self { - dims : X2( width, height ), + dims, frame_rate, color_type : color_type.clone(), images_buffer : vec![], diff --git a/rust/test/video/inc/apng_test.rs b/rust/test/video/inc/apng_test.rs index 42e19776b5..ef1e5b628f 100644 --- a/rust/test/video/inc/apng_test.rs +++ b/rust/test/video/inc/apng_test.rs @@ -4,7 +4,7 @@ tests_impls! { fn basic_rgb() -> Result< (), Box< dyn std::error::Error > > { - let mut encoder = super::encoders::Png::new( 100, 100, 30, None, &ColorType::Rgb, "../../../target/out_rgb.png" )?; + let mut encoder = super::encoders::Png::new( X2( 100, 100 ), 30, None, &ColorType::Rgb, "../../../target/out_rgb.png" )?; let mut buf = [ 255u8; 30_000 ]; buf[ 0 ] = 0; buf[ 1 ] = 0; @@ -34,7 +34,7 @@ tests_impls! fn basic_rgba() -> Result< (), Box< dyn std::error::Error > > { - let mut encoder = super::encoders::Png::new( 100, 100, 30, None, &ColorType::Rgba, "../../../target/out_rgba.png" )?; + let mut encoder = super::encoders::Png::new( X2( 100, 100 ), 30, None, &ColorType::Rgba, "../../../target/out_rgba.png" )?; let mut buf = [ 255u8; 40_000 ]; buf[ 0 ] = 0; buf[ 1 ] = 0; diff --git a/rust/test/video/inc/encoder_strategy_test.rs b/rust/test/video/inc/encoder_strategy_test.rs index 5e4fd1a787..00ee89e2d2 100644 --- a/rust/test/video/inc/encoder_strategy_test.rs +++ b/rust/test/video/inc/encoder_strategy_test.rs @@ -48,9 +48,9 @@ tests_impls! { fn basic() -> Result< (), Box< dyn std::error::Error > > { - let mut encoder_gif = super::encoder_strategy::Encoder::new( EncoderType::Gif, 100, 100, 30, None, ColorType::Rgb, "../../../target/strategy.gif" )?; - let mut encoder_png = super::encoder_strategy::Encoder::new( EncoderType::Png, 100, 100, 30, None, ColorType::Rgb, "../../../target/strategy.png" )?; - let mut encoder_mp4 = super::encoder_strategy::Encoder::new( EncoderType::Mp4, 100, 100, 30, None, ColorType::Rgb, "../../../target/strategy.mp4" )?; + let mut encoder_gif = super::encoder_strategy::Encoder::new( EncoderType::Gif, X2( 100, 100 ), 30, None, ColorType::Rgb, "../../../target/strategy.gif" )?; + let mut encoder_png = super::encoder_strategy::Encoder::new( EncoderType::Png, X2( 100, 100 ), 30, None, ColorType::Rgb, "../../../target/strategy.png" )?; + let mut encoder_mp4 = super::encoder_strategy::Encoder::new( EncoderType::Mp4, X2( 100, 100 ), 30, None, ColorType::Rgb, "../../../target/strategy.mp4" )?; animation_write( &mut encoder_gif )?; animation_write( &mut encoder_png )?; animation_write( &mut encoder_mp4 )?; @@ -69,7 +69,7 @@ tests_impls! fn basic_with_change() -> Result< (), Box< dyn std::error::Error > > { - let mut encoder = super::encoder_strategy::Encoder::new( EncoderType::Gif, 100, 100, 30, None, ColorType::Rgb, "../../../target/encoder_change.gif" )?; + let mut encoder = super::encoder_strategy::Encoder::new( EncoderType::Gif, X2( 100, 100 ), 30, None, ColorType::Rgb, "../../../target/encoder_change.gif" )?; animation_write( &mut encoder )?; encoder.type_change( EncoderType::Mp4 )?; animation_write( &mut encoder )?; @@ -86,9 +86,9 @@ tests_impls! fn basic_with_images_rgb() -> Result< (), Box< dyn std::error::Error > > { - let mut encoder_gif = super::encoder_strategy::Encoder::new( EncoderType::Gif, 512, 512, 1, None, ColorType::Rgb, "../../../target/image.gif" )?; - let mut encoder_png = super::encoder_strategy::Encoder::new( EncoderType::Png, 512, 512, 1, None, ColorType::Rgb, "../../../target/image.png" )?; - let mut encoder_mp4 = super::encoder_strategy::Encoder::new( EncoderType::Mp4, 512, 512, 1, None, ColorType::Rgb, "../../../target/image.mp4" )?; + let mut encoder_gif = super::encoder_strategy::Encoder::new( EncoderType::Gif, X2( 512, 512 ), 1, None, ColorType::Rgb, "../../../target/image.gif" )?; + let mut encoder_png = super::encoder_strategy::Encoder::new( EncoderType::Png, X2( 512, 512 ), 1, None, ColorType::Rgb, "../../../target/image.png" )?; + let mut encoder_mp4 = super::encoder_strategy::Encoder::new( EncoderType::Mp4, X2( 512, 512 ), 1, None, ColorType::Rgb, "../../../target/image.mp4" )?; animation_write_from_img_rgb( &mut encoder_gif )?; animation_write_from_img_rgb( &mut encoder_png )?; animation_write_from_img_rgb( &mut encoder_mp4 )?; diff --git a/rust/test/video/inc/gif_test.rs b/rust/test/video/inc/gif_test.rs index f687b6c470..17b790d94a 100644 --- a/rust/test/video/inc/gif_test.rs +++ b/rust/test/video/inc/gif_test.rs @@ -4,7 +4,7 @@ tests_impls! { fn basic_rgb() -> Result< (), Box< dyn std::error::Error > > { - let mut encoder = super::encoders::Gif::new( 100, 100, 30, None, &ColorType::Rgb, "../../../target/out_rgb.gif" )?; + let mut encoder = super::encoders::Gif::new( X2( 100, 100 ), 30, None, &ColorType::Rgb, "../../../target/out_rgb.gif" )?; let mut buf = [ 255u8; 30_000 ]; buf[ 0 ] = 0; buf[ 1 ] = 0; @@ -34,7 +34,7 @@ tests_impls! fn basic_rgba() -> Result< (), Box< dyn std::error::Error > > { - let mut encoder = super::encoders::Gif::new( 100, 100, 30, None, &ColorType::Rgba, "../../../target/out_rgba.gif" )?; + let mut encoder = super::encoders::Gif::new( X2( 100, 100 ), 30, None, &ColorType::Rgba, "../../../target/out_rgba.gif" )?; let mut buf = [ 255u8; 40_000 ]; buf[ 0 ] = 0; buf[ 1 ] = 0; diff --git a/rust/test/video/inc/mp4_test.rs b/rust/test/video/inc/mp4_test.rs index ffda78effc..85fbbc50ae 100644 --- a/rust/test/video/inc/mp4_test.rs +++ b/rust/test/video/inc/mp4_test.rs @@ -4,7 +4,7 @@ tests_impls! { fn basic_rgb() -> Result< (), Box< dyn std::error::Error > > { - let mut encoder = super::encoders::Mp4::new( 100, 100, 30, None, &ColorType::Rgb, "../../../target/out_rgb.mp4" )?; + let mut encoder = super::encoders::Mp4::new( X2( 100, 100 ), 30, None, &ColorType::Rgb, "../../../target/out_rgb.mp4" )?; let mut buf = [ 255u8; 30_000 ]; buf[ 0 ] = 0; buf[ 1 ] = 0; @@ -34,7 +34,7 @@ tests_impls! fn basic_rgba() -> Result< (), Box< dyn std::error::Error > > { - let mut encoder = super::encoders::Mp4::new( 100, 100, 30, None, &ColorType::Rgba, "../../../target/out_rgba.mp4" )?; + let mut encoder = super::encoders::Mp4::new( X2( 100, 100 ), 30, None, &ColorType::Rgba, "../../../target/out_rgba.mp4" )?; let mut buf = [ 255u8; 40_000 ]; buf[ 0 ] = 0; buf[ 1 ] = 0; diff --git a/rust/test/video/video_experiment_tests.rs b/rust/test/video/video_experiment_tests.rs index 82fad779bf..8b492b4080 100644 --- a/rust/test/video/video_experiment_tests.rs +++ b/rust/test/video/video_experiment_tests.rs @@ -1,6 +1,7 @@ use video_experiment::encoders; use video_experiment::encoder_strategy; use video_experiment::prelude::*; +use wmath::X2; use test_tools::exposed::*; From 28b2243153577449faefff362af3c4f63bd657fb Mon Sep 17 00:00:00 2001 From: dmvict Date: Wed, 27 Jul 2022 08:55:36 +0300 Subject: [PATCH 08/17] Improve sample `mod_interface_with_debug_sample`, use import --- sample/rust/mod_interface_with_debug_sample/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sample/rust/mod_interface_with_debug_sample/src/main.rs b/sample/rust/mod_interface_with_debug_sample/src/main.rs index 4ef799c060..fc3dbb8348 100644 --- a/sample/rust/mod_interface_with_debug_sample/src/main.rs +++ b/sample/rust/mod_interface_with_debug_sample/src/main.rs @@ -9,7 +9,7 @@ fn main() // -mod_interface::mod_interface! +mod_interface! { #![ debug ] /// Inner. From ea0901014c4c857e10cfdaf9816fb26ff43efc73 Mon Sep 17 00:00:00 2001 From: dmvict Date: Wed, 27 Jul 2022 08:56:14 +0300 Subject: [PATCH 09/17] Improve config file `Cargo.toml`, exclude experiment from testing --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index cbf8d3f829..b098a94999 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ members = [ ] exclude = [ "*", + "module/move/_video_experiment", # "module/rust/-*", # "sample/rust/-*", # "module/rust/_*", From 58e7dabe59287553117d8925a95b21ebe5495d71 Mon Sep 17 00:00:00 2001 From: dmvict Date: Mon, 1 Aug 2022 11:07:02 +0300 Subject: [PATCH 10/17] Add test suite `unsigned_primitive_types`, form unsigned primitives --- rust/impl/string/string/isolate.rs | 2 +- .../former/all/unsigned_primitive_types.rs | 144 ++++++++++++++++++ rust/test/former/common_front_test.rs | 4 +- 3 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 rust/test/former/all/unsigned_primitive_types.rs diff --git a/rust/impl/string/string/isolate.rs b/rust/impl/string/string/isolate.rs index b9037da6f4..c5ab6af92e 100644 --- a/rust/impl/string/string/isolate.rs +++ b/rust/impl/string/string/isolate.rs @@ -22,7 +22,7 @@ pub( crate ) mod private #[ default( true ) ] left : bool, #[ default( 1 ) ] - times : u8, /* qqq : former do not form u16, u32, u64, usize */ + times : u8, /* rrr : Dmytro : former do not form u16, u32, u64, usize, replace after fix */ #[ default( true ) ] none : bool, } diff --git a/rust/test/former/all/unsigned_primitive_types.rs b/rust/test/former/all/unsigned_primitive_types.rs new file mode 100644 index 0000000000..edaa0f292f --- /dev/null +++ b/rust/test/former/all/unsigned_primitive_types.rs @@ -0,0 +1,144 @@ +#[ allow( unused_imports ) ] +use super::*; +#[ allow( unused_imports ) ] +use test_tools::exposed::*; + +only_for_wtools! +{ + #[ allow( unused_imports ) ] + use wtools::meta::*; + #[ allow( unused_imports ) ] + use wtools::former::Former; +} + +only_for_local_module! +{ + #[ allow( unused_imports ) ] + use meta_tools::*; + #[ allow( unused_imports ) ] + use former::Former; +} + +// + +tests_impls! +{ + fn with_u8() + { + #[ derive( Debug, PartialEq, Former ) ] + pub struct Counter + { + count : u8, + } + + let counter = Counter::former() + .count( 0 ) + .form(); + + let expected = Counter + { + count : 0, + }; + + a_id!( counter, expected ); + } + + // + + fn with_u16() + { + // #[ derive( Debug, PartialEq, Former ) ] + // pub struct Counter + // { + // count : u16, + // } + // + // let counter = Counter::former() + // .count( 0 ) + // .form(); + // + // let expected = Counter + // { + // count : 0, + // }; + // + // a_id!( counter, expected ); + } + + // + + fn with_u32() + { + // #[ derive( Debug, PartialEq, Former ) ] + // pub struct Counter + // { + // count : u32, + // } + // + // let counter = Counter::former() + // .count( 0 ) + // .form(); + // + // let expected = Counter + // { + // count : 0, + // }; + // + // a_id!( counter, expected ); + } + + // + + fn with_u64() + { + // #[ derive( Debug, PartialEq, Former ) ] + // pub struct Counter + // { + // count : u64, + // } + // + // let counter = Counter::former() + // .count( 0 ) + // .form(); + // + // let expected = Counter + // { + // count : 0, + // }; + // + // a_id!( counter, expected ); + } + + // + + fn with_usize() + { + // #[ derive( Debug, PartialEq, Former ) ] + // pub struct Counter + // { + // count : usize, + // } + // + // let counter = Counter::former() + // .count( 0 ) + // .form(); + // + // let expected = Counter + // { + // count : 0, + // }; + // + // a_id!( counter, expected ); + } +} + +// + +tests_index! +{ + with_u8, + with_u16, + with_u32, + with_u64, + with_usize, +} diff --git a/rust/test/former/common_front_test.rs b/rust/test/former/common_front_test.rs index 914eb736b3..70996b1c03 100644 --- a/rust/test/former/common_front_test.rs +++ b/rust/test/former/common_front_test.rs @@ -23,7 +23,9 @@ mod user_type_no_default; mod user_type_no_debug; #[ path = "./all/default_primitive.rs" ] mod default_primitive; -#[ path = "./all/default_container.rs" ] +#[ path = "./all/default_primitive.rs" ] +mod unsigned_primitive_types; +#[ path = "./all/unsigned_primitive_types.rs" ] mod default_container; #[ path = "./all/perform.rs" ] mod perform; From 2c1a239bbc8f15e39d22ff0020d65268153718ca Mon Sep 17 00:00:00 2001 From: dmvict Date: Tue, 2 Aug 2022 08:37:38 +0300 Subject: [PATCH 11/17] Improve module `wca`, replace former-like implementation by `Former` --- rust/impl/ca/ca/command.rs | 166 +++++++++++++++++++++++-------------- rust/impl/ca/ca/common.rs | 119 -------------------------- rust/impl/ca/ca/mod.rs | 2 - rust/impl/ca/wca_lib.rs | 2 +- 4 files changed, 105 insertions(+), 184 deletions(-) delete mode 100644 rust/impl/ca/ca/common.rs diff --git a/rust/impl/ca/ca/command.rs b/rust/impl/ca/ca/command.rs index 04f182b271..43e46a45e1 100644 --- a/rust/impl/ca/ca/command.rs +++ b/rust/impl/ca/ca/command.rs @@ -1,17 +1,20 @@ +#![ allow( missing_docs ) ] +/* does not work locally */ +/* rrr : for Dmytro : remove when former will be extended */ + pub( crate ) mod private { - use std::collections::HashMap; - use std::rc::Rc; - use core::fmt; - use wtools::error::{ Result, BasicError }; - use crate::protected::*; - // use crate:: - // { - // field_str, - // field_map_str_str, - // field_map_str_vec_str, - // field_routine, - // }; + use std:: + { + collections::HashMap, + rc::Rc, + fmt, + }; + use wtools:: + { + error::{ Result, BasicError }, + meta::Former, + }; /// /// Handle for command routine. @@ -90,23 +93,100 @@ pub( crate ) mod private /// Command descriptor. /// - #[derive( Default, Debug, Clone )] + #[ derive( Debug, Clone ) ] + #[ derive( Former ) ] pub struct Command { - /// Command common hint. + // /// Command common hint. pub hint : String, - /// Command full hint. + // /// Command full hint. pub long_hint : String, - /// Phrase descriptor for command. + // /// Phrase descriptor for command. pub phrase : String, - /// Command subject hint. + // /// Command subject hint. pub subject_hint : String, - /// Hints for command options. + // /// Hints for command options. pub properties_hints : HashMap< String, String >, - /// Map of aliases. + // /// Map of aliases. pub properties_aliases : HashMap< String, Vec< String > >, - /// Command routine. - pub routine : OnCommand, + // /// Command routine. + /* rrr : for Dmytro : use name `routine` when former will be extended */ + pub _routine : OnCommand, + } + + impl CommandFormer + { + /// Alias for routine `routine`. + pub fn routine( mut self, src : &'static dyn Fn( &crate::instruction::Instruction ) -> Result< () > ) -> Self + { + self._routine = ::core::option::Option::Some( OnCommand( Some( Rc::new( src ) ) ) ); + self + } + + /// Alias for routine `hint`. + pub fn h( mut self, help : impl AsRef< str > ) -> Self + { + self.hint = Some( help.as_ref().into() ); + self + } + + /// Alias for routine `long_hint`. + pub fn lh( mut self, help : impl AsRef< str > ) -> Self + { + self.long_hint = Some( help.as_ref().into() ); + self + } + + /// Alias for routine `routine`. + pub fn ro( mut self, src : &'static dyn Fn( &crate::instruction::Instruction ) -> Result< () > ) -> Self + { + self._routine = ::core::option::Option::Some( OnCommand( Some( Rc::new( src ) ) ) ); + self + } + + /// Setter for separate properties. + pub fn property_hint< S : AsRef< str > >( mut self, key : S, hint : S ) -> Self + { + let key = key.as_ref(); + let hint = hint.as_ref(); + + if self.properties_hints.is_none() + { + self.properties_hints = Some( HashMap::from([ ( key.into(), hint.into() ) ]) ); + } + else + { + let hmap = self.properties_hints.as_mut().unwrap(); + hmap.insert( key.into(), hint.into() ); + } + self + } + + /// Setter for separate properties aliases. + pub fn property_alias< S : AsRef< str > >( mut self, key : S, alias : S ) -> Self + { + let key = key.as_ref(); + let alias = alias.as_ref(); + + if self.properties_aliases.is_none() + { + self.properties_aliases = Some( HashMap::from([ ( key.into(), vec![ alias.into() ] ) ]) ); + } + else + { + let hmap = self.properties_aliases.as_mut().unwrap(); + if hmap.get( key ).is_some() + { + let vec_aliases = hmap.get_mut( key ).unwrap(); + vec_aliases.push( alias.into() ); + } + else + { + hmap.insert( key.into(), vec![ alias.into() ] ); + } + } + self + } } impl PartialEq for Command @@ -151,52 +231,14 @@ pub( crate ) mod private return Err( BasicError::new( "Unknown option." ) ); } } - if self.routine.callable() + if self._routine.callable() { - return self.routine.perform( instruction ); + return self._routine.perform( instruction ); } Ok( () ) } } - - /// - /// Options for command. - /// - - #[derive( Debug, Clone, Default )] - pub struct CommandOptions - { - ins : Command, - } - - // - - // ro : null, - // h : null, - // lh : null, - - impl CommandOptions - { - field_str!{ hint } - field_str!{ hint, h } - field_str!{ long_hint } - field_str!{ long_hint, lh } - field_str!{ phrase } - field_str!{ subject_hint } - field_str!{ subject_hint, sh } - field_map_str_str!{ properties_hints, property_hint } - field_map_str_vec_str!{ properties_aliases, property_alias } - field_routine!{ routine } - field_routine!{ routine, ro } - - /// Command former. - pub fn form( &self ) -> Command - { - self.ins.clone() - } - - } } // @@ -205,5 +247,5 @@ crate::mod_interface! { prelude use OnCommand; prelude use Command; - prelude use CommandOptions; + prelude use CommandFormer; } diff --git a/rust/impl/ca/ca/common.rs b/rust/impl/ca/ca/common.rs deleted file mode 100644 index 1c1cbd9f1b..0000000000 --- a/rust/impl/ca/ca/common.rs +++ /dev/null @@ -1,119 +0,0 @@ -/// Private namespace of the module. -pub( crate ) mod private -{ - /// - /// Expand field to method of instance. - /// - - #[ macro_export ] - macro_rules! field_str - { - ( $name:ident ) => - { - #[ allow( missing_docs ) ] // qqq : make proper solution, maybe use Former - pub fn $name< Str : AsRef< str > >( &mut self, src : Str ) -> &mut Self - where - String : From - { - self.ins.$name = src.into(); - self - } - }; - ( $name1:ident, $name2:ident ) => - { - #[ allow( missing_docs ) ] // qqq : make proper solution, maybe use Former - pub fn $name2< Str : AsRef< str > >( &mut self, src : Str ) -> &mut Self - where - String : From - { - self.ins.$name1 = src.into(); - self - } - }; - } - - /// - /// Expand field to alias method of instance. - /// - - #[ macro_export ] - macro_rules! field_map_str_str - { - ( $name1:ident, $name2:ident ) => - { - #[ allow( missing_docs ) ] // qqq : make proper solution, maybe use Former - pub fn $name2< Str : AsRef< str > >( &mut self, property : Str, hint : Str ) -> &mut Self - where - String : From - { - self.ins.$name1.insert( property.into(), hint.into() ); - self - } - }; - } - - /// - /// Expand field to method that works with a vector of strings. - /// - - #[ macro_export ] - macro_rules! field_map_str_vec_str - { - ( $name1:ident, $name2:ident ) => - { - #[ allow( missing_docs ) ] // qqq : make proper solution, maybe use Former - pub fn $name2< Str : AsRef< str > >( &mut self, property : Str, alias : Str ) -> &mut Self - where - String : From - { - let entry = self.ins.$name1.entry( property.into() ).or_insert_with( || -> Vec< String > { vec![] } ); - entry.push( alias.into() ); - self - } - }; - } - - /// - /// Expand field to method of instance to setup routine. - /// - - #[ macro_export ] - macro_rules! field_routine - { - ( $name:ident ) => - { - #[ allow( missing_docs ) ] // qqq : make proper solution, maybe use Former - pub fn $name( &mut self, routine : &'static dyn Fn( &crate::instruction::Instruction ) -> Result< () > ) -> &mut Self - { - self.ins.$name = routine.into(); - self - } - }; - ( $name1:ident, $name2:ident ) => - { - #[ allow( missing_docs ) ] // qqq : make proper solution, maybe use Former - pub fn $name2( &mut self, routine : &'static dyn Fn( &crate::instruction::Instruction ) -> Result< () > ) -> &mut Self - { - self.ins.$name1 = routine.into(); - self - } - }; - } - - pub( crate ) use field_str; - pub( crate ) use field_map_str_str; - pub( crate ) use field_map_str_vec_str; - pub( crate ) use field_routine; - -} - -// - -crate::mod_interface! -{ - // qqq : for Dima : bad : list all elements, don't use * for private /* aaa : Dmytro : expanded */ - prelude( crate ) use field_str; - prelude( crate ) use field_map_str_str; - prelude( crate ) use field_map_str_vec_str; - prelude( crate ) use field_routine; -} diff --git a/rust/impl/ca/ca/mod.rs b/rust/impl/ca/ca/mod.rs index a319f9e815..9a242ee2b7 100644 --- a/rust/impl/ca/ca/mod.rs +++ b/rust/impl/ca/ca/mod.rs @@ -3,8 +3,6 @@ crate::mod_interface! { /// Command aggregator. layer commands_aggregator; - /// Common macroses to fill modules. - layer common; /// Handle commands. layer command; /// Get input. diff --git a/rust/impl/ca/wca_lib.rs b/rust/impl/ca/wca_lib.rs index 581a867a7d..6b3c6999e6 100644 --- a/rust/impl/ca/wca_lib.rs +++ b/rust/impl/ca/wca_lib.rs @@ -42,7 +42,7 @@ crate::mod_interface! pub use ca:: { commands_aggregator, - common, + // common, command, input, instruction, From 26b51fa259148d5419d15bbbd59b694881866951 Mon Sep 17 00:00:00 2001 From: dmvict Date: Tue, 2 Aug 2022 08:38:41 +0300 Subject: [PATCH 12/17] Update sample `wca_trivial_sample`, tests, change interface to interface of Former --- rust/test/ca/inc/command_test.rs | 12 ++++++------ rust/test/ca/inc/commands_aggregator_test.rs | 6 +++--- sample/rust/wca_trivial_sample/src/main.rs | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/rust/test/ca/inc/command_test.rs b/rust/test/ca/inc/command_test.rs index d872152dd8..bb060e3f52 100644 --- a/rust/test/ca/inc/command_test.rs +++ b/rust/test/ca/inc/command_test.rs @@ -7,7 +7,7 @@ tests_impls! { fn basic() { - let command = wca::CommandOptions::default() + let command = wca::Command::former() .hint( "hint" ) .long_hint( "long_hint" ) .phrase( "phrase" ) @@ -44,7 +44,7 @@ tests_impls! fn shortcut() { - let command = wca::CommandOptions::default() + let command = wca::Command::former() .h( "hint2" ) .lh( "long_hint2" ) .ro( &| _i : &wca::instruction::Instruction | { println!( "hello" ); Ok( () ) } ) @@ -62,7 +62,7 @@ tests_impls! fn perform_trivial() { - let command = wca::CommandOptions::default() + let command = wca::Command::former() .hint( "hint" ) .long_hint( "long_hint" ) .phrase( "phrase" ) @@ -85,7 +85,7 @@ tests_impls! fn perform_with_subject() { - let command = wca::CommandOptions::default() + let command = wca::Command::former() .hint( "hint" ) .subject_hint( "" ) .routine( &| _i : &wca::instruction::Instruction | { println!( "hello" ); Ok( () ) } ) @@ -96,7 +96,7 @@ tests_impls! let perform = command.perform( &instruction ); assert!( perform.is_err() ); - let command = wca::CommandOptions::default() + let command = wca::Command::former() .hint( "hint" ) .subject_hint( "subject" ) .routine( &| _i : &wca::instruction::Instruction | { println!( "hello" ); Ok( () ) } ) @@ -112,7 +112,7 @@ tests_impls! fn perform_with_props() { - let command = wca::CommandOptions::default() + let command = wca::Command::former() .hint( "hint" ) .long_hint( "long_hint" ) .phrase( "phrase" ) diff --git a/rust/test/ca/inc/commands_aggregator_test.rs b/rust/test/ca/inc/commands_aggregator_test.rs index 6f8df90abb..2cc1bd00f3 100644 --- a/rust/test/ca/inc/commands_aggregator_test.rs +++ b/rust/test/ca/inc/commands_aggregator_test.rs @@ -8,21 +8,21 @@ use wca::string::parse_request::OpType::Primitive; fn commands_form() -> std::collections::HashMap< String, Command > { - let help_command : Command = wca::CommandOptions::default() + let help_command : Command = wca::Command::former() .hint( "Get help." ) .long_hint( "Get help for command [command]" ) .phrase( ".help" ) .subject_hint( "some command" ) .routine( &| _i : &Instruction | { println!( "this is help" ); Ok( () ) } ) .form(); - let list_command : Command = wca::CommandOptions::default() + let list_command : Command = wca::Command::former() .hint( "Get list." ) .long_hint( "Get list of" ) .phrase( ".list" ) .subject_hint( "some subject" ) .routine( &| _i : &Instruction | { println!( "this is list" ); Ok( () ) } ) .form(); - let err_command : Command = wca::CommandOptions::default() + let err_command : Command = wca::Command::former() .hint( "Error." ) .long_hint( "Throw error" ) .phrase( ".error" ) diff --git a/sample/rust/wca_trivial_sample/src/main.rs b/sample/rust/wca_trivial_sample/src/main.rs index 4dd471084c..82474e1bd3 100644 --- a/sample/rust/wca_trivial_sample/src/main.rs +++ b/sample/rust/wca_trivial_sample/src/main.rs @@ -5,7 +5,7 @@ fn main() use wca::*; use wca::instruction::Instruction; - let help_command : Command = wca::CommandOptions::default() + let help_command : Command = wca::Command::former() .hint( "Get help." ) .long_hint( "Get help for command [command]" ) .phrase( ".help" ) From b1aaaff51b74d73b6b97067c657e74830e1b6446 Mon Sep 17 00:00:00 2001 From: dmvict Date: Tue, 2 Aug 2022 08:39:07 +0300 Subject: [PATCH 13/17] Update modules `wtest` and `wpublisher`, use new interface of module `wca` --- rust/impl/publisher/commands/init.rs | 4 ++-- rust/impl/test/commands/init.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rust/impl/publisher/commands/init.rs b/rust/impl/publisher/commands/init.rs index 5f90c91242..508c7bb1a1 100644 --- a/rust/impl/publisher/commands/init.rs +++ b/rust/impl/publisher/commands/init.rs @@ -6,7 +6,7 @@ #[ cfg( feature = "use_std" ) ] pub fn commands_form() -> std::collections::HashMap< String, wca::command::Command > { - let publish_command = wca::CommandOptions::default() + let publish_command = wca::Command::former() .hint( "Publish package on `crates.io`." ) .long_hint( "Publish package on `crates.io`." ) .phrase( "publish" ) @@ -17,7 +17,7 @@ pub fn commands_form() -> std::collections::HashMap< String, wca::command::Comma .routine( &super::publish::publish ) .form(); - let list_command = wca::CommandOptions::default() + let list_command = wca::Command::former() .hint( "List packages." ) .long_hint( "List packages" ) .phrase( "list" ) diff --git a/rust/impl/test/commands/init.rs b/rust/impl/test/commands/init.rs index 3f79a19a33..d60ed42874 100644 --- a/rust/impl/test/commands/init.rs +++ b/rust/impl/test/commands/init.rs @@ -5,7 +5,7 @@ pub fn commands_form() -> std::collections::HashMap< String, wca::command::Command > { - let smoke_command = wca::CommandOptions::default() + let smoke_command = wca::Command::former() .hint( "Perform smoke testing on module." ) .long_hint( "Perform smoke testing on module." ) .phrase( "smoke" ) From e4c317dacb5cd9c6dda3e76a1d68f76ba5d75a2d Mon Sep 17 00:00:00 2001 From: dmvict Date: Tue, 2 Aug 2022 09:32:00 +0300 Subject: [PATCH 14/17] Extend method `instruction_perform` of CommandsAggregator, handle error taking into account properties --- rust/impl/ca/ca/commands_aggregator.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/rust/impl/ca/ca/commands_aggregator.rs b/rust/impl/ca/ca/commands_aggregator.rs index c055010d6d..2024cae028 100644 --- a/rust/impl/ca/ca/commands_aggregator.rs +++ b/rust/impl/ca/ca/commands_aggregator.rs @@ -101,7 +101,13 @@ pub( crate ) mod private .unquoting( true ) .perform(); - self._instruction_perform( &parsed ) + let result = self._instruction_perform( &parsed ); + if result.is_err() && self.changing_exit_code + { + eprintln!( "{}", result.err().unwrap().to_string() ); + std::process::exit( 1 ); + } + result } // @@ -332,11 +338,6 @@ pub( crate ) mod private /// Handle error. fn on_error( &self, err : BasicError ) -> Result< () > { - if self.changing_exit_code - { - /* qqq : implement */ - // unimplemented!(); - } Err( err ) } } From 75ace0040b6ce589a5f85f96e4fbb2666ac344e4 Mon Sep 17 00:00:00 2001 From: dmvict Date: Tue, 2 Aug 2022 10:12:05 +0300 Subject: [PATCH 15/17] Extend submodule `command` of module `wca`, improve implementation of trait `PartialEq` --- rust/impl/ca/ca/command.rs | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/rust/impl/ca/ca/command.rs b/rust/impl/ca/ca/command.rs index 43e46a45e1..c5266b0f5b 100644 --- a/rust/impl/ca/ca/command.rs +++ b/rust/impl/ca/ca/command.rs @@ -57,7 +57,7 @@ pub( crate ) mod private } } - impl From<&'static dyn Fn( &crate::instruction::Instruction ) -> Result< () >> for OnCommand + impl From< &'static dyn Fn( &crate::instruction::Instruction ) -> Result< () > > for OnCommand { fn from( src : &'static dyn Fn( &crate::instruction::Instruction ) -> Result< () > ) -> Self { @@ -79,7 +79,7 @@ pub( crate ) mod private impl fmt::Debug for OnCommand { - fn fmt( &self, f: &mut fmt::Formatter<'_> ) -> fmt::Result + fn fmt( &self, f : &mut fmt::Formatter<'_> ) -> fmt::Result { match self { @@ -89,6 +89,23 @@ pub( crate ) mod private } } + impl PartialEq for OnCommand + { + fn eq( &self, other : &Self ) -> bool + { + match self + { + OnCommand( Option::None ) => + { + if other.0.is_none() + { + return true; + } + false + }, + } + } + /// /// Command descriptor. /// @@ -191,12 +208,14 @@ pub( crate ) mod private impl PartialEq for Command { - /* qqq : for Dmytro : extend */ - fn eq( &self, other: &Self ) -> bool + fn eq( &self, other : &Self ) -> bool { self.hint == other.hint && self.long_hint == other.long_hint && self.subject_hint == other.subject_hint + && self.properties_hints == other.properties_hints + && self.properties_aliases == other.properties_aliases + /* rrr : for Dmytro : try to extend using option OnCommand */ } } From 05b8913b2ce68cbcd75b71a5b8d33d4fd6f21c20 Mon Sep 17 00:00:00 2001 From: f01dab1e Date: Wed, 3 Aug 2022 12:57:47 +0300 Subject: [PATCH 16/17] docs and fmt --- rust/impl/mem/mem.rs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/rust/impl/mem/mem.rs b/rust/impl/mem/mem.rs index 013ee1124c..a6fece990e 100644 --- a/rust/impl/mem/mem.rs +++ b/rust/impl/mem/mem.rs @@ -3,19 +3,25 @@ pub( crate ) mod private { // use crate::protected::*; - /// TODO + /// + /// Are two pointers points on the same data. + /// + /// Does not require arguments to have the same type. + /// + pub fn same_data< T1 : ?Sized, T2 : ?Sized >( src1 : &T1, src2 : &T2 ) -> bool { - extern "C" { fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32; } + extern "C" { fn memcmp( s1 : *const u8, s2 : *const u8, n : usize ) -> i32; } let mem1 = src1 as *const _ as *const u8; let mem2 = src2 as *const _ as *const u8; - if same_size( src1, src2 ) { - unsafe { memcmp( mem1, mem2, core::mem::size_of_val( src1 ) ) == 0 } - } else { - false + if !same_size( src1, src2 ) + { + return false; } + + unsafe { memcmp( mem1, mem2, core::mem::size_of_val( src1 ) ) == 0 } } /* zzz : qqq : implement mem::same_data, comparing data. discuss */ From 57bca92a7d2932e9b3b349752df2992712481d5f Mon Sep 17 00:00:00 2001 From: dmvict Date: Thu, 25 Aug 2022 10:09:12 +0300 Subject: [PATCH 17/17] Add makefile --- Makefile | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..045789c938 --- /dev/null +++ b/Makefile @@ -0,0 +1,115 @@ +# abc def +# === common +# + +# Comma +comma := , + +# Checks two given strings for equality. +eq = $(if $(or $(1),$(2)),$(and $(findstring $(1),$(2)),\ + $(findstring $(2),$(1))),1) + +# +# === Parameters +# + +VERSION ?= $(strip $(shell grep -m1 'version = "' Cargo.toml | cut -d '"' -f2)) + +# +# === Git +# + +# Sync local repostiry. +# +# Usage : +# make git.sync [message='description of changes'] + +git.sync : + git add --all && git commit -am $(message) && git pull + +sync : git.sync + +# +# === General commands +# + +# Generate crates documentation from Rust sources. +# +# Usage : +# make doc [private=(yes|no)] [open=(yes|no)] [clean=(no|yes)] + +doc : +ifeq ($(clean),yes) + @rm -rf target/doc/ +endif + cargo doc --all-features --package editor_tui \ + $(if $(call eq,$(private),no),,--document-private-items) \ + $(if $(call eq,$(open),no),,--open) + +# Format Rust sources with rustfmt. +# +# Usage : +# make fmt [check=(no|yes)] + +fmt : + { find -L module -name *.rs -print0 ; } | xargs -0 rustfmt +nightly $(if $(call eq,$(check),yes),-- --check,) + +# cargo +nightly fmt --all $(if $(call eq,$(check),yes),-- --check,) + +# Lint Rust sources with Clippy. +# +# Usage : +# make lint + +lint : + cargo clippy --all-features -- -D warnings + +# Format nad lint Rust sources. +# +# Usage : +# make lint + +normalize : fmt lint + +# Run project Rust sources with Cargo. +# +# Usage : +# make up + +up : + cargo up + +# Run project Rust sources with Cargo. +# +# Usage : +# make clean + +clean : + cargo clean && rm -rf Cargo.lock && cargo cache -a && cargo update + +# Run Rust tests of project. +# +# Usage : +# make test + +test : + cargo test --all-features + +# Run format link test and tests. +# +# Usage : +# make all + +all : fmt lint test +# +# === .PHONY section +# + +.PHONY : \ + all \ + docs \ + fmt \ + lint \ + test \ + up \ + doc