use crate::run_cli;
use linux_memutils::agesa::{FoundVersion, SearchError};
use pyo3::create_exception;
use pyo3::exceptions::{PyOSError, PySystemExit};
use pyo3::prelude::*;
use std::env;
create_exception!(
agesafetch,
DevMemOpenError,
PyOSError,
"Raised when the `/dev/mem` file could not be opened."
);
create_exception!(
agesafetch,
IomemReadError,
PyOSError,
"Raised when the `/dev/iomem` file could not be read."
);
create_exception!(
agesafetch,
ByteReadError,
PyOSError,
"Raised when a byte in `/dev/mem` could not be read."
);
struct PySearchError(SearchError);
impl From<PySearchError> for PyErr {
fn from(error: PySearchError) -> Self {
match error.0 {
SearchError::DevMemUnopenable(source) => {
DevMemOpenError::new_err(format!("Could not open `/dev/mem`: {source}"))
}
SearchError::IomemUnreadable(source) => {
IomemReadError::new_err(format!("Could not read `/proc/iomem`: {source}"))
}
SearchError::ByteUnreadable(source) => {
ByteReadError::new_err(format!("Could not read byte in `/dev/mem`: {source}"))
}
}
}
}
impl From<SearchError> for PySearchError {
fn from(error: SearchError) -> Self {
Self(error)
}
}
#[pyclass(name = "AGESAVersion", module = "agesafetch")]
struct AgesaVersion {
#[pyo3(get, set)]
version_string: String,
#[pyo3(get, set)]
absolute_address: usize,
}
impl From<FoundVersion> for AgesaVersion {
fn from(found_version: FoundVersion) -> Self {
Self {
version_string: found_version.agesa_version,
absolute_address: found_version.absolute_address,
}
}
}
#[pyfunction]
fn find_agesa_version() -> Result<Option<AgesaVersion>, PySearchError> {
let maybe_found_version = linux_memutils::agesa::find_agesa_version()?;
Ok(maybe_found_version.map(AgesaVersion::from))
}
#[pyfunction]
fn run_py() -> PyResult<()> {
let args = env::args_os().skip(1).collect();
let exit_code = run_cli(args);
Err(PySystemExit::new_err(exit_code as u8))
}
#[pymodule]
fn agesafetch(py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_class::<AgesaVersion>()?;
m.add_function(wrap_pyfunction!(find_agesa_version, m)?)?;
m.add_wrapped(wrap_pyfunction!(run_py))?;
m.add("DevMemOpenError", py.get_type::<DevMemOpenError>())?;
m.add("IomemReadError", py.get_type::<IomemReadError>())?;
m.add("ByteReadError", py.get_type::<ByteReadError>())?;
Ok(())
}