1use alloc::{borrow::Cow, boxed::Box, string::ToString};
4
5#[derive(Debug, thiserror::Error)]
9#[error("{msg}")]
10pub struct ValueError<T> {
11    msg: Cow<'static, str>,
12    value: Box<T>,
13}
14
15impl<T> ValueError<T> {
16    pub fn new(value: T, msg: impl core::fmt::Display) -> Self {
18        Self { msg: Cow::Owned(msg.to_string()), value: Box::new(value) }
19    }
20
21    pub fn new_static(value: T, msg: &'static str) -> Self {
23        Self { msg: Cow::Borrowed(msg), value: Box::new(value) }
24    }
25
26    pub fn convert<U>(self) -> ValueError<U>
28    where
29        U: From<T>,
30    {
31        self.map(U::from)
32    }
33
34    pub fn map<U>(self, f: impl FnOnce(T) -> U) -> ValueError<U> {
36        ValueError { msg: self.msg, value: Box::new(f(*self.value)) }
37    }
38
39    pub fn into_value(self) -> T {
41        *self.value
42    }
43
44    pub const fn value(&self) -> &T {
46        &self.value
47    }
48}