Skip to content

Commit

Permalink
docs: Add documentation for the async API
Browse files Browse the repository at this point in the history
This adds a section to the README and some doc tests. This also gates
the sync and async doc tests behind their respective features.

Signed-off-by: Kiran Ostrolenk <[email protected]>
  • Loading branch information
CardboardTurkey committed Feb 8, 2024
1 parent 3b5a738 commit cbea9ca
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 8 deletions.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ tokio = ["hepmc2-macros/tokio", "dep:tokio"]
criterion = "0.5.1"
rand = "0.8.4"
rand_xoshiro = "0.6.0"
tokio = { version = "1.35.1", features = ["rt", "macros"] }
tokio = { version = "1.35.1", features = ["rt", "macros", "fs"] }
tokio-test = "0.4.3"

[[bench]]
name = "benchmark"
Expand Down
44 changes: 44 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,48 @@ for event in in_events {
writer.finish()?;
```

## Async API

By default this crate enables the `sync` feature which exposes a sync API. You
can however switch to using a `tokio`-backed async API by disabling the `sync`
feature and enabling the `tokio` feature.

Either run the following in the root of your crate:

```sh
cargo add hepmc2 --no-default-features -F tokio
```

or make sure a line like the following is present in your `Cargo.toml`:

```toml
hepmc2 = { version = "0.6.0", default-features = false, features = ["tokio"] }
```

The async API is exactly the same as the sync one but IO operations will return
futures that you will, as usual, need to call `await` on.

### Example

```rust
// Read events from `events_in.hepmc2` and write them to `events_out.hepmc2`
use hepmc2::{Reader, Writer};

use tokio::io::BufReader;
use tokio::fs::File;

let input = BufReader::new(File::open("events_in.hepmc2").await?);
let mut in_events = Reader::from(input);

let output = File::create("events_out.hepmc2").await?;
let mut writer = Writer::try_from(output).await?;

while let Some(event) = in_events.next().await {
let event = event?;
println!("Current cross section: {}", event.xs);
writer.write(&event).await?
}
writer.finish().await?;
```

License: GPL-3.0-or-later
2 changes: 2 additions & 0 deletions benches/benchmark.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![cfg(feature = "sync")]

use std::convert::{AsRef, From};
use std::default::Default;
use std::f64::consts::PI;
Expand Down
58 changes: 57 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
//!
//! # Example
//!
//! ```rust,no_run
#![cfg_attr(feature = "sync", doc = "```no_run")]
#![cfg_attr(not(feature = "sync"), doc = "```ignore")]
//! // Read events from `events_in.hepmc2` and write them to `events_out.hepmc2`
//! use hepmc2::{Reader, Writer};
//!
Expand All @@ -31,6 +32,61 @@
//! writer.finish()?;
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! ## Async API
//!
//! By default this crate enables the `sync` feature which exposes a sync API. You
//! can however switch to using a `tokio`-backed async API by disabling the `sync`
//! feature and enabling the `tokio` feature.
//!
//! Either run the following in the root of your crate:
//!
//! ```sh
//! cargo add hepmc2 --no-default-features -F tokio
//! ```
//!
//! or make sure a line like the following is present in your `Cargo.toml`:
//!
//! ```toml
//! hepmc2 = { version = "0.6.0", default-features = false, features = ["tokio"] }
//! ```
//!
//! The async API is exactly the same as the sync one but IO operations will return
//! futures that you will, as usual, need to call `await` on. For examples, generate
//! the async API documentation in the root of this project:
//!
//! ```sh
//! cargo doc --open --no-default-features -F tokio
//! ```
//!
//! ### Example
//!
#![cfg_attr(feature = "sync", doc = "```ignore")]
#![cfg_attr(not(feature = "sync"), doc = "```no_run")]
//! # async fn try_main() -> Result<(), Box<dyn std::error::Error>> {
//! // Read events from `events_in.hepmc2` and write them to `events_out.hepmc2`
//! use hepmc2::{Reader, Writer};
//!
//! use tokio::io::BufReader;
//! use tokio::fs::File;
//!
//! let input = BufReader::new(File::open("events_in.hepmc2").await?);
//! let mut in_events = Reader::from(input);
//!
//! let output = File::create("events_out.hepmc2").await?;
//! let mut writer = Writer::try_from(output).await?;
//!
//! while let Some(event) = in_events.next().await {
//! let event = event?;
//! println!("Current cross section: {}", event.xs);
//! writer.write(&event).await?
//! }
//! writer.finish().await?;
//! # Ok(())
//! # }
//! # tokio_test::block_on(async {try_main().await.unwrap()})
//! ```

pub mod event;
pub mod reader;
pub mod writer;
Expand Down
79 changes: 73 additions & 6 deletions src/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ impl<T> Writer<T> {
///
/// # Example
///
/// ```rust
#[cfg_attr(feature = "sync", doc = "```")]
#[cfg_attr(not(feature = "sync"), doc = "```ignore")]
/// use hepmc2::writer::Writer;
///
/// let mut output = Vec::new();
Expand All @@ -50,6 +51,18 @@ impl<T> Writer<T> {
/// writer.finish()?;
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
///
#[cfg_attr(feature = "sync", doc = "```ignore")]
#[cfg_attr(not(feature = "sync"), doc = "```")]
/// # tokio_test::block_on(async {
/// use hepmc2::writer::Writer;
///
/// let mut output = Vec::new();
/// let mut writer = Writer::new(&mut output).await.unwrap();
/// // always call finish at the end
/// writer.finish().await.unwrap();
/// # })
/// ```
#[maybe_async::maybe_async]
pub async fn new(stream: T) -> Result<Self, io::Error> {
Self::with_header(stream, DEFAULT_HEADER).await
Expand All @@ -62,7 +75,10 @@ impl<T> Writer<T> {
///
/// # Example
///
/// ```rust
/// ## Sync
///
#[cfg_attr(feature = "sync", doc = "```")]
#[cfg_attr(not(feature = "sync"), doc = "```ignore")]
/// use hepmc2::writer::Writer;
///
/// let mut output = Vec::new();
Expand All @@ -71,6 +87,20 @@ impl<T> Writer<T> {
/// writer.finish()?;
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
///
/// ## Async
///
#[cfg_attr(feature = "sync", doc = "```ignore")]
#[cfg_attr(not(feature = "sync"), doc = "```")]
/// # tokio_test::block_on(async {
/// use hepmc2::writer::Writer;
///
/// let mut output = Vec::new();
/// let mut writer = Writer::with_header(output, "").await.unwrap();
/// // always call finish at the end
/// writer.finish().await.unwrap();
/// # })
/// ```
#[maybe_async::maybe_async]
pub async fn with_header<U: Display>(
stream: T,
Expand All @@ -90,15 +120,32 @@ impl<T> Writer<T> {
///
/// # Example
///
/// ```rust
/// ## Sync
///
#[cfg_attr(feature = "sync", doc = "```")]
#[cfg_attr(not(feature = "sync"), doc = "```ignore")]
/// use hepmc2::writer::Writer;
///
///
/// let mut output = Vec::new();
/// let mut writer = Writer::new(&mut output)?;
/// // always call finish at the end
/// writer.finish()?;
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
///
/// ## Async
///
#[cfg_attr(feature = "sync", doc = "```ignore")]
#[cfg_attr(not(feature = "sync"), doc = "```")]
/// # tokio_test::block_on(async {
/// use hepmc2::writer::Writer;
///
/// let mut output = Vec::new();
/// let mut writer = Writer::new(&mut output).await.unwrap();
/// // always call finish at the end
/// writer.finish().await.unwrap();
/// # })
/// ```
#[maybe_async::maybe_async]
pub async fn finish(mut self) -> Result<(), std::io::Error> {
self.ref_finish().await
Expand All @@ -108,10 +155,13 @@ impl<T> Writer<T> {
///
/// # Example
///
/// ```rust
/// ## Sync
///
#[cfg_attr(feature = "sync", doc = "```")]
#[cfg_attr(not(feature = "sync"), doc = "```ignore")]
/// use hepmc2::writer::Writer;
/// use hepmc2::event::Event;
///
///
/// let mut output = Vec::new();
/// let mut writer = Writer::new(&mut output)?;
/// let event = Event::default();
Expand All @@ -120,6 +170,23 @@ impl<T> Writer<T> {
/// writer.finish()?;
/// # Ok::<(), Box<dyn std::error::Error>>(())
/// ```
///
/// ## Async
///
#[cfg_attr(feature = "sync", doc = "```ignore")]
#[cfg_attr(not(feature = "sync"), doc = "```")]
/// # tokio_test::block_on(async {
/// use hepmc2::writer::Writer;
/// use hepmc2::event::Event;
///
/// let mut output = Vec::new();
/// let mut writer = Writer::new(&mut output).await.unwrap();
/// let event = Event::default();
/// writer.write(&event).await.unwrap();
/// // always call finish at the end
/// writer.finish().await.unwrap();
/// # })
/// ```
#[maybe_async::maybe_async]
pub async fn write(&mut self, event: &Event) -> Result<(), io::Error> {
self.write_event_line(event).await?;
Expand Down

0 comments on commit cbea9ca

Please sign in to comment.