Skip to main content

ferroui_dynamic_data/kernel/
error.rs

1//! `Error<TObject, TKey>` (`Kernel/Error.cs`).
2
3use ferroui_system::ObservableError;
4use std::fmt;
5use std::hash::{Hash, Hasher};
6use std::rc::Rc;
7
8/// An item that an operator could not handle, with its key and the error it raised
9/// (`Error<TObject, TKey>`): what the error handler of `TransformSafe` receives.
10pub struct Error<T, K> {
11    exception: Option<ObservableError>,
12    key: K,
13    value: T,
14}
15
16impl<T, K> Error<T, K> {
17    /// `Error(Exception?, TObject value, TKey key)`.
18    pub fn new(exception: Option<ObservableError>, value: T, key: K) -> Self {
19        Self { exception, key, value }
20    }
21
22    /// The error (`Exception`).
23    pub fn exception(&self) -> Option<&ObservableError> {
24        self.exception.as_ref()
25    }
26
27    /// The key of the item (`Key`).
28    pub fn key(&self) -> &K {
29        &self.key
30    }
31
32    /// The item (`Value`).
33    pub fn value(&self) -> &T {
34        &self.value
35    }
36}
37
38impl<T: Clone, K: Clone> Clone for Error<T, K> {
39    fn clone(&self) -> Self {
40        Self { exception: self.exception.clone(), key: self.key.clone(), value: self.value.clone() }
41    }
42}
43
44impl<T: PartialEq, K: PartialEq> PartialEq for Error<T, K> {
45    /// `Equals(Error<TObject, TKey>)`: the same key, an equal item and the same error (the error
46    /// compares by reference, as an `Exception` does).
47    fn eq(&self, other: &Self) -> bool {
48        let same_exception = match (&self.exception, &other.exception) {
49            (None, None) => true,
50            (Some(a), Some(b)) => Rc::ptr_eq(a, b),
51            _ => false,
52        };
53        self.key == other.key && self.value == other.value && same_exception
54    }
55}
56
57impl<T: Eq, K: Eq> Eq for Error<T, K> {}
58
59impl<T: Hash, K: Hash> Hash for Error<T, K> {
60    /// `GetHashCode`: the key, the item and the identity of the error.
61    fn hash<H: Hasher>(&self, state: &mut H) {
62        self.key.hash(state);
63        self.value.hash(state);
64        self.exception.as_ref().map(|exception| Rc::as_ptr(exception) as *const () as usize).hash(state);
65    }
66}
67
68impl<T: fmt::Debug, K: fmt::Debug> fmt::Display for Error<T, K> {
69    /// `ToString`: `Key: {Key}, Value: {Value}, Exception: {Exception}`.
70    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
71        match &self.exception {
72            Some(exception) => write!(f, "Key: {:?}, Value: {:?}, Exception: {}", self.key, self.value, exception),
73            None => write!(f, "Key: {:?}, Value: {:?}, Exception: ", self.key, self.value),
74        }
75    }
76}
77
78impl<T: fmt::Debug, K: fmt::Debug> fmt::Debug for Error<T, K> {
79    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80        fmt::Display::fmt(self, f)
81    }
82}