rstmt_nrt/
lib.rs

1/*
2    Appellation: rstmt-nrt <library>
3    Contrib: @FL03
4*/
5//! This crate works to establish a solid foundation fo exploring the neo-riemannian theory,
6//! providing implementations of the [`Triad`], its transformations [`LPR`], and the
7//! generalized tonnetz ([`HyperTonnetz`]).
8//!
9//! ## Background
10//!
11//! The neo-riemannian theory is a loose collection of musical theories focused on the triad.
12//! Research in the field has been ongoing for over a century, culminating in the successful
13//! generalization of the tonnetz, a geometric representation of the triad and its
14//! transformations, into a single topological entity composed of individual simplices.
15//!
16//! ## Examples
17//!
18//! ### _Basic Usage_
19//!
20//! Create a C major triad and perform some basic operations.
21//!
22//! ```rust
23//! use rstmt_nrt::Triad;
24//! // initialize a c-major triad: (0, 4, 7)
25//! let triad = Triad::major(0);
26//! // verify the composition
27//! assert_eq! { triad.is_major(), triad == [0, 4, 7] }
28//! // apply a single, parallel transformation and verify
29//! assert_eq! { triad.parallel(), [0, 3, 7] }
30//! // chain together two parallel transformations to confirm inversion
31//! assert_eq! { triad.parallel().parallel(), triad }
32//! ```
33#![allow(
34    clippy::derivable_impls,
35    clippy::len_without_is_empty,
36    clippy::missing_errors_doc,
37    clippy::missing_panics_doc,
38    clippy::missing_safety_doc,
39    clippy::module_inception,
40    clippy::needless_doctest_main,
41    clippy::non_canonical_partial_ord_impl,
42    clippy::should_implement_trait,
43    clippy::upper_case_acronyms
44)]
45#![cfg_attr(not(feature = "std"), no_std)]
46#![cfg_attr(all(feature = "alloc", feature = "nightly"), feature(allocator_api))]
47// compiler check
48#[cfg(not(any(feature = "std", feature = "alloc")))]
49compile_error! { "either the \"std\" or \"alloc\" feature must be enabled" }
50// external crates
51#[cfg(feature = "alloc")]
52extern crate alloc;
53/// re-declare the external `rstmt_core` crate as `rstmt` for convenience
54extern crate rstmt_core as rstmt;
55
56#[macro_use]
57pub(crate) mod macros {
58    #[macro_use]
59    pub mod seal;
60}
61/// this module defines the standard error type, [`TriadError`], for the crate
62pub mod error;
63#[cfg(feature = "motion")]
64pub mod motion;
65#[cfg(feature = "tonnetz")]
66pub mod tonnetz;
67pub mod triad;
68
69mod impls {
70    mod impl_triad_base;
71    mod impl_triad_ext;
72    mod impl_triad_repr;
73}
74
75pub mod iter {
76    //! this module defines various iterators for traversing a tonnetz, chaining
77    //! transformations and more.
78
79    #[cfg(feature = "rayon")]
80    #[doc(inline)]
81    pub use self::parallel::ParIter;
82    #[doc(inline)]
83    pub use self::walker::Walk;
84
85    #[cfg(feature = "rayon")]
86    pub mod parallel;
87    pub mod walker;
88
89    pub(crate) mod prelude {
90        #[cfg(feature = "rayon")]
91        pub use super::parallel::*;
92        pub use super::walker::*;
93    }
94}
95
96mod traits {
97    #[doc(inline)]
98    pub use self::{raw_triad::*, triad_type::*};
99
100    mod raw_triad;
101    mod triad_type;
102}
103
104mod types {
105    #[doc(inline)]
106    pub use self::{factors::*, kinds::*, lpr::*};
107
108    mod factors;
109    mod kinds;
110    mod lpr;
111}
112// re-exports
113#[doc(inline)]
114#[cfg(feature = "tonnetz")]
115pub use self::tonnetz::HyperTonnetz;
116#[doc(inline)]
117pub use self::{error::*, iter::prelude::*, traits::*, triad::*, types::*};
118// prelude
119#[doc(hidden)]
120pub mod prelude {
121    pub use crate::iter::prelude::*;
122    #[cfg(feature = "motion")]
123    pub use crate::motion::prelude::*;
124    #[cfg(feature = "tonnetz")]
125    pub use crate::tonnetz::*;
126    pub use crate::traits::*;
127    pub use crate::triad::*;
128    pub use crate::types::*;
129}