rubbl_core/lib.rs
1// Copyright 2017-2023 Peter Williams and collaborators
2// Licensed under the MIT License.
3
4//! Core types and concepts of the Rubbl framework.
5//!
6//! This crate provides low-level types that are expected to be used throughout
7//! the Rubbl framework.
8//!
9//! # Crate Duplication and Re-Exports
10//!
11//! This crate depends on several foundational crates that your upstream project
12//! may also explicitly depend on, such as [`ndarray`]. If your project depends
13//! on a version of one of these crates that is not compatible with the version
14//! required by this crate, Cargo will build duplicated versions of these crates
15//! that, while they have the same name, cannot be intermixed. See [this crate’s
16//! Crates.io README][1] for a more detailed discussion.
17//!
18//! [1]: https://crates.io/crates/rubbl_core/
19//!
20//! If you are in a situation where you can't avoid this duplication, this crate
21//! re-exports some of its dependencies, providing a way to reliably name the specific
22//! version that it’s referencing.
23
24#![deny(missing_docs)]
25
26// convenience re-exports; these can help consumers make sure they're referencing the
27// same types if a crate gets duplicated. See also the README.
28#[cfg(feature = "anyhow")]
29pub use anyhow;
30pub use ndarray::{self, Array, CowArray};
31pub use num_complex::{self, Complex};
32
33pub mod io;
34#[cfg(feature = "notifications")]
35pub mod notify;
36pub mod num;
37
38/// A “contextualized try” macro.
39///
40/// This macro is syntactic sugar. The expression
41///
42/// ```rust
43/// # use rubbl_core::ctry;
44/// # use anyhow::*;
45/// # fn myfun() -> Result<(), Error> {
46/// # let op: Result<(), Error> = Ok(());
47/// # let value = "something";
48/// ctry!(op; "spec: {}", value)
49/// # ;
50/// # Ok(())
51/// # }
52/// ```
53///
54/// is equivalent to:
55///
56/// ```rust
57/// # use anyhow::*;
58/// # fn myfun() -> Result<(), Error> {
59/// # let op: Result<(), Error> = Ok(());
60/// # let value = "something";
61/// {
62/// use anyhow::Context;
63/// op.with_context(|| format!("spec: {}", value))?
64/// }
65/// # Ok(())
66/// # }
67/// ```
68///
69/// So, it attempts an operation that returns a [`Result`] (or [`Option`]) and
70/// evaluates to its [`Ok`] (or [`Some`]) value if the operation is successful.
71/// If not, it exits the current function with an [`Err`] value that has a
72/// formatted context string attached to it.
73///
74/// #### Example
75///
76/// ```rust
77/// # use anyhow::Error;
78/// # fn myfun() -> Result<(), Error> {
79/// use rubbl_core::ctry;
80/// use std::{fs::File, io::Write};
81///
82/// let path = "myfile.txt";
83/// let mut myfile = ctry!(File::open(path); "failed to open file `{}`", path);
84/// ctry!(write!(myfile, "hello"); "failed to write to file `{}`", path);
85/// # Ok(())
86/// # }
87/// ```
88#[macro_export]
89macro_rules! ctry {
90 ($op:expr ; $( $chain_fmt_args:expr ),*) => {
91 {
92 use anyhow::Context;
93 $op.with_context(|| format!($( $chain_fmt_args ),*))?
94 }
95 }
96}