bellframe 0.11.5

Fast and idiomatic primitives for Change Ringing.
Documentation
use crate::{method::LABEL_LEAD_END, Block, PnBlock, Row, Stage};

pub const NOTATION_BOB: char = '-';
pub const NOTATION_SINGLE: char = 's';

#[derive(Debug, Clone)]
pub struct Call {
    notation: char,
    label: String,
    covers: usize,
    /// The block replaced by this `Call`.
    ///
    /// Invariant: This must start with rounds
    block: Block<()>,
}

// `Call`s can't have size 0 because it is backed by a `Block`, which enforces a non-zero size
// invariant.
#[allow(clippy::len_without_is_empty)]
impl Call {
    /// Creates a new `Call` from its parts
    #[inline]
    pub fn new(notation: char, label: String, covers: usize, block: Block<()>) -> Self {
        Call {
            notation,
            label,
            covers,
            block,
        }
    }

    /// Creates a call with notation `'-'`, which covers only the lead end
    pub fn le_bob(pn_block: PnBlock) -> Self {
        Self::new(
            NOTATION_BOB,
            LABEL_LEAD_END.to_owned(),
            pn_block.len(),
            pn_block.to_block_from_rounds(),
        )
    }

    /// Creates a call with notation `'s'`, which covers only the lead end
    pub fn le_single(pn_block: PnBlock) -> Self {
        Self::new(
            NOTATION_SINGLE,
            LABEL_LEAD_END.to_owned(),
            pn_block.len(),
            pn_block.to_block_from_rounds(),
        )
    }

    /// Gets the [`Block`] representing the chunk of composition generated by this `Call`.
    #[inline]
    pub fn block(&self) -> &Block<()> {
        &self.block
    }

    /// Gets the [`Stage`] of this `Call`
    #[inline]
    pub fn stage(&self) -> Stage {
        self.block.stage()
    }

    /// Gets the effective [`Stage`] of this `Call` (i.e. no places above this [`Stage`] are
    /// affected by the call).
    #[inline]
    pub fn effective_stage(&self) -> Stage {
        self.block.effective_stage()
    }

    /// Gets the number of [`Row`]s that will be covered by this `Call`
    #[inline]
    pub fn cover_len(&self) -> usize {
        self.covers
    }

    /// Gets the number of [`Row`]s that will be **generated** by this `Call`
    #[inline]
    pub fn len(&self) -> usize {
        self.block.len()
    }

    /// Gets the [`char`] that represents this `Call`.
    #[inline]
    pub fn notation(&self) -> char {
        self.notation
    }

    /// Gets the label that this `Call` can be applied to
    #[inline]
    pub fn label(&self) -> &str {
        &self.label
    }

    /// Returns a [`Row`] representing the overall transposition of this `Call` (i.e. the
    /// permutation which maps the [`Row`] where this `Call` starts to the [`Row`] where it ends).
    #[inline]
    pub fn transposition(&self) -> &Row {
        self.block.leftover_row()
    }
}