use crate::macos::ax::{element_bbox, set_value_attribute, AXDispatchError, AXRef};
use crate::tools::ax_response;
use crate::tools::ax_session::{AxSession, LookupError};
use rmcp::model::CallToolResult;
use serde::Deserialize;
use std::sync::Arc;
const DISPATCHED_VIA: &str = "AXSetAttributeValue";
#[derive(Deserialize)]
pub struct AxSetValueParams {
pub uid: String,
pub text: String,
}
pub async fn ax_set_value(params: AxSetValueParams, session: Arc<AxSession>) -> CallToolResult {
if let Some(err) = crate::tools::input::check_permission() {
return err;
}
let outcome = session
.dispatch(¶ms.uid, |ax_ref: &AXRef| {
let pre_bbox = unsafe { element_bbox(ax_ref.as_raw()) };
match set_value_attribute(ax_ref, ¶ms.text) {
Ok(()) => {
let post_bbox = unsafe { element_bbox(ax_ref.as_raw()) }.or(pre_bbox);
ax_response::success(DISPATCHED_VIA, post_bbox)
}
Err(AXDispatchError::NotDispatchable) => ax_response::error(
"not_dispatchable",
"element does not expose a writable kAXValueAttribute",
pre_bbox,
),
Err(AXDispatchError::AxError(code)) => ax_response::error(
"ax_error",
&format!("AXUIElementSetAttributeValue failed with AX error {}", code),
pre_bbox,
),
}
})
.await;
match outcome {
Ok(result) => result,
Err(LookupError::SnapshotExpired { reason }) => {
ax_response::error("snapshot_expired", &reason, None)
}
Err(LookupError::UidNotFound) => ax_response::error(
"uid_not_found",
&format!("uid {} is not present in the current snapshot", params.uid),
None,
),
}
}