Skip to main content

geop_ops_harness/
cable.rs

1//! A part's cables, kept as its target [`cables`]: what a routed harness is
2//! cut from — its wires, each with the length to cut it to — recorded by
3//! the step that routed it, for its editor to show. What a bill of
4//! materials orders of it is noted on its bundle (see
5//! [`geop_ops_model::solid_notes`]).
6
7use geop_core_math::{
8    geop_error::{GeopError, GeopResult},
9    scalars::Scalar,
10};
11use geop_core_program::{
12    element::{ElementReference, HasElements, Kind},
13    reader::Reader,
14    target::TargetReference,
15};
16use geop_ops_model::{CutWire, Records};
17
18/// A bundle of wires laid along one route.
19#[derive(Clone, Debug, PartialEq)]
20pub struct Cable {
21    /// How long the route is, end to end.
22    pub length: Scalar,
23    /// The bundle's diameter, which its solid is swept with.
24    pub diameter: f64,
25    /// The smallest radius the route may bend with.
26    pub min_bend_radius: f64,
27    /// The smallest radius it does bend with — `None` for a straight one.
28    pub tightest_bend: Option<Scalar>,
29    pub wires: Vec<CutWire>,
30}
31
32/// A part's cables, by the name of the solid each is swept into: the value
33/// of its target [`cables`], which every step that routes one revises.
34pub type Cables = Records<Cable>;
35
36/// The part's cables.
37pub fn cables() -> TargetReference<Cables> {
38    TargetReference::new("cables")
39}
40
41/// A cable, by the name of the solid it is swept into: an element of
42/// [`cables`].
43impl Kind for Cable {
44    const NAME: &'static str = "cable";
45}
46
47impl HasElements<Cable> for Cables {
48    type Element<'a> = &'a Cable;
49    const SINGLETON: Option<&'static str> = Some("cables");
50
51    fn element(&self, name: &str) -> GeopResult<&Cable> {
52        self.get(name)
53            .ok_or_else(|| GeopError::new(format!("the part has no cable named {name:?}")))
54    }
55}
56
57/// The cable `name` of the part `reader` reads, if it has one: none before
58/// a step routed one.
59pub fn cable<'a>(reader: &Reader<'a>, name: &str) -> Option<&'a Cable> {
60    reader.defines(&cables()).then_some(())?;
61    reader
62        .retrieve_element(&ElementReference::new(cables(), name))
63        .ok()
64}