Loading

RUST日常使用.md

RUST日常使用

Log日志

依赖:

[dependencies]
log = "0.4.20"
env_logger = "0.10.0"

一般使用:

// 使用RUST_LOG默认或环境变量
env_logger::Builder::from_env(Env::default().default_filter_or("warn")).init();

log::warn!("This is an example message.");

自定义日志格式化实现:

use env_logger::{Builder, Env};
use std::io::Write;

/// 初始化日志输出
/// json_format: 是否使用json格式进行输出
pub fn init_log() {
    let mut builder = Builder::from_env(Env::default().default_filter_or("info"));
    builder.format(|buf, record| {
        let message = record.args().to_string();
        let level = recors.level.as_str();
        writeln!(buf, "{} -- {}", level, message)
    });
    builder.init();
}

// 使用
#[cfg(test)]
mod tests {
    use log::{error};
    use crate::logs::init_log;
    #[test]
    fn test_log() {
        init_log();
        error!("测试");
    }
}

Clap命令行解析

依赖:

[dependencies]
clap = { version = "4.4.6", features = ["derive"] }

基本使用:

use clap::Parser;
use clap::ValueEnum;

/// Simple program to greet a person
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
struct Args {
    /// 源目录
    #[arg(short, long)]
    src_path: String,

    /// 目的目录
    #[arg(short, long)]
    dest_path: String,

    /// 支持的格式 为空表示支持所有格式
    #[arg(short, long)]
    format: Vec<PhotoSuffix>,

    /// 当图片没有exif时,是否使用文件的create time进行时间处理
    #[arg(short, long, default_value_t = false)]
    allow_no_exif: bool,
}

// 图片格式枚举
#[derive(Debug, Eq, Hash, PartialEq, ValueEnum, Clone)]
pub enum PhotoSuffix {
    WEBP,
    JPG,
    JPEG,
    PNG,
    TIFF,
    HEIF,
}

// 使用
fn main() {
    // 1. 命令行解析
    let arg = Args::parse();
}

条件编译

/// 判断两个文件是否为同一分区
/// 如果文件不存在,则会判断此文件所在的文件夹
/// 任何错误,都将返回false
/// 如果为同一分区,则返回true;否则,返回false
#[cfg(not(target_os = "linux"))]
fn same_partition(mut file1: PathBuf, mut file2: PathBuf) -> bool {
	// something
}

fn same_partition2(mut file1: PathBuf, mut file2: PathBuf) -> bool {
    if cfg!(target_os = "linux") {
        // something
    }
}

图片读取

依赖:

[dependencies]
image = { version = "0.24.8", features = ["webp-encoder"] }

使用:

use image::codecs::webp::{WebPEncoder, WebPQuality};
use image::EncodableLayout;
use image::io::Reader as ImageReader;

/// 转换图片为webp格式
pub fn convert(img_path: &str, tmp_file: &mut File) -> Result<()> {
    // 1. 解码图片数据
    let image = if img_path.starts_with("http") {
        let vec = Self::downloads_file(img_path)?;
        ImageReader::new(Cursor::new(vec)).with_guessed_format()?.decode()?
    } else {
        // 解码图片文件
        ImageReader::open(img_path)?.decode()?
    };

    // 2. 转换图片为webp格式
    let mut buf_writer = BufWriter::new(&tmp_file);
    let img_webp = WebPEncoder::new_with_quality(&mut buf_writer, WebPQuality::default());
    img_webp.encode(image.as_bytes(), image.width(), image.height(), image.color())?;

    // 3. 返回
    Ok(())
}

http客户端 - Curl

依赖:

[dependencies]
curl = "0.4.44"

简单下载:

use curl::easy::Easy;

fn downloads_file(url: &str) -> Result<Vec<u8>> {
    let mut buf = Vec::new();
    let mut handle = Easy::new();
    handle.url(url)?;
    handle.show_header(false)?;
    {
        let mut transfer = handle.transfer();
        transfer.write_function(|data| {
            buf.extend_from_slice(data);
            Ok(data.len())
        })?;
        transfer.perform()?;
    }
    Ok(buf)
}

图片exif读取

依赖:

[dependencies]
kamadak-exif = "0.5.5"

使用:

use exif::{DateTime, In, Reader, Tag, Value};
use chrono::{Local};
use anyhow::{Error, Result};

// 读取给定图片文件的exif信息,返回图片的创建时间 格式 2023-10-17
// allow_no_exif: 如果没有exif信息,是否使用图片文件的创建信息
pub fn read_datetime(img: &mut File, allow_no_exif: bool) -> Result<(String, String)> {
    // 1. 打开文件
    let metadata = img.metadata();
    let mut buf_reader = BufReader::new(img);

    // 2. 加载exif
    if let Ok(exif) = Reader::new().read_from_container(&mut buf_reader) {

        // 3. 读取datetime
        if let Some(field) = exif.get_field(Tag::DateTime, In::PRIMARY) {
            if let Value::Ascii(ref data) = field.value {
                if !data.is_empty() {
                    let datetime = DateTime::from_ascii(&data[0])?;
                    return Ok((datetime.year.to_string() ,format!("{}-{:02}-{:02}", datetime.year, datetime.month, datetime.day)));
                }
            }
        }
    }

    // 4. 否则返回文件最后修改时间
    let date = metadata?.created()?;
    if allow_no_exif {
        let dt: chrono::DateTime<Local> = date.into();
        return Ok((dt.format("%Y").to_string(), dt.format("%Y-%m-%d").to_string()));
    }

    return Err(Error::msg("无法获取图片拍摄信息!"));
}
posted @ 2024-03-06 15:46  nsfoxer  阅读(23)  评论(0编辑  收藏  举报