Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
Signed-off-by: Joe McCain III <jo3mccain@icloud.com>
  • Loading branch information
FL03 committed Aug 22, 2024
1 parent 379165d commit 8d714ad
Show file tree
Hide file tree
Showing 12 changed files with 110 additions and 74 deletions.
14 changes: 7 additions & 7 deletions neo/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#[doc(hidden)]
pub use res::EResult;
/// A type alias for a [`Result`](core::result::Result) that uses the [`TriadError`](TriadError) type.
pub type TriadResult<T = ()> = core::result::Result<T, TriadError>;
pub type TriadResult<T = ()> = core::result::Result<T, NeoError>;

use rstmt::{Note, Pitch};

Expand All @@ -29,7 +29,7 @@ use rstmt::{Note, Pitch};
)]
#[repr(C)]
#[strum(serialize_all = "PascalCase")]
pub enum TriadError {
pub enum NeoError {
#[error("InvalidPitch: {0}")]
InvalidPitch(String),
#[error(
Expand All @@ -46,7 +46,7 @@ pub enum TriadError {
Unknown(String),
}

impl TriadError {
impl NeoError {
pub fn invalid_pitch(msg: impl ToString) -> Self {
Self::InvalidPitch(msg.to_string())
}
Expand All @@ -68,15 +68,15 @@ impl TriadError {
}
}

impl From<Pitch> for TriadError {
impl From<Pitch> for NeoError {
fn from(err: Pitch) -> Self {
TriadError::InvalidPitch(err.to_string())
NeoError::InvalidPitch(err.to_string())
}
}

impl From<(Note, Note, Note)> for TriadError {
impl From<(Note, Note, Note)> for NeoError {
fn from((r, t, f): (Note, Note, Note)) -> Self {
TriadError::InvalidTriad(format!("({}, {}, {})", r, t, f))
NeoError::InvalidTriad(format!("({}, {}, {})", r, t, f))
}
}

Expand Down
4 changes: 2 additions & 2 deletions neo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ extern crate rstmt_core as rstmt;

#[doc(inline)]
pub use self::{
error::{TriadError, TriadResult},
error::{NeoError, TriadResult},
transform::LPR,
triad::{
kinds::{Augmented, Diminished, Major, Minor},
Expand Down Expand Up @@ -40,7 +40,7 @@ pub(crate) mod impls {
}

pub mod prelude {
pub use crate::error::{TriadError, TriadResult};
pub use crate::error::{NeoError, TriadResult};
pub use crate::tonnetz::prelude::*;
pub use crate::transform::prelude::*;
pub use crate::triad::prelude::*;
Expand Down
20 changes: 19 additions & 1 deletion neo/src/transform/lpr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
Appellation: lpr <module>
Contrib: FL03 <jo3mccain@icloud.com>
*/
use crate::triad::{Triad, TriadKind};
use crate::NeoError;
/// # LPR Transformations
///
///
/// The neo-Riemannian theory focuses on three primary transformations, namely: leading (L),
/// parallel (P), and relative (R). Each transformation operates on a particular chord factor
/// determined by the class of the triad. Additionally, each transformation is its own inverse
Expand Down Expand Up @@ -67,4 +69,20 @@ impl LPR {
pub fn relative() -> Self {
LPR::R
}

pub fn apply<K, J>(self, triad: Triad<K>) -> Result<Triad<J>, NeoError>
where
K: TriadKind<Rel = J>,
{
use super::utils::{_leading, _parallel, _relative};
let rt = triad.root_to_third()?;
let chord = triad.as_tuple();
let (r, t, f) = match self {
LPR::L => _leading(chord, rt),
LPR::P => _parallel(chord, rt),
LPR::R => _relative(chord, rt),
};

Triad::try_from_notes(r, t, f)
}
}
5 changes: 2 additions & 3 deletions neo/src/transform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#[doc(inline)]
pub use self::{lpr::LPR, transformer::Transformer};


pub(crate) mod lpr;
pub(crate) mod transformer;

Expand All @@ -23,13 +22,13 @@ pub trait Transform<F> {
}
pub(crate) mod utils {
use super::LPR;
use crate::prelude::TriadError;
use crate::prelude::NeoError;
use rstmt::{IntervalOps, Note, Third};

pub(crate) fn _transform(
chord: (Note, Note, Note),
dirac: LPR,
) -> Result<(Note, Note, Note), TriadError> {
) -> Result<(Note, Note, Note), NeoError> {
let rt = Third::new(chord.0, chord.1)?;
let (r, t, f) = match dirac {
LPR::L => _leading(chord, rt),
Expand Down
26 changes: 21 additions & 5 deletions neo/src/transform/transformer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
*/
use super::{utils::*, LPR};
use crate::triad::{Triad, TriadKind};
use crate::TriadError;
use crate::NeoError;

pub struct Transformer<K> {
delta: Option<LPR>,
triad: Triad<K>,
}

impl<K> Transformer<K> {
#[allow(dead_code)]
pub(crate) fn new(triad: Triad<K>) -> Self {
Self { delta: None, triad }
}
Expand All @@ -23,22 +24,37 @@ impl<K> Transformer<K> {
}
}

pub fn transform<J>(self) -> Result<Triad<J>, TriadError>
pub fn leading(self) -> Self {
self.apply(LPR::L)
}

pub fn parallel(self) -> Self {
self.apply(LPR::P)
}

pub fn relative(self) -> Self {
self.apply(LPR::R)
}
/// Transforms a triad into another triad based on the specified transformation.
pub fn transform<J>(self) -> Result<Triad<J>, NeoError>
where
K: TriadKind<Rel = J>,
{
let Transformer { triad, delta } = self;
let delta = delta.ok_or(TriadError::transformation_error(
let delta = delta.ok_or(NeoError::transformation_error(
"No transformation specified...",
))?;
let rt = triad.root_to_third()?;
// compute the interval between the root and third factors
let rt = rstmt::Third::new(triad.root(), triad.third())?;
// convert the triad into a 3-tuple
let chord = triad.as_tuple();
// match the transformation
let (r, t, f) = match delta {
LPR::L => _leading(chord, rt),
LPR::P => _parallel(chord, rt),
LPR::R => _relative(chord, rt),
};

// try constructing a new triad from the transformed notes
Triad::try_from_notes(r, t, f)
}
}
6 changes: 3 additions & 3 deletions neo/src/triad/kinds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pub use self::{classes::*, traits::*};
mod classes;
mod traits;

use crate::TriadError;
use crate::NeoError;
use core::marker::PhantomData;
use rstmt::{Fifth, Note, Third};

Expand Down Expand Up @@ -58,14 +58,14 @@ impl Triads {
Triads::Diminished
}
}
pub fn try_from_notes(root: Note, third: Note, fifth: Note) -> Result<Self, TriadError> {
pub fn try_from_notes(root: Note, third: Note, fifth: Note) -> Result<Self, NeoError> {
use strum::IntoEnumIterator;
for i in Self::iter() {
if i.is_valid(root, third, fifth) {
return Ok(i);
}
}
Err(TriadError::invalid_triad(
Err(NeoError::invalid_triad(
"The given notes do not form a valid triad...",
))
}
Expand Down
10 changes: 3 additions & 7 deletions neo/src/triad/kinds/classes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Appellation: classes <module>
Contrib: FL03 <jo3mccain@icloud.com>
*/
use super::{Class, Kind, Relative, TriadCls, TriadKind};
use super::{Kind, Relative, TriadCls, TriadKind};
use crate::triad::Triads;

macro_rules! class {
Expand Down Expand Up @@ -38,8 +38,6 @@ macro_rules! class {
}
}

impl Class for $name {}

impl Kind for $name {
type Class = Triads;

Expand All @@ -52,8 +50,6 @@ macro_rules! class {
}
}



impl TriadCls for $name {
seal!();

Expand Down Expand Up @@ -105,9 +101,9 @@ macro_rules! class {
};
}

class!(
class! {
Augmented::augmented(relative: Diminished),
Diminished::diminished(relative: Augmented),
Major::major(relative: Minor),
Minor::minor(relative: Major),
);
}
17 changes: 8 additions & 9 deletions neo/src/triad/kinds/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ use crate::triad::Triads;
use core::marker::PhantomData;
use rstmt::{Fifth, Note, Third};

pub trait Class {}
#[doc(hidden)]
pub trait Group {}

#[doc(hidden)]
pub trait Kind {
type Class: Class;
type Class;

fn class() -> Self::Class
where
Expand All @@ -23,7 +25,7 @@ pub trait Kind {
/// This trait denotes privately declared instances of different classes of triads.
/// Traditionally, triads have two primary classes: [major](Major) and [minor](Minor), however, there are
/// two additional classes: [augmented](Augmented) and [diminished](Diminished). This trait is used to determine
pub trait TriadCls: Class {
pub trait TriadCls {
private!();

fn named(&self) -> &'static str;
Expand All @@ -43,9 +45,8 @@ pub trait TriadKind: Kind<Class = Triads> {
type Rel: TriadKind;
private!();

/// Returns a new instance of [PhantomData](core::marker::PhantomData);
/// This method is the only possible constructor for these objects,
/// a charecteristic enfored with 0-variant enum declarations.
/// Returns a new instance of [PhantomData]; This method is the only possible constructor
/// for these objects, a charecteristic enfored with 0-variant enum declarations.
fn phantom() -> core::marker::PhantomData<Self>
where
Self: Sized,
Expand Down Expand Up @@ -128,7 +129,7 @@ pub trait TriadKind: Kind<Class = Triads> {
/*
************* Implementations *************
*/
impl Class for Triads {}
impl Group for Triads {}

impl TriadCls for Triads {
seal!();
Expand All @@ -154,8 +155,6 @@ where
}
}

impl<K> Class for PhantomData<K> where K: Kind<Class = Triads> {}

impl<K> Kind for PhantomData<K>
where
K: Kind<Class = Triads>,
Expand Down
10 changes: 5 additions & 5 deletions neo/src/triad/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ pub(crate) mod prelude {
}

pub(crate) mod utils {
use crate::error::TriadError;
use crate::error::NeoError;
use rstmt::{Fifth, Note, Third};

#[doc(hidden)]
pub fn try_from_arr(notes: [Note; 3]) -> Result<(Note, Note, Note), TriadError> {
pub fn try_from_arr(notes: [Note; 3]) -> Result<(Note, Note, Note), NeoError> {
use itertools::Itertools;
for (&a, &b, &c) in notes.iter().circular_tuple_windows() {
if Third::new(a, b).is_ok() && Third::new(b, c).is_ok() && Fifth::new(a, c).is_ok() {
Expand All @@ -29,13 +29,13 @@ pub(crate) mod utils {
continue;
}
}
Err(TriadError::invalid_triad(
Err(NeoError::invalid_triad(
"Failed to find the required relationships within the given notes...",
))
}
}

use crate::{Factors, TriadError};
use crate::{Factors, NeoError};

/// [IntoTriad] converts a type into a [Triad].
pub trait IntoTriad {
Expand All @@ -47,7 +47,7 @@ pub trait IntoTriad {
pub trait TryIntoTriad {
type Kind;

fn try_into_triad(self) -> Result<Triad<Self::Kind>, TriadError>;
fn try_into_triad(self) -> Result<Triad<Self::Kind>, NeoError>;
}

pub trait TriadData {
Expand Down
Loading

0 comments on commit 8d714ad

Please sign in to comment.