use crate::{Result, brlapi_call, connection::Connection, error::BrlApiError};
use brlapi_sys::*;
use std::ffi::CString;
#[derive(Debug)]
pub struct RawMode<'a> {
connection: &'a Connection,
driver_name: String,
}
impl<'a> RawMode<'a> {
pub fn enter(connection: &'a Connection, driver: &str) -> Result<Self> {
if driver.is_empty() {
return Err(BrlApiError::custom("Driver name cannot be empty"));
}
let c_driver = CString::new(driver).map_err(|e| BrlApiError::NullByteInString(e))?;
brlapi_call!(unsafe { brlapi__enterRawMode(connection.handle_ptr(), c_driver.as_ptr()) })?;
Ok(RawMode {
connection,
driver_name: driver.to_string(),
})
}
pub fn is_driver_supported(driver_name: &str) -> bool {
if driver_name.is_empty() {
return false;
}
match driver_name.to_lowercase().as_str() {
"alva" | "baum" | "braillepen" | "braillelite" | "braillememo" | "braillenote"
| "canbraille" | "cebra" | "ec" | "eureka" | "freedomscientific" | "handy" | "hedo"
| "hims" | "ht" | "humanware" | "iris" | "logtext" | "md" | "mn" | "mt" | "pegasus"
| "pm" | "seika" | "voyager" | "vr" | "vs" => true,
"noblraille" | "fake" | "dummy" | "test" => false,
_ => true,
}
}
pub fn send_data(&self, data: &[u8]) -> Result<usize> {
if data.is_empty() {
return Ok(0);
}
let result = brlapi_call!(unsafe {
brlapi__sendRaw(
self.connection.handle_ptr(),
data.as_ptr() as *const std::ffi::c_void,
data.len(),
)
})?;
Ok(result as usize)
}
pub fn receive_data(&self, buffer: &mut [u8]) -> Result<usize> {
if buffer.is_empty() {
return Ok(0);
}
let result = brlapi_call!(unsafe {
brlapi__recvRaw(
self.connection.handle_ptr(),
buffer.as_mut_ptr() as *mut std::ffi::c_void,
buffer.len(),
)
})?;
Ok(result as usize)
}
pub fn driver_name(&self) -> &str {
&self.driver_name
}
pub fn connection(&self) -> &Connection {
self.connection
}
}
impl<'a> Drop for RawMode<'a> {
fn drop(&mut self) {
let _ = crate::brlapi_call!(unsafe { brlapi__leaveRawMode(self.connection.handle_ptr()) });
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_driver_support_detection() {
assert!(RawMode::is_driver_supported("alva"));
assert!(RawMode::is_driver_supported("baum"));
assert!(RawMode::is_driver_supported("hims"));
assert!(!RawMode::is_driver_supported("noblraille"));
assert!(!RawMode::is_driver_supported("dummy"));
assert!(RawMode::is_driver_supported("ALVA"));
assert!(RawMode::is_driver_supported("Baum"));
assert!(RawMode::is_driver_supported("unknown_driver"));
}
#[test]
fn test_empty_driver_validation() {
assert!(!RawMode::is_driver_supported(""));
}
}