Skip to main content

libghostty_vt/
error.rs

1//! Error handling.
2use std::mem::MaybeUninit;
3
4use crate::ffi;
5
6/// Convenient alias for fallible return values from libghostty-vt.
7pub type Result<T> = std::result::Result<T, Error>;
8
9/// Possible errors libghostty-vt may return.
10#[derive(Debug, Clone, Copy)]
11pub enum Error {
12    /// Out of memory.
13    OutOfMemory,
14    /// Invalid value was specified or returned.
15    InvalidValue,
16    /// Ran out of space when writing to a buffer.
17    OutOfSpace {
18        /// Required minimum size of the buffer.
19        required: usize,
20    },
21}
22
23impl std::fmt::Display for Error {
24    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25        match self {
26            Self::OutOfMemory => write!(f, "out of memory"),
27            Self::InvalidValue => write!(f, "invalid value"),
28            Self::OutOfSpace { required } => {
29                write!(f, "out of space, {required} bytes required")
30            }
31        }
32    }
33}
34
35impl std::error::Error for Error {}
36
37pub(crate) fn from_result(code: ffi::Result::Type) -> Result<()> {
38    match code {
39        ffi::Result::SUCCESS => Ok(()),
40        ffi::Result::OUT_OF_MEMORY => Err(Error::OutOfMemory),
41        ffi::Result::OUT_OF_SPACE => Err(Error::OutOfSpace { required: 0 }),
42        _ => Err(Error::InvalidValue),
43    }
44}
45
46pub(crate) fn from_optional_result_uninit<T>(
47    code: ffi::Result::Type,
48    v: MaybeUninit<T>,
49) -> Result<Option<T>> {
50    match code {
51        // SAFETY: Value should be initialized after successful call.
52        ffi::Result::SUCCESS => Ok(Some(unsafe { v.assume_init() })),
53        ffi::Result::OUT_OF_MEMORY => Err(Error::OutOfMemory),
54        ffi::Result::OUT_OF_SPACE => Err(Error::OutOfSpace { required: 0 }),
55        ffi::Result::NO_VALUE => Ok(None),
56        _ => Err(Error::InvalidValue),
57    }
58}
59
60pub(crate) fn from_optional_result<T>(code: ffi::Result::Type, v: T) -> Result<Option<T>> {
61    match code {
62        // SAFETY: Value should be initialized after successful call.
63        ffi::Result::SUCCESS => Ok(Some(v)),
64        ffi::Result::OUT_OF_MEMORY => Err(Error::OutOfMemory),
65        ffi::Result::OUT_OF_SPACE => Err(Error::OutOfSpace { required: 0 }),
66        ffi::Result::NO_VALUE => Ok(None),
67        _ => Err(Error::InvalidValue),
68    }
69}
70
71pub(crate) fn from_result_with_len(code: ffi::Result::Type, len: usize) -> Result<usize> {
72    match code {
73        ffi::Result::SUCCESS => Ok(len),
74        ffi::Result::OUT_OF_MEMORY => Err(Error::OutOfMemory),
75        ffi::Result::OUT_OF_SPACE => Err(Error::OutOfSpace { required: len }),
76        _ => Err(Error::InvalidValue),
77    }
78}
79
80pub(crate) fn from_optional_result_with_len(
81    code: ffi::Result::Type,
82    len: usize,
83) -> Result<Option<usize>> {
84    match code {
85        ffi::Result::SUCCESS => Ok(Some(len)),
86        ffi::Result::OUT_OF_MEMORY => Err(Error::OutOfMemory),
87        ffi::Result::OUT_OF_SPACE => Err(Error::OutOfSpace { required: len }),
88        ffi::Result::NO_VALUE => Ok(None),
89        _ => Err(Error::InvalidValue),
90    }
91}