leibniz 0.2.0

The package provides a differentiable vector graphics rasterization loss.
Documentation
//! Quadratic segment indexing.

/// Segment-local point indices for a closed quadratic contour.
#[derive(Clone, Copy)]
pub struct Indices {
    segment: usize,
    end_segment: usize,
}

impl Indices {
    /// Create indices for a segment.
    ///
    /// # Panics
    ///
    /// Panics if the segment count is zero, or if the segment index is out of
    /// bounds.
    pub fn new(segment: usize, segment_count: usize) -> Self {
        assert!(
            segment_count > 0 && segment < segment_count,
            "segment index must be in bounds for a non-empty quadratic contour"
        );

        Self {
            segment,
            end_segment: (segment + 1) % segment_count,
        }
    }

    /// Control point index.
    pub const fn control(&self) -> [usize; 2] {
        [self.segment, 1]
    }

    /// End point index.
    pub const fn end(&self) -> [usize; 2] {
        [self.end_segment, 0]
    }

    /// Start point index.
    pub const fn start(&self) -> [usize; 2] {
        [self.segment, 0]
    }
}

#[cfg(test)]
mod tests {
    use super::Indices;

    #[test]
    #[should_panic]
    fn indices_reject_empty_contour() {
        let _ = Indices::new(0, 0);
    }

    #[test]
    #[should_panic]
    fn indices_reject_out_of_bounds_segment() {
        let _ = Indices::new(2, 2);
    }

    #[test]
    fn indices_wrap_last_segment() {
        let first = Indices::new(0, 2);
        let last = Indices::new(1, 2);

        assert_eq!(first.start(), [0, 0]);
        assert_eq!(first.control(), [0, 1]);
        assert_eq!(first.end(), [1, 0]);
        assert_eq!(last.start(), [1, 0]);
        assert_eq!(last.control(), [1, 1]);
        assert_eq!(last.end(), [0, 0]);
    }
}