clack_plugin/factory/error.rs
1use clap_sys::ext::log::{
2 CLAP_LOG_ERROR, CLAP_LOG_HOST_MISBEHAVING, CLAP_LOG_PLUGIN_MISBEHAVING, clap_log_severity,
3};
4use std::error::Error;
5use std::fmt::{Display, Formatter};
6
7/// Errors raised by a [`FactoryWrapper`](super::wrapper::FactoryWrapper).
8#[derive(Debug)]
9#[non_exhaustive]
10pub enum FactoryWrapperError {
11 /// The factory raw pointer was null.
12 NullFactoryInstance,
13 /// An unexpectedly null raw pointer was encountered.
14 ///
15 /// The given string may contain more information about which pointer was found to be null.
16 NulPtr(&'static str),
17 /// The plugin factory panicked during a function call.
18 Panic,
19 /// A generic or custom error of a given severity.
20 Error(clap_log_severity, Box<dyn Error>),
21}
22
23impl FactoryWrapperError {
24 /// Returns the severity of this error.
25 ///
26 /// This is mainly useful for logging.
27 ///
28 /// # Example
29 ///
30 /// ```
31 /// use clap_sys::ext::log::CLAP_LOG_PLUGIN_MISBEHAVING;
32 /// use clack_plugin::extensions::wrapper::PluginWrapperError;
33 /// let error = PluginWrapperError::Panic;
34 ///
35 /// assert_eq!(error.severity(), CLAP_LOG_PLUGIN_MISBEHAVING);
36 /// ```
37 pub fn severity(&self) -> clap_log_severity {
38 match self {
39 FactoryWrapperError::Panic => CLAP_LOG_PLUGIN_MISBEHAVING,
40 FactoryWrapperError::Error(s, _) => *s,
41 _ => CLAP_LOG_HOST_MISBEHAVING,
42 }
43 }
44
45 /// Returns a closure that maps an error to a [`FactoryWrapperError::Error`] error of a given
46 /// severity.
47 ///
48 /// This is a useful helper method when paired with [`Result::map_err`].
49 ///
50 /// # Example
51 /// ```
52 /// use clap_sys::ext::log::CLAP_LOG_PLUGIN_MISBEHAVING;
53 /// use clack_plugin::extensions::wrapper::PluginWrapperError;
54 ///
55 /// let x: Result<(), _> = Err(std::env::VarError::NotPresent); // Some random error type
56 /// let clap_error = x.map_err(PluginWrapperError::with_severity(CLAP_LOG_PLUGIN_MISBEHAVING));
57 ///
58 /// assert_eq!(clap_error.unwrap_err().severity(), CLAP_LOG_PLUGIN_MISBEHAVING);
59 /// ```
60 #[inline]
61 pub fn with_severity<E: 'static + Error>(
62 severity: clap_log_severity,
63 ) -> impl Fn(E) -> FactoryWrapperError {
64 move |e| FactoryWrapperError::Error(severity, Box::new(e))
65 }
66}
67
68impl Display for FactoryWrapperError {
69 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
70 use FactoryWrapperError::*;
71 match self {
72 NullFactoryInstance => f.write_str(
73 "Plugin factory method was called with null clap_plugin_factory pointer",
74 ),
75 NulPtr(ptr_name) => {
76 write!(
77 f,
78 "Plugin factory method was called with null {ptr_name} pointer"
79 )
80 }
81 Error(_, e) => std::fmt::Display::fmt(e, f),
82 Panic => f.write_str("Plugin factory panicked"),
83 }
84 }
85}
86
87impl<E: Error + 'static> From<E> for FactoryWrapperError {
88 fn from(value: E) -> Self {
89 Self::Error(CLAP_LOG_ERROR, Box::new(value))
90 }
91}