Skip to main content

sim_lib_pitch_serial/
error.rs

1//! Typed tone-row construction failures.
2
3use sim_lib_serial_core::{AlphabetError, OrdinalMapError, SeriesError};
4use thiserror::Error;
5
6/// Failure while constructing the canonical alphabet or a strict tone row.
7#[derive(Clone, Debug, PartialEq, Eq, Error)]
8pub enum RowError {
9    /// The canonical pitch-class alphabet could not be constructed.
10    #[error(transparent)]
11    Alphabet(#[from] AlphabetError),
12    /// The supplied row failed canonical membership or exactly-once validation.
13    #[error(transparent)]
14    Aggregate(#[from] SeriesError),
15    /// A caller-supplied ordinal permutation was not a complete bijection.
16    #[error(transparent)]
17    OrdinalMap(#[from] OrdinalMapError),
18    /// A contiguous row segment reached outside the twelve row positions.
19    #[error("segment start {start} with length {len} is out of bounds for a twelve-tone row")]
20    SegmentOutOfBounds {
21        /// Zero-based start ordinal requested by the caller.
22        start: usize,
23        /// Number of row positions requested from `start`.
24        len: usize,
25    },
26    /// A wrapped row segment exceeded the row length.
27    #[error("wrapped segment length {len} exceeds the row length")]
28    WrappedSegmentTooLong {
29        /// Number of row positions requested for the wrapped segment.
30        len: usize,
31    },
32    /// An indexed segment referenced an invalid row ordinal.
33    #[error("row ordinal {ordinal} is out of bounds for a twelve-tone row")]
34    InvalidOrdinal {
35        /// Zero-based row ordinal that fell outside `0..12`.
36        ordinal: usize,
37    },
38    /// A requested partition block contained no row ordinals.
39    #[error("partition block {block_index} is empty")]
40    EmptyPartitionBlock {
41        /// Zero-based block index in caller order.
42        block_index: usize,
43    },
44    /// A requested partition assigned one row ordinal to more than one block.
45    #[error(
46        "row ordinal {ordinal} appears in multiple partition blocks ({first_block_index} and {second_block_index})"
47    )]
48    DuplicatePartitionOrdinal {
49        /// Zero-based row ordinal that appeared more than once.
50        ordinal: u8,
51        /// First block index that claimed the ordinal.
52        first_block_index: usize,
53        /// Later block index that duplicated the ordinal.
54        second_block_index: usize,
55    },
56    /// A requested partition failed to cover the full row exactly once.
57    #[error("partition coverage is incomplete; missing row ordinals {missing:?}")]
58    PartitionCoverageMismatch {
59        /// Zero-based row ordinals that were not assigned to any block.
60        missing: Vec<u8>,
61    },
62    /// A derivation or combinatoriality partition size was unsupported.
63    #[error("partition size {size} is invalid; expected one of 2, 3, 4, or 6")]
64    InvalidPartitionSize {
65        /// The invalid partition size requested by the caller.
66        size: usize,
67    },
68}