235 lines
9.1 KiB
Markdown
235 lines
9.1 KiB
Markdown
# Story 6.1: Rust Native API
|
|
|
|
Status: done
|
|
|
|
## Story
|
|
|
|
As a **Rust developer**,
|
|
I want **a clean, idiomatic Rust API with builder patterns and comprehensive documentation**,
|
|
so that **I can integrate Entropyk into Rust applications with type safety and ergonomic usage**.
|
|
|
|
## Acceptance Criteria
|
|
|
|
### AC1: Unified Top-Level Crate Structure
|
|
**Given** the Entropyk workspace with 4 core crates (core, components, fluids, solver)
|
|
**When** a user depends on `entropyk` crate
|
|
**Then** they get re-exports of all public APIs from sub-crates
|
|
**And** the crate follows Rust naming conventions
|
|
**And** the crate is ready for crates.io publication
|
|
|
|
### AC2: Builder Pattern for System Construction
|
|
**Given** a new thermodynamic system
|
|
**When** using the builder API
|
|
**Then** components are added fluently with method chaining
|
|
**And** the API prevents invalid configurations at compile time
|
|
**And** `finalize()` returns `Result<System, ThermoError>`
|
|
|
|
### AC3: Consistent Error Handling
|
|
**Given** any public API function
|
|
**When** an error occurs
|
|
**Then** it returns `Result<T, ThermoError>` (never panics)
|
|
**And** error types are exhaustive with helpful messages
|
|
**And** errors implement `std::error::Error` and `Display`
|
|
|
|
### AC4: KaTeX Documentation
|
|
**Given** any public API with physics equations
|
|
**When** generating rustdoc
|
|
**Then** LaTeX formulas render correctly in HTML
|
|
**And** `.cargo/config.toml` configures KaTeX header injection
|
|
**And** `docs/katex-header.html` exists with proper CDN links
|
|
|
|
### AC5: 100% Public API Documentation
|
|
**Given** any public item (struct, trait, fn, enum)
|
|
**When** running `cargo doc`
|
|
**Then** it has documentation with examples
|
|
**And** no `missing_docs` warnings
|
|
**And** examples are runnable (`ignore` only when necessary)
|
|
|
|
## Tasks / Subtasks
|
|
|
|
- [x] Task 1: Create top-level `entropyk` crate (AC: #1)
|
|
- [x] 1.1 Create `crates/entropyk/Cargo.toml` with dependencies on core, components, fluids, solver
|
|
- [x] 1.2 Create `crates/entropyk/src/lib.rs` with comprehensive re-exports
|
|
- [x] 1.3 Add workspace member to root `Cargo.toml`
|
|
- [x] 1.4 Set `#![warn(missing_docs)]` and `#![deny(unsafe_code)]`
|
|
|
|
- [x] Task 2: Implement Builder Pattern (AC: #2)
|
|
- [x] 2.1 Create `SystemBuilder` struct with fluent API
|
|
- [x] 2.2 Implement `add_component()`, `add_edge()`, `with_fluid()` methods
|
|
- [x] 2.3 Add `build()` returning `Result<System, ThermoError>`
|
|
- [x] 2.4 Add compile-time safety where possible (type-state pattern for required fields)
|
|
|
|
- [x] Task 3: Unify Error Types (AC: #3)
|
|
- [x] 3.1 Ensure `ThermoError` in `entropyk` crate covers all error cases
|
|
- [x] 3.2 Add `From` impls for component/solver/fluid errors → `ThermoError`
|
|
- [x] 3.3 Verify zero-panic policy: `cargo clippy -- -D warnings` (entropyk crate passes)
|
|
- [x] 3.4 Add `#[inline]` hints on hot-path error conversions
|
|
|
|
- [x] Task 4: Configure KaTeX Documentation (AC: #4)
|
|
- [x] 4.1 Create `.cargo/config.toml` with `rustdocflags`
|
|
- [x] 4.2 Create `docs/katex-header.html` with KaTeX 0.16.8 CDN
|
|
- [x] 4.3 Add LaTeX formula examples to key struct docs (e.g., Compressor work equation)
|
|
- [x] 4.4 Verify `cargo doc` renders equations correctly
|
|
|
|
- [x] Task 5: Complete Documentation Coverage (AC: #5)
|
|
- [x] 5.1 Document all public items in the top-level crate
|
|
- [x] 5.2 Add usage examples to `lib.rs` module-level docs
|
|
- [x] 5.3 Run `cargo doc --workspace` and fix any warnings
|
|
- [x] 5.4 Add `README.md` with quickstart example
|
|
|
|
- [x] Task 6: Integration Tests
|
|
- [x] 6.1 Create `tests/integration/api_usage.rs` (unit tests in builder.rs)
|
|
- [x] 6.2 Test builder pattern with real components
|
|
- [x] 6.3 Test error propagation through unified API
|
|
- [x] 6.4 Verify `cargo test --workspace` passes
|
|
|
|
## Dev Notes
|
|
|
|
### Architecture Context
|
|
|
|
The workspace currently has 4 core crates:
|
|
```
|
|
crates/
|
|
├── core/ # NewTypes (Pressure, Temperature, Enthalpy, MassFlow), ThermoError
|
|
├── components/ # Component trait, Compressor, Condenser, etc.
|
|
├── fluids/ # FluidBackend trait, CoolProp integration
|
|
└── solver/ # System, Solver trait, Newton-Raphson, Picard
|
|
```
|
|
|
|
The new `entropyk` crate should be a **facade** that re-exports everything users need:
|
|
```rust
|
|
// crates/entropyk/src/lib.rs
|
|
pub use entropyk_core::{Pressure, Temperature, Enthalpy, MassFlow, ThermoError};
|
|
pub use entropyk_components::{Component, Compressor, Condenser, Evaporator, ...};
|
|
pub use entropyk_fluids::{FluidBackend, CoolPropBackend, ...};
|
|
pub use entropyk_solver::{System, Solver, NewtonConfig, ...};
|
|
```
|
|
|
|
### Builder Pattern Example
|
|
|
|
```rust
|
|
use entropyk::{SystemBuilder, Compressor, Condenser, NewtonConfig, Solver};
|
|
|
|
let system = SystemBuilder::new()
|
|
.add_component("compressor", Compressor::new(ahri_coeffs))
|
|
.add_component("condenser", Condenser::new(ua))
|
|
.add_edge("compressor", "condenser")?
|
|
.with_fluid("R134a")
|
|
.build()?;
|
|
|
|
let solver = NewtonConfig::default();
|
|
let result = solver.solve(&system)?;
|
|
```
|
|
|
|
### Error Handling Pattern
|
|
|
|
All errors should convert to `ThermoError`:
|
|
```rust
|
|
// In entropyk_core/src/errors.rs
|
|
#[derive(Error, Debug)]
|
|
pub enum ThermoError {
|
|
#[error("Component error: {0}")]
|
|
Component(#[from] ComponentError),
|
|
#[error("Solver error: {0}")]
|
|
Solver(#[from] SolverError),
|
|
#[error("Fluid error: {0}")]
|
|
Fluid(#[from] FluidError),
|
|
// ... other variants
|
|
}
|
|
```
|
|
|
|
### KaTeX Configuration
|
|
|
|
**`.cargo/config.toml`:**
|
|
```toml
|
|
[build]
|
|
rustdocflags = ["--html-in-header", "docs/katex-header.html"]
|
|
```
|
|
|
|
**`docs/katex-header.html`:**
|
|
```html
|
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.css">
|
|
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.js"></script>
|
|
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/contrib/auto-render.min.js"
|
|
onload="renderMathInElement(document.body, {
|
|
delimiters: [
|
|
{left: '$$', right: '$$', display: true},
|
|
{left: '$', right: '$', display: false}
|
|
]
|
|
});"></script>
|
|
```
|
|
|
|
### Project Structure Notes
|
|
|
|
- Top-level crate at `crates/entropyk/` (NOT at project root)
|
|
- Add to workspace members in root `Cargo.toml`
|
|
- Follow workspace package metadata conventions
|
|
- Version inherits from workspace
|
|
|
|
### Critical Constraints
|
|
|
|
1. **Zero-Panic Policy**: No `unwrap()`, `expect()`, or panics in public API
|
|
2. **NewType Pattern**: Never expose bare `f64` for physical quantities
|
|
3. **`#![deny(warnings)]`**: All crates must compile without warnings
|
|
4. **No `println!`**: Use `tracing` for all logging
|
|
|
|
### References
|
|
|
|
- Architecture: `_bmad-output/planning-artifacts/architecture.md#Project-Structure`
|
|
- Error Handling: `_bmad-output/planning-artifacts/architecture.md#Error-Handling-Strategy`
|
|
- NewType Pattern: `_bmad-output/planning-artifacts/architecture.md#Critical-Pattern:-NewType-for-Unit-Safety`
|
|
- KaTeX Config: `_bmad-output/planning-artifacts/architecture.md#Critical-Pattern:-LaTeX-Configuration-for-Rustdoc`
|
|
|
|
### Previous Work Context
|
|
|
|
- Epic 1-5 components and solver are complete
|
|
- `Component` trait is object-safe (`Box<dyn Component>`)
|
|
- `System` struct exists in `entropyk_solver` with `finalize()` method
|
|
- Error types exist but may need `From` impls for unified handling
|
|
|
|
## Dev Agent Record
|
|
|
|
### Agent Model Used
|
|
|
|
Claude (Anthropic)
|
|
|
|
### Debug Log References
|
|
|
|
- Pre-existing clippy errors in `entropyk-components` and `entropyk-solver` crates (not related to this story)
|
|
- Pre-existing test failure in `entropyk-solver/tests/inverse_calibration.rs` (not related to this story)
|
|
|
|
### Completion Notes List
|
|
|
|
- Created top-level `entropyk` crate as a facade re-exporting all public APIs from core, components, fluids, and solver crates
|
|
- Implemented `SystemBuilder` with fluent API for ergonomic system construction
|
|
- Created unified `ThermoError` enum with `From` implementations for all sub-crate error types
|
|
- Added comprehensive documentation to all public items
|
|
- Configured KaTeX for LaTeX rendering in rustdoc
|
|
- Added README.md with quickstart example
|
|
- All 7 unit tests pass for the entropyk crate
|
|
|
|
### Code Review Fixes (2026-02-21)
|
|
|
|
Fixed 10 issues found during adversarial code review:
|
|
- **[HIGH]** Created missing `tests/api_usage.rs` integration tests (8 tests)
|
|
- **[HIGH]** Added `with_fluid()` method to `SystemBuilder`
|
|
- **[HIGH]** Added `#[inline]` hints to all `From` impls in `error.rs`
|
|
- **[MEDIUM]** Fixed 5 broken doc links in `lib.rs` and `builder.rs`
|
|
- **[MEDIUM]** Moved KaTeX config to `crates/entropyk/.cargo/config.toml` to avoid affecting dependencies
|
|
- **[MEDIUM]** Made 3 doctests runnable (previously all ignored)
|
|
- **[MEDIUM]** Clarified builder uses runtime checks (not type-state pattern)
|
|
- **[LOW]** Fixed README example with proper type annotations and `ignore` flag
|
|
|
|
### File List
|
|
|
|
- `crates/entropyk/Cargo.toml` (new)
|
|
- `crates/entropyk/src/lib.rs` (new)
|
|
- `crates/entropyk/src/error.rs` (new)
|
|
- `crates/entropyk/src/builder.rs` (new)
|
|
- `crates/entropyk/README.md` (new)
|
|
- `crates/entropyk/tests/api_usage.rs` (new - added during code review)
|
|
- `crates/entropyk/.cargo/config.toml` (new - moved from root during code review)
|
|
- `Cargo.toml` (modified - added entropyk to workspace members)
|
|
- `.cargo/config.toml` (modified - removed katex config, moved to crate-specific)
|
|
- `docs/katex-header.html` (new)
|