Learning Rust : Solar Systems

How do I store non-owning references to collection members?
<

I want to make a data-driven viewer for the solar system, as part of a game inspired by Aurora 4x but Rust is an entirely different beast from C.

I have prior experience writing systems like this, so I figured it would be as easy as:


pub struct Orbital {
    //Some optional non-owning reference to the parent orbital
    mass : f64,
    semi_major_axis : f64,
    eccentricity : f64,
    inclination : f64,
    long_asc_node : f64,
    argument_periapsis : f64,
    mean_anomaly_epoch : f64
}
            

The question then is: How do we store the reference to the parent orbital?

note: by parent orbital, I mean the orbital body that the given orbital body orbits.

In C, we would just store a pointer into the data of the owning container (i.e. a dynamic array).

I understand that the method above could cause problems with object lifetimes and dead references, but in this case we are assuming a static lifetime with a fixed-width container.

So my first instinct is to look in the Rust docs for a non-owning reference type.

I wasted about a day researching Rc's and RefCell's when I had a revelation; what I wanted was over-engineered. Instead of storing a reference to the parent orbital, I could just store an index into the system's orbital container. All I need to do to make this work is pass a borrowed ref to the system object to the orbital's update function.

But not every part of the update function needs the parent orbital's position, so I can split the update into two parts:

1: Update the orbital elements relative to the parent object

2: Use the parent orbital's position to transform the relative coordinates into absolute coordinates

So here's what I came up with.


pub struct Orbital {
    parent_index : usize,
    //Temporary state variables for later update.
    rel_pos : (f64, f64, f64)
    //Orbital parameters
    mass : f64,
    semi_major_axis : f64,
    eccentricity : f64,
    inclination : f64,
    long_asc_node : f64,
    argument_periapsis : f64,
    mean_anomaly_epoch : f64
}
//...
impl Orbital {
//...
    pub fn update_rel(&mut self) -> Orbital {
        //...
    }
    
    pub fn update(&self, &system : System) -> (f64, f64, f64) {
        //...
    }
}