anyhow

ΠšΡ€Π΅ΠΉΡ‚ anyhow Π½Π°Π΄Π°Ρ” Π±Π°Π³Π°Ρ‚ΠΈΠΉ Ρ‚ΠΈΠΏ ΠΏΠΎΠΌΠΈΠ»ΠΎΠΊ Π· ΠΏΡ–Π΄Ρ‚Ρ€ΠΈΠΌΠΊΠΎΡŽ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Ρ– Π΄ΠΎΠ΄Π°Ρ‚ΠΊΠΎΠ²ΠΎΡ— контСкстної Ρ–Π½Ρ„ΠΎΡ€ΠΌΠ°Ρ†Ρ–Ρ—, яка ΠΌΠΎΠΆΠ΅ Π±ΡƒΡ‚ΠΈ використана для сСмантичного відстСТСння Π΄Ρ–ΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΈ, Ρ‰ΠΎ ΠΏΡ€ΠΈΠ·Π²Π΅Π»ΠΈ Π΄ΠΎ виникнСння ΠΏΠΎΠΌΠΈΠ»ΠΊΠΈ.

Π¦Π΅ ΠΌΠΎΠΆΠ½Π° ΠΏΠΎΡ”Π΄Π½Π°Ρ‚ΠΈ Π·Ρ– Π·Ρ€ΡƒΡ‡Π½ΠΈΠΌΠΈ макросами Π· thiserror, Ρ‰ΠΎΠ± ΡƒΠ½ΠΈΠΊΠ½ΡƒΡ‚ΠΈ написання Ρ€Π΅Π°Π»Ρ–Π·Π°Ρ†Ρ–ΠΉ Ρ‚Ρ€Π΅ΠΉΡ‚Ρ–Π² явно для ΠΊΠΎΡ€ΠΈΡΡ‚ΡƒΠ²Π°Ρ†ΡŒΠΊΠΈΡ… Ρ‚ΠΈΠΏΡ–Π² ΠΏΠΎΠΌΠΈΠ»ΠΎΠΊ.

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!("Помилка: {err:?}"),
    }
}
This slide should take about 5 minutes.
  • anyhow::Error ΠΏΠΎ суті Ρ” ΠΎΠ±Π³ΠΎΡ€Ρ‚ΠΊΠΎΡŽ Π½Π°Π²ΠΊΠΎΠ»ΠΎ Box<dyn Error>. Π’Π°ΠΊΠΈΠΌ Ρ‡ΠΈΠ½ΠΎΠΌ, Ρ†Π΅ Π·Π½ΠΎΠ²Ρƒ ΠΆ Ρ‚Π°ΠΊΠΈ, як ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ, Π½Π΅ Ρ” Ρ…ΠΎΡ€ΠΎΡˆΠΈΠΌ Π²ΠΈΠ±ΠΎΡ€ΠΎΠΌ для Π·Π°Π³Π°Π»ΡŒΠ½ΠΎΠ΄ΠΎΡΡ‚ΡƒΠΏΠ½ΠΎΠ³ΠΎ API Π±Ρ–Π±Π»Ρ–ΠΎΡ‚Π΅ΠΊΠΈ, Π°Π»Π΅ ΡˆΠΈΡ€ΠΎΠΊΠΎ Π²ΠΈΠΊΠΎΡ€ΠΈΡΡ‚ΠΎΠ²ΡƒΡ”Ρ‚ΡŒΡΡ Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠ°Ρ….
  • anyhow::Result<V> β€” Ρ†Π΅ псСвдонім Ρ‚ΠΈΠΏΡƒ для Result<V, anyhow::Error>.
  • Π€ΡƒΠ½ΠΊΡ†Ρ–ΠΎΠ½Π°Π»ΡŒΠ½Ρ–ΡΡ‚ΡŒ, яку Π½Π°Π΄Π°Ρ” anyhow::Error, ΠΌΠΎΠΆΠ΅ Π±ΡƒΡ‚ΠΈ Π·Π½Π°ΠΉΠΎΠΌΠ° Ρ€ΠΎΠ·Ρ€ΠΎΠ±Π½ΠΈΠΊΠ°ΠΌ Go, ΠΎΡΠΊΡ–Π»ΡŒΠΊΠΈ Π²ΠΎΠ½Π° Π·Π°Π±Π΅Π·ΠΏΠ΅Ρ‡ΡƒΡ” ΠΏΠΎΠ²Π΅Π΄Ρ–Π½ΠΊΡƒ, ΠΏΠΎΠ΄Ρ–Π±Π½Ρƒ Π΄ΠΎ Ρ‚ΠΈΠΏΡƒ Go error, Π° Result<T, anyhow::Error> Π΄ΡƒΠΆΠ΅ схоТа Π½Π° Go (T, error) (Π· ΡƒΠΌΠΎΠ²ΠΎΡŽ, Ρ‰ΠΎ Ρ‚Ρ–Π»ΡŒΠΊΠΈ ΠΎΠ΄ΠΈΠ½ Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚ ΠΏΠ°Ρ€ΠΈ Ρ” Π·Π½Π°Ρ‡ΡƒΡ‰ΠΈΠΌ).
  • anyhow::Context - Ρ†Π΅ Ρ‚Ρ€Π΅ΠΉΡ‚, Ρ€Π΅Π°Π»Ρ–Π·ΠΎΠ²Π°Π½ΠΈΠΉ для стандартних Ρ‚ΠΈΠΏΡ–Π² Result Ρ‚Π° Option. Використання anyhow::Context Π½Π΅ΠΎΠ±Ρ…Ρ–Π΄Π½Π΅ для Ρ‚ΠΎΠ³ΠΎ, Ρ‰ΠΎΠ± Π΄ΠΎΠ·Π²ΠΎΠ»ΠΈΡ‚ΠΈ використання .context() Ρ‚Π° .with_context() для Ρ†ΠΈΡ… Ρ‚ΠΈΠΏΡ–Π².

Π‘Ρ–Π»ΡŒΡˆΠ΅ Ρ–Π½Ρ„ΠΎΡ€ΠΌΠ°Ρ†Ρ–Ρ— для вивчСння

  • anyhow::Error ΠΌΠ°Ρ” ΠΏΡ–Π΄Ρ‚Ρ€ΠΈΠΌΠΊΡƒ даункастингу, ΠΏΠΎΠ΄Ρ–Π±Π½ΠΎ Π΄ΠΎ std::any::Any; ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΈΠΉ Ρ‚ΠΈΠΏ ΠΏΠΎΠΌΠΈΠ»ΠΊΠΈ, Ρ‰ΠΎ Π·Π±Π΅Ρ€Ρ–Π³Π°Ρ”Ρ‚ΡŒΡΡ всСрСдині, ΠΌΠΎΠΆΠ΅ Π±ΡƒΡ‚ΠΈ витягнутий для вивчСння Π·Π° допомогою Error::downcast.