Skip to main content

fre_rs/
error.rs

1use super::*;
2
3
4#[derive(Debug, Clone, Copy)]
5pub enum ExternalError<'a> {
6    C(FfiError),
7
8    /// May be [`None`] if the thrown object is ignored or unavailable.
9    ActionScript(Option<Object<'a>>),
10}
11impl<'a> ExternalError<'a> {
12    /// Attempts to convert a [`FREResult`] into [`ExternalError`].
13    ///
14    /// If the result represents an AS3 error and `thrown` is [`Some`],
15    /// the provided object is used as the error object.
16    ///
17    /// If `thrown` is [`None`], the thrown object is ignored or unavailable.
18    ///
19    /// When an AS3 throw occurs, the provided object is assumed to be a valid [`Object`].
20    /// However, AS3 may throw [`as3::null`].
21    /// 
22    pub fn try_from (result: FREResult, thrown: Option<Object<'a>>) -> Option<Self> {
23        let r = <Self as TryFrom<FREResult>>::try_from(result);
24        if let Ok(Self::ActionScript(_)) = r {
25            Some(Self::ActionScript(thrown))
26        }else{
27            r.ok()
28        }
29    }
30}
31impl From<FfiError> for ExternalError<'_> {
32    fn from(value: FfiError) -> Self {Self::C(value)}
33}
34impl TryFrom<FREResult> for ExternalError<'_> {
35    type Error = ();
36    fn try_from(value: FREResult) -> Result<Self, ()> {
37        FfiError::try_from(value).map(|e|{
38            if let FfiError::UnexpectedResult(v)=e && v==FREResult::FRE_ACTIONSCRIPT_ERROR {
39                Self::ActionScript(None)
40            }else{e.into()}
41        })
42    }
43}
44impl Display for ExternalError<'_> {
45    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46        match *self {
47            Self::C(ref err) => Display::fmt(err, f),
48            Self::ActionScript(thrown) => {
49                const PREFIX: &str = "[ExternalError]";
50                if let Some(thrown) = thrown {
51                    write!(f, "{PREFIX} An ActionScript error occurred, and an object was thrown: {thrown}")
52                } else {
53                    write!(f, "{PREFIX} An ActionScript error occurred, but the thrown object was ignored or unavailable.")
54                }
55            },
56        }
57    }
58}
59
60
61#[derive(Debug, Clone, Copy, PartialEq, Eq)]
62pub enum FfiError {
63    NoSuchName,
64    InvalidObject,
65    TypeMismatch,
66    InvalidArgument,
67    ReadOnly,
68    WrongThread,
69    IllegalState,
70    InsufficientMemory,
71    UnexpectedResult(FREResult),
72}
73impl Display for FfiError {
74    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75        const PREFIX: &str = "[FfiError]";
76        match *self {
77            FfiError::NoSuchName => write!(f, "{PREFIX} The name of a class, property, or method passed as a parameter does not match an ActionScript class name, property, or method."),
78            FfiError::InvalidObject => write!(f, "{PREFIX} An FREObject parameter is invalid. For examples of invalid FREObject variables, see 'FREObject validity'. https://help.adobe.com/en_US/air/extensions/WS460ee381960520ad-866f9c112aa6e1ad46-7ff9.html"),
79            FfiError::TypeMismatch => write!(f, "{PREFIX} An FREObject parameter does not represent an object of the ActionScript class expected by the called function."),
80            FfiError::InvalidArgument => write!(f, "{PREFIX} A pointer parameter is `NULL`."),
81            FfiError::ReadOnly => write!(f, "{PREFIX} The function attempted to modify a read-only property of an ActionScript object."),
82            FfiError::WrongThread => write!(f, "{PREFIX} The method was called from a thread other than the one on which the runtime has an outstanding call to a native extension function."),
83            FfiError::IllegalState => write!(f, "{PREFIX} A call was made to a native extensions C API function when the extension context was in an illegal state for that call. This return value occurs in the following situation. The context has acquired access to an ActionScript BitmapData or ByteArray class object. With one exception, the context can call no other C API functions until it releases the BitmapData or ByteArray object. The one exception is that the context can call `FREInvalidateBitmapDataRect()` after calling `FREAcquireBitmapData()` or `FREAcquireBitmapData2()`."),
84            FfiError::InsufficientMemory => write!(f, "{PREFIX} The runtime could not allocate enough memory to change the size of an Array or Vector object."),
85            FfiError::UnexpectedResult(code) => write!(f, "{PREFIX} Unexpected FREResult({code})."),
86        }
87    }
88}
89impl std::error::Error for FfiError {}
90impl TryFrom<FREResult> for FfiError {
91    type Error = ();
92
93    /// Converts a [`FREResult`] into [`FfiError`].
94    ///
95    /// Assumes `value` is **not** [`FREResult::FRE_ACTIONSCRIPT_ERROR`].
96    /// If it is, it will be treated as an unexpected result.
97    /// 
98    fn try_from(value: FREResult) -> Result<Self, ()> {
99        Ok(match value {
100            FREResult::FRE_OK => return Err(()),
101            FREResult::FRE_INVALID_OBJECT => Self::InvalidObject,
102            FREResult::FRE_TYPE_MISMATCH => Self::TypeMismatch,
103            FREResult::FRE_INVALID_ARGUMENT => Self::InvalidArgument,
104            FREResult::FRE_READ_ONLY => Self::ReadOnly,
105            FREResult::FRE_WRONG_THREAD => Self::WrongThread,
106            FREResult::FRE_ILLEGAL_STATE => Self::IllegalState,
107            FREResult::FRE_INSUFFICIENT_MEMORY => Self::InsufficientMemory,
108            _ => Self::UnexpectedResult(value),
109        })
110    }
111}
112
113
114#[derive(Debug, Clone, Copy, PartialEq, Eq)]
115pub enum ContextError {
116    InvalidContext,
117    NullRegistry,
118    InvalidRegistry,
119    MethodsNotRegistered,
120    MethodNotFound,
121    FfiCallFailed(FfiError),
122    BorrowRegistryConflict,
123    ContextConflict,
124}
125impl Display for ContextError {
126    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127        write!(f, "[ContextError] {self:?}")
128    }
129}
130impl std::error::Error for ContextError {}
131impl From<FfiError> for ContextError {
132    fn from(value: FfiError) -> Self {Self::FfiCallFailed(value)}
133}
134