2020-10-15 05:41:37 +13:00
use std ::ffi ::OsString ;
2023-05-03 08:37:12 +12:00
use std ::fs ::{ DirEntry , File , OpenOptions } ;
2022-01-01 10:34:24 +13:00
use std ::io ::BufReader ;
2020-10-15 05:41:37 +13:00
use std ::path ::{ Path , PathBuf } ;
2023-05-03 08:37:12 +12:00
use std ::sync ::atomic ::{ AtomicBool , AtomicUsize , Ordering } ;
use std ::sync ::Arc ;
use std ::thread ::{ sleep , JoinHandle } ;
use std ::time ::{ Duration , SystemTime } ;
use std ::{ fs , thread } ;
2020-09-01 05:37:30 +12:00
2022-07-25 06:48:02 +12:00
#[ cfg(feature = " heif " ) ]
use anyhow ::Result ;
2022-06-01 03:52:55 +12:00
use directories_next ::ProjectDirs ;
2023-05-03 08:37:12 +12:00
use futures ::channel ::mpsc ::UnboundedSender ;
2022-06-01 03:52:55 +12:00
use image ::{ DynamicImage , ImageBuffer , Rgb } ;
use imagepipe ::{ ImageSource , Pipeline } ;
2022-06-09 07:42:51 +12:00
#[ cfg(feature = " heif " ) ]
2023-03-06 08:54:02 +13:00
use libheif_rs ::{ ColorSpace , HeifContext , RgbChroma } ;
2022-06-09 07:42:51 +12:00
2023-05-03 08:37:12 +12:00
// #[cfg(feature = "heif")]
// use libheif_rs::LibHeif;
2023-05-11 07:27:41 +12:00
use crate ::common_dir_traversal ::{ CheckingMethod , ProgressData , ToolType } ;
2023-05-03 08:37:12 +12:00
use crate ::common_directory ::Directories ;
use crate ::common_items ::ExcludedItems ;
2023-05-08 06:54:05 +12:00
use crate ::common_traits ::ResultEntry ;
2023-05-03 08:37:12 +12:00
2023-06-10 08:11:47 +12:00
static NUMBER_OF_THREADS : state ::InitCell < usize > = state ::InitCell ::new ( ) ;
2022-11-26 08:38:27 +13:00
pub fn get_number_of_threads ( ) -> usize {
let data = NUMBER_OF_THREADS . get ( ) ;
if * data > = 1 {
* data
} else {
num_cpus ::get ( )
}
}
2023-05-03 08:37:12 +12:00
2022-11-26 08:38:27 +13:00
pub fn set_default_number_of_threads ( ) {
set_number_of_threads ( num_cpus ::get ( ) ) ;
}
2023-05-03 08:37:12 +12:00
2023-01-29 06:54:02 +13:00
#[ must_use ]
2022-11-26 08:38:27 +13:00
pub fn get_default_number_of_threads ( ) -> usize {
num_cpus ::get ( )
}
2023-05-03 08:37:12 +12:00
2022-11-26 08:38:27 +13:00
pub fn set_number_of_threads ( thread_number : usize ) {
NUMBER_OF_THREADS . set ( thread_number ) ;
rayon ::ThreadPoolBuilder ::new ( ) . num_threads ( get_number_of_threads ( ) ) . build_global ( ) . unwrap ( ) ;
}
2020-09-02 05:34:39 +12:00
/// Class for common functions used across other class/functions
2022-05-17 04:23:07 +12:00
pub const RAW_IMAGE_EXTENSIONS : & [ & str ] = & [
" .mrw " , " .arw " , " .srf " , " .sr2 " , " .mef " , " .orf " , " .srw " , " .erf " , " .kdc " , " .kdc " , " .dcs " , " .rw2 " , " .raf " , " .dcr " , " .dng " , " .pef " , " .crw " , " .iiq " , " .3fr " , " .nrw " , " .nef " , " .mos " ,
" .cr2 " , " .ari " ,
] ;
pub const IMAGE_RS_EXTENSIONS : & [ & str ] = & [
2022-06-09 07:42:51 +12:00
" .jpg " , " .jpeg " , " .png " , " .bmp " , " .tiff " , " .tif " , " .tga " , " .ff " , " .jif " , " .jfi " , " .webp " , " .gif " , " .ico " , " .exr " ,
2022-05-17 04:23:07 +12:00
] ;
2022-06-09 07:42:51 +12:00
pub const IMAGE_RS_SIMILAR_IMAGES_EXTENSIONS : & [ & str ] = & [ " .jpg " , " .jpeg " , " .png " , " .tiff " , " .tif " , " .tga " , " .ff " , " .jif " , " .jfi " , " .bmp " , " .webp " , " .exr " ] ;
2022-05-17 04:23:07 +12:00
pub const IMAGE_RS_BROKEN_FILES_EXTENSIONS : & [ & str ] = & [
2022-06-09 07:42:51 +12:00
" .jpg " , " .jpeg " , " .png " , " .tiff " , " .tif " , " .tga " , " .ff " , " .jif " , " .jfi " , " .gif " , " .bmp " , " .ico " , " .jfif " , " .jpe " , " .pnz " , " .dib " , " .webp " , " .exr " ,
2022-05-17 04:23:07 +12:00
] ;
2022-06-09 07:42:51 +12:00
pub const HEIC_EXTENSIONS : & [ & str ] = & [ " .heif " , " .heifs " , " .heic " , " .heics " , " .avci " , " .avcs " , " .avif " , " .avifs " ] ;
2022-05-17 04:23:07 +12:00
pub const ZIP_FILES_EXTENSIONS : & [ & str ] = & [ " .zip " ] ;
pub const PDF_FILES_EXTENSIONS : & [ & str ] = & [ " .pdf " ] ;
pub const AUDIO_FILES_EXTENSIONS : & [ & str ] = & [
2022-05-31 02:26:27 +12:00
" .mp3 " , " .flac " , " .wav " , " .ogg " , " .m4a " , " .aac " , " .aiff " , " .pcm " , " .aif " , " .aiff " , " .aifc " , " .m3a " , " .mp2 " , " .mp4a " , " .mp2a " , " .mpga " , " .wave " , " .weba " , " .wma " , " .oga " ,
2022-05-17 04:23:07 +12:00
] ;
pub const VIDEO_FILES_EXTENSIONS : & [ & str ] = & [
" .mp4 " , " .mpv " , " .flv " , " .mp4a " , " .webm " , " .mpg " , " .mp2 " , " .mpeg " , " .m4p " , " .m4v " , " .avi " , " .wmv " , " .qt " , " .mov " , " .swf " , " .mkv " ,
] ;
2020-09-02 05:34:39 +12:00
2022-01-14 18:34:43 +13:00
pub const LOOP_DURATION : u32 = 200 ; //ms
2020-09-01 05:37:30 +12:00
pub struct Common ( ) ;
2021-11-28 08:57:10 +13:00
2022-01-06 10:47:27 +13:00
pub fn open_cache_folder ( cache_file_name : & str , save_to_cache : bool , use_json : bool , warnings : & mut Vec < String > ) -> Option < ( ( Option < File > , PathBuf ) , ( Option < File > , PathBuf ) ) > {
if let Some ( proj_dirs ) = ProjectDirs ::from ( " pl " , " Qarmin " , " Czkawka " ) {
let cache_dir = PathBuf ::from ( proj_dirs . cache_dir ( ) ) ;
let cache_file = cache_dir . join ( cache_file_name ) ;
let cache_file_json = cache_dir . join ( cache_file_name . replace ( " .bin " , " .json " ) ) ;
let mut file_handler_default = None ;
let mut file_handler_json = None ;
if save_to_cache {
if cache_dir . exists ( ) {
if ! cache_dir . is_dir ( ) {
warnings . push ( format! ( " Config dir {} is a file! " , cache_dir . display ( ) ) ) ;
return None ;
}
} else if let Err ( e ) = fs ::create_dir_all ( & cache_dir ) {
warnings . push ( format! ( " Cannot create config dir {} , reason {} " , cache_dir . display ( ) , e ) ) ;
return None ;
}
file_handler_default = Some ( match OpenOptions ::new ( ) . truncate ( true ) . write ( true ) . create ( true ) . open ( & cache_file ) {
Ok ( t ) = > t ,
Err ( e ) = > {
warnings . push ( format! ( " Cannot create or open cache file {} , reason {} " , cache_file . display ( ) , e ) ) ;
return None ;
}
} ) ;
if use_json {
file_handler_json = Some ( match OpenOptions ::new ( ) . truncate ( true ) . write ( true ) . create ( true ) . open ( & cache_file_json ) {
Ok ( t ) = > t ,
Err ( e ) = > {
warnings . push ( format! ( " Cannot create or open cache file {} , reason {} " , cache_file_json . display ( ) , e ) ) ;
return None ;
}
} ) ;
}
} else {
if let Ok ( t ) = OpenOptions ::new ( ) . read ( true ) . open ( & cache_file ) {
file_handler_default = Some ( t ) ;
} else {
if use_json {
file_handler_json = Some ( match OpenOptions ::new ( ) . read ( true ) . open ( & cache_file_json ) {
Ok ( t ) = > t ,
Err ( _ ) = > return None ,
} ) ;
} else {
// messages.push(format!("Cannot find or open cache file {}", cache_file.display())); // No error or warning
return None ;
}
}
} ;
return Some ( ( ( file_handler_default , cache_file ) , ( file_handler_json , cache_file_json ) ) ) ;
}
None
}
2022-06-09 07:42:51 +12:00
#[ cfg(feature = " heif " ) ]
pub fn get_dynamic_image_from_heic ( path : & str ) -> Result < DynamicImage > {
2023-04-05 18:08:43 +12:00
// let libheif = LibHeif::new();
2022-06-09 07:42:51 +12:00
let im = HeifContext ::read_from_file ( path ) ? ;
let handle = im . primary_image_handle ( ) ? ;
2023-04-05 18:08:43 +12:00
// let image = libheif.decode(&handle, ColorSpace::Rgb(RgbChroma::Rgb), None)?; // Enable when using libheif 0.19
2023-02-19 22:21:14 +13:00
let image = handle . decode ( ColorSpace ::Rgb ( RgbChroma ::Rgb ) , None ) ? ;
2023-03-06 08:54:02 +13:00
let width = image . width ( ) ;
let height = image . height ( ) ;
2022-06-09 07:42:51 +12:00
let planes = image . planes ( ) ;
let interleaved_plane = planes . interleaved . unwrap ( ) ;
ImageBuffer ::from_raw ( width , height , interleaved_plane . data . to_owned ( ) )
. map ( DynamicImage ::ImageRgb8 )
. ok_or_else ( | | anyhow ::anyhow! ( " Failed to create image buffer " ) )
}
2022-01-01 10:34:24 +13:00
pub fn get_dynamic_image_from_raw_image ( path : impl AsRef < Path > + std ::fmt ::Debug ) -> Option < DynamicImage > {
let file_handler = match OpenOptions ::new ( ) . read ( true ) . open ( & path ) {
Ok ( t ) = > t ,
Err ( _e ) = > {
return None ;
}
} ;
let mut reader = BufReader ::new ( file_handler ) ;
let raw = match rawloader ::decode ( & mut reader ) {
Ok ( raw ) = > raw ,
Err ( _e ) = > {
return None ;
}
} ;
let source = ImageSource ::Raw ( raw ) ;
2022-05-17 04:23:07 +12:00
let mut pipeline = match Pipeline ::new_from_source ( source ) {
2022-01-01 10:34:24 +13:00
Ok ( pipeline ) = > pipeline ,
Err ( _e ) = > {
return None ;
}
} ;
pipeline . run ( None ) ;
let image = match pipeline . output_8bit ( None ) {
Ok ( image ) = > image ,
Err ( _e ) = > {
return None ;
}
} ;
2023-05-03 08:37:12 +12:00
let Some ( image ) = ImageBuffer ::< Rgb < u8 > , Vec < u8 > > ::from_raw ( image . width as u32 , image . height as u32 , image . data ) else {
return None ;
2022-01-01 10:34:24 +13:00
} ;
// println!("Properly hashed {:?}", path);
2022-06-01 03:52:55 +12:00
Some ( DynamicImage ::ImageRgb8 ( image ) )
2022-01-01 10:34:24 +13:00
}
2023-01-29 06:54:02 +13:00
#[ must_use ]
2022-06-05 07:20:21 +12:00
pub fn split_path ( path : & Path ) -> ( String , String ) {
match ( path . parent ( ) , path . file_name ( ) ) {
( Some ( dir ) , Some ( file ) ) = > ( dir . display ( ) . to_string ( ) , file . to_string_lossy ( ) . into_owned ( ) ) ,
( Some ( dir ) , None ) = > ( dir . display ( ) . to_string ( ) , String ::new ( ) ) ,
( None , _ ) = > ( String ::new ( ) , String ::new ( ) ) ,
}
}
2023-01-29 06:54:02 +13:00
#[ must_use ]
2022-07-28 17:29:50 +12:00
pub fn create_crash_message ( library_name : & str , file_path : & str , home_library_url : & str ) -> String {
format! ( " {library_name} library crashed when opening \" {file_path} \" , please check if this is fixed with the latest version of {library_name} (e.g. with https://github.com/qarmin/crates_tester) and if it is not fixed, please report bug here - {home_library_url} " )
}
2020-09-01 05:37:30 +12:00
impl Common {
2020-09-12 23:25:23 +12:00
/// Printing time which took between start and stop point and prints also function name
2020-10-10 09:32:08 +13:00
#[ allow(unused_variables) ]
2023-01-29 06:54:02 +13:00
pub fn print_time ( start_time : SystemTime , end_time : SystemTime , function_name : & str ) {
2020-09-17 22:07:58 +12:00
#[ cfg(debug_assertions) ]
2021-12-22 06:44:20 +13:00
println! (
" Execution of function \" {} \" took {:?} " ,
function_name ,
end_time . duration_since ( start_time ) . expect ( " Time cannot go reverse. " )
) ;
2020-09-01 05:37:30 +12:00
}
2020-09-12 08:32:17 +12:00
2023-01-29 06:54:02 +13:00
#[ must_use ]
2020-09-12 23:25:23 +12:00
pub fn delete_multiple_entries ( entries : & [ String ] ) -> Vec < String > {
let mut path : & Path ;
let mut warnings : Vec < String > = Vec ::new ( ) ;
for entry in entries {
path = Path ::new ( entry ) ;
if path . is_dir ( ) {
2022-11-24 08:23:17 +13:00
if let Err ( e ) = fs ::remove_dir_all ( entry ) {
2022-12-21 20:44:26 +13:00
warnings . push ( format! ( " Failed to remove folder {entry} , reason {e} " ) ) ;
2020-09-12 23:25:23 +12:00
}
2022-11-24 08:23:17 +13:00
} else if let Err ( e ) = fs ::remove_file ( entry ) {
2022-12-21 20:44:26 +13:00
warnings . push ( format! ( " Failed to remove file {entry} , reason {e} " ) ) ;
2020-09-12 23:25:23 +12:00
}
}
warnings
}
2023-01-29 06:54:02 +13:00
#[ must_use ]
2020-09-12 23:25:23 +12:00
pub fn delete_one_entry ( entry : & str ) -> String {
let path : & Path = Path ::new ( entry ) ;
2023-01-29 06:54:02 +13:00
let mut warning : String = String ::new ( ) ;
2020-09-16 05:17:13 +12:00
if path . is_dir ( ) {
2022-11-24 08:23:17 +13:00
if let Err ( e ) = fs ::remove_dir_all ( entry ) {
2023-01-29 06:54:02 +13:00
warning = format! ( " Failed to remove folder {entry} , reason {e} " ) ;
2020-09-16 05:17:13 +12:00
}
2022-11-24 08:23:17 +13:00
} else if let Err ( e ) = fs ::remove_file ( entry ) {
2023-01-29 06:54:02 +13:00
warning = format! ( " Failed to remove file {entry} , reason {e} " ) ;
2020-09-12 23:25:23 +12:00
}
warning
}
2020-09-12 08:32:17 +12:00
/// Function to check if directory match expression
2023-05-03 08:37:12 +12:00
#[ must_use ]
2020-10-15 05:41:37 +13:00
pub fn regex_check ( expression : & str , directory : impl AsRef < Path > ) -> bool {
2021-12-03 01:31:10 +13:00
if expression = = " * " {
return true ;
}
2020-09-12 08:32:17 +12:00
let temp_splits : Vec < & str > = expression . split ( '*' ) . collect ( ) ;
let mut splits : Vec < & str > = Vec ::new ( ) ;
for i in temp_splits {
2021-01-01 07:53:49 +13:00
if ! i . is_empty ( ) {
2020-09-12 08:32:17 +12:00
splits . push ( i ) ;
}
}
if splits . is_empty ( ) {
return false ;
}
2020-10-15 05:41:37 +13:00
// Get rid of non unicode characters
let directory = directory . as_ref ( ) . to_string_lossy ( ) ;
2020-09-12 08:32:17 +12:00
// Early checking if directory contains all parts needed by expression
for split in & splits {
if ! directory . contains ( split ) {
return false ;
}
}
let mut position_of_splits : Vec < usize > = Vec ::new ( ) ;
// `git*` shouldn't be true for `/gitsfafasfs`
2022-11-24 08:23:17 +13:00
if ! expression . starts_with ( '*' ) & & directory . find ( splits [ 0 ] ) . unwrap ( ) > 0 {
2020-09-12 08:32:17 +12:00
return false ;
}
// `*home` shouldn't be true for `/homeowner`
if ! expression . ends_with ( '*' ) & & ! directory . ends_with ( splits . last ( ) . unwrap ( ) ) {
return false ;
}
// At the end we check if parts between * are correctly positioned
2022-11-24 08:23:17 +13:00
position_of_splits . push ( directory . find ( splits [ 0 ] ) . unwrap ( ) ) ;
2020-09-12 08:32:17 +12:00
let mut current_index : usize ;
let mut found_index : usize ;
for i in splits [ 1 .. ] . iter ( ) . enumerate ( ) {
current_index = * position_of_splits . get ( i . 0 ) . unwrap ( ) + i . 1. len ( ) ;
found_index = match directory [ current_index .. ] . find ( i . 1 ) {
Some ( t ) = > t ,
None = > return false ,
} ;
position_of_splits . push ( found_index + current_index ) ;
}
true
}
2020-10-15 05:41:37 +13:00
2023-05-03 08:37:12 +12:00
#[ must_use ]
2020-10-15 05:41:37 +13:00
pub fn normalize_windows_path ( path_to_change : impl AsRef < Path > ) -> PathBuf {
let path = path_to_change . as_ref ( ) ;
2020-12-31 01:41:18 +13:00
// Don't do anything, because network path may be case intensive
if path . to_string_lossy ( ) . starts_with ( '\\' ) {
return path . to_path_buf ( ) ;
}
2020-10-15 05:41:37 +13:00
match path . to_str ( ) {
Some ( path ) if path . is_char_boundary ( 1 ) = > {
2021-12-19 11:45:37 +13:00
let replaced = path . replace ( '/' , " \\ " ) ;
2020-10-15 05:41:37 +13:00
let mut new_path = OsString ::new ( ) ;
if replaced [ 1 .. ] . starts_with ( ':' ) {
new_path . push ( replaced [ .. 1 ] . to_ascii_uppercase ( ) ) ;
new_path . push ( replaced [ 1 .. ] . to_ascii_lowercase ( ) ) ;
} else {
new_path . push ( replaced . to_ascii_lowercase ( ) ) ;
}
PathBuf ::from ( new_path )
}
_ = > path . to_path_buf ( ) ,
}
2020-10-11 02:18:04 +13:00
}
2020-09-12 08:32:17 +12:00
}
2020-09-18 17:32:37 +12:00
2023-05-03 08:37:12 +12:00
pub fn check_folder_children (
dir_result : & mut Vec < PathBuf > ,
warnings : & mut Vec < String > ,
current_folder : & Path ,
entry_data : & DirEntry ,
recursive_search : bool ,
directories : & Directories ,
excluded_items : & ExcludedItems ,
) {
if ! recursive_search {
return ;
}
let next_folder = current_folder . join ( entry_data . file_name ( ) ) ;
if directories . is_excluded ( & next_folder ) {
return ;
}
if excluded_items . is_excluded ( & next_folder ) {
return ;
}
#[ cfg(target_family = " unix " ) ]
if directories . exclude_other_filesystems ( ) {
match directories . is_on_other_filesystems ( & next_folder ) {
Ok ( true ) = > return ,
Err ( e ) = > warnings . push ( e ) ,
_ = > ( ) ,
}
}
dir_result . push ( next_folder ) ;
}
2023-05-08 06:54:05 +12:00
#[ must_use ]
pub fn filter_reference_folders_generic < T > ( entries_to_check : Vec < Vec < T > > , directories : & Directories ) -> Vec < ( T , Vec < T > ) >
where
T : ResultEntry ,
{
entries_to_check
. into_iter ( )
. filter_map ( | vec_file_entry | {
let ( mut files_from_referenced_folders , normal_files ) : ( Vec < _ > , Vec < _ > ) =
vec_file_entry . into_iter ( ) . partition ( | e | directories . is_in_referenced_directory ( e . get_path ( ) ) ) ;
if files_from_referenced_folders . is_empty ( ) | | normal_files . is_empty ( ) {
None
} else {
Some ( ( files_from_referenced_folders . pop ( ) . unwrap ( ) , normal_files ) )
}
} )
. collect ::< Vec < ( T , Vec < T > ) > > ( )
}
#[ must_use ]
2023-05-03 08:37:12 +12:00
pub fn prepare_thread_handler_common (
progress_sender : Option < & UnboundedSender < ProgressData > > ,
current_stage : u8 ,
max_stage : u8 ,
max_value : usize ,
checking_method : CheckingMethod ,
2023-05-11 07:27:41 +12:00
tool_type : ToolType ,
2023-05-08 06:54:05 +12:00
) -> ( JoinHandle < ( ) > , Arc < AtomicBool > , Arc < AtomicUsize > , AtomicBool ) {
let progress_thread_run = Arc ::new ( AtomicBool ::new ( true ) ) ;
let atomic_counter = Arc ::new ( AtomicUsize ::new ( 0 ) ) ;
let check_was_stopped = AtomicBool ::new ( false ) ;
let progress_thread_sender = if let Some ( progress_sender ) = progress_sender {
2023-05-03 08:37:12 +12:00
let progress_send = progress_sender . clone ( ) ;
let progress_thread_run = progress_thread_run . clone ( ) ;
let atomic_counter = atomic_counter . clone ( ) ;
thread ::spawn ( move | | loop {
progress_send
. unbounded_send ( ProgressData {
checking_method ,
current_stage ,
max_stage ,
entries_checked : atomic_counter . load ( Ordering ::Relaxed ) ,
entries_to_check : max_value ,
2023-05-11 07:27:41 +12:00
tool_type ,
2023-05-03 08:37:12 +12:00
} )
. unwrap ( ) ;
if ! progress_thread_run . load ( Ordering ::Relaxed ) {
break ;
}
sleep ( Duration ::from_millis ( LOOP_DURATION as u64 ) ) ;
} )
} else {
thread ::spawn ( | | { } )
2023-05-08 06:54:05 +12:00
} ;
( progress_thread_sender , progress_thread_run , atomic_counter , check_was_stopped )
2023-05-03 08:37:12 +12:00
}
pub fn send_info_and_wait_for_ending_all_threads ( progress_thread_run : & Arc < AtomicBool > , progress_thread_handle : JoinHandle < ( ) > ) {
progress_thread_run . store ( false , Ordering ::Relaxed ) ;
progress_thread_handle . join ( ) . unwrap ( ) ;
}
2020-09-12 08:32:17 +12:00
#[ cfg(test) ]
mod test {
2020-10-15 05:41:37 +13:00
use std ::path ::PathBuf ;
2020-09-12 08:32:17 +12:00
2021-11-28 08:49:20 +13:00
use crate ::common ::Common ;
2020-09-12 08:32:17 +12:00
#[ test ]
fn test_regex ( ) {
assert! ( Common ::regex_check ( " *home* " , " /home/rafal " ) ) ;
assert! ( Common ::regex_check ( " *home " , " /home " ) ) ;
assert! ( Common ::regex_check ( " *home/ " , " /home/ " ) ) ;
assert! ( Common ::regex_check ( " *home/* " , " /home/ " ) ) ;
assert! ( Common ::regex_check ( " *.git* " , " /home/.git " ) ) ;
assert! ( Common ::regex_check ( " */home/rafal*rafal*rafal*rafal* " , " /home/rafal/rafalrafalrafal " ) ) ;
2020-12-15 01:07:35 +13:00
assert! ( Common ::regex_check ( " AAA " , " AAA " ) ) ;
assert! ( Common ::regex_check ( " AAA* " , " AAABDGG/QQPW* " ) ) ;
2020-09-12 08:32:17 +12:00
assert! ( ! Common ::regex_check ( " *home " , " /home/ " ) ) ;
assert! ( ! Common ::regex_check ( " *home " , " /homefasfasfasfasf/ " ) ) ;
assert! ( ! Common ::regex_check ( " *home " , " /homefasfasfasfasf " ) ) ;
assert! ( ! Common ::regex_check ( " rafal*afal*fal " , " rafal " ) ) ;
2020-09-17 23:35:11 +12:00
assert! ( ! Common ::regex_check ( " rafal*a " , " rafal " ) ) ;
2020-09-12 08:32:17 +12:00
assert! ( ! Common ::regex_check ( " AAAAAAAA**** " , " /AAAAAAAAAAAAAAAAA " ) ) ;
assert! ( ! Common ::regex_check ( " *.git/* " , " /home/.git " ) ) ;
assert! ( ! Common ::regex_check ( " *home/*koc " , " /koc/home/ " ) ) ;
assert! ( ! Common ::regex_check ( " *home/ " , " /home " ) ) ;
assert! ( ! Common ::regex_check ( " *TTT " , " /GGG " ) ) ;
2021-05-09 07:54:01 +12:00
#[ cfg(target_family = " windows " ) ]
{
assert! ( Common ::regex_check ( " * \\ home " , " C: \\ home " ) ) ;
assert! ( Common ::regex_check ( " */home " , " C: \\ home " ) ) ;
}
2020-09-12 08:32:17 +12:00
}
2021-11-28 08:57:10 +13:00
2020-10-11 02:18:04 +13:00
#[ test ]
fn test_windows_path ( ) {
2020-12-22 06:22:59 +13:00
assert_eq! ( PathBuf ::from ( " C: \\ path.txt " ) , Common ::normalize_windows_path ( " c:/PATH.tXt " ) ) ;
assert_eq! ( PathBuf ::from ( " H: \\ reka \\ weza \\ roman.txt " ) , Common ::normalize_windows_path ( " h:/RekA/Weza \\ roMan.Txt " ) ) ;
assert_eq! ( PathBuf ::from ( " T: \\ a " ) , Common ::normalize_windows_path ( " T: \\ A " ) ) ;
2020-12-31 01:41:18 +13:00
assert_eq! ( PathBuf ::from ( " \\ \\ aBBa " ) , Common ::normalize_windows_path ( " \\ \\ aBBa " ) ) ;
assert_eq! ( PathBuf ::from ( " a " ) , Common ::normalize_windows_path ( " a " ) ) ;
assert_eq! ( PathBuf ::from ( " " ) , Common ::normalize_windows_path ( " " ) ) ;
2020-10-11 02:18:04 +13:00
}
2020-09-01 05:37:30 +12:00
}