pub struct GravParam<P>where
P: Planet,{
pub value: f64,
/* private fields */
}Expand description
Gravitational parameter μ = GM tagged with the source planet P.
GravParam<Earth> and GravParam<Sun> are distinct types so the
compiler refuses to silently feed μ_Sun into a function expecting
μ_Earth. The numeric value is stored in SI base units (m³/s²) and
reachable via GravParam::value (also a public field for the
kernel-level call sites that already do mu.value).
§Construction
Mission code constructs a GravParam<P> through the inferred-planet
factory f64::m3_per_s2() (planet <P> inferred from the
expected-type context at the call site — see
crate::ext::F64Ext::m3_per_s2 for the full story; a bare
let mu = 1.0.m3_per_s2(); with no expected-type context fails to
compile), the explicit-planet factory f64::m3_per_s2_for::<P>(), or
one of the curated mu_*() constants in
astrodyn::recipes::constants. Calling a typed consumer with a
SelfPlanet-tagged μ in a planet-pinned slot is rejected at compile
time, so a planet-erased μ only flows through SelfPlanet-typed
surfaces (the registry-side boundary code, GravitySource, etc.).
use astrodyn_quantities::prelude::*;
// Planet-pinned construction (Earth):
let mu_earth: GravParam<Earth> = 3.986_004_415e14_f64.m3_per_s2_for::<Earth>();
// Type ascription supplies the inference context for `<P>`:
let mu_sun: GravParam<Sun> = 1.327_124_400_18e20_f64.m3_per_s2();
// The numeric SI value in m³/s² is reachable via `.value`:
assert!(mu_earth.value > 0.0);
assert!(mu_sun.value > 0.0);§Compile-fail: cross-planet construction is rejected
Building a planet-pinned GravParam<Earth> directly from a
GravParam<Sun> is a type error — the compiler refuses the
assignment.
use astrodyn_quantities::prelude::*;
let mu_sun: GravParam<Sun> = 1.327e20.m3_per_s2_for::<Sun>();
let _bad: GravParam<Earth> = mu_sun; // planet phantom mismatchA planet-erased GravParam<SelfPlanet> cannot be assigned to a
planet-pinned slot either — SelfPlanet is not Earth:
use astrodyn_quantities::prelude::*;
let mu_any: GravParam<SelfPlanet> = 3.986e14.m3_per_s2();
let _bad: GravParam<Earth> = mu_any; // SelfPlanet vs Earth mismatch§Compile-fail: there is no <P = SelfPlanet> default
GravParam<P> carries no default planet — every call site must
commit to a planet via turbofish, type ascription, or argument
inference. A bare GravParam::from_si(...) with no inference
context is rejected. There is deliberately no <P = SelfPlanet>
fallback: a default would silently relax to <SelfPlanet> whenever
inference had no constraint, hiding missing planet-pinning
decisions. The type system is meant to surface those at compile
time, not satisfy them with a wildcard:
use astrodyn_quantities::prelude::*;
// No type context for `<P>`, no turbofish, no default — type
// annotations needed.
let _mu = GravParam::from_si(3.986_004_415e14);The fix is to commit to a planet at the call site:
use astrodyn_quantities::prelude::*;
let _mu = GravParam::<Earth>::from_si(3.986_004_415e14);Fields§
§value: f64Numeric value in SI base units (m³/s²).
The field is public so internal physics kernels can read it via
mu.value without going through an accessor — the typed planet
phantom is the load-bearing part, not the wrapping ceremony.
Implementations§
Source§impl<P> GravParam<P>where
P: Planet,
impl<P> GravParam<P>where
P: Planet,
Sourcepub const fn from_si(value: f64) -> GravParam<P>
pub const fn from_si(value: f64) -> GravParam<P>
Construct a GravParam<P> from its SI base value (m³/s²).
This is the witness-gated constructor: the planet phantom is
fixed by the turbofish or by the surrounding type context.
Mission code typically reaches this through
crate::ext::F64Ext::m3_per_s2_for or the curated mu_*()
constants rather than calling from_si directly.
Source§impl GravParam<SelfPlanet>
impl GravParam<SelfPlanet>
Sourcepub fn relabel<Q>(self) -> GravParam<Q>where
Q: Planet,
pub fn relabel<Q>(self) -> GravParam<Q>where
Q: Planet,
Relabel a planet-erased (SelfPlanet) μ as belonging to a
specific planet Q.
Restricted to impl GravParam<SelfPlanet> so it can only retag a
μ that is already planet-erased — a planet-pinned GravParam<Sun>
cannot accidentally be relabeled as GravParam<Earth> via this
method. Provided only for the registry-side boundary code
that stores μ values keyed by a runtime source ID — the gravity
source registry, GravitySourceTyped, the dynamic mu carried on
PlanetShape, and similar surfaces where the planet identity is
determined at runtime. Mission code that knows the planet at
compile time should construct a planet-tagged GravParam<Q>
directly via m3_per_s2_for::<Q>() or one of the mu_*()
constants.
A genuine <P> → <Q> retag for two distinct named planets is
almost never the right operation (μ is per-body); if you need it
for a different reason, add a separate, clearly-named escape
hatch instead of widening this impl block.
Trait Implementations§
Source§impl<P> IntoGravParam<P> for GravParam<P>where
P: Planet,
impl<P> IntoGravParam<P> for GravParam<P>where
P: Planet,
Source§fn into_grav_param(self) -> GravParam<P>
fn into_grav_param(self) -> GravParam<P>
self into a typed GravParam<P> (m³/s²).Source§impl<P> PartialEq for GravParam<P>where
P: Planet,
impl<P> PartialEq for GravParam<P>where
P: Planet,
impl<P> Copy for GravParam<P>where
P: Planet,
Auto Trait Implementations§
impl<P> Freeze for GravParam<P>
impl<P> RefUnwindSafe for GravParam<P>where
P: RefUnwindSafe,
impl<P> Send for GravParam<P>
impl<P> Sync for GravParam<P>
impl<P> Unpin for GravParam<P>where
P: Unpin,
impl<P> UnsafeUnpin for GravParam<P>
impl<P> UnwindSafe for GravParam<P>where
P: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.