thiserror و anyhow

این thiserror و anyhow crateها به طور گسترده ای برای ساده کردن رسیدگی به خطا استفاده می‌شوند.

  • thiserror is often used in libraries to create custom error types that implement From<T>.
  • اغلب anyhow توسط برنامه‌ها برای کمک به مدیریت خطا در توابع، از جمله افزودن اطلاعات متنی به خطاهای شما، استفاده می‌شود.
use anyhow::{bail, Context, Result};
use std::fs;
use std::io::Read;
use thiserror::Error;

#[derive(Clone, Debug, Eq, Error, PartialEq)]
#[error("هیچ نام‌کاربری در {0} یافت نشد")]
struct EmptyUsernameError(String);

fn read_username(path: &str) -> Result<String> {
    let mut username = String::with_capacity(100);
    fs::File::open(path)
        .with_context(|| format!("{path} باز نشد"))?
        .read_to_string(&mut username)
        .context("شکست در خواندن")?;
    if username.is_empty() {
        bail!(EmptyUsernameError(path.to_string()));
    }
    Ok(username)
}

fn main() {
    //fs::write("config.dat", "").unwrap();
    match read_username("config.dat") {
        Ok(username) => println!("نام‌کاربری: {username}"),
        Err(err) => println!("Error: {err:?}"),
    }
}
This slide should take about 5 minutes.

thiserror

  • ماکرو استخراج Error توسط thiserror ارائه می‌شود و دارای ویژگی‌های مفید زیادی برای کمک به تعریف انواع خطا به روشی فشرده است.
  • ویژگی std::error::Error به طور خودکار مشتق می‌شود.
  • پیام #[error] برای استخراج ویژگی Display استفاده می‌شود.

anyhow

  • anyhow::Error اساساً پوششی (wrapper) در اطرافBox<dyn Error> است. به این ترتیب معمولاً انتخاب خوبی برای API عمومی یک کتابخانه نیست، اما به طور گسترده در برنامه‌های مختلف استفاده می‌شود.
  • anyhow::Result<V>یک type مستعار برای استResult<V, anyhow::Error>.
  • در صورت لزوم می‌توان نوع خطای واقعی داخل آن را برای بررسی استخراج کرد.
  • عملکرد ارائه شده توسط anyhow::Result<T> ممکن است برای توسعه‌دهندگان Go آشنا باشد، زیرا الگوهای استفاده و ارگونومی مشابهی را با (T, error) از Go ارائه می‌دهد.
  • anyhow::Context یک ویژگی است که برای typeهای استاندارد Result و Option پیاده‌سازی شده است. use anyhow::Context برای فعال کردن .context() و .with_context() در آن typeها ضروری است.