x-common-lib 0.1.8

DXMesh rust dxc develop library
Documentation
use std::collections::{LinkedList, VecDeque};

use std::future::Future;
use std::io::ErrorKind;
use std::io::{self, Read};
use std::path::{Path, PathBuf};
use std::pin::Pin;
use tokio::fs;
use tokio::fs::File;
use tokio::io::{AsyncReadExt, AsyncWriteExt};

#[allow(dead_code)]
pub async fn is_file_exist(file_path: &str) -> bool {
    match fs::metadata(file_path).await {
        Ok(metadata) => metadata.is_file(),
        Err(_) => false,
    }
}

#[allow(dead_code)]
pub async fn is_dir_exist(dir_path: &str) -> bool {
    match fs::metadata(dir_path).await {
        Ok(metadata) => metadata.is_dir(),
        Err(_) => false,
    }
}

/**

 * 递归创建目录
 */
#[allow(dead_code)]
pub async fn create_dir(dir_path: &str) -> bool {
 
    match fs::create_dir_all(dir_path).await {
        Ok(_) => true,
        Err(_) => false,
    }
}





#[allow(dead_code)]
pub fn get_file_path_dir(file_path: &str) -> Option<String> {
    if let Some(parent) = Path::new(file_path).parent() {
        if let Some(dir) = parent.to_str() {
            Some(dir.to_owned())
        } else {
            None
        }
    } else {
        None
    }
}

#[allow(dead_code)]
pub fn get_absoule_path(file_path: &str) -> Option<String> {
    let relative_path = Path::new(file_path);

    if relative_path.is_relative() {
        let current_dir = std::env::current_dir().unwrap();
        let full_path = current_dir.join(relative_path).canonicalize().unwrap();

        let mut path_buf = PathBuf::new();

        for component in full_path.components() {
            if let Some(str_component) = component.as_os_str().to_str() {
                path_buf.push(str_component);
            }
        }
        let full_path = path_buf.to_string_lossy().into_owned();

        Some(full_path.replace("\\\\?\\", ""))
    } else {
        Some(file_path.to_string())
    }
}

#[allow(dead_code)]
pub async fn create_file(file_path: &str) -> bool {
    if is_file_exist(file_path).await {
        return true;
    }
    let dir_path = get_file_path_dir(file_path);
    if dir_path.is_none() {
        return false;
    }
    let dir_path = dir_path.expect("获取文件夹路径失败!");
    if !create_dir(&dir_path).await {
        return false;
    }
    match File::create(file_path).await {
        Ok(_) => true,
        Err(_) => false,
    }
}

#[allow(dead_code)]
pub fn create_dir_sync(dir_path: &str) -> bool {
  std::fs::create_dir_all(dir_path).unwrap();
  true
}



#[allow(dead_code)]
pub fn create_file_path_sync(file_path: &str) -> bool {

    let dir_path = get_file_path_dir(file_path);
    if dir_path.is_none() {
        return false;
    }
    let dir_path = dir_path.unwrap();

    if Path::new(&dir_path).exists() {
      return true;
    }
    return create_dir_sync(&dir_path);
}

#[allow(dead_code)]
pub async fn write_content_to_file(file_path: &str, content: &str) -> std::io::Result<()> {
    fs::write(file_path, content).await
}

#[allow(dead_code)]
pub async fn read_file_as_string(file_path: &str) -> std::io::Result<String> {
    fs::read_to_string(file_path).await
}

#[allow(dead_code)]
pub async fn get_file_list(dir_path: &str) -> std::io::Result<LinkedList<String>> {
    let mut file_list = LinkedList::new();
    let mut entries = fs::read_dir(dir_path).await?;
    while let Some(entry) = entries.next_entry().await? {
        let file_name = entry.file_name();
        let file_name = file_name.to_string_lossy().to_string();
        file_list.push_back(file_name);
    }
    Ok(file_list)
}

#[allow(dead_code)]
pub async fn get_file_list_recursively(
    dir_path: &str,
    is_add_path: bool,
) -> std::io::Result<LinkedList<String>> {
    let mut dirs_to_explore = VecDeque::new();
    let mut file_list = LinkedList::new();
    let base_path = PathBuf::from(dir_path);
    dirs_to_explore.push_back(base_path.clone());
    while let Some(current_dir) = dirs_to_explore.pop_front() {
        let mut dir_entries = fs::read_dir(current_dir).await?;
        while let Some(entry) = dir_entries.next_entry().await? {
            let path = entry.path();
            if path.is_dir() {
                dirs_to_explore.push_back(path);
            } else {
                if is_add_path {
                    if let Ok(stripped_path) = path.strip_prefix(&base_path) {
                        file_list.push_back(stripped_path.display().to_string());
                    }
                } else {
                    let file_name = entry.file_name();
                    let file_name = file_name.to_string_lossy().to_string();
                    file_list.push_back(file_name);
                }
            }
        }
    }
    Ok(file_list)
}

#[allow(dead_code)]
pub async fn copy_file(source_path: &str, destination_path: &str) -> std::io::Result<()> {
    // 打开源文件和目标文件
    let mut source_file = File::open(source_path).await?;
    if !create_file(destination_path).await {
        // "创建目标文件失败!"
        return Err(io::Error::new(ErrorKind::Other, "创建目标文件失败!"));
    }
    let mut destination_file = File::create(destination_path).await?;
    // 从源文件读取数据并写入目标文件
    let mut buffer = vec![0; 4096];
    loop {
        let bytes_read = source_file.read(&mut buffer).await?;
        if bytes_read == 0 {
            // 已完成拷贝
            break;
        }
        destination_file.write_all(&buffer[..bytes_read]).await?;
    }
    Ok(())
}

#[allow(dead_code)]
pub fn get_file_name_from_path(file_path: &str) -> Option<String> {
    let path = Path::new(file_path);
    // 使用file_name方法获取文件名
    if let Some(file_name) = path.file_name() {
        if let Some(file_name_str) = file_name.to_str() {
            return Some(String::from(file_name_str));
        }
    }
    None
}

#[allow(dead_code)]
pub async fn remove_all_dir(dir_path: &str) -> std::io::Result<()> {
    if !is_dir_exist(dir_path).await {
        return Ok(());
    }
    fs::remove_dir_all(dir_path).await?;
    Ok(())
}

#[allow(dead_code)]
pub fn get_md5(file_path: &str) -> std::io::Result<String> {
    let file = std::fs::File::open(file_path)?;
    let mut reader = std::io::BufReader::new(file);
    let mut context = md5::Context::new();
    let mut buffer = vec![0u8; 4 * 1024 * 1024];
    loop {
        let bytes_read = reader.read(&mut buffer)?;
        if bytes_read == 0 {
            break;
        }
        context.consume(&buffer[..bytes_read]);
    }

    let digest = context.compute();
    Ok(format!("{:x}", digest))
}