Skip to main content

use_linkage/
lib.rs

1#![forbid(unsafe_code)]
2#![doc = include_str!("../README.md")]
3
4/// A linkage joint identifier.
5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
6pub struct JointId(pub usize);
7
8/// A bar connecting two joints.
9#[derive(Debug, Clone, Copy, PartialEq)]
10pub struct Bar {
11    start: usize,
12    end: usize,
13    length: f64,
14}
15
16impl Bar {
17    /// Creates a bar with a positive finite length.
18    #[must_use]
19    pub const fn new(start: usize, end: usize, length: f64) -> Option<Self> {
20        if start != end && length.is_finite() && length > 0.0 {
21            Some(Self { start, end, length })
22        } else {
23            None
24        }
25    }
26
27    /// Returns the endpoint joint indices.
28    #[must_use]
29    pub const fn endpoints(self) -> (usize, usize) {
30        (self.start, self.end)
31    }
32
33    /// Returns the bar length.
34    #[must_use]
35    pub const fn length(self) -> f64 {
36        self.length
37    }
38}
39
40/// A linkage summary.
41#[derive(Debug, Clone, PartialEq)]
42pub struct Linkage {
43    joint_count: usize,
44    bars: Vec<Bar>,
45}
46
47impl Linkage {
48    /// Creates a linkage with at least one joint.
49    #[must_use]
50    pub fn new(joint_count: usize, bars: Vec<Bar>) -> Option<Self> {
51        if joint_count > 0 {
52            Some(Self { joint_count, bars })
53        } else {
54            None
55        }
56    }
57
58    /// Returns the joint count.
59    #[must_use]
60    pub const fn joint_count(&self) -> usize {
61        self.joint_count
62    }
63
64    /// Returns the bars.
65    #[must_use]
66    pub fn bars(&self) -> &[Bar] {
67        &self.bars
68    }
69}
70
71#[cfg(test)]
72mod tests {
73    use super::{Bar, JointId, Linkage};
74
75    #[test]
76    fn stores_linkage_records() {
77        let bar = Bar::new(0, 1, 2.0).expect("valid bar");
78        let linkage = Linkage::new(4, vec![bar]).expect("valid linkage");
79
80        assert_eq!(JointId(2).0, 2);
81        assert_eq!(bar.endpoints(), (0, 1));
82        assert_eq!(bar.length(), 2.0);
83        assert_eq!(linkage.joint_count(), 4);
84        assert_eq!(linkage.bars(), &[bar]);
85    }
86}