Skip to content

feat: expose ruxguitar as a library crate#31

Open
sethbrasile wants to merge 4 commits intoagourlay:masterfrom
sethbrasile:expose-ruxguitar-as-lib
Open

feat: expose ruxguitar as a library crate#31
sethbrasile wants to merge 4 commits intoagourlay:masterfrom
sethbrasile:expose-ruxguitar-as-lib

Conversation

@sethbrasile
Copy link

@agourlay are you open to this? I would like to build an application that uses ruxguitar as its parsing / playback engine. I would like to also contribute some future serialization features for the sake of "save" / "conversion" functionality as my application concept would be stacking a new UI and some editing features on top.

If this is a new direction that deviates from your vision for the project, no pressure, I am happy to maintain a fork with my adjustments! :D


Summary

This PR exposes ruxguitar as a library crate, allowing external Rust projects to use its Guitar Pro parsing and MIDI generation capabilities as a Cargo dependency.

I found myself wanting to use ruxguitar's parsing logic in another project and realized the crate is currently binary-only. Rather than forking, I thought it might be useful to expose the existing functionality as a library that others could also benefit from.

Changes

New files:

  • src/lib.rs - Library entry point with public module declarations and convenient re-exports
  • src/error.rs - Library-safe error type (RuxError) without iced dependency
  • tests/library_usage.rs - Integration tests demonstrating library usage

Modified files:

  • Cargo.toml - Added [lib] and [[bin]] sections for dual-target crate
  • src/main.rs - Binary now imports from the library; renamed error type to AppError to avoid confusion with library's RuxError
  • src/config.rs - Updated to use library's RuxError
  • UI modules - Updated imports to use ruxguitar:: namespace

Rationale

Why separate RuxError from AppError?

The existing RuxError in main.rs includes an IcedError variant for GUI errors. Since the library shouldn't depend on iced (library consumers may not want the GUI), I created a library-safe RuxError in src/error.rs with only the core variants (ParsingError, ConfigError, AudioError, IoError). The binary keeps its own AppError that includes IcedError and implements From<RuxError> for ergonomic error handling.

What's exposed?

The library re-exports commonly needed types at the crate root for convenience:

  • parse_gp_data - Main parsing function
  • Song, Track, Measure, Beat, Note, etc. - Song structure types
  • MidiBuilder, MidiEvent, MidiEventType, MidiSequencer - MIDI generation
  • FIRST_TICK, QUARTER_TIME - Timing constants
  • RuxError - Error type

Example usage

use ruxguitar::{parse_gp_data, MidiBuilder};
use std::rc::Rc;

let file_data = std::fs::read("song.gp5")?;
let song = parse_gp_data(&file_data)?;
let midi_events = MidiBuilder::new().build_for_song(&Rc::new(song));

Testing

- All existing tests pass (14 unit tests)
- Added 4 integration tests verifying library API works from external perspective
- Verified binary still builds and runs correctly
- Verified cargo build --lib compiles the library independently

Breaking changes

None. The binary works exactly as before. This is purely additive.

Notes

I tried to keep the diff minimal and focused. Happy to adjust anything based on your preferences for API design, module organization, or naming conventions.

Add library entry point and public API for external crate usage:

- Add src/lib.rs with public module declarations and re-exports
- Add src/error.rs with library-safe RuxError enum (no iced dependency)
- Configure Cargo.toml for dual library/binary crate

External projects can now depend on ruxguitar to:
- Parse Guitar Pro files with parse_gp_data()
- Access Song, Track, Measure, Beat, Note types
- Generate MIDI events with MidiBuilder
- Sequence playback with MidiSequencer

Build commands:
- `cargo build --lib` - library only
- `cargo build --bin ruxguitar` - binary only
- `cargo build` - both
- Removed mod parser/audio declarations from main.rs (use library)
- Renamed binary RuxError to AppError (keeps IcedError variant)
- Added From<LibRuxError> for AppError conversion
- Updated config.rs to use ruxguitar::RuxError
- Updated UI modules to import from ruxguitar library
- Test that all major types are accessible from library
- Test parsing GP5 file using library API
- Test MIDI event generation using MidiBuilder
- Test error handling for invalid input

Verifies COMPAT-03: Library usable as dependency from external project
- Fixed doctest in lib.rs to use MidiBuilder::new()
- Updated integration tests to use correct API
- Added Default impl for MidiBuilder (clippy warning)
- Formatted code with cargo fmt
@agourlay
Copy link
Owner

Thanks for the PR.

TBH I have not thought yet about exposing some of the internals as a library crate.

I think having more context would help me understand the use case.

What are you building exactly?
What would you need in the future?

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.

2 participants