We resolved two issues when running turtle programs with `--export-svg`:
1. **Missing filename**: Previously, running `--export-svg` without a
filename caused the CLI parser to ignore the flag and open the GUI
window. Now, it emits `Error: --export-svg: option requires an
argument` and terminates with exit code 1.
2. **Missing `svg` feature**: Previously, running `--export-svg` without
the `svg` feature enabled ignored the flag if no filename was passed
and opened the window. Now, any invocation of `--export-svg` without
`--features svg` emits `Error: SVG export feature is not enabled.
Please rebuild with --features svg` and terminates with exit code 1.
---
- Added [`pico-args = { version = "0.5", features = ["eq-separator"]
}`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/Cargo.toml)
under `[dependencies]`.
- In
[`turtle-lib/src/export.rs`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/export.rs):
- Added `MissingFeature(String)` to `ExportError` for clean error
display.
- Implemented `parse_svg_export_from_args(args: &mut
pico_args::Arguments) -> Result<Option<String>, pico_args::Error>`
to parse `--export-svg <file>` and `--export-svg=<file>`, treating
empty or flag arguments as missing values (`OptionWithoutAValue`).
- Updated `parse_svg_export_arg() -> Option<String>` for backward
compatibility.
- In `handle_svg_export`:
- Under `#[cfg(not(feature = "svg"))]`: detects any presence of
`--export-svg`, outputs `Error: SVG export feature is not enabled.
Please rebuild with --features svg`, and exits with code 1.
- Under `#[cfg(feature = "svg")]`: handles missing arguments with
`Error: --export-svg: option requires an argument` (exit 1), valid
exports (exit 0), and leaves unknown arguments untouched so
Macroquad or user flags continue to work.
- Added unit tests covering all flag parsing variants and error
displays.
- In
[`turtle-lib-macros/src/lib.rs`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib-macros/src/lib.rs):
- Simplified the macro expansion in `turtle_main` to delegate directly
to `turtle_lib::export::handle_svg_export(&mut build_commands);`.
- Updated documentation comments to match.
---
```bash
cargo test --package turtle-lib
cargo test --package turtle-lib --features svg
cargo test --package turtle-lib-macros
cargo clippy --package turtle-lib -- -Wclippy::pedantic
-Aclippy::cast_precision_loss -Aclippy::cast_sign_loss
-Aclippy::cast_possible_truncation
cargo clippy --package turtle-lib --features svg -- -Wclippy::pedantic
-Aclippy::cast_precision_loss -Aclippy::cast_sign_loss
-Aclippy::cast_possible_truncation
cargo clippy --package turtle-lib-macros -- -Wclippy::pedantic
```
- **Unit tests**: All 29 unit tests in `turtle-lib` and 18 unit tests in
`turtle-lib-macros` passed.
- **Doctests**: All 34 doctests passed.
- **Clippy**: Passed with zero warnings across all crates and feature
configurations.
| Scenario | Command | Result | Exit Code | Window Opened? |
|---|---|---|---|---|
| Missing feature, missing filename | `cargo run --example hello_turtle
-- --export-svg` | `Error: SVG export feature is not enabled. Please
rebuild with --features svg` | 1 | No |
| Missing feature, with filename | `cargo run --example hello_turtle --
--export-svg test.svg` | `Error: SVG export feature is not enabled.
Please rebuild with --features svg` | 1 | No |
| Feature enabled, missing filename | `cargo run --example hello_turtle
--features svg -- --export-svg` | `Error: --export-svg: option requires
an argument` | 1 | No |
| Feature enabled, with filename | `cargo run --example hello_turtle
--features svg -- --export-svg /tmp/pico_test.svg` | `SVG exported
successfully to: /tmp/pico_test.svg` | 0 | No |
| Feature enabled, equals syntax | `cargo run --example hello_turtle
--features svg -- --export-svg=/tmp/pico_test_eq.svg` | `SVG exported
successfully to: /tmp/pico_test_eq.svg` | 0 | No |
| Feature enabled, extra flags | `cargo run --example hello_turtle
--features svg -- --export-svg /tmp/pico_test_extra.svg --custom-flag` |
`SVG exported successfully to: /tmp/pico_test_extra.svg` | 0 | No |
| Normal run (no flag) | `cargo run --example hello_turtle` |
Interactive window opens normally | 0 | Yes |
turtle-lib-macros
Procedural macros for turtle-lib.
turtle_main Macro
The turtle_main macro simplifies creating turtle graphics programs by automatically setting up:
- The Macroquad window
- Turtle initialization
- The main rendering loop
- Quit handling (ESC or Q keys)
Usage
With a function parameter:
use macroquad::prelude::*;
use turtle_lib::*;
#[turtle_main("My Drawing")]
fn my_drawing(turtle: &mut TurtlePlan) {
turtle.set_pen_color(RED);
turtle.forward(100.0);
turtle.right(90.0);
turtle.forward(100.0);
}
With inline code:
use macroquad::prelude::*;
use turtle_lib::*;
#[turtle_main("My Drawing")]
fn my_drawing() {
turtle.set_pen_color(RED);
turtle.forward(100.0);
turtle.right(90.0);
turtle.forward(100.0);
}
What it does
The macro expands your code into a full Macroquad application with:
#[macroquad::main]attribute for window creation- Turtle instance creation
- TurtleApp initialization with your commands
- A main loop that:
- Clears the background to WHITE
- Updates the turtle app
- Renders the drawing
- Shows "Press ESC or Q to quit" message
- Handles quit keys
Benefits
- Less boilerplate: No need to write the same loop structure in every example
- Consistent UI: All examples have the same quit behavior
- Beginner-friendly: Makes turtle graphics examples more approachable
- Focus on drawing: Your code focuses on the turtle commands, not the framework
License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.