5.5 KiB
Story 9.8: SystemState Dedicated Struct
Status: ready-for-dev
Story
As a Rust developer,
I want a dedicated SystemState struct instead of a type alias,
so that I have layout validation, typed access methods, and better semantics for the solver state.
Acceptance Criteria
-
Given
SystemStateis currentlyVec<f64>incrates/components/src/lib.rs:182When the struct is created Thenpressure(edge_idx)returnsPressuretype Andenthalpy(edge_idx)returnsEnthalpytype Andset_pressure()andset_enthalpy()accept typed physical quantities -
Given a
SystemStateinstance When accessing data ThenAsRef<[f64]>andAsMut<[f64]>are implemented for solver compatibility AndFrom<Vec<f64>>andFrom<SystemState> for Vec<f64>enable migration -
Given invalid data (odd length vector) When calling
SystemState::from_vec()Then panic with clear error message -
Given out-of-bounds edge index When calling
pressure()orenthalpy()Then returnsNone(safe, no panic) -
Given all tests passing before change When refactoring is complete Then
cargo test --workspacepasses And public API is unchanged for solver consumers
Tasks / Subtasks
-
Task 1: Create
SystemStatestruct inentropyk_core(AC: 1, 3, 4)- Create
crates/core/src/state.rswithSystemStatestruct - Implement
new(edge_count),from_vec(),edge_count() - Implement
pressure(),enthalpy()returningOption<Pressure/Enthalpy> - Implement
set_pressure(),set_enthalpy()accepting typed values - Implement
as_slice(),as_mut_slice(),into_vec() - Implement
iter_edges()iterator
- Create
-
Task 2: Implement trait compatibility (AC: 2)
- Implement
AsRef<[f64]>for solver compatibility - Implement
AsMut<[f64]>for mutable access - Implement
From<Vec<f64>>andFrom<SystemState> for Vec<f64> - Implement
Defaulttrait
- Implement
-
Task 3: Export from
entropyk_core(AC: 5)- Add
statemodule tocrates/core/src/lib.rs - Export
SystemStatefrom crate root
- Add
-
Task 4: Migrate from type alias (AC: 5)
- Remove
pub type SystemState = Vec<f64>;fromcrates/components/src/lib.rs - Add
use entropyk_core::SystemState;to components crate - Update solver crate imports if needed
- Remove
-
Task 5: Add unit tests (AC: 3, 4)
- Test
new()creates correct size - Test
pressure()/enthalpy()accessors - Test out-of-bounds returns
None - Test
from_vec()with valid and invalid data - Test
iter_edges()iteration - Test
From/Intoconversions
- Test
-
Task 6: Add documentation (AC: 5)
- Add rustdoc for struct and all public methods
- Document layout:
[P_edge0, h_edge0, P_edge1, h_edge1, ...] - Add inline code examples
Dev Notes
Current Implementation
// crates/components/src/lib.rs:182
pub type SystemState = Vec<f64>;
Layout: Each edge in the system graph has 2 variables: [P0, h0, P1, h1, ...]
P: Pressure in Pascalsh: Enthalpy in J/kg
Proposed Implementation
// crates/core/src/state.rs
pub struct SystemState {
data: Vec<f64>,
edge_count: usize,
}
impl SystemState {
pub fn new(edge_count: usize) -> Self;
pub fn from_vec(data: Vec<f64>) -> Self; // panics on odd length
pub fn edge_count(&self) -> usize;
pub fn pressure(&self, edge_idx: usize) -> Option<Pressure>;
pub fn enthalpy(&self, edge_idx: usize) -> Option<Enthalpy>;
pub fn set_pressure(&mut self, edge_idx: usize, p: Pressure);
pub fn set_enthalpy(&mut self, edge_idx: usize, h: Enthalpy);
pub fn as_slice(&self) -> &[f64];
pub fn as_mut_slice(&mut self) -> &mut [f64];
pub fn into_vec(self) -> Vec<f64>;
pub fn iter_edges(&self) -> impl Iterator<Item = (Pressure, Enthalpy)> + '_;
}
Architecture Compliance
- NewType Pattern: Consistent with architecture requirement for type-safe physical quantities
- Zero-Allocation in Hot Path: Internal
Vec<f64>is pre-allocated; no allocation in accessors - Error Handling: Out-of-bounds returns
Option::None, not panic (exceptfrom_vecwith odd length)
Files to Touch
| File | Action |
|---|---|
crates/core/src/state.rs |
Create |
crates/core/src/lib.rs |
Add pub mod state; and re-export |
crates/components/src/lib.rs |
Remove type alias, add import from core |
crates/solver/src/*.rs |
Update imports if needed (may work via re-export) |
Project Structure Notes
SystemStatebelongs inentropyk_core(shared between solver and components)- Physical types (
Pressure,Enthalpy) already exist inentropyk_core - Solver uses
AsRef<[f64]>trait - no breaking change
Testing Standards
- Use
approxcrate for float comparisons - Tolerance: 1e-9 for exact values (matches NFR determinism requirement)
- Run
cargo test --workspaceto verify no regressions
References
- [Source: architecture.md#Core-Architectural-Decisions] - NewType pattern requirement
- [Source: epics.md#Story-9.8] - Story definition
- [Source: crates/components/src/lib.rs:182] - Current type alias location
Dev Agent Record
Agent Model Used
(To be filled during implementation)
Debug Log References
(To be filled during implementation)
Completion Notes List
(To be filled during implementation)
File List
(To be filled during implementation)