1use bbclient::{DataType, adaptor::VecShape};
2use num_complex::Complex64;
3use pyo3::prelude::*;
4use std::time::Duration;
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<PyObject> = 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.into_pyobject(py).unwrap().into());
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).into_pyobject(py).unwrap().into());
113 }
114 }
115 DataType::SignedInteger => {
116 if elem.dimension() == 0 {
117 let val: i128 = elem.try_into().unwrap();
118 res.push(val.into_pyobject(py).unwrap().into());
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).into_pyobject(py).unwrap().into());
124 }
125 }
126 DataType::Real => {
127 if elem.dimension() == 0 {
128 let val: f64 = elem.try_into().unwrap();
129 res.push(val.into_pyobject(py).unwrap().into());
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).into_pyobject(py).unwrap().into());
135 }
136 }
137 DataType::Complex => {
138 if elem.dimension() == 0 {
139 let val: Complex64 = elem.try_into().unwrap();
140 res.push(val.into_pyobject(py).unwrap().into());
141 } else {
142 let VecShape::<Complex64>(val, shape) = elem.try_into().unwrap();
143 res.push((val, shape).into_pyobject(py).unwrap().into());
144 }
145 }
146 DataType::String => {
147 if elem.dimension() == 0 {
148 let val: String = elem.try_into().unwrap();
149 res.push(val.into_pyobject(py).unwrap().into());
150 } else {
151 let VecShape::<String>(val, shape) = elem.try_into().unwrap();
152 res.push((val, shape).into_pyobject(py).unwrap().into());
153 }
154 }
155 }
156 }
157 Ok(res.into_pyobject(py).unwrap().into())
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.into_pyobject(py).unwrap().into())
184}
185
186#[pyfunction]
188fn server_version(py: Python<'_>) -> PyResult<PyObject> {
189 let server_version = bbclient::server_version().unwrap();
190 Ok(server_version.into_pyobject(py).unwrap().into())
191}
192
193#[pyfunction]
195fn status_raw(py: Python<'_>) -> PyResult<PyObject> {
196 Ok(bbclient::status()
197 .unwrap()
198 .into_pyobject(py)
199 .unwrap()
200 .into())
201}
202
203#[pyfunction]
205fn log(py: Python<'_>) -> PyResult<PyObject> {
206 Ok(bbclient::log().unwrap().into_pyobject(py).unwrap().into())
207}
208
209#[pyfunction]
210fn view_board_raw(py: Python<'_>) -> PyResult<PyObject> {
211 Ok(bbclient::view_board()
212 .unwrap()
213 .into_pyobject(py)
214 .unwrap()
215 .into())
216}
217
218#[pyfunction]
219#[pyo3(signature = (title, tag=None))]
220fn get_info_raw(py: Python<'_>, title: String, tag: Option<String>) -> PyResult<PyObject> {
221 Ok(bbclient::get_info(&title, tag.as_deref())
222 .unwrap()
223 .into_pyobject(py)
224 .unwrap()
225 .into())
226}
227
228#[pyfunction]
229#[pyo3(signature = (title, revisions, tag=None))]
230fn clear_revisions_raw(title: String, revisions: Vec<u64>, tag: Option<String>) -> PyResult<()> {
231 bbclient::clear_revisions(&title, tag.as_deref(), revisions).unwrap();
232 Ok(())
233}
234
235#[pyfunction]
237#[pyo3(signature = (title, tag=None))]
238fn remove(title: String, tag: Option<String>) -> PyResult<()> {
239 bbclient::remove(&title, tag.as_deref()).unwrap();
240 Ok(())
241}
242
243#[pyfunction]
245#[pyo3(signature = (acv_name, title, tag=None))]
246fn archive(acv_name: String, title: String, tag: Option<String>) -> PyResult<()> {
247 bbclient::archive(&acv_name, &title, tag.as_deref()).unwrap();
248 Ok(())
249}
250
251#[pyfunction]
253fn load(acv_name: String) -> PyResult<()> {
254 bbclient::load(&acv_name).unwrap();
255 Ok(())
256}
257
258#[pyfunction]
260fn list_archive(py: Python<'_>) -> PyResult<PyObject> {
261 Ok(bbclient::list_archive()
262 .unwrap()
263 .into_pyobject(py)
264 .unwrap()
265 .into())
266}
267
268#[pyfunction]
270fn rename_archive(name_from: String, name_to: String) -> PyResult<()> {
271 bbclient::rename_archive(&name_from, &name_to).unwrap();
272 Ok(())
273}
274
275#[pyfunction]
277fn delete_archive(acv_name: String) -> PyResult<()> {
278 bbclient::delete_archive(&acv_name).unwrap();
279 Ok(())
280}
281
282#[pyfunction]
284fn dump(acv_name: String) -> PyResult<()> {
285 bbclient::dump(&acv_name).unwrap();
286 Ok(())
287}
288
289#[pyfunction]
291fn restore(acv_name: String) -> PyResult<()> {
292 bbclient::restore(&acv_name).unwrap();
293 Ok(())
294}
295
296#[pyfunction]
298fn clear_log() -> PyResult<()> {
299 bbclient::clear_log().unwrap();
300 Ok(())
301}
302
303#[pyfunction]
305fn reset_server() -> PyResult<()> {
306 bbclient::reset_server().unwrap();
307 Ok(())
308}
309
310#[pyfunction]
312fn terminate_server() -> PyResult<()> {
313 bbclient::terminate_server().unwrap();
314 Ok(())
315}
316
317#[pymodule]
319fn bulletin_board_client(m: &Bound<'_, PyModule>) -> PyResult<()> {
320 m.add_function(wrap_pyfunction!(set_addr, m)?)?;
321 m.add_function(wrap_pyfunction!(set_timeout, m)?)?;
322 m.add_function(wrap_pyfunction!(post_integer, m)?)?;
323 m.add_function(wrap_pyfunction!(post_real, m)?)?;
324 m.add_function(wrap_pyfunction!(post_complex, m)?)?;
325 m.add_function(wrap_pyfunction!(post_string, m)?)?;
326 m.add_function(wrap_pyfunction!(post_integer_array, m)?)?;
327 m.add_function(wrap_pyfunction!(post_real_array, m)?)?;
328 m.add_function(wrap_pyfunction!(post_complex_array, m)?)?;
329 m.add_function(wrap_pyfunction!(post_string_array, m)?)?;
330 m.add_function(wrap_pyfunction!(read_raw, m)?)?;
331 m.add_function(wrap_pyfunction!(relabel, m)?)?;
332 m.add_function(wrap_pyfunction!(client_version, m)?)?;
333 m.add_function(wrap_pyfunction!(server_version, m)?)?;
334 m.add_function(wrap_pyfunction!(status_raw, m)?)?;
335 m.add_function(wrap_pyfunction!(log, m)?)?;
336 m.add_function(wrap_pyfunction!(view_board_raw, m)?)?;
337 m.add_function(wrap_pyfunction!(get_info_raw, m)?)?;
338 m.add_function(wrap_pyfunction!(clear_revisions_raw, m)?)?;
339 m.add_function(wrap_pyfunction!(remove, m)?)?;
340 m.add_function(wrap_pyfunction!(archive, m)?)?;
341 m.add_function(wrap_pyfunction!(load, m)?)?;
342 m.add_function(wrap_pyfunction!(list_archive, m)?)?;
343 m.add_function(wrap_pyfunction!(rename_archive, m)?)?;
344 m.add_function(wrap_pyfunction!(delete_archive, m)?)?;
345 m.add_function(wrap_pyfunction!(dump, m)?)?;
346 m.add_function(wrap_pyfunction!(restore, m)?)?;
347 m.add_function(wrap_pyfunction!(clear_log, m)?)?;
348 m.add_function(wrap_pyfunction!(reset_server, m)?)?;
349 m.add_function(wrap_pyfunction!(terminate_server, m)?)?;
350 Ok(())
351}