1use std::borrow::Cow;
2use std::ffi::CStr;
3use std::num::NonZeroUsize;
4use std::str::Utf8Error;
5
6#[derive(thiserror::Error, Debug)]
13pub enum VclError {
14 #[error("{0}")]
16 String(String),
17 #[error("{0}")]
19 Str(&'static str),
20 #[error("{}", cstr_to_string(.0))]
22 CStr(&'static CStr),
23 #[error("Unable to allocate {0} bytes in a Workspace")]
25 WsOutOfMemory(NonZeroUsize),
26 #[error("{0}")]
28 Utf8Error(#[from] Utf8Error),
29 #[error("{0}")]
31 Box(#[from] Box<dyn std::error::Error>),
32}
33
34impl VclError {
35 pub fn new(s: String) -> Self {
37 Self::String(s)
38 }
39
40 pub fn as_str(&self) -> Cow<str> {
41 match self {
42 Self::String(s) => Cow::Borrowed(s.as_str()),
43 Self::Utf8Error(e) => Cow::Owned(e.to_string()),
44 Self::Str(s) => Cow::Borrowed(s),
45 Self::Box(e) => Cow::Owned(e.to_string()),
46 Self::CStr(s) => Cow::Owned(cstr_to_string(s)),
47 Self::WsOutOfMemory(sz) => {
48 Cow::Owned(format!("Unable to allocate {sz} bytes in a Workspace"))
49 }
50 }
51 }
52}
53
54fn cstr_to_string(value: &CStr) -> String {
55 match value.to_string_lossy() {
56 Cow::Borrowed(s) => s.to_string(),
57 Cow::Owned(s) => {
58 format!("{s} (error is not exact because it contains non-utf8 characters)")
59 }
60 }
61}
62
63impl From<String> for VclError {
66 fn from(s: String) -> Self {
67 Self::String(s)
68 }
69}
70
71impl From<&'static str> for VclError {
72 fn from(s: &'static str) -> Self {
73 Self::Str(s)
74 }
75}
76
77impl From<&'static CStr> for VclError {
78 fn from(s: &'static CStr) -> Self {
79 Self::CStr(s)
80 }
81}
82
83pub type VclResult<T> = Result<T, VclError>;