1use std::time::Duration;
2use bbclient::{adaptor::VecShape, DataType};
3use num_complex::Complex64;
4use pyo3::prelude::*;
5
6#[pyfunction]
8fn set_addr(addr: String) -> PyResult<()> {
9 bbclient::set_addr(&addr);
10 Ok(())
11}
12
13#[pyfunction]
15#[pyo3(signature = (timeout=None))]
16fn set_timeout(timeout: Option<u64>) -> PyResult<()> {
17 bbclient::set_timeout(timeout.map(|t| Duration::from_millis(t)));
18 Ok(())
19}
20
21#[pyfunction]
22fn post_integer(title: String, tag: String, val: i128) -> PyResult<()> {
23 let obj = val.try_into().unwrap();
24 bbclient::post(&title, &tag, obj).unwrap();
25 Ok(())
26}
27
28#[pyfunction]
29fn post_real(title: String, tag: String, val: f64) -> PyResult<()> {
30 let obj = val.try_into().unwrap();
31 bbclient::post(&title, &tag, obj).unwrap();
32 Ok(())
33}
34
35#[pyfunction]
36fn post_complex(title: String, tag: String, val: Complex64) -> PyResult<()> {
37 let obj = val.try_into().unwrap();
38 bbclient::post(&title, &tag, obj).unwrap();
39 Ok(())
40}
41
42#[pyfunction]
43fn post_string(title: String, tag: String, val: String) -> PyResult<()> {
44 let obj = val.try_into().unwrap();
45 bbclient::post(&title, &tag, obj).unwrap();
46 Ok(())
47}
48
49#[pyfunction]
50fn post_integer_array(title: String, tag: String, val: Vec<i128>, shape: Vec<u64>) -> PyResult<()> {
51 let obj = VecShape(val, shape).try_into().unwrap();
52 bbclient::post(&title, &tag, obj).unwrap();
53 Ok(())
54}
55
56#[pyfunction]
57fn post_real_array(title: String, tag: String, val: Vec<f64>, shape: Vec<u64>) -> PyResult<()> {
58 let obj = VecShape(val, shape).try_into().unwrap();
59 bbclient::post(&title, &tag, obj).unwrap();
60 Ok(())
61}
62
63#[pyfunction]
64fn post_complex_array(
65 title: String,
66 tag: String,
67 val: Vec<Complex64>,
68 shape: Vec<u64>,
69) -> PyResult<()> {
70 let obj = VecShape(val, shape).try_into().unwrap();
71 bbclient::post(&title, &tag, obj).unwrap();
72 Ok(())
73}
74
75#[pyfunction]
76fn post_string_array(
77 title: String,
78 tag: String,
79 val: Vec<String>,
80 shape: Vec<u64>,
81) -> PyResult<()> {
82 let obj = VecShape(val, shape).try_into().unwrap();
83 bbclient::post(&title, &tag, obj).unwrap();
84 Ok(())
85}
86
87#[pyfunction]
88#[pyo3(signature = (title, tag=None, revisions=None))]
89fn read_raw(
90 py: Python<'_>,
91 title: String,
92 tag: Option<String>,
93 revisions: Option<Vec<u64>>,
94) -> PyResult<PyObject> {
95 let revisions = match revisions {
96 Some(rev) => rev,
97 None => vec![],
98 };
99
100 let list = bbclient::read(&title, tag.as_deref(), revisions).unwrap();
101 let mut res = vec![];
102 for elem in list {
103 match elem.datatype() {
104 DataType::UnsignedInteger => {
105 if elem.dimension() == 0 {
106 let val: u128 = elem.try_into().unwrap();
107 res.push(val.to_object(py));
108 } else {
109 let VecShape::<u128>(val, shape) = elem.try_into().unwrap();
110 let shape: Vec<usize> =
111 shape.into_iter().map(|x| x.try_into().unwrap()).collect();
112 res.push((val, shape).to_object(py));
113 }
114 }
115 DataType::SignedInteger => {
116 if elem.dimension() == 0 {
117 let val: i128 = elem.try_into().unwrap();
118 res.push(val.to_object(py));
119 } else {
120 let VecShape::<i128>(val, shape) = elem.try_into().unwrap();
121 let shape: Vec<usize> =
122 shape.into_iter().map(|x| x.try_into().unwrap()).collect();
123 res.push((val, shape).to_object(py));
124 }
125 }
126 DataType::Real => {
127 if elem.dimension() == 0 {
128 let val: f64 = elem.try_into().unwrap();
129 res.push(val.to_object(py));
130 } else {
131 let VecShape::<f64>(val, shape) = elem.try_into().unwrap();
132 let shape: Vec<usize> =
133 shape.into_iter().map(|x| x.try_into().unwrap()).collect();
134 res.push((val, shape).to_object(py));
135 }
136 }
137 DataType::Complex => {
138 if elem.dimension() == 0 {
139 let val: Complex64 = elem.try_into().unwrap();
140 res.push(val.to_object(py));
141 } else {
142 let VecShape::<Complex64>(val, shape) = elem.try_into().unwrap();
143 res.push((val, shape).to_object(py));
144 }
145 }
146 DataType::String => {
147 if elem.dimension() == 0 {
148 let val: String = elem.try_into().unwrap();
149 res.push(val.to_object(py));
150 } else {
151 let VecShape::<String>(val, shape) = elem.try_into().unwrap();
152 res.push((val, shape).to_object(py));
153 }
154 }
155 }
156 }
157 Ok(res.to_object(py))
158}
159
160#[pyfunction]
162#[pyo3(signature = (title_from, tag_from=None, title_to=None, tag_to=None))]
163fn relabel(
164 title_from: String,
165 tag_from: Option<String>,
166 title_to: Option<String>,
167 tag_to: Option<String>,
168) -> PyResult<()> {
169 bbclient::relabel(
170 &title_from,
171 tag_from.as_deref(),
172 title_to.as_deref(),
173 tag_to.as_deref(),
174 )
175 .unwrap();
176 Ok(())
177}
178
179#[pyfunction]
181fn client_version(py: Python<'_>) -> PyResult<PyObject> {
182 let client_version = env!("CARGO_PKG_VERSION").to_string();
183 Ok(client_version.to_object(py))
184}
185
186#[pyfunction]
188fn server_version(py: Python<'_>) -> PyResult<PyObject> {
189 let server_version = bbclient::server_version().unwrap();
190 Ok(server_version.to_object(py))
191}
192
193#[pyfunction]
195fn status_raw(py: Python<'_>) -> PyResult<PyObject> {
196 Ok(bbclient::status().unwrap().to_object(py))
197}
198
199#[pyfunction]
201fn log(py: Python<'_>) -> PyResult<PyObject> {
202 Ok(bbclient::log().unwrap().to_object(py))
203}
204
205#[pyfunction]
206fn view_board_raw(py: Python<'_>) -> PyResult<PyObject> {
207 Ok(bbclient::view_board().unwrap().to_object(py))
208}
209
210#[pyfunction]
211#[pyo3(signature = (title, tag=None))]
212fn get_info_raw(py: Python<'_>, title: String, tag: Option<String>) -> PyResult<PyObject> {
213 Ok(bbclient::get_info(&title, tag.as_deref())
214 .unwrap()
215 .to_object(py))
216}
217
218#[pyfunction]
219#[pyo3(signature = (title, revisions, tag=None))]
220fn clear_revisions_raw(title: String, revisions: Vec<u64>, tag: Option<String>) -> PyResult<()> {
221 bbclient::clear_revisions(&title, tag.as_deref(), revisions).unwrap();
222 Ok(())
223}
224
225#[pyfunction]
227#[pyo3(signature = (title, tag=None))]
228fn remove(title: String, tag: Option<String>) -> PyResult<()> {
229 bbclient::remove(&title, tag.as_deref()).unwrap();
230 Ok(())
231}
232
233#[pyfunction]
235#[pyo3(signature = (acv_name, title, tag=None))]
236fn archive(acv_name: String, title: String, tag: Option<String>) -> PyResult<()> {
237 bbclient::archive(&acv_name, &title, tag.as_deref()).unwrap();
238 Ok(())
239}
240
241#[pyfunction]
243fn load(acv_name: String) -> PyResult<()> {
244 bbclient::load(&acv_name).unwrap();
245 Ok(())
246}
247
248#[pyfunction]
250fn list_archive(py: Python<'_>) -> PyResult<PyObject> {
251 Ok(bbclient::list_archive().unwrap().to_object(py))
252}
253
254#[pyfunction]
256fn rename_archive(name_from: String, name_to: String) -> PyResult<()> {
257 bbclient::rename_archive(&name_from, &name_to).unwrap();
258 Ok(())
259}
260
261#[pyfunction]
263fn delete_archive(acv_name: String) -> PyResult<()> {
264 bbclient::delete_archive(&acv_name).unwrap();
265 Ok(())
266}
267
268#[pyfunction]
270fn dump(acv_name: String) -> PyResult<()> {
271 bbclient::dump(&acv_name).unwrap();
272 Ok(())
273}
274
275#[pyfunction]
277fn restore(acv_name: String) -> PyResult<()> {
278 bbclient::restore(&acv_name).unwrap();
279 Ok(())
280}
281
282#[pyfunction]
284fn clear_log() -> PyResult<()> {
285 bbclient::clear_log().unwrap();
286 Ok(())
287}
288
289#[pyfunction]
291fn reset_server() -> PyResult<()> {
292 bbclient::reset_server().unwrap();
293 Ok(())
294}
295
296#[pyfunction]
298fn terminate_server() -> PyResult<()> {
299 bbclient::terminate_server().unwrap();
300 Ok(())
301}
302
303#[pymodule]
305fn bulletin_board_client(m: &Bound<'_, PyModule>) -> PyResult<()> {
306 m.add_function(wrap_pyfunction!(set_addr, m)?)?;
307 m.add_function(wrap_pyfunction!(set_timeout, m)?)?;
308 m.add_function(wrap_pyfunction!(post_integer, m)?)?;
309 m.add_function(wrap_pyfunction!(post_real, m)?)?;
310 m.add_function(wrap_pyfunction!(post_complex, m)?)?;
311 m.add_function(wrap_pyfunction!(post_string, m)?)?;
312 m.add_function(wrap_pyfunction!(post_integer_array, m)?)?;
313 m.add_function(wrap_pyfunction!(post_real_array, m)?)?;
314 m.add_function(wrap_pyfunction!(post_complex_array, m)?)?;
315 m.add_function(wrap_pyfunction!(post_string_array, m)?)?;
316 m.add_function(wrap_pyfunction!(read_raw, m)?)?;
317 m.add_function(wrap_pyfunction!(relabel, m)?)?;
318 m.add_function(wrap_pyfunction!(client_version, m)?)?;
319 m.add_function(wrap_pyfunction!(server_version, m)?)?;
320 m.add_function(wrap_pyfunction!(status_raw, m)?)?;
321 m.add_function(wrap_pyfunction!(log, m)?)?;
322 m.add_function(wrap_pyfunction!(view_board_raw, m)?)?;
323 m.add_function(wrap_pyfunction!(get_info_raw, m)?)?;
324 m.add_function(wrap_pyfunction!(clear_revisions_raw, m)?)?;
325 m.add_function(wrap_pyfunction!(remove, m)?)?;
326 m.add_function(wrap_pyfunction!(archive, m)?)?;
327 m.add_function(wrap_pyfunction!(load, m)?)?;
328 m.add_function(wrap_pyfunction!(list_archive, m)?)?;
329 m.add_function(wrap_pyfunction!(rename_archive, m)?)?;
330 m.add_function(wrap_pyfunction!(delete_archive, m)?)?;
331 m.add_function(wrap_pyfunction!(dump, m)?)?;
332 m.add_function(wrap_pyfunction!(restore, m)?)?;
333 m.add_function(wrap_pyfunction!(clear_log, m)?)?;
334 m.add_function(wrap_pyfunction!(reset_server, m)?)?;
335 m.add_function(wrap_pyfunction!(terminate_server, m)?)?;
336 Ok(())
337}