1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
//! # psrdada-rs
//!
//! [](#license)
//! [](https://docs.rs/psrdada/latest/psrdada/index.html)
//! [](https://www.rust-lang.org)
//! [](https://github.com/kiranshila/psrdada-rs/actions)
//! [](https://app.codecov.io/gh/kiranshila/psrdada-rs)
//!
//! This is a rust library around the [psrdada](http://psrdada.sourceforge.net/) library commonly used in radio astronomy.
//! Unfortunately, the C library is for the most part undocumented, so the behavior presented by this rust library is what the authors have been able to ascertain by reading the original example code.
//! As such, this might not be a 1-to-1 implementation of the original use case and implements only a subset
//! of the features available in the C library.
//!
//! ## Installation
//!
//! You need to build and install PSRDADA manually, following the installation guide found [here](https://psrdada.sourceforge.net/download.shtml).
//! Alternatively, you can use the [nix](https://nixos.org/) flake [here](https://github.com/kiranshila/psrdada.nix/blob/main/flake.nix) to declaratively create environments (shells/docker containers/operating systems) with PSRDADA baked in (deterministically).
//!
//! ## Safety
//!
//! The original library is intrinsically unsafe as it is written in C, but also there are very few checks that the user uses it correctly.
//! This library tries to ensure at compile time some of the things the C library checks at runtime. For example, If you try to write to buffer
//! while something else is trying to read, this would usually fail a lock. Instead, in this library, we use Rust's borrowing system to ensure
//! you can't build both at the same time. The same goes for read/write blocks. References to these cannot exist once you mark them as cleared.
//!
//! This is a huge ergonomic improvement over the C library (and the C++ library to some extent, as they attempt to implement some RAII patterns).
//!
//! Take the following code as an example
//!
//! ```rust
//! use std::io::{Read, Write};
//!
//! use psrdada::prelude::*;
//!
//! // Build the paired client
//! let key = 0xb0ba;
//! let mut client = DadaClientBuilder::new(key).build().unwrap();
//!
//! // Split into individual clients
//! let (_, mut data_client) = client.split();
//!
//! // Construct the writer (mutable borrow), panicking if a lock is not obtainable
//! let mut writer = data_client.writer().unwrap();
//!
//! // Grab the next block in the ring (assuming we can)
//! let mut write_block = writer.next().unwrap();
//!
//! // Write using std::io::Write so you can write chunks at a time
//! write_block.write_all(&[0u8; 10]).unwrap();
//!
//! // Inform the backend that we've completed writing
//! write_block.commit();
//!
//! // Drop the writer to unlock it (this would happen also when the writer leaves scope)
//! drop(writer);
//!
//! // Construct the reader (mutable borrow), panicking if a lock is not obtainable
//! let mut reader = data_client.reader().unwrap();
//!
//! // Grab the next read block in the ring
//! let mut read_block = reader.next().unwrap();
//!
//! // Read using std::io::Read
//! let mut buf = [0u8; 10];
//! read_block.read_exact(&mut buf).unwrap();
//! ```
//!
//! without that `write_block.commit()` line, this code would not compile as there still exists a write in progress.
//! Additionally, you can only ever `split` once, so you'll only ever have a single reader and writer for each type.
//!
//! Please see the examples for some more use cases.
//!
//! ### Thanks
//!
//! Much of the implementation is inspired by other "modern" wrappings of PSRDADA, especially [PSRDADA_CPP](https://gitlab.mpcdf.mpg.de/mpifr-bdg/psrdada_cpp).
//!
//! ### License
//!
//! `psrdada-rs` is distributed under the terms of both the MIT license and the Apache License (Version 2.0).
//!
//! See [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT) for details.