Skip to content

Refactor CLI to use crate library functions (eliminate code duplication) (#9)#10

Merged
nerdCopter merged 4 commits into
masterfrom
20251130_FIX_ISSUE_9
Dec 1, 2025
Merged

Refactor CLI to use crate library functions (eliminate code duplication) (#9)#10
nerdCopter merged 4 commits into
masterfrom
20251130_FIX_ISSUE_9

Conversation

@nerdCopter
Copy link
Copy Markdown
Owner

@nerdCopter nerdCopter commented Nov 30, 2025

resolves #9

  • refactor: import GPS conversion functions from crate library
  • refactor: import flag formatting functions from crate library
  • refactor: migrate crate library to use anyhow::Result
  • fix: align crate parse_h_frame and 14-bit encoding with CLI behavior

Summary by CodeRabbit

  • Bug Fixes

    • Improved GPS parsing fallback for unsupported encodings and adjusted internal decoding semantics for certain numeric fields.
  • Refactor

    • Centralized formatting and GPS conversion utilities to reduce duplication.
    • Standardized error handling across parsing modules.
  • API

    • Expanded public surface and re-exported core modules for downstream use.

✏️ Tip: You can customize this high-level summary in your review settings.

- Add import for convert_gps_coordinate, convert_gps_altitude,
  convert_gps_speed, convert_gps_course from bbl_parser::conversion
- Remove duplicate conversion function definitions from CLI main.rs
- Eliminates ~40 lines of duplicated code
- Addresses Issue #9: Refactor CLI to use crate library functions
- Add imports for format_flight_mode_flags, format_state_flags,
  format_failsafe_phase from bbl_parser::conversion
- Remove ~90 lines of duplicate formatting function definitions
- Addresses Issue #9: Refactor CLI to use crate library functions
This enables CLI and crate to share the same error handling pattern,
which is a prerequisite for deduplicating stream and parser code.

- parser/stream.rs: use anyhow::Result instead of BBLError
- parser/decoder.rs: use anyhow::anyhow! for error messages
- parser/event.rs: use anyhow::Result
- parser/frame.rs: use anyhow::Result
- parser/gps.rs: use anyhow::Result
- parser/header.rs: use anyhow::Result and anyhow::anyhow!
- parser/main.rs: use anyhow::Result
- export.rs: use anyhow::Result

Addresses Issue #9: Refactor CLI to use crate library functions
- parser/gps.rs: parse_h_frame now uses graceful fallback for unknown
  encodings (read_signed_vb with unwrap_or(0)) matching CLI behavior
- parser/stream.rs: read_neg_14bit now uses sign-magnitude encoding
  matching CLI's bbl_format::sign_extend_14bit + negation
- Updated tests for sign-magnitude encoding
- Removed unused two's complement sign extension function

This ensures crate's H-frame parsing matches the working CLI logic.
Addresses Issue #9: CLI logic takes precedence
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Nov 30, 2025

📝 Walkthrough

Walkthrough

Migration from crate-specific BBLError/Result to anyhow::Result across parser modules, import reorganizations, removal of local helper functions in main.rs in favor of crate conversions, GPS H-frame fallback changes, and refactor of 14-bit stream decoding from two's-complement to sign-magnitude.

Changes

Cohort / File(s) Change Summary
Import formatting & consolidation
src/export.rs, src/parser/main.rs
Combined anyhow imports (e.g., anyhow::{Context, Result}) and simplified import lists.
Main CLI helper removal / conversion usage
src/main.rs
Removed local formatting and GPS-conversion helpers and replaced with imports from bbl_parser::conversion. No public API changes.
Error type migration — decoder/event/frame/header
src/parser/decoder.rs, src/parser/event.rs, src/parser/frame.rs, src/parser/header.rs
Replaced crate-specific error types (BBLError, crate::Result) with anyhow::Result; updated error construction sites to use anyhow::anyhow!() and adjusted error messages.
GPS parsing adjustments
src/parser/gps.rs
Switched to anyhow::Result; for unsupported H-frame encodings, added optional debug logging and a graceful fallback using read_signed_vb().unwrap_or(0) instead of returning an error.
Stream decoding refactor + tests
src/parser/stream.rs
Reworked 14-bit decoding from two's-complement to sign-magnitude encoding, added sign_extend_14bit_sign_magnitude helper, updated read_neg_14bit, and adjusted/renamed tests to match new semantics.
Library surface changes
src/lib.rs
Made bbl_format public, added pub mod parser; and pub mod types;, and added public re-exports for modules and anyhow::Result.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Pay extra attention to src/parser/stream.rs for bit-level sign-magnitude implementation and test correctness.
  • Verify intended semantics for GPS H-frame fallback in src/parser/gps.rs (changing error -> default value).
  • Confirm error-message parity and any behavioral differences where BBLError variants were replaced by anyhow::anyhow!().

Possibly related PRs

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main refactoring objective: migrating CLI code to use crate library functions to eliminate duplication.
Linked Issues check ✅ Passed The PR partially addresses issue #9 by eliminating ~140 lines of duplicate code for GPS conversion and flag formatting functions, migrating error handling to anyhow::Result, and fixing H-frame/14-bit encoding alignment.
Out of Scope Changes check ✅ Passed All changes align with issue #9 scope: import refactoring, error handling migration to anyhow, and behavior alignment. Library API exposure and internal helper consolidation support the duplication-elimination goal.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 20251130_FIX_ISSUE_9

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nerdCopter
Copy link
Copy Markdown
Owner Author

@coderabbitai, these first 4 commits only partially resolve #9. my AI agent rports the follwing:

What Remains
The CLI still has its own bbl_format module with BBLDataStream and parse_frame_data. Full unification would require:

Making the CLI use the crate's stream type (requires significant refactoring of type usages)
Unifying the parse_frame_data functions (similar signatures but different debug parameters)
This was deferred because:

The changes would be much more invasive
Both implementations work correctly for their use cases
The current commits already eliminate ~140 lines of duplicate code
A/B testing confirms output is identical to the reference

Propose further AI-instructional "how-to" plans to continue the project. Append #9 via comment as seen fit, while still acknowledging here.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Nov 30, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Fetch issue #9 details
gh issue view 9 --repo nerdCopter/bbl_parser --json title,body,number,url

# Find and examine the CLI's bbl_format module
fd -t f bbl_format

# Examine the crate's stream module structure
cat src/parser/stream.rs | head -100

# Find parse_frame_data implementations
rg -n "fn parse_frame_data" -A 5

Length of output: 5599


🏁 Script executed:

#!/bin/bash
# Get the full CLI bbl_format module if it exists in bin/ or similar
fd -t f "\.rs$" bin cli examples 2>/dev/null | head -20

# List all rust files to understand structure
fd -t f "\.rs$" | grep -v target

Length of output: 508


🏁 Script executed:

#!/bin/bash
# Examine main.rs to understand CLI structure
cat src/main.rs | head -150

# Look for bbl_format references
rg -n "bbl_format" -C 2

# Look for BBLDataStream
rg -n "BBLDataStream" -C 2

Length of output: 20571


🏁 Script executed:

#!/bin/bash
# Compare the two BBLDataStream implementations
echo "=== CLI BBLDataStream (src/bbl_format.rs) ==="
head -100 src/bbl_format.rs

echo -e "\n=== Crate BBLDataStream (src/parser/stream.rs) ==="
head -100 src/parser/stream.rs

# Compare parse_frame_data signatures
echo -e "\n=== parse_frame_data in CLI (src/bbl_format.rs) ==="
rg -A 20 "^pub fn parse_frame_data" src/bbl_format.rs

echo -e "\n=== parse_frame_data in Crate (src/parser/frame.rs) ==="
rg -A 20 "^pub fn parse_frame_data" src/parser/frame.rs

Length of output: 6890


🏁 Script executed:

#!/bin/bash
# Check what functions are exported from bbl_format module
echo "=== Functions exported from src/bbl_format.rs ==="
rg "^pub fn" src/bbl_format.rs | head -30

echo -e "\n=== Functions exported from src/parser/stream.rs ==="
rg "^pub fn" src/parser/stream.rs

echo -e "\n=== What does lib.rs export from bbl_format? ==="
rg "bbl_format" src/lib.rs -A 2 -B 2

Length of output: 790


🏁 Script executed:

#!/bin/bash
# Check the differences in parse_frame_data debug parameter usage
echo "=== CLI parse_frame_data usage in main.rs ==="
rg "bbl_format::parse_frame_data" src/main.rs -B 2 -A 8

echo -e "\n=== Crate parse_frame_data signature ==="
ast-grep --pattern 'pub fn parse_frame_data($$$) {
  $$$
}'

Length of output: 1940


🏁 Script executed:

#!/bin/bash
# Check what's publicly exported from parser module
echo "=== What does lib.rs export from parser? ==="
cat src/lib.rs

echo -e "\n=== What's in parser/mod.rs? ==="
cat src/parser/mod.rs

# Check if BBLDataStream is accessible from the crate
echo -e "\n=== Check examples using BBLDataStream ==="
rg "BBLDataStream" examples/ -n | head -20

Length of output: 1455


🏁 Script executed:

#!/bin/bash
# Compare the line counts
echo "=== Line count of CLI bbl_format.rs ==="
wc -l src/bbl_format.rs

echo -e "\n=== Line count of crate parser/stream.rs ==="
wc -l src/parser/stream.rs

# Check what parse_frame_data is called from in the crate library
echo -e "\n=== parse_frame_data usage in crate ==="
rg "parse_frame_data" src/parser/ -n | grep -v "^src/parser/frame.rs"

Length of output: 282


🏁 Script executed:

#!/bin/bash
# Identify all helper functions in CLI bbl_format that might need migration
echo "=== All public functions in CLI bbl_format.rs ==="
rg "^pub fn" src/bbl_format.rs -A 1

echo -e "\n=== Check if these exist in crate ==="
echo "sign_extend functions:"
rg "pub fn sign_extend" src/parser/ -n

echo -e "\napply_predictor:"
rg "pub fn apply_predictor" src/parser/ -n

echo -e "\ndecode_frame_field / decode_field_value:"
rg "pub fn decode" src/parser/ -n

Length of output: 972


@nerdCopter, excellent progress on PR #10! I've analyzed the remaining duplication and can propose a phased approach to complete the unification. Let me break down what remains and provide actionable steps.

Current State Analysis

Already Unified (PR #10)

  • GPS conversion functions (~50 lines)
  • Flag formatting functions (~40 lines)
  • Error handling (migrated to anyhow::Result)
  • H-frame parsing alignment
  • Total eliminated: ~140 lines

Still Duplicated 🔄

  1. BBLDataStream (~100 lines) - Implementations appear identical in:

    • CLI: src/bbl_format.rs (655 lines total)
    • Crate: src/parser/stream.rs (356 lines)
  2. parse_frame_data (~160 lines) - Nearly identical except:

    • CLI version has debug: bool parameter
    • Crate version uses _ prefix for unused params
  3. Helper functions (~50 lines):

    • sign_extend_* functions (2/4/6/8/14/16/24 bit variants)
    • Encoding/predictor constants

Proposed Phased Refactoring Plan

Phase 1: Unify Helper Functions (Least Invasive)

Estimated: ~50 lines eliminated

Goal: Move sign_extend and constant definitions to crate, make CLI import them

// Add to src/parser/decoder.rs or new src/parser/helpers.rs
pub fn sign_extend_2bit(value: u8) -> i32 { ... }
pub fn sign_extend_4bit(value: u8) -> i32 { ... }
pub fn sign_extend_14bit(value: u16) -> i32 { ... }
// etc.

AI Instructions:

1. Extract all sign_extend_* functions from src/bbl_format.rs
2. Move them to src/parser/decoder.rs (or create src/parser/helpers.rs)
3. Export from src/parser/mod.rs and src/lib.rs
4. Update src/main.rs to import: use bbl_parser::sign_extend_14bit;
5. Remove sign_extend functions from src/bbl_format.rs
6. Run tests to verify identical behavior

Phase 2: Unify parse_frame_data (Moderate Invasiveness)

Estimated: ~160 lines eliminated

Challenge: Debug parameter difference

Solution Option A (Recommended): Make debug optional in crate

// In src/parser/frame.rs
pub fn parse_frame_data(
    stream: &mut BBLDataStream,
    frame_def: &FrameDefinition,
    current_frame: &mut [i32],
    previous_frame: Option<&[i32]>,
    previous2_frame: Option<&[i32]>,
    skipped_frames: u32,
    raw: bool,
    data_version: u8,
    sysconfig: &HashMap<String, i32>,
    debug: bool,  // Add this parameter
) -> Result<()>

AI Instructions:

1. Add debug: bool parameter to crate's parse_frame_data in src/parser/frame.rs
2. Add debug logging where appropriate (mirror CLI behavior)
3. Update src/main.rs to use: bbl_parser::parse_frame_data
4. Remove parse_frame_data from src/bbl_format.rs
5. Update all call sites in main.rs to use crate function
6. A/B test CLI output against reference to confirm identical behavior

Solution Option B: Remove debug from CLI (if not critical)

  • Simpler but loses debug capability

Phase 3: Unify BBLDataStream (Most Invasive)

Estimated: ~100 lines eliminated, enables removing src/bbl_format.rs entirely

Challenge: Type changes throughout main.rs

Strategy: Global find-replace + import updates

AI Instructions:

1. Verify BBLDataStream implementations are byte-for-byte identical:
   - Compare src/bbl_format.rs::BBLDataStream with src/parser/stream.rs::BBLDataStream
   - If differences exist, align crate version with CLI behavior first

2. Update imports in src/main.rs:
   - Add: use bbl_parser::BBLDataStream;
   - Remove: mod bbl_format;

3. Global replace in src/main.rs:
   - bbl_format::BBLDataStream -> BBLDataStream
   - bbl_format::ENCODING_* -> ENCODING_* (if moved to crate)
   - bbl_format::parse_frame_data -> parse_frame_data (if Phase 2 done)

4. After Phase 1 & 2 complete and src/bbl_format.rs empty:
   - Delete src/bbl_format.rs entirely
   - Remove from src/lib.rs: mod bbl_format;

5. Comprehensive testing:
   - Run full test suite
   - A/B test CLI against reference implementation
   - Verify all frame types parse identically

Recommended Sequence

Immediate Next Steps (for PR #11):

  1. ✅ Phase 1: Unify helper functions
  2. ✅ Phase 2: Unify parse_frame_data
    • These can be done together in one PR
    • Expected: ~210 lines eliminated

Follow-up (for PR #12):
3. ✅ Phase 3: Unify BBLDataStream + delete bbl_format.rs

  • This is the big one but becomes straightforward after 1 & 2
  • Expected: ~100 lines eliminated, entire module removed

Benefits Summary

After Full Unification:

  • ~450 total lines eliminated from CLI
  • Single source of truth for all parsing logic
  • Identical behavior guaranteed between CLI and library
  • Simplified maintenance - fix bugs once
  • Better testing - crate tests validate both use cases

Testing Strategy

For each phase:

Would you like me to:

  1. Comment on issue Refactor CLI to use crate library functions (eliminate code duplication) #9 with this plan?
  2. Generate specific code changes for Phase 1 to get started?
  3. Create a checklist for tracking progress?

🏁 Script executed:

# Build and test
cargo build --release
cargo test

# A/B test specific log file
./target/release/bbl_parser test_flight.BBL --csv --gpx --event
# Compare output against reference implementation
diff output.csv reference.csv

Length of output: 384


🏁 Script executed:

#!/bin/bash
# Comment on issue #9 with the refactoring plan
gh issue comment 9 --repo nerdCopter/bbl_parser --body "## Continuation Plan for Full Unification

Based on analysis of PR #10's progress, here's the roadmap to complete the refactoring:

### ✅ Completed in PR #10 (~140 lines eliminated)
- GPS conversion functions
- Flag formatting functions  
- anyhow::Result migration
- H-frame parsing alignment

### 🔄 Remaining Work

**Phase 1: Unify Helper Functions** (~50 lines)
- Move \`sign_extend_*\` functions to crate
- Move encoding/predictor constants to crate

**Phase 2: Unify parse_frame_data** (~160 lines)
- Add \`debug\` parameter to crate version or remove from CLI
- Replace CLI usage with crate import

**Phase 3: Unify BBLDataStream** (~100 lines)
- Replace \`bbl_format::BBLDataStream\` with \`bbl_parser::BBLDataStream\`
- Delete \`src/bbl_format.rs\` entirely

### Expected Outcome
- **~450 total lines eliminated** from CLI
- **Complete DRY compliance**
- **Single source of truth** for all parsing logic

Detailed implementation guide available in PR #10 review comments.

Recommended approach: Phase 1+2 together (PR #11), then Phase 3 (PR #12)."

Length of output: 73


Perfect! I've posted the continuation plan to issue #9.

Summary

Your PR #10 has made excellent progress eliminating ~140 lines of duplication. Here's the complete roadmap to finish the job:

📋 Three-Phase Completion Plan

Phase 1: Helper Functions (~50 lines)

  • What: Move sign_extend_* functions and constants to crate
  • Difficulty: ⭐ Easy
  • Impact: Low risk, immediate cleanup

Phase 2: parse_frame_data (~160 lines)

  • What: Unify the two parse_frame_data implementations
  • Difficulty: ⭐⭐ Moderate
  • Key Decision: Add debug param to crate version (recommended) or remove from CLI
  • Impact: Medium risk, significant deduplication

Phase 3: BBLDataStream (~100 lines)

  • What: Replace CLI's BBLDataStream with crate's, delete bbl_format.rs
  • Difficulty: ⭐⭐⭐ Invasive
  • Impact: High impact, enables complete module removal

🎯 Recommended Execution

Next PR (#11): Phases 1 + 2 together

  • Natural pairing since both involve function unification
  • Combined testing reduces overhead
  • ~210 lines eliminated

Following PR (#12): Phase 3

  • After helper functions unified, this becomes mostly find-replace
  • Final ~100 lines eliminated
  • Delete src/bbl_format.rs entirely 🎉

🔧 Detailed Implementation Guides

I've provided specific AI-agent instructions for each phase in my comment above. Each phase includes:

  • Exact file changes needed
  • Import statements to add/remove
  • Testing commands to verify correctness
  • A/B testing strategy

📊 Final Expected Results

  • ~450 total lines eliminated (140 already + 310 remaining)
  • Zero duplication between CLI and library
  • Single source of truth for all parsing logic
  • Stronger guarantees of identical behavior

The key insight is that Phases 1 & 2 are straightforward refactoring that can be done safely together, while Phase 3 becomes trivial once the functions are unified—it's just replacing type references and deleting the now-empty module.

Would you like me to generate the specific code changes for Phase 1 to kickstart the next PR?


🧠 Learnings used
Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 2
File: LICENSE_COMMERCIAL:1-4
Timestamp: 2025-08-29T19:52:05.099Z
Learning: nerdCopter prefers to avoid publishing personal information in license files for privacy and security reasons, as they are an individual maintainer rather than a company.

Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 2
File: README.md:520-521
Timestamp: 2025-08-29T19:53:41.354Z
Learning: nerdCopter uses AGPL-3.0-or-later licensing for the bbl_parser project with a dual-licensing approach that includes a separate commercial license option.

Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 2
File: CONTRIBUTING.md:9-14
Timestamp: 2025-08-21T20:25:45.741Z
Learning: nerdCopter prefers to keep CLA language general using "project maintainer" rather than specifying a legal entity name, as they are an individual maintainer without an associated company.

Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 2
File: LICENSE_COMMERCIAL:0-0
Timestamp: 2025-08-29T20:15:04.624Z
Learning: nerdCopter prefers clear positive indicators (✅) when describing fixes rather than using ❌ symbols which can be confusing when describing what was corrected in a positive context.

Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 2
File: README.md:0-0
Timestamp: 2025-08-29T19:55:43.912Z
Learning: nerdCopter updated the bbl_parser project license from GPL-3.0-or-later to AGPL-3.0-or-later across all repository files (Cargo.toml, LICENSE, README.md) for consistency with the dual-licensing approach that includes a commercial license option.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
src/lib.rs (1)

27-38: Consider explicit re-exports for clearer public API.

The glob re-export pattern with #[allow(ambiguous_glob_reexports)] makes it difficult for users to discover the public API and silently permits naming conflicts between modules. While functional, explicit re-exports (e.g., pub use module::{Type1, Type2, function1}) would improve API clarity and make breaking changes more visible.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 850fc27 and 2904762.

📒 Files selected for processing (1)
  • src/lib.rs (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.rs

📄 CodeRabbit inference engine (AGENTS.md)

**/*.rs: Do not remove or modify comments unless the related code is changed
Only add comments that explain code functionality; do not add AI instructional comments
Never embed or call external binaries from Rust code

Files:

  • src/lib.rs
{src/**/*.rs,Cargo.*,README.md,OVERVIEW.md,.gitignore,.github/**}

📄 CodeRabbit inference engine (AGENTS.md)

Only commit changes to src/**/*.rs, Cargo.*, README.md, OVERVIEW.md, .gitignore, and .github/**; never use git add . or git add -A

Files:

  • src/lib.rs
🧠 Learnings (2)
📓 Common learnings
Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 2
File: LICENSE_COMMERCIAL:1-4
Timestamp: 2025-08-29T19:52:05.099Z
Learning: nerdCopter prefers to avoid publishing personal information in license files for privacy and security reasons, as they are an individual maintainer rather than a company.
Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 2
File: README.md:520-521
Timestamp: 2025-08-29T19:53:41.354Z
Learning: nerdCopter uses AGPL-3.0-or-later licensing for the bbl_parser project with a dual-licensing approach that includes a separate commercial license option.
Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 2
File: CONTRIBUTING.md:9-14
Timestamp: 2025-08-21T20:25:45.741Z
Learning: nerdCopter prefers to keep CLA language general using "project maintainer" rather than specifying a legal entity name, as they are an individual maintainer without an associated company.
Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 2
File: LICENSE_COMMERCIAL:0-0
Timestamp: 2025-08-29T20:15:04.624Z
Learning: nerdCopter prefers clear positive indicators (✅) when describing fixes rather than using ❌ symbols which can be confusing when describing what was corrected in a positive context.
📚 Learning: 2025-10-08T18:00:17.944Z
Learnt from: CR
Repo: nerdCopter/bbl_parser PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-10-08T18:00:17.944Z
Learning: Code must pass `cargo fmt --all -- --check` with no formatting issues

Applied to files:

  • src/lib.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test (windows-latest)
🔇 Additional comments (2)
src/lib.rs (2)

19-19: LGTM! Module exposure aligns with refactoring goals.

Making bbl_format, parser, and types public enables the CLI to import and use crate functions instead of maintaining duplicate implementations, as intended by issue #9.

Also applies to: 23-24


41-41: LGTM! Result re-export supports anyhow migration.

Re-exporting anyhow::Result provides convenient access for library users and aligns with the stated migration to anyhow-based error handling throughout the crate.

@nerdCopter
Copy link
Copy Markdown
Owner Author

@coderabbitai, my AI agent committed 2904762 based on your plan, but i'm not sure it is adhering to the plan.

see AI summary:

Summary of Issue #9 Progress
I've made 5 commits that address the CodeRabbitAI issue #9 while preserving the CLI's working logic:

Commits Made:
refactor: import GPS conversion functions from crate library

Removed ~40 lines of duplicate conversion functions
CLI now imports convert_gps_* functions from bbl_parser::conversion
refactor: import flag formatting functions from crate library

Removed ~90 lines of duplicate formatting functions
CLI now imports format_flight_mode_flags, format_state_flags, format_failsafe_phase
refactor: migrate crate library to use anyhow::Result

Updated all crate parser modules to use anyhow::Result
This aligns error handling between CLI and crate
fix: align crate parse_h_frame and 14-bit encoding with CLI behavior

Fixed crate's read_neg_14bit to use sign-magnitude encoding (matching CLI)
Updated crate's parse_h_frame to use graceful fallback (matching CLI)
refactor: make bbl_format module public for crate users

Export bbl_format module publicly for crate API users
What Was NOT Changed (by design):
CLI's local bbl_format module remains (it's the source of truth)
CLI's local type definitions remain (tightly coupled with local bbl_format)
CLI's parsing logic is unchanged
Why Full Type Migration Was Not Done:
The CLI has local types (FrameDefinition, BBLHeader, etc.) that are tightly coupled with the local bbl_format::parse_frame_data. Migrating to crate types would require either:

Changing CLI to use crate's BBLDataStream (different type, breaks function signatures)
Rewriting significant portions of CLI code
This would violate the user's constraint that "existing logic must NOT be changed or re-implemented."

Verification:
All tests pass ✅
Output matches blackbox_decode reference ✅
CLI functionality unchanged ✅

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Nov 30, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Fetch commit 2904762 details
echo "=== Commit 2904762 Details ==="
git log --format=fuller -n 1 2904762 2>/dev/null || git log --format=fuller -n 1 | head -20

echo -e "\n=== Files changed in recent commits ==="
git log --oneline --name-status -10 | head -50

echo -e "\n=== Current state of src/bbl_format.rs - check for sign_extend functions ==="
rg "^pub fn sign_extend" src/bbl_format.rs || echo "No sign_extend functions found in CLI bbl_format"

echo -e "\n=== Check if sign_extend functions exist in crate ==="
rg "^pub fn sign_extend" src/parser/ || echo "No sign_extend functions found in crate"

echo -e "\n=== Current line count of CLI bbl_format.rs ==="
wc -l src/bbl_format.rs

echo -e "\n=== Check what functions remain in CLI bbl_format.rs ==="
rg "^pub fn" src/bbl_format.rs | head -20

echo -e "\n=== Check if parse_frame_data still exists in both places ==="
echo "CLI version:"
rg "^pub fn parse_frame_data" src/bbl_format.rs -A 2
echo -e "\nCrate version:"
rg "^pub fn parse_frame_data" src/parser/frame.rs -A 2

Length of output: 3683


@nerdCopter, you're absolutely correct — commit 2904762 does NOT adhere to the plan. Your AI agent took the opposite approach from what was intended. Let me explain the deviation:

❌ What Went Wrong

My Plan's Direction: CLI should use crate functions → eventually delete CLI's bbl_format.rs

Agent's Actual Direction: Made CLI's bbl_format module PUBLIC so crate users can access it

This creates a reverse dependency and moves away from the unification goal rather than towards it.

📊 Current State Analysis

✅ What Was Done Well (commits 1-4):

  • Imported GPS conversion functions (~40 lines eliminated)
  • Imported flag formatting functions (~90 lines eliminated)
  • Migrated crate to anyhow::Result (alignment ✓)
  • Fixed H-frame/14-bit encoding alignment (behavior parity ✓)

❌ What Was NOT Done (commit 5 went the wrong way):

  • Phase 1: sign_extend_* functions remain in CLI bbl_format.rs (not moved to crate)
  • Phase 2: parse_frame_data still duplicated in both places
  • Phase 3: BBLDataStream still duplicated
  • src/bbl_format.rs still 655 lines (no reduction)

🔧 Corrective Action Needed

Revert commit 2904762 or modify it to follow the correct direction:

# Option A: Revert the "make public" commit
git revert 2904762

# Option B: Keep it if you want dual-direction compatibility (but still need Phase 1-3)

Then execute Phase 1 properly:

Phase 1 Implementation (Correct Approach)

Goal: Move sign_extend helpers FROM src/bbl_format.rs TO crate

// 1. Create src/parser/helpers.rs (NEW FILE)
pub fn sign_extend_2bit(value: u8) -> i32 {
    if value & 0x02 != 0 { (value as i32) | !0x03 } else { value as i32 }
}

pub fn sign_extend_4bit(value: u8) -> i32 {
    if value & 0x08 != 0 { (value as i32) | !0x0F } else { value as i32 }
}

pub fn sign_extend_6bit(value: u8) -> i32 {
    if value & 0x20 != 0 { (value as i32) | !0x3F } else { value as i32 }
}

pub fn sign_extend_8bit(value: u8) -> i32 {
    if value & 0x80 != 0 { (value as i32) | !0xFF } else { value as i32 }
}

pub fn sign_extend_14bit(value: u16) -> i32 {
    if value & 0x2000 != 0 { (value as i32) | !0x3FFF } else { value as i32 }
}

pub fn sign_extend_16bit(value: u16) -> i32 {
    if value & 0x8000 != 0 { (value as i32) | !0xFFFF } else { value as i32 }
}

pub fn sign_extend_24bit(value: u32) -> i32 {
    if value & 0x800000 != 0 { (value as i32) | !0xFFFFFF } else { value as i32 }
}

// 2. Update src/parser/mod.rs
mod helpers;
pub use helpers::*;

// 3. Update src/bbl_format.rs - IMPORT instead of define
use crate::parser::{
    sign_extend_2bit, sign_extend_4bit, sign_extend_6bit, 
    sign_extend_8bit, sign_extend_14bit, sign_extend_16bit, 
    sign_extend_24bit
};

// DELETE the 7 sign_extend function definitions from bbl_format.rs

// 4. Update src/main.rs if needed
use bbl_parser::sign_extend_14bit; // if used directly

📋 Corrected Execution Plan

Immediate Next Steps:

  1. Decide on commit 2904762:

    • Revert it (cleaner), OR
    • Keep it (dual compatibility) but understand it's not part of the unification plan
  2. Execute Phase 1 properly:

    • Create src/parser/helpers.rs
    • Copy sign_extend functions TO crate
    • Make CLI src/bbl_format.rs IMPORT them
    • Delete sign_extend implementations from src/bbl_format.rs
    • Test: cargo test && cargo build --release
    • Expected: ~50 lines eliminated from CLI
  3. Then Phase 2: Unify parse_frame_data (~160 lines)

  4. Then Phase 3: Unify BBLDataStream, delete bbl_format.rs entirely (~100 lines)

🎯 Key Principle

Direction of dependency:

CLI (src/main.rs, src/bbl_format.rs) 
  ↓ depends on ↓
Crate (src/lib.rs, src/parser/*)

NOT the reverse!

Would you like me to:

  1. Generate the exact code for Phase 1 (create helpers.rs with correct implementations)?
  2. Provide a script to verify the sign_extend implementations match before migration?
  3. Help decide whether to revert or keep commit 2904762?

🧠 Learnings used
Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 2
File: LICENSE_COMMERCIAL:1-4
Timestamp: 2025-08-29T19:52:05.099Z
Learning: nerdCopter prefers to avoid publishing personal information in license files for privacy and security reasons, as they are an individual maintainer rather than a company.

Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 2
File: README.md:520-521
Timestamp: 2025-08-29T19:53:41.354Z
Learning: nerdCopter uses AGPL-3.0-or-later licensing for the bbl_parser project with a dual-licensing approach that includes a separate commercial license option.

Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 2
File: CONTRIBUTING.md:9-14
Timestamp: 2025-08-21T20:25:45.741Z
Learning: nerdCopter prefers to keep CLA language general using "project maintainer" rather than specifying a legal entity name, as they are an individual maintainer without an associated company.

Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 2
File: LICENSE_COMMERCIAL:0-0
Timestamp: 2025-08-29T20:15:04.624Z
Learning: nerdCopter prefers clear positive indicators (✅) when describing fixes rather than using ❌ symbols which can be confusing when describing what was corrected in a positive context.

@nerdCopter
Copy link
Copy Markdown
Owner Author

@coderabbitai, should i hard-reset to 850fc27 ? and just merge? does 850fc27 work toward the goals of both CLI and CRATE functionality?

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Nov 30, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Get details of commit 850fc27
echo "=== Commit 850fc27 Details ==="
git log --format=fuller --stat -n 1 850fc27 2>/dev/null || echo "Commit not found"

# Get the commit history to see the order
echo -e "\n=== Recent commit history ==="
git log --oneline -15 | head -20

# Check if 2904762 comes after 850fc27
echo -e "\n=== Is 2904762 an ancestor of current HEAD? ==="
git log --oneline --all | grep -E "(850fc27|2904762)" | head -10

# Check what's in the diff at 850fc27
echo -e "\n=== Changes introduced at 850fc27 ==="
git show 850fc27 --stat

# Check the commit message
echo -e "\n=== Commit 850fc27 message ==="
git log --format=%B -n 1 850fc27

# List all commits in this PR branch
echo -e "\n=== All commits on this branch ==="
git log --oneline master..HEAD 2>/dev/null || git log --oneline -10

Length of output: 4333


@nerdCopter, YES — hard-reset to 850fc27 and merge! ✅

🎯 Why 850fc27 is Perfect

Commit 850fc27 is the last good commit before 2904762 went the wrong direction. Here's what resetting to it accomplishes:

✅ What 850fc27 Includes (Commits 1-4)

  1. 08b3f1b: Import GPS conversion functions (~40 lines eliminated)
  2. 0f9d196: Import flag formatting functions (~90 lines eliminated)
  3. 20a8f0a: Migrate crate to anyhow::Result (unified error handling)
  4. 850fc27: Align H-frame parsing and 14-bit encoding (behavior parity)

Total: ~140 lines of duplication eliminated

✅ Works Toward Both CLI and CRATE Goals

CLI Benefits:

  • Uses crate functions for GPS/flag conversions (DRY principle)
  • Maintains all existing functionality unchanged
  • Has unified error handling with crate

CRATE Benefits:

  • Exports proper GPS and flag formatting functions
  • Uses anyhow::Result (standard, idiomatic)
  • Has correct H-frame and 14-bit encoding behavior matching CLI

Direction: CLI depends on crate (correct ✓), not the reverse

❌ What Gets Removed

  • 2904762: The problematic commit that made bbl_format public and went the wrong direction

🚀 Recommendation

# Reset to 850fc27
git reset --hard 850fc27

# Force push to update the PR
git push origin 20251130_FIX_ISSUE_9 --force

Then merge — this PR will:

📋 What's Next (Future PRs)

After merging this PR:

This is the right approach — incremental, testable, and moves in the correct direction. Commit 850fc27 is merge-ready! 🎉


🧠 Learnings used
Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 2
File: LICENSE_COMMERCIAL:1-4
Timestamp: 2025-08-29T19:52:05.099Z
Learning: nerdCopter prefers to avoid publishing personal information in license files for privacy and security reasons, as they are an individual maintainer rather than a company.

Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 2
File: README.md:520-521
Timestamp: 2025-08-29T19:53:41.354Z
Learning: nerdCopter uses AGPL-3.0-or-later licensing for the bbl_parser project with a dual-licensing approach that includes a separate commercial license option.

Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 2
File: CONTRIBUTING.md:9-14
Timestamp: 2025-08-21T20:25:45.741Z
Learning: nerdCopter prefers to keep CLA language general using "project maintainer" rather than specifying a legal entity name, as they are an individual maintainer without an associated company.

Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 2
File: LICENSE_COMMERCIAL:0-0
Timestamp: 2025-08-29T20:15:04.624Z
Learning: nerdCopter prefers clear positive indicators (✅) when describing fixes rather than using ❌ symbols which can be confusing when describing what was corrected in a positive context.

@nerdCopter nerdCopter force-pushed the 20251130_FIX_ISSUE_9 branch from 2904762 to 850fc27 Compare December 1, 2025 14:15
@nerdCopter nerdCopter merged commit e20e467 into master Dec 1, 2025
17 checks passed
@nerdCopter
Copy link
Copy Markdown
Owner Author

@coderabbitai, i have force-pushed and merged. create a new issue ticket with AI-instructional HOW-TO continue the resolution of #9. It should be highly detailed, iterative, and all-encompassing and should also tell AI how not to regress or do the opposite.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 1, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Create a comprehensive issue ticket for continuing issue #9 resolution

gh issue create --repo nerdCopter/bbl_parser \
  --title "Complete CLI-to-Crate Unification (Phase 1-3): Eliminate Remaining Duplication" \
  --assignee nerdCopter \
  --body "## Context

This issue continues the work from **issue #9** and **PR #10**.

**✅ Completed in PR #10** (~140 lines eliminated):
- GPS conversion functions migrated to crate
- Flag formatting functions migrated to crate
- Error handling unified with anyhow::Result
- H-frame parsing and 14-bit encoding aligned

**🔄 Remaining Work** (~310 lines to eliminate):
This issue covers the final three phases to complete full unification.

---

## 🎯 Critical Principle: Dependency Direction

\`\`\`
CLI (src/main.rs, src/bbl_format.rs)
  ↓ DEPENDS ON ↓
Crate (src/lib.rs, src/parser/*)
\`\`\`

**✅ CORRECT**: CLI imports and uses crate functions  
**❌ WRONG**: Making CLI modules public for crate to use (creates reverse dependency)

---

## Phase 1: Unify Helper Functions (~50 lines)

### Objective
Move \`sign_extend_*\` helper functions FROM \`src/bbl_format.rs\` TO crate library.

### Current State
- **CLI**: \`src/bbl_format.rs\` contains 7 sign_extend functions (lines vary)
- **Crate**: No centralized helper functions module

### AI Agent Instructions

#### Step 1.1: Create Helper Module in Crate

Create new file: \`src/parser/helpers.rs\`

\`\`\`rust
//! Helper functions for BBL parsing

/// Sign-extend a 2-bit value to i32
pub fn sign_extend_2bit(value: u8) -> i32 {
    if value & 0x02 != 0 {
        (value as i32) | !0x03
    } else {
        value as i32
    }
}

/// Sign-extend a 4-bit value to i32
pub fn sign_extend_4bit(value: u8) -> i32 {
    if value & 0x08 != 0 {
        (value as i32) | !0x0F
    } else {
        value as i32
    }
}

/// Sign-extend a 6-bit value to i32
pub fn sign_extend_6bit(value: u8) -> i32 {
    if value & 0x20 != 0 {
        (value as i32) | !0x3F
    } else {
        value as i32
    }
}

/// Sign-extend an 8-bit value to i32
pub fn sign_extend_8bit(value: u8) -> i32 {
    if value & 0x80 != 0 {
        (value as i32) | !0xFF
    } else {
        value as i32
    }
}

/// Sign-extend a 14-bit value to i32
pub fn sign_extend_14bit(value: u16) -> i32 {
    if value & 0x2000 != 0 {
        (value as i32) | !0x3FFF
    } else {
        value as i32
    }
}

/// Sign-extend a 16-bit value to i32
pub fn sign_extend_16bit(value: u16) -> i32 {
    if value & 0x8000 != 0 {
        (value as i32) | !0xFFFF
    } else {
        value as i32
    }
}

/// Sign-extend a 24-bit value to i32
pub fn sign_extend_24bit(value: u32) -> i32 {
    if value & 0x800000 != 0 {
        (value as i32) | !0xFFFFFF
    } else {
        value as i32
    }
}
\`\`\`

**Verification**: Ensure implementations exactly match \`src/bbl_format.rs\`

#### Step 1.2: Export from Parser Module

Update: \`src/parser/mod.rs\`

\`\`\`rust
// ... existing module declarations ...
mod helpers;

// ... existing pub use statements ...
pub use helpers::*;
\`\`\`

#### Step 1.3: Export from Crate Root

Update: \`src/lib.rs\`

Ensure parser module is already public and re-exported (should be from PR #10):
\`\`\`rust
pub mod parser;
pub use parser::*;
\`\`\`

#### Step 1.4: Update CLI to Import Helpers

Update: \`src/bbl_format.rs\`

**Add at top of file**:
\`\`\`rust
use bbl_parser::parser::{
    sign_extend_2bit, 
    sign_extend_4bit, 
    sign_extend_6bit,
    sign_extend_8bit, 
    sign_extend_14bit, 
    sign_extend_16bit, 
    sign_extend_24bit,
};
\`\`\`

**DELETE the 7 sign_extend function definitions from \`src/bbl_format.rs\`**

Estimated lines removed: ~35-50

#### Step 1.5: Validation

\`\`\`bash
# Build and test
cargo build --release
cargo test

# A/B test CLI against reference
./target/release/bbl_parser test_logs/*.BBL --csv --gpx --event
# Compare outputs against known-good reference
\`\`\`

**Checkpoint**: Verify no behavior changes, all tests pass.

---

## Phase 2: Unify parse_frame_data (~160 lines)

### Objective
Replace CLI's \`parse_frame_data\` with crate's version, handling the debug parameter difference.

### Current State
- **CLI**: \`src/bbl_format.rs::parse_frame_data\` has \`debug: bool\` parameter
- **Crate**: \`src/parser/frame.rs::parse_frame_data\` does NOT have debug parameter

### AI Agent Instructions

#### Step 2.1: Add Debug Parameter to Crate Function

Update: \`src/parser/frame.rs\`

**Modify function signature**:
\`\`\`rust
pub fn parse_frame_data(
    stream: &mut BBLDataStream,
    frame_def: &FrameDefinition,
    current_frame: &mut [i32],
    previous_frame: Option<&[i32]>,
    previous2_frame: Option<&[i32]>,
    skipped_frames: u32,
    raw: bool,
    data_version: u8,
    sysconfig: &HashMap<String, i32>,
    debug: bool,  // ADD THIS PARAMETER
) -> Result<()>
\`\`\`

**Add debug logging** (mirror CLI behavior):
- When \`debug == true\`, log field decoding steps
- Example locations: after \`decode_field_value\`, after \`apply_predictor\`

Reference CLI implementation in \`src/bbl_format.rs\` for exact debug output format.

#### Step 2.2: Update Crate Call Sites

Search for \`parse_frame_data\` calls in \`src/parser/\`:
\`\`\`bash
rg \"parse_frame_data\\(\" src/parser/ -A 2
\`\`\`

Add \`debug: false\` to any internal crate calls.

#### Step 2.3: Update CLI to Use Crate Function

Update: \`src/main.rs\`

**Add import**:
\`\`\`rust
use bbl_parser::parser::parse_frame_data;
\`\`\`

**Replace call sites**:
Find: \`bbl_format::parse_frame_data(\`
Replace with: \`parse_frame_data(\`

#### Step 2.4: Remove CLI Implementation

Update: \`src/bbl_format.rs\`

**DELETE** the entire \`parse_frame_data\` function (approximately 160 lines).

#### Step 2.5: Validation

\`\`\`bash
# Full build and test suite
cargo clean
cargo build --release
cargo test --all

# A/B test with debug enabled
./target/release/bbl_parser test_logs/flight1.BBL --debug --csv
# Compare against reference implementation output

# Test without debug
./target/release/bbl_parser test_logs/flight1.BBL --csv
diff output.csv reference.csv
\`\`\`

**Checkpoint**: Verify identical output with and without debug flag.

---

## Phase 3: Unify BBLDataStream & Delete bbl_format.rs (~100 lines)

### Objective
Make CLI use crate's \`BBLDataStream\`, eliminate \`src/bbl_format.rs\` entirely.

### Current State
- **CLI**: \`src/bbl_format.rs::BBLDataStream\` (~100 lines)
- **Crate**: \`src/parser/stream.rs::BBLDataStream\` (~200 lines)

### AI Agent Instructions

#### Step 3.1: Verify Implementation Compatibility

\`\`\`bash
# Compare the two implementations
diff -u <(sed -n '/pub struct BBLDataStream/,/^}/p' src/bbl_format.rs) \\
        <(sed -n '/pub struct BBLDataStream/,/^}/p' src/parser/stream.rs)
\`\`\`

**Action**: If implementations differ, align crate version with CLI behavior first (separate commit).

#### Step 3.2: Update CLI Imports

Update: \`src/main.rs\`

**Remove**:
\`\`\`rust
mod bbl_format;
\`\`\`

**Add**:
\`\`\`rust
use bbl_parser::BBLDataStream;
\`\`\`

If any constants remain in \`bbl_format\`:
\`\`\`rust
use bbl_parser::parser::{ENCODING_*, PREDICTOR_*}; // if needed
\`\`\`

#### Step 3.3: Global Type Replacement in main.rs

Find all occurrences:
\`\`\`bash
rg \"bbl_format::\" src/main.rs
\`\`\`

Replace:
- \`bbl_format::BBLDataStream\` → \`BBLDataStream\`
- \`bbl_format::ENCODING_*\` → \`ENCODING_*\` (if constants moved)
- Any other \`bbl_format::\` references

#### Step 3.4: Verify No Remaining bbl_format Dependencies

\`\`\`bash
# Check for any remaining references
rg \"bbl_format\" src/main.rs
# Should return zero results
\`\`\`

#### Step 3.5: Delete CLI bbl_format Module

\`\`\`bash
# Remove the file
git rm src/bbl_format.rs

# Verify it's not referenced in lib.rs
rg \"bbl_format\" src/lib.rs
\`\`\`

Update \`src/lib.rs\` if any \`bbl_format\` references remain (should already be clean from PR #10).

#### Step 3.6: Comprehensive Validation

\`\`\`bash
# Full rebuild
cargo clean
cargo build --release
cargo test --all

# Test all frame types
for file in test_logs/*.BBL; do
    echo \"Testing: \$file\"
    ./target/release/bbl_parser \"\$file\" --csv --gpx --event
done

# Compare against reference implementation
diff -r output_new/ output_reference/
\`\`\`

**Final Checkpoint**: 
- ✅ All tests pass
- ✅ CLI output identical to reference
- ✅ \`src/bbl_format.rs\` deleted
- ✅ ~310 total lines eliminated

---

## ❌ Anti-Patterns: What NOT to Do

### DO NOT: Make CLI Modules Public

**Wrong Example** (from commit 2904762):
\`\`\`rust
// ❌ WRONG in src/lib.rs
pub mod bbl_format;  // Making CLI module public
pub use bbl_format::*;
\`\`\`

**Why Wrong**: Creates reverse dependency (crate depends on CLI module)

**Correct Approach**: Move functionality TO crate, CLI imports FROM crate

### DO NOT: Add crate → CLI Dependencies

**Wrong Pattern**:
\`\`\`rust
// ❌ WRONG in src/parser/gps.rs
use crate::bbl_format::some_helper;
\`\`\`

**Why Wrong**: Crate should never import from CLI modules

**Correct Pattern**:
\`\`\`rust
// ✅ CORRECT in src/main.rs
use bbl_parser::parser::some_helper;
\`\`\`

### DO NOT: Skip Validation Steps

**Wrong Approach**:
- Making all changes at once without testing
- Skipping A/B testing against reference
- Not verifying behavior parity

**Correct Approach**:
- Complete one phase at a time
- Validate after each step
- Run full test suite + A/B comparison
- Commit and test before moving to next phase

### DO NOT: Change Working Logic

**Wrong Example**:
\`\`\`rust
// ❌ WRONG: Changing the algorithm while migrating
pub fn sign_extend_14bit(value: u16) -> i32 {
    // Don't optimize or refactor the logic here!
    // Just move it exactly as-is
}
\`\`\`

**Correct Approach**: Copy implementation byte-for-byte, refactor in separate PR if needed

---

## Execution Checklist

### Phase 1: Helper Functions
- [ ] Create \`src/parser/helpers.rs\` with 7 sign_extend functions
- [ ] Export from \`src/parser/mod.rs\`
- [ ] Verify exports in \`src/lib.rs\`
- [ ] Import in \`src/bbl_format.rs\`
- [ ] Delete sign_extend definitions from \`src/bbl_format.rs\`
- [ ] Run \`cargo build --release\`
- [ ] Run \`cargo test\`
- [ ] A/B test CLI output
- [ ] Commit: \"refactor: move sign_extend helpers to crate library\"

### Phase 2: parse_frame_data
- [ ] Add \`debug: bool\` param to crate's \`parse_frame_data\`
- [ ] Add debug logging in crate function
- [ ] Update internal crate call sites
- [ ] Import crate's \`parse_frame_data\` in \`src/main.rs\`
- [ ] Replace CLI call sites
- [ ] Delete \`parse_frame_data\` from \`src/bbl_format.rs\`
- [ ] Run \`cargo clean && cargo build --release\`
- [ ] Run \`cargo test --all\`
- [ ] Test with \`--debug\` flag
- [ ] A/B test with/without debug
- [ ] Commit: \"refactor: unify parse_frame_data implementation\"

### Phase 3: BBLDataStream
- [ ] Verify BBLDataStream implementations match
- [ ] Remove \`mod bbl_format;\` from \`src/main.rs\`
- [ ] Import \`BBLDataStream\` from crate
- [ ] Replace all \`bbl_format::*\` references in \`src/main.rs\`
- [ ] Verify no remaining \`bbl_format\` references
- [ ] Delete \`src/bbl_format.rs\`
- [ ] Run \`cargo clean && cargo build --release\`
- [ ] Run \`cargo test --all\`
- [ ] Full A/B test suite on all test logs
- [ ] Commit: \"refactor: unify BBLDataStream, eliminate CLI bbl_format module\"

---

## Expected Outcomes

### Code Metrics
- **Lines Eliminated**: ~310 (Phase 1: ~50, Phase 2: ~160, Phase 3: ~100)
- **Total with PR #10**: ~450 lines of duplication eliminated
- **Modules Deleted**: \`src/bbl_format.rs\` (entire file)

### Architecture
- ✅ CLI fully depends on crate library
- ✅ Single source of truth for all parsing logic
- ✅ Identical behavior guaranteed between CLI and library
- ✅ Simplified maintenance (fix bugs once)

### Testing
- ✅ All unit tests pass
- ✅ Integration tests pass
- ✅ CLI output identical to reference implementation
- ✅ Debug mode works correctly
- ✅ All frame types parse correctly (H, G, E, etc.)

---

## References

- **Issue #9**: Original duplication issue
- **PR #10**: Completed phases (GPS, flags, error handling, H-frame alignment)
- **Commit 850fc27**: Last good commit with ~140 lines eliminated

---

## Notes for AI Agents

1. **One Phase at a Time**: Complete Phase 1 fully before starting Phase 2
2. **Validate Between Phases**: Run full test suite after each phase
3. **Preserve Working Code**: Don't refactor logic while migrating
4. **Direction Matters**: Always CLI → crate dependencies, never reverse
5. **A/B Testing is Mandatory**: Compare against reference implementation
6. **Commit Granularity**: One commit per phase with clear message
7. **When in Doubt**: Ask the human maintainer for clarification

**Success Criteria**: All tests pass + CLI output identical to reference + \`src/bbl_format.rs\` deleted" \
  --label "enhancement" \
  --label "refactoring"

Length of output: 44


🏁 Script executed:

#!/bin/bash
# Check if the issue was created despite the label error
echo "=== Checking recent issues ==="
gh issue list --repo nerdCopter/bbl_parser --limit 5

# Create the issue without the problematic label
echo -e "\n=== Creating issue with correct label ==="
gh issue create --repo nerdCopter/bbl_parser \
  --title "Complete CLI-to-Crate Unification (Phase 1-3): Eliminate Remaining Duplication" \
  --assignee nerdCopter \
  --label "enhancement" \
  --body "## Context

This issue continues the work from **issue #9** and **PR #10**.

**✅ Completed in PR #10** (~140 lines eliminated):
- GPS conversion functions migrated to crate
- Flag formatting functions migrated to crate
- Error handling unified with anyhow::Result
- H-frame parsing and 14-bit encoding aligned

**🔄 Remaining Work** (~310 lines to eliminate):
This issue covers the final three phases to complete full unification.

---

## 🎯 Critical Principle: Dependency Direction

\`\`\`
CLI (src/main.rs, src/bbl_format.rs)
  ↓ DEPENDS ON ↓
Crate (src/lib.rs, src/parser/*)
\`\`\`

**✅ CORRECT**: CLI imports and uses crate functions  
**❌ WRONG**: Making CLI modules public for crate to use (creates reverse dependency)

---

## Phase 1: Unify Helper Functions (~50 lines)

### Objective
Move \`sign_extend_*\` helper functions FROM \`src/bbl_format.rs\` TO crate library.

### Current State
- **CLI**: \`src/bbl_format.rs\` contains 7 sign_extend functions (lines vary)
- **Crate**: No centralized helper functions module

### AI Agent Instructions

#### Step 1.1: Create Helper Module in Crate

Create new file: \`src/parser/helpers.rs\`

\`\`\`rust
//! Helper functions for BBL parsing

/// Sign-extend a 2-bit value to i32
pub fn sign_extend_2bit(value: u8) -> i32 {
    if value & 0x02 != 0 {
        (value as i32) | !0x03
    } else {
        value as i32
    }
}

/// Sign-extend a 4-bit value to i32
pub fn sign_extend_4bit(value: u8) -> i32 {
    if value & 0x08 != 0 {
        (value as i32) | !0x0F
    } else {
        value as i32
    }
}

/// Sign-extend a 6-bit value to i32
pub fn sign_extend_6bit(value: u8) -> i32 {
    if value & 0x20 != 0 {
        (value as i32) | !0x3F
    } else {
        value as i32
    }
}

/// Sign-extend an 8-bit value to i32
pub fn sign_extend_8bit(value: u8) -> i32 {
    if value & 0x80 != 0 {
        (value as i32) | !0xFF
    } else {
        value as i32
    }
}

/// Sign-extend a 14-bit value to i32
pub fn sign_extend_14bit(value: u16) -> i32 {
    if value & 0x2000 != 0 {
        (value as i32) | !0x3FFF
    } else {
        value as i32
    }
}

/// Sign-extend a 16-bit value to i32
pub fn sign_extend_16bit(value: u16) -> i32 {
    if value & 0x8000 != 0 {
        (value as i32) | !0xFFFF
    } else {
        value as i32
    }
}

/// Sign-extend a 24-bit value to i32
pub fn sign_extend_24bit(value: u32) -> i32 {
    if value & 0x800000 != 0 {
        (value as i32) | !0xFFFFFF
    } else {
        value as i32
    }
}
\`\`\`

**Verification**: Ensure implementations exactly match \`src/bbl_format.rs\`

#### Step 1.2: Export from Parser Module

Update: \`src/parser/mod.rs\`

\`\`\`rust
// ... existing module declarations ...
mod helpers;

// ... existing pub use statements ...
pub use helpers::*;
\`\`\`

#### Step 1.3: Export from Crate Root

Update: \`src/lib.rs\`

Ensure parser module is already public and re-exported (should be from PR #10):
\`\`\`rust
pub mod parser;
pub use parser::*;
\`\`\`

#### Step 1.4: Update CLI to Import Helpers

Update: \`src/bbl_format.rs\`

**Add at top of file**:
\`\`\`rust
use bbl_parser::parser::{
    sign_extend_2bit, 
    sign_extend_4bit, 
    sign_extend_6bit,
    sign_extend_8bit, 
    sign_extend_14bit, 
    sign_extend_16bit, 
    sign_extend_24bit,
};
\`\`\`

**DELETE the 7 sign_extend function definitions from \`src/bbl_format.rs\`**

Estimated lines removed: ~35-50

#### Step 1.5: Validation

\`\`\`bash
# Build and test
cargo build --release
cargo test

# A/B test CLI against reference
./target/release/bbl_parser test_logs/*.BBL --csv --gpx --event
# Compare outputs against known-good reference
\`\`\`

**Checkpoint**: Verify no behavior changes, all tests pass.

---

## Phase 2: Unify parse_frame_data (~160 lines)

### Objective
Replace CLI's \`parse_frame_data\` with crate's version, handling the debug parameter difference.

### Current State
- **CLI**: \`src/bbl_format.rs::parse_frame_data\` has \`debug: bool\` parameter
- **Crate**: \`src/parser/frame.rs::parse_frame_data\` does NOT have debug parameter

### AI Agent Instructions

#### Step 2.1: Add Debug Parameter to Crate Function

Update: \`src/parser/frame.rs\`

**Modify function signature**:
\`\`\`rust
pub fn parse_frame_data(
    stream: &mut BBLDataStream,
    frame_def: &FrameDefinition,
    current_frame: &mut [i32],
    previous_frame: Option<&[i32]>,
    previous2_frame: Option<&[i32]>,
    skipped_frames: u32,
    raw: bool,
    data_version: u8,
    sysconfig: &HashMap<String, i32>,
    debug: bool,  // ADD THIS PARAMETER
) -> Result<()>
\`\`\`

**Add debug logging** (mirror CLI behavior):
- When \`debug == true\`, log field decoding steps
- Example locations: after \`decode_field_value\`, after \`apply_predictor\`

Reference CLI implementation in \`src/bbl_format.rs\` for exact debug output format.

#### Step 2.2: Update Crate Call Sites

Search for \`parse_frame_data\` calls in \`src/parser/\`:
\`\`\`bash
rg \"parse_frame_data\\(\" src/parser/ -A 2
\`\`\`

Add \`debug: false\` to any internal crate calls.

#### Step 2.3: Update CLI to Use Crate Function

Update: \`src/main.rs\`

**Add import**:
\`\`\`rust
use bbl_parser::parser::parse_frame_data;
\`\`\`

**Replace call sites**:
Find: \`bbl_format::parse_frame_data(\`
Replace with: \`parse_frame_data(\`

#### Step 2.4: Remove CLI Implementation

Update: \`src/bbl_format.rs\`

**DELETE** the entire \`parse_frame_data\` function (approximately 160 lines).

#### Step 2.5: Validation

\`\`\`bash
# Full build and test suite
cargo clean
cargo build --release
cargo test --all

# A/B test with debug enabled
./target/release/bbl_parser test_logs/flight1.BBL --debug --csv
# Compare against reference implementation output

# Test without debug
./target/release/bbl_parser test_logs/flight1.BBL --csv
diff output.csv reference.csv
\`\`\`

**Checkpoint**: Verify identical output with and without debug flag.

---

## Phase 3: Unify BBLDataStream & Delete bbl_format.rs (~100 lines)

### Objective
Make CLI use crate's \`BBLDataStream\`, eliminate \`src/bbl_format.rs\` entirely.

### Current State
- **CLI**: \`src/bbl_format.rs::BBLDataStream\` (~100 lines)
- **Crate**: \`src/parser/stream.rs::BBLDataStream\` (~200 lines)

### AI Agent Instructions

#### Step 3.1: Verify Implementation Compatibility

\`\`\`bash
# Compare the two implementations
diff -u <(sed -n '/pub struct BBLDataStream/,/^}/p' src/bbl_format.rs) \\
        <(sed -n '/pub struct BBLDataStream/,/^}/p' src/parser/stream.rs)
\`\`\`

**Action**: If implementations differ, align crate version with CLI behavior first (separate commit).

#### Step 3.2: Update CLI Imports

Update: \`src/main.rs\`

**Remove**:
\`\`\`rust
mod bbl_format;
\`\`\`

**Add**:
\`\`\`rust
use bbl_parser::BBLDataStream;
\`\`\`

If any constants remain in \`bbl_format\`:
\`\`\`rust
use bbl_parser::parser::{ENCODING_*, PREDICTOR_*}; // if needed
\`\`\`

#### Step 3.3: Global Type Replacement in main.rs

Find all occurrences:
\`\`\`bash
rg \"bbl_format::\" src/main.rs
\`\`\`

Replace:
- \`bbl_format::BBLDataStream\` → \`BBLDataStream\`
- \`bbl_format::ENCODING_*\` → \`ENCODING_*\` (if constants moved)
- Any other \`bbl_format::\` references

#### Step 3.4: Verify No Remaining bbl_format Dependencies

\`\`\`bash
# Check for any remaining references
rg \"bbl_format\" src/main.rs
# Should return zero results
\`\`\`

#### Step 3.5: Delete CLI bbl_format Module

\`\`\`bash
# Remove the file
git rm src/bbl_format.rs

# Verify it's not referenced in lib.rs
rg \"bbl_format\" src/lib.rs
\`\`\`

Update \`src/lib.rs\` if any \`bbl_format\` references remain (should already be clean from PR #10).

#### Step 3.6: Comprehensive Validation

\`\`\`bash
# Full rebuild
cargo clean
cargo build --release
cargo test --all

# Test all frame types
for file in test_logs/*.BBL; do
    echo \"Testing: \$file\"
    ./target/release/bbl_parser \"\$file\" --csv --gpx --event
done

# Compare against reference implementation
diff -r output_new/ output_reference/
\`\`\`

**Final Checkpoint**: 
- ✅ All tests pass
- ✅ CLI output identical to reference
- ✅ \`src/bbl_format.rs\` deleted
- ✅ ~310 total lines eliminated

---

## ❌ Anti-Patterns: What NOT to Do

### DO NOT: Make CLI Modules Public

**Wrong Example** (from commit 2904762):
\`\`\`rust
// ❌ WRONG in src/lib.rs
pub mod bbl_format;  // Making CLI module public
pub use bbl_format::*;
\`\`\`

**Why Wrong**: Creates reverse dependency (crate depends on CLI module)

**Correct Approach**: Move functionality TO crate, CLI imports FROM crate

### DO NOT: Add crate → CLI Dependencies

**Wrong Pattern**:
\`\`\`rust
// ❌ WRONG in src/parser/gps.rs
use crate::bbl_format::some_helper;
\`\`\`

**Why Wrong**: Crate should never import from CLI modules

**Correct Pattern**:
\`\`\`rust
// ✅ CORRECT in src/main.rs
use bbl_parser::parser::some_helper;
\`\`\`

### DO NOT: Skip Validation Steps

**Wrong Approach**:
- Making all changes at once without testing
- Skipping A/B testing against reference
- Not verifying behavior parity

**Correct Approach**:
- Complete one phase at a time
- Validate after each step
- Run full test suite + A/B comparison
- Commit and test before moving to next phase

### DO NOT: Change Working Logic

**Wrong Example**:
\`\`\`rust
// ❌ WRONG: Changing the algorithm while migrating
pub fn sign_extend_14bit(value: u16) -> i32 {
    // Don't optimize or refactor the logic here!
    // Just move it exactly as-is
}
\`\`\`

**Correct Approach**: Copy implementation byte-for-byte, refactor in separate PR if needed

---

## Execution Checklist

### Phase 1: Helper Functions
- [ ] Create \`src/parser/helpers.rs\` with 7 sign_extend functions
- [ ] Export from \`src/parser/mod.rs\`
- [ ] Verify exports in \`src/lib.rs\`
- [ ] Import in \`src/bbl_format.rs\`
- [ ] Delete sign_extend definitions from \`src/bbl_format.rs\`
- [ ] Run \`cargo build --release\`
- [ ] Run \`cargo test\`
- [ ] A/B test CLI output
- [ ] Commit: \"refactor: move sign_extend helpers to crate library\"

### Phase 2: parse_frame_data
- [ ] Add \`debug: bool\` param to crate's \`parse_frame_data\`
- [ ] Add debug logging in crate function
- [ ] Update internal crate call sites
- [ ] Import crate's \`parse_frame_data\` in \`src/main.rs\`
- [ ] Replace CLI call sites
- [ ] Delete \`parse_frame_data\` from \`src/bbl_format.rs\`
- [ ] Run \`cargo clean && cargo build --release\`
- [ ] Run \`cargo test --all\`
- [ ] Test with \`--debug\` flag
- [ ] A/B test with/without debug
- [ ] Commit: \"refactor: unify parse_frame_data implementation\"

### Phase 3: BBLDataStream
- [ ] Verify BBLDataStream implementations match
- [ ] Remove \`mod bbl_format;\` from \`src/main.rs\`
- [ ] Import \`BBLDataStream\` from crate
- [ ] Replace all \`bbl_format::*\` references in \`src/main.rs\`
- [ ] Verify no remaining \`bbl_format\` references
- [ ] Delete \`src/bbl_format.rs\`
- [ ] Run \`cargo clean && cargo build --release\`
- [ ] Run \`cargo test --all\`
- [ ] Full A/B test suite on all test logs
- [ ] Commit: \"refactor: unify BBLDataStream, eliminate CLI bbl_format module\"

---

## Expected Outcomes

### Code Metrics
- **Lines Eliminated**: ~310 (Phase 1: ~50, Phase 2: ~160, Phase 3: ~100)
- **Total with PR #10**: ~450 lines of duplication eliminated
- **Modules Deleted**: \`src/bbl_format.rs\` (entire file)

### Architecture
- ✅ CLI fully depends on crate library
- ✅ Single source of truth for all parsing logic
- ✅ Identical behavior guaranteed between CLI and library
- ✅ Simplified maintenance (fix bugs once)

### Testing
- ✅ All unit tests pass
- ✅ Integration tests pass
- ✅ CLI output identical to reference implementation
- ✅ Debug mode works correctly
- ✅ All frame types parse correctly (H, G, E, etc.)

---

## References

- **Issue #9**: https://github.com/nerdCopter/bbl_parser/issues/9
- **PR #10**: https://github.com/nerdCopter/bbl_parser/pull/10
- **Commit 850fc27**: Last good commit with ~140 lines eliminated

---

## Notes for AI Agents

1. **One Phase at a Time**: Complete Phase 1 fully before starting Phase 2
2. **Validate Between Phases**: Run full test suite after each phase
3. **Preserve Working Code**: Don't refactor logic while migrating
4. **Direction Matters**: Always CLI → crate dependencies, never reverse
5. **A/B Testing is Mandatory**: Compare against reference implementation
6. **Commit Granularity**: One commit per phase with clear message
7. **When in Doubt**: Ask the human maintainer for clarification

**Success Criteria**: All tests pass + CLI output identical to reference + \`src/bbl_format.rs\` deleted"

Length of output: 124


@nerdCopter, I've successfully created Issue #11 with comprehensive AI-instructional documentation! 🎉

What's Included

📋 Three Detailed Phases

Phase 1: Unify Helper Functions (~50 lines)

  • Step-by-step instructions to create src/parser/helpers.rs
  • Exact code for all 7 sign_extend_* functions
  • Import/export instructions
  • Validation steps

Phase 2: Unify parse_frame_data (~160 lines)

  • How to add debug parameter to crate function
  • Call site updates
  • CLI migration steps
  • Debug flag testing

Phase 3: Unify BBLDataStream (~100 lines)

  • Import refactoring instructions
  • Module deletion steps
  • Comprehensive validation suite

❌ Anti-Patterns Section

Explicitly documents what NOT to do with examples from the commit 2904762 mistake:

  • ❌ Don't make CLI modules public (creates reverse dependency)
  • ❌ Don't add crate → CLI dependencies
  • ❌ Don't skip validation steps
  • ❌ Don't change working logic during migration

✅ Additional Features

  • Execution Checklist: Task-by-task checkboxes for all three phases
  • Expected Outcomes: Metrics, architecture goals, testing criteria
  • Notes for AI Agents: 7 specific guidelines including:
    • One phase at a time
    • Direction matters (CLI → crate, never reverse)
    • A/B testing is mandatory
    • Preserve working code
    • When in doubt, ask the human

🔗 References

Success Criteria

The issue clearly states what completion looks like:

  • ✅ All tests pass
  • ✅ CLI output identical to reference
  • src/bbl_format.rs deleted
  • ✅ ~310 lines of duplication eliminated

This should provide your AI agent with crystal-clear instructions that prevent regression and ensure incremental, validated progress! 🚀


🧠 Learnings used
Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 2
File: LICENSE_COMMERCIAL:1-4
Timestamp: 2025-08-29T19:52:05.099Z
Learning: nerdCopter prefers to avoid publishing personal information in license files for privacy and security reasons, as they are an individual maintainer rather than a company.

Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 2
File: README.md:520-521
Timestamp: 2025-08-29T19:53:41.354Z
Learning: nerdCopter uses AGPL-3.0-or-later licensing for the bbl_parser project with a dual-licensing approach that includes a separate commercial license option.

Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 2
File: CONTRIBUTING.md:9-14
Timestamp: 2025-08-21T20:25:45.741Z
Learning: nerdCopter prefers to keep CLA language general using "project maintainer" rather than specifying a legal entity name, as they are an individual maintainer without an associated company.

Learnt from: nerdCopter
Repo: nerdCopter/bbl_parser PR: 2
File: LICENSE_COMMERCIAL:0-0
Timestamp: 2025-08-29T20:15:04.624Z
Learning: nerdCopter prefers clear positive indicators (✅) when describing fixes rather than using ❌ symbols which can be confusing when describing what was corrected in a positive context.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Refactor CLI to use crate library functions (eliminate code duplication)

1 participant