Skip to content

Commit

Permalink
Merge pull request #4 from tmandry/type-error
Browse files Browse the repository at this point in the history
Check attribute types for safety
  • Loading branch information
eiz authored Jan 29, 2024
2 parents 8812e50 + a2ccee3 commit 589d55a
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 5 deletions.
22 changes: 22 additions & 0 deletions accessibility-sys/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,25 @@ pub const kAXErrorAPIDisabled: i32 = -25211;
pub const kAXErrorNoValue: i32 = -25212;
pub const kAXErrorParameterizedAttributeUnsupported: i32 = -25213;
pub const kAXErrorNotEnoughPrecision: i32 = -25214;

pub fn error_string(error: AXError) -> &'static str {
match error {
kAXErrorSuccess => "kAXErrorSuccess",
kAXErrorFailure => "kAXErrorFailure",
kAXErrorIllegalArgument => "kAXErrorIllegalArgument",
kAXErrorInvalidUIElement => "kAXErrorInvalidUIElement",
kAXErrorInvalidUIElementObserver => "kAXErrorInvalidUIElementObserver",
kAXErrorCannotComplete => "kAXErrorCannotComplete",
kAXErrorAttributeUnsupported => "kAXErrorAttributeUnsupported",
kAXErrorActionUnsupported => "kAXErrorActionUnsupported",
kAXErrorNotificationUnsupported => "kAXErrorNotificationUnsupported",
kAXErrorNotImplemented => "kAXErrorNotImplemented",
kAXErrorNotificationAlreadyRegistered => "kAXErrorNotificationAlreadyRegistered",
kAXErrorNotificationNotRegistered => "kAXErrorNotificationNotRegistered",
kAXErrorAPIDisabled => "kAXErrorAPIDisabled",
kAXErrorNoValue => "kAXErrorNoValue",
kAXErrorParameterizedAttributeUnsupported => "kAXErrorParameterizedAttributeUnsupported",
kAXErrorNotEnoughPrecision => "kAXErrorNotEnoughPrecision",
_ => "unknown error",
}
}
25 changes: 22 additions & 3 deletions accessibility/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@ pub mod attribute;
pub mod ui_element;
mod util;

use accessibility_sys::AXError;
use core_foundation::{array::CFArray, base::TCFType, string::CFString};
use accessibility_sys::{error_string, AXError};
use core_foundation::{
array::CFArray,
base::CFTypeID,
base::{CFCopyTypeIDDescription, TCFType},
string::CFString,
};
use std::{
cell::{Cell, RefCell},
thread,
Expand All @@ -16,14 +21,28 @@ pub use action::*;
pub use attribute::*;
pub use ui_element::*;

#[non_exhaustive]
#[derive(Debug, TError)]
pub enum Error {
#[error("element not found")]
NotFound,
#[error("accessibility error {0:?}")]
#[error(
"expected attribute type {} but got {}",
type_name(*expected),
type_name(*received),
)]
UnexpectedType {
expected: CFTypeID,
received: CFTypeID,
},
#[error("accessibility error {}", error_string(*.0))]
Ax(AXError),
}

fn type_name(type_id: CFTypeID) -> CFString {
unsafe { CFString::wrap_under_create_rule(CFCopyTypeIDDescription(type_id)) }
}

pub trait TreeVisitor {
fn enter_element(&self, element: &AXUIElement) -> TreeWalkerFlow;
fn exit_element(&self, element: &AXUIElement);
Expand Down
13 changes: 11 additions & 2 deletions accessibility/src/ui_element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use cocoa::{
};
use core_foundation::{
array::CFArray,
base::{TCFType, TCFTypeRef},
base::{CFType, TCFType, TCFTypeRef},
declare_TCFType, impl_CFTypeDescription, impl_TCFType,
string::CFString,
};
Expand Down Expand Up @@ -92,7 +92,7 @@ impl AXUIElement {
}

pub fn attribute<T: TCFType>(&self, attribute: &AXAttribute<T>) -> Result<T, Error> {
unsafe {
let res = unsafe {
Ok(T::wrap_under_create_rule(T::Ref::from_void_ptr(
ax_call(|x| {
AXUIElementCopyAttributeValue(
Expand All @@ -103,7 +103,16 @@ impl AXUIElement {
})
.map_err(Error::Ax)?,
)))
};
if let Ok(val) = &res {
if T::type_id() != CFType::type_id() && !val.instance_of::<T>() {
return Err(Error::UnexpectedType {
expected: T::type_id(),
received: val.type_of(),
});
}
}
res
}

pub fn set_attribute<T: TCFType>(
Expand Down

0 comments on commit 589d55a

Please sign in to comment.