use pyo3::{Bound, PyAny, prelude::PyAnyMethods};
pub trait Node {
fn lineno(&self) -> Option<usize> {
None
}
fn col_offset(&self) -> Option<usize> {
None
}
fn end_lineno(&self) -> Option<usize> {
None
}
fn end_col_offset(&self) -> Option<usize> {
None
}
fn error_message(&self, mod_name: impl AsRef<str>, message: impl AsRef<str>) -> String {
format!(
"{} {}:{:?}:{:?}",
message.as_ref(),
mod_name.as_ref(),
self.lineno(),
self.col_offset()
)
}
}
fn extract_position_attr(obj: &Bound<PyAny>, attr_name: &str) -> Option<usize> {
obj.getattr(attr_name)
.ok()
.and_then(|attr| attr.extract().ok())
}
impl<'py> Node for &Bound<'py, PyAny> {
fn lineno(&self) -> Option<usize> {
extract_position_attr(self, "lineno")
}
fn col_offset(&self) -> Option<usize> {
extract_position_attr(self, "col_offset")
}
fn end_lineno(&self) -> Option<usize> {
extract_position_attr(self, "end_lineno")
}
fn end_col_offset(&self) -> Option<usize> {
extract_position_attr(self, "end_col_offset")
}
}