Skip to main content

lindera/
error.rs

1//! Error types for Lindera operations.
2//!
3//! This module provides error types used throughout the Lindera Python bindings.
4
5use std::fmt;
6
7use pyo3::exceptions::{PyException, PyIOError, PyValueError};
8use pyo3::prelude::*;
9
10use lindera_binding_core::{CoreError, ErrorKind};
11
12/// Error type for Lindera operations.
13///
14/// Represents errors that can occur during tokenization, dictionary operations,
15/// or other Lindera functionality.
16#[pyclass(name = "LinderaError", from_py_object)]
17#[derive(Debug, Clone)]
18pub struct PyLinderaError {
19    message: String,
20}
21
22#[pymethods]
23impl PyLinderaError {
24    #[new]
25    pub fn new(message: String) -> Self {
26        PyLinderaError { message }
27    }
28
29    #[getter]
30    pub fn message(&self) -> &str {
31        &self.message
32    }
33
34    fn __str__(&self) -> String {
35        self.message.clone()
36    }
37
38    fn __repr__(&self) -> String {
39        format!("LinderaError('{}')", self.message)
40    }
41}
42
43impl fmt::Display for PyLinderaError {
44    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45        write!(f, "{}", self.message)
46    }
47}
48
49impl std::error::Error for PyLinderaError {}
50
51impl From<PyLinderaError> for PyErr {
52    fn from(err: PyLinderaError) -> PyErr {
53        PyException::new_err(err.message)
54    }
55}
56
57/// Maps a [`CoreError`] onto the matching Python exception.
58///
59/// I/O failures become `IOError`; everything else becomes `ValueError`,
60/// preserving the exception types the bindings raised before the migration.
61/// (A `From<CoreError> for PyErr` impl is not possible here because of the
62/// orphan rule, so binding methods use this with `map_err`.)
63///
64/// # 引数
65///
66/// * `err` - The core error to convert.
67///
68/// # 戻り値
69///
70/// The equivalent Python exception.
71pub fn to_py_error(err: CoreError) -> PyErr {
72    let message = err.message().to_string();
73    match err.kind() {
74        ErrorKind::Io => PyIOError::new_err(message),
75        _ => PyValueError::new_err(message),
76    }
77}
78
79pub fn register(parent_module: &Bound<'_, PyModule>) -> PyResult<()> {
80    let py = parent_module.py();
81    let m = PyModule::new(py, "error")?;
82    m.add_class::<PyLinderaError>()?;
83    parent_module.add_submodule(&m)?;
84    Ok(())
85}