use auv_api_proto::auv::api::driver::v1 as proto;
use auv_driver::{CoordinateSpace, Point, Position};
#[derive(Clone, Copy, Debug, PartialEq, Eq, thiserror::Error)]
pub enum DecodeError {
#[error("position coordinates must be finite")]
NonFiniteCoordinates,
#[error("position requires an explicit coordinate space and nonempty resource id")]
InvalidCoordinateSpace,
}
pub fn encode(position: Position) -> proto::Position {
use proto::position::CoordinateSpace as Space;
proto::Position {
x: position.point.x,
y: position.point.y,
coordinate_space: Some(match position.coordinate_space {
CoordinateSpace::Screen => Space::Screen(true),
CoordinateSpace::Display(id) => Space::DisplayId(id),
CoordinateSpace::Window(id) => Space::WindowId(id),
}),
}
}
pub fn decode(position: proto::Position) -> Result<Position, DecodeError> {
use proto::position::CoordinateSpace as Space;
if !position.x.is_finite() || !position.y.is_finite() {
return Err(DecodeError::NonFiniteCoordinates);
}
let coordinate_space = match position.coordinate_space {
Some(Space::Screen(true)) => CoordinateSpace::Screen,
Some(Space::DisplayId(id)) if !id.is_empty() => CoordinateSpace::Display(id),
Some(Space::WindowId(id)) if !id.is_empty() => CoordinateSpace::Window(id),
_ => return Err(DecodeError::InvalidCoordinateSpace),
};
Ok(Position {
point: Point::new(position.x, position.y),
coordinate_space,
})
}
#[cfg(test)]
#[path = "position_test.rs"]
mod tests;