1use std::path::Path;
2
3use pyo3::{exceptions::PyValueError, prelude::*};
4
5use lindera::dictionary::{
6 Dictionary, DictionaryBuilder, Metadata, UserDictionary,
7 load_dictionary as lindera_load_dictionary,
8 load_user_dictionary as lindera_load_user_dictionary,
9};
10
11use crate::metadata::PyMetadata;
12
13#[pyclass(name = "Dictionary")]
14#[derive(Clone)]
15pub struct PyDictionary {
16 pub inner: Dictionary,
17}
18
19#[pymethods]
20impl PyDictionary {
21 pub fn metadata_name(&self) -> String {
22 self.inner.metadata.name.clone()
23 }
24
25 pub fn metadata_encoding(&self) -> String {
26 self.inner.metadata.encoding.clone()
27 }
28
29 pub fn metadata(&self) -> PyMetadata {
30 PyMetadata::from(self.inner.metadata.clone())
31 }
32
33 fn __str__(&self) -> String {
34 "Dictionary".to_string()
35 }
36
37 fn __repr__(&self) -> String {
38 "Dictionary()".to_string()
39 }
40}
41
42impl PyDictionary {
43 pub fn new(dictionary: Dictionary) -> Self {
45 Self { inner: dictionary }
46 }
47}
48
49#[pyclass(name = "UserDictionary")]
50#[derive(Clone)]
51pub struct PyUserDictionary {
52 pub inner: UserDictionary,
53}
54
55#[pymethods]
56impl PyUserDictionary {
57 fn __str__(&self) -> String {
58 "UserDictionary".to_string()
59 }
60
61 fn __repr__(&self) -> String {
62 "UserDictionary()".to_string()
63 }
64}
65
66impl PyUserDictionary {
67 pub fn new(user_dictionary: UserDictionary) -> Self {
69 Self {
70 inner: user_dictionary,
71 }
72 }
73}
74
75#[pyfunction]
76#[pyo3(signature = (input_dir, output_dir, metadata))]
77pub fn build_dictionary(input_dir: &str, output_dir: &str, metadata: PyMetadata) -> PyResult<()> {
78 let input_path = Path::new(input_dir);
79 let output_path = Path::new(output_dir);
80
81 if !input_path.exists() {
82 return Err(PyValueError::new_err(format!(
83 "Input directory does not exist: {input_dir}"
84 )));
85 }
86
87 let builder = DictionaryBuilder::new(metadata.into());
88
89 builder
90 .build_dictionary(input_path, output_path)
91 .map_err(|e| PyValueError::new_err(format!("Failed to build dictionary: {e}")))?;
92
93 Ok(())
94}
95
96#[pyfunction]
97#[pyo3(signature = (_kind, input_file, output_dir, metadata=None))]
98pub fn build_user_dictionary(
99 _kind: &str,
100 input_file: &str,
101 output_dir: &str,
102 metadata: Option<crate::metadata::PyMetadata>,
103) -> PyResult<()> {
104 let input_path = Path::new(input_file);
105 let output_path = Path::new(output_dir);
106
107 if !input_path.exists() {
108 return Err(PyValueError::new_err(format!(
109 "Input file does not exist: {input_file}"
110 )));
111 }
112
113 let meta = match metadata {
115 Some(py_metadata) => {
116 let lindera_meta: Metadata = py_metadata.into();
117 lindera_meta
118 }
119 None => Metadata::default(),
120 };
121
122 let builder = DictionaryBuilder::new(meta);
123
124 builder
126 .build_user_dictionary(input_path, output_path)
127 .map_err(|e| PyValueError::new_err(format!("Failed to build user dictionary: {e}")))?;
128
129 Ok(())
130}
131
132#[pyfunction]
133#[pyo3(signature = (uri))]
134pub fn load_dictionary(uri: &str) -> PyResult<PyDictionary> {
135 lindera_load_dictionary(uri)
136 .map_err(|e| PyValueError::new_err(format!("Failed to load dictionary from '{uri}': {e}")))
137 .map(PyDictionary::new)
138}
139
140#[pyfunction]
141#[pyo3(signature = (uri, metadata))]
142pub fn load_user_dictionary(uri: &str, metadata: PyMetadata) -> PyResult<PyUserDictionary> {
143 let meta: Metadata = metadata.into();
144 lindera_load_user_dictionary(uri, &meta)
145 .map_err(|e| {
146 PyValueError::new_err(format!("Failed to load user dictionary from '{uri}': {e}"))
147 })
148 .map(PyUserDictionary::new)
149}