9.1 KiB

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

  • Task 1: Create top-level entropyk crate (AC: #1)

    • 1.1 Create crates/entropyk/Cargo.toml with dependencies on core, components, fluids, solver
    • 1.2 Create crates/entropyk/src/lib.rs with comprehensive re-exports
    • 1.3 Add workspace member to root Cargo.toml
    • 1.4 Set #![warn(missing_docs)] and #![deny(unsafe_code)]
  • Task 2: Implement Builder Pattern (AC: #2)

    • 2.1 Create SystemBuilder struct with fluent API
    • 2.2 Implement add_component(), add_edge(), with_fluid() methods
    • 2.3 Add build() returning Result<System, ThermoError>
    • 2.4 Add compile-time safety where possible (type-state pattern for required fields)
  • Task 3: Unify Error Types (AC: #3)

    • 3.1 Ensure ThermoError in entropyk crate covers all error cases
    • 3.2 Add From impls for component/solver/fluid errors → ThermoError
    • 3.3 Verify zero-panic policy: cargo clippy -- -D warnings (entropyk crate passes)
    • 3.4 Add #[inline] hints on hot-path error conversions
  • Task 4: Configure KaTeX Documentation (AC: #4)

    • 4.1 Create .cargo/config.toml with rustdocflags
    • 4.2 Create docs/katex-header.html with KaTeX 0.16.8 CDN
    • 4.3 Add LaTeX formula examples to key struct docs (e.g., Compressor work equation)
    • 4.4 Verify cargo doc renders equations correctly
  • Task 5: Complete Documentation Coverage (AC: #5)

    • 5.1 Document all public items in the top-level crate
    • 5.2 Add usage examples to lib.rs module-level docs
    • 5.3 Run cargo doc --workspace and fix any warnings
    • 5.4 Add README.md with quickstart example
  • Task 6: Integration Tests

    • 6.1 Create tests/integration/api_usage.rs (unit tests in builder.rs)
    • 6.2 Test builder pattern with real components
    • 6.3 Test error propagation through unified API
    • 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:

// 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

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:

// 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:

[build]
rustdocflags = ["--html-in-header", "docs/katex-header.html"]

docs/katex-header.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)