chore: sync project state and current artifacts
This commit is contained in:
@@ -0,0 +1,164 @@
|
||||
# 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
|
||||
|
||||
1. **Given** `SystemState` is currently `Vec<f64>` in `crates/components/src/lib.rs:182`
|
||||
**When** the struct is created
|
||||
**Then** `pressure(edge_idx)` returns `Pressure` type
|
||||
**And** `enthalpy(edge_idx)` returns `Enthalpy` type
|
||||
**And** `set_pressure()` and `set_enthalpy()` accept typed physical quantities
|
||||
|
||||
2. **Given** a `SystemState` instance
|
||||
**When** accessing data
|
||||
**Then** `AsRef<[f64]>` and `AsMut<[f64]>` are implemented for solver compatibility
|
||||
**And** `From<Vec<f64>>` and `From<SystemState> for Vec<f64>` enable migration
|
||||
|
||||
3. **Given** invalid data (odd length vector)
|
||||
**When** calling `SystemState::from_vec()`
|
||||
**Then** panic with clear error message
|
||||
|
||||
4. **Given** out-of-bounds edge index
|
||||
**When** calling `pressure()` or `enthalpy()`
|
||||
**Then** returns `None` (safe, no panic)
|
||||
|
||||
5. **Given** all tests passing before change
|
||||
**When** refactoring is complete
|
||||
**Then** `cargo test --workspace` passes
|
||||
**And** public API is unchanged for solver consumers
|
||||
|
||||
## Tasks / Subtasks
|
||||
|
||||
- [ ] Task 1: Create `SystemState` struct in `entropyk_core` (AC: 1, 3, 4)
|
||||
- [ ] Create `crates/core/src/state.rs` with `SystemState` struct
|
||||
- [ ] Implement `new(edge_count)`, `from_vec()`, `edge_count()`
|
||||
- [ ] Implement `pressure()`, `enthalpy()` returning `Option<Pressure/Enthalpy>`
|
||||
- [ ] Implement `set_pressure()`, `set_enthalpy()` accepting typed values
|
||||
- [ ] Implement `as_slice()`, `as_mut_slice()`, `into_vec()`
|
||||
- [ ] Implement `iter_edges()` iterator
|
||||
|
||||
- [ ] Task 2: Implement trait compatibility (AC: 2)
|
||||
- [ ] Implement `AsRef<[f64]>` for solver compatibility
|
||||
- [ ] Implement `AsMut<[f64]>` for mutable access
|
||||
- [ ] Implement `From<Vec<f64>>` and `From<SystemState> for Vec<f64>`
|
||||
- [ ] Implement `Default` trait
|
||||
|
||||
- [ ] Task 3: Export from `entropyk_core` (AC: 5)
|
||||
- [ ] Add `state` module to `crates/core/src/lib.rs`
|
||||
- [ ] Export `SystemState` from crate root
|
||||
|
||||
- [ ] Task 4: Migrate from type alias (AC: 5)
|
||||
- [ ] Remove `pub type SystemState = Vec<f64>;` from `crates/components/src/lib.rs`
|
||||
- [ ] Add `use entropyk_core::SystemState;` to components crate
|
||||
- [ ] Update solver crate imports if needed
|
||||
|
||||
- [ ] 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`/`Into` conversions
|
||||
|
||||
- [ ] 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
|
||||
|
||||
```rust
|
||||
// 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 Pascals
|
||||
- `h`: Enthalpy in J/kg
|
||||
|
||||
### Proposed Implementation
|
||||
|
||||
```rust
|
||||
// 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 (except `from_vec` with 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
|
||||
|
||||
- `SystemState` belongs in `entropyk_core` (shared between solver and components)
|
||||
- Physical types (`Pressure`, `Enthalpy`) already exist in `entropyk_core`
|
||||
- Solver uses `AsRef<[f64]>` trait - no breaking change
|
||||
|
||||
### Testing Standards
|
||||
|
||||
- Use `approx` crate for float comparisons
|
||||
- Tolerance: 1e-9 for exact values (matches NFR determinism requirement)
|
||||
- Run `cargo test --workspace` to 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)
|
||||
Reference in New Issue
Block a user