Skip to main content

_formatparse/
error.rs

1use formatparse_core::error::FormatParseError;
2use pyo3::prelude::*;
3
4/// Convert a formatparse-core error to a PyO3 error.
5///
6/// Error types for formatparse PyO3 bindings; bridges formatparse-core errors to PyO3.
7pub fn core_error_to_py_err(err: FormatParseError) -> PyErr {
8    match err {
9        FormatParseError::PatternError(msg) => {
10            PyErr::new::<pyo3::exceptions::PyValueError, _>(format!("Pattern error: {}", msg))
11        }
12        FormatParseError::RegexError(msg) => errors::regex_error(msg.as_str()),
13        FormatParseError::ConversionError(value, target_type) => {
14            PyErr::new::<pyo3::exceptions::PyValueError, _>(format!(
15                "Invalid {}: {}",
16                target_type, value
17            ))
18        }
19        FormatParseError::RepeatedNameError(name) => {
20            PyErr::new::<pyo3::exceptions::PyValueError, _>(format!(
21                "Repeated name '{}' with mismatched types",
22                name
23            ))
24        }
25        FormatParseError::CustomTypeError(type_name, msg) => {
26            PyErr::new::<pyo3::exceptions::PyValueError, _>(format!(
27                "Custom type '{}' error: {}",
28                type_name, msg
29            ))
30        }
31        FormatParseError::RegexGroupIndexError(type_name, actual, expected) => {
32            PyErr::new::<pyo3::exceptions::PyIndexError, _>(format!(
33                "Custom type '{}' pattern has {} capturing groups but regex_group_count is {}",
34                type_name, actual, expected
35            ))
36        }
37        FormatParseError::NotImplementedError(feature) => {
38            PyErr::new::<pyo3::exceptions::PyNotImplementedError, _>(format!(
39                "{} is not supported",
40                feature
41            ))
42        }
43        FormatParseError::MissingFieldError(field) => {
44            PyErr::new::<pyo3::exceptions::PyValueError, _>(format!(
45                "Missing required field: {}",
46                field
47            ))
48        }
49    }
50}
51
52/// Match-time error from the fancy-regex engine (used for compiled format patterns).
53pub fn fancy_regex_match_error(e: fancy_regex::Error) -> PyErr {
54    PyErr::new::<pyo3::exceptions::PyRuntimeError, _>(format!("Regex match error: {}", e))
55}
56
57// Subclass of ValueError: malformed patterns where reference `parse` returns None from
58// `parse()`. `compile()` still raises this type. Used by `parse` / `parse_batch` without string matching.
59pyo3::create_exception!(
60    _formatparse,
61    PatternParseMismatch,
62    pyo3::exceptions::PyValueError
63);
64
65/// Error module for formatparse PyO3 operations
66pub mod errors {
67    use super::*;
68
69    /// Create a regex compilation error
70    pub fn regex_error(msg: &str) -> PyErr {
71        PyErr::new::<pyo3::exceptions::PyValueError, _>(format!("Invalid regex pattern: {}", msg))
72    }
73
74    /// Create a type conversion error
75    pub fn conversion_error(value: &str, target_type: &str) -> PyErr {
76        PyErr::new::<pyo3::exceptions::PyValueError, _>(format!(
77            "Invalid {}: {}",
78            target_type, value
79        ))
80    }
81
82    /// Create a repeated name error with type mismatch
83    pub fn repeated_name_error(name: &str) -> PyErr {
84        PyErr::new::<pyo3::exceptions::PyValueError, _>(format!(
85            "Repeated name '{}' with mismatched types",
86            name
87        ))
88    }
89
90    /// Create a custom type validation error
91    pub fn custom_type_error(type_name: &str, msg: &str) -> PyErr {
92        PyErr::new::<pyo3::exceptions::PyValueError, _>(format!(
93            "Custom type '{}' error: {}",
94            type_name, msg
95        ))
96    }
97
98    /// Create an index error for regex group access
99    pub fn regex_group_index_error(type_name: &str, actual: usize, expected: i64) -> PyErr {
100        PyErr::new::<pyo3::exceptions::PyIndexError, _>(format!(
101            "Custom type '{}' pattern has {} capturing groups but regex_group_count is {}",
102            type_name, actual, expected
103        ))
104    }
105
106    /// Create a missing field error
107    pub fn missing_field_error(field: &str) -> PyErr {
108        PyErr::new::<pyo3::exceptions::PyValueError, _>(format!(
109            "Missing required field: {}",
110            field
111        ))
112    }
113}
114
115/// Re-export error functions for convenience
116pub use errors::*;