error.rs

 1//! Crate wrapping what we need from ICU’s C API for JIDs.
 2//!
 3//! See http://site.icu-project.org/
 4
 5use crate::bindings::{icu_error_code_to_name, UErrorCode};
 6use std::ffi::CStr;
 7
 8/// Errors this library can produce.
 9#[derive(Debug)]
10pub enum Error {
11    /// An error produced by one of the ICU functions.
12    Icu(String),
13
14    /// An error produced by one of the IDNA2008 ICU functions.
15    Idna(u32),
16
17    /// Some ICU function didn’t produce a valid UTF-8 string, should never happen.
18    Utf8(std::string::FromUtf8Error),
19
20    /// Some ICU function didn’t produce a valid UTF-8 string, should never happen.
21    Utf16(std::char::DecodeUtf16Error),
22
23    /// Some string was too long for its profile in JID.
24    TooLong,
25}
26
27impl PartialEq for Error {
28    fn eq(&self, other: &Self) -> bool {
29        match (self, other) {
30            (Error::Icu(s1), Error::Icu(s2)) => s1 == s2,
31            (Error::Idna(s1), Error::Idna(s2)) => s1 == s2,
32            // TODO: compare by something here?
33            (Error::Utf8(_s1), Error::Utf8(_s2)) => true,
34            (Error::Utf16(_s1), Error::Utf16(_s2)) => true,
35            (Error::TooLong, Error::TooLong) => true,
36            _ => false,
37        }
38    }
39}
40
41impl Eq for Error {}
42
43impl Error {
44    pub(crate) fn from_icu_code(err: UErrorCode) -> Error {
45        let ptr = unsafe { icu_error_code_to_name(err) };
46        let c_str = unsafe { CStr::from_ptr(ptr) };
47        Error::Icu(c_str.to_string_lossy().into_owned())
48    }
49}
50
51impl From<UErrorCode> for Error {
52    fn from(err: UErrorCode) -> Error {
53        Error::from_icu_code(err)
54    }
55}
56
57impl From<std::string::FromUtf8Error> for Error {
58    fn from(err: std::string::FromUtf8Error) -> Error {
59        Error::Utf8(err)
60    }
61}
62
63impl From<std::char::DecodeUtf16Error> for Error {
64    fn from(err: std::char::DecodeUtf16Error) -> Error {
65        Error::Utf16(err)
66    }
67}