solunatus 0.5.0

High-precision astronomical calculation library and CLI for sun/moon positions, rise/set times, and lunar phases
Documentation
# Architecture Overview

High-level guide to the Solunatus codebase structure and design principles.

## Design Philosophy

Solunatus is designed as a **dual-purpose Rust project**:

1. **Library** (`solunatus` crate) - Reusable astronomical calculations
2. **CLI** (Binary `solunatus`) - Standalone command-line application

This separation allows:
- Clean API for Rust developers
- Feature-rich command-line tool
- Shared calculation engine
- Easy testing and maintenance

## Project Structure

```
solunatus/
├── src/
│   ├── lib.rs                 # Library root - exports public API
│   ├── main.rs                # CLI entry point
│   ├── astro/                 # Core calculations
│   ├── tui/                   # Terminal UI
│   ├── cli.rs                 # CLI argument parsing
│   ├── city.rs                # City database
│   ├── config.rs              # Configuration
│   ├── output.rs              # Output formatting
│   └── time_sync.rs           # Clock sync checking
├── examples/                  # Library usage examples
├── data/                      # Embedded data (city database)
├── docs/                      # Documentation
├── Cargo.toml                 # Project manifest
└── README.md                  # User guide
```

## Core Modules

### `astro/` - Astronomical Calculations

**Purpose:** Pure astronomical calculation engine with no I/O or UI dependencies.

**Files:**
- `mod.rs` - Common types and constants
  - `Location` struct (latitude, longitude)
  - `julian_day()`, `julian_century()` calculations
  - Mathematical constants (`DEG_TO_RAD`, etc.)

- `sun.rs` - Solar position and events
  - `solar_position()` - Current altitude and azimuth
  - `solar_event_time()` - Sunrise, sunset, twilight times
  - `solar_noon()` - Time of solar noon
  - `SolarEvent` enum - Event type classification

- `moon.rs` - Lunar position and events
  - `lunar_position()` - Current altitude, azimuth, phase
  - `lunar_event_time()` - Moonrise and moonset
  - `lunar_phases()` - Monthly phase calendar
  - `LunarPhase` enum - Phase type classification

**Key Algorithms:**
- **Solar:** NOAA solar calculation methods
- **Lunar:** Jean Meeus "Astronomical Algorithms"
- **Rise/Set:** Bisection method for precise event times

### `tui/` - Terminal User Interface

**Purpose:** Interactive watch mode with keyboard controls and real-time updates.

**Files:**
- `app.rs` - Application state management
  - `App` struct - Holds current state
  - Location management (city, coordinates, timezone)
  - Mode switching (watch vs. city picker)
  - Update logic for real-time calculations

- `ui.rs` - Rendering logic
  - Display formatting
  - Layout management
  - Event and moon information display
  - City picker interface

- `events.rs` - Keyboard input handling
  - Key press processing
  - Watch mode controls
  - City picker navigation

**Architecture:**
- Event-driven model
- Separate state from rendering
- Efficient screen updates

### `cli.rs` - Command-Line Interface

**Purpose:** Parse and validate command-line arguments using `clap`.

**Responsibilities:**
- Argument parsing
- Validation
- Help text generation
- Default values

**Key Structures:**
- `Args` struct - Clap-derived argument definitions

### `city.rs` - City Database

**Purpose:** Manage built-in city database with fuzzy search.

**Features:**
- 570+ cities worldwide
- Fuzzy matching with `fuzzy-matcher` crate
- Timezone data per city
- Country and state information

**Key Functions:**
- `search()` - Fuzzy search by name
- `find_exact()` - Exact match lookup
- `filter()` - Filter by country/state/timezone

**Data Format:**
```json
{
  "name": "New York",
  "lat": 40.7128,
  "lon": -74.0060,
  "tz": "America/New_York",
  "state": "NY",
  "country": "US"
}
```

### `config.rs` - Configuration Persistence

**Purpose:** Save/load user preferences.

**Saved Location:** `~/.solunatus.json`

**Stored Data:**
- Last used location (latitude, longitude)
- Timezone
- City name

**Functions:**
- `load()` - Read config file
- `save()` - Write config file
- `default()` - Create default config

### `output.rs` - Output Formatting

**Purpose:** Format data for JSON output.

**Responsibilities:**
- JSON serialization
- Event formatting
- Position formatting
- Calendar data preparation

**Uses:** `serde_json` for JSON generation

### `time_sync.rs` - System Clock Verification

**Purpose:** Check system clock accuracy against NTP.

**Features:**
- Startup verification
- 15-minute auto-refresh in watch mode
- Graceful error handling
- Optional bypass with environment variable

## Data Flow

### CLI Application Flow

```
main.rs
  ↓
cli.rs (Parse arguments)
  ↓
[Location Resolution]
  ├─ --lat/--lon/--tz: Direct use
  ├─ --city: Lookup in city.rs
  ├─ config.rs: Load from ~/.solunatus.json
  └─ Prompt user to select city: Fallback
  ↓
[Mode Selection]
  ├─ --json: output.rs → JSON serialization
  ├─ --calendar: Calendar generation
  ├─ --no-prompt: Single snapshot output
  └─ Default: TUI watch mode (tui/)
  ↓
[Calculation]
  └─ astro/ (sun.rs, moon.rs)
  ↓
[Output]
  ├─ Text: main.rs formatting
  ├─ JSON: output.rs formatting
  ├─ TUI: tui/ rendering
  └─ Calendar: Calendar generation
```

### Library API Flow

```
User Code
  ↓
lib.rs (public API)
  ↓
astro/ (calculations)
  ├─ Location, DateTime inputs
  ├─ Astronomical calculations
  └─ Events, Positions, Phases outputs
```

## Key Design Patterns

### Separation of Concerns

- **`astro/`** - Pure calculations, no I/O
- **`tui/`, `cli.rs`, `output.rs`** - Presentation logic
- **`city.rs`, `config.rs`** - Data management

### Error Handling

- `anyhow` - Application errors
- `thiserror` - Library error types
- Graceful degradation for optional features

### Calculation Accuracy

- Double-precision floating point
- Meeus and NOAA algorithm implementations
- Verified against USNO reference data
- ~1-3 minute accuracy for solar events

## Key Types

### `Location`
```rust
pub struct Location {
    pub lat: f64,      // Latitude in degrees
    pub lon: f64,      // Longitude in degrees
}
```

### `SolarEvent`
```rust
pub enum SolarEvent {
    Sunrise,
    Sunset,
    SolarNoon,
    CivilDawn,
    CivilDusk,
    NauticalDawn,
    NauticalDusk,
    AstronomicalDawn,
    AstronomicalDusk,
}
```

### `LunarPhase`
```rust
pub enum LunarPhase {
    NewMoon,
    WaxingCrescent,
    FirstQuarter,
    WaxingGibbous,
    FullMoon,
    WaningGibbous,
    LastQuarter,
    WaningCrescent,
}
```

## Dependencies Strategy

### Core Calculations
- **No external astronomical libraries** - Custom Meeus and NOAA implementations
- Pure Rust for maximum portability and control

### Essential Libraries
- `chrono`, `chrono-tz` - Date/time handling (de facto standard)
- `serde`, `serde_json` - Serialization (standard, reliable)

### UI
- `ratatui` + `crossterm` - Terminal rendering (modern, efficient)

### CLI
- `clap` - Argument parsing (ergonomic, standard)

### Supporting
- `fuzzy-matcher` - City search
- `reqwest` - HTTP (optional features)
- `anyhow`, `thiserror` - Error handling

## Testing Strategy

### Unit Tests
- Located in same file as code being tested
- Focus on calculation accuracy
- Compare against USNO reference data

### Integration Tests
- End-to-end workflows
- CLI behavior
- File I/O

### Property-Based Testing
- Consider for astronomical edge cases (polar regions, date boundaries)

## Performance Considerations

### Optimization Profile
Default release profile balances speed and compile time:
```toml
[profile.release]
opt-level = 3          # Maximum optimization
lto = true             # Link-time optimization
codegen-units = 1      # Better optimization
```

### Runtime Performance
- Single-threaded: <100ms startup
- Memory usage: ~5-10 MB
- Watch mode: Updates every 1-10 seconds (configurable)

### Calculation Cost
- Solar events: O(1) per location/date
- Lunar events: O(n) iterations with bisection
- Calendar: O(days) for date ranges

## Future Architecture Considerations

### Possible Enhancements
1. **Plugin system** - User-defined calculations
2. **Multi-threading** - Batch calendar generation
3. **WebAssembly** - Browser compatibility
4. **Alternative data sources** - Earth elevation maps, eclipse predictions

### Backward Compatibility
- Maintain semver compatibility
- Document breaking changes
- Provide migration guides

## Key Files for Developers

**Starting points:**
- `src/lib.rs` - Public API
- `src/main.rs` - CLI flow
- `src/astro/mod.rs` - Constants and types

**For calculations:**
- `src/astro/sun.rs` - Solar algorithms
- `src/astro/moon.rs` - Lunar algorithms

**For CLI:**
- `src/cli.rs` - Argument definitions
- `src/main.rs` - Orchestration

**For UI:**
- `src/tui/app.rs` - State management
- `src/tui/ui.rs` - Rendering

## Contributing to Architecture

When making significant changes:

1. **Maintain separation of concerns** - Keep calculations separate from I/O
2. **Update this documentation** - Reflect architectural changes
3. **Preserve public API** - Don't break library users
4. **Test thoroughly** - Especially calculations
5. **Consider performance** - Profile before optimizing

## Resources

- [Rust Book]https://doc.rust-lang.org/book/ - Language fundamentals
- [Cargo Guide]https://doc.rust-lang.org/cargo/ - Project management
- [Meeus Algorithms]https://www.amazon.com/Astronomical-Algorithms-Jean-Meeus/dp/0943396343 - Lunar calculations reference
- [NOAA Solar Calculator]https://gml.noaa.gov/grad/solcalc/ - Solar algorithm reference

## Next Steps

- **[Setup Guide]setup.md** - Get your development environment ready
- **[Contributing]../../CONTRIBUTING.md** - How to contribute code
- **[Accuracy Testing]accuracy.md** - Verify calculations
- **[API Docs]https://docs.rs/solunatus** - Auto-generated documentation