Builder Pattern Trait Hierarchy Refactoring

We refactored the builder pattern in
[`turtle-lib`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib)
to eliminate inherent method asymmetry and organize all turtle
capabilities into six cohesive traits.

[`builders.rs`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/builders.rs)

The legacy traits (`DirectionalMovement`, `Turnable`, `CurvedMovement`)
and orphaned inherent methods have been reorganized into six
domain-focused traits:

-
  **[`Movement`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/builders.rs#L14)**:
  - `forward()`
  - `backward()`
  - `go_to()`
  - `circle_left()`
  - `circle_right()`
-
  **[`Rotation`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/builders.rs#L191)**:
  - `left()`
  - `right()`
  - `set_heading()`
-
  **[`Pen`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/builders.rs#L279)**:
  - `pen_up()`
  - `pen_down()`
  - `set_pen_color()`
  - `set_pen_width()`
-
  **[`Fill`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/builders.rs#L393)**:
  - `begin_fill()`
  - `end_fill()`
  - `set_fill_color()`
-
  **[`Cursor`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/builders.rs#L481)**:
  - `hide()`
  - `show()`
  - `shape()`
  - `set_shape()`
  - `set_speed()`
  - `reset()`
-
  **[`Text`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/builders.rs#L646)**:
  - `write_text()`

[`TurtlePlan`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/builders.rs#L688)

`TurtlePlan`'s inherent methods are now strictly builder lifecycle
controls:
- `new() -> Self`
- `build(self) -> CommandQueue`

`TurtlePlan` implements `WithCommands`, `Movement`, `Rotation`, `Pen`,
`Fill`, `Cursor`, and `Text`.

-
  **[`lib.rs`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/lib.rs#L62-L65)**:
  Re-exports `Cursor`, `Fill`, `Movement`, `Pen`, `Rotation`, `Text`,
  `TurtlePlan`, `WithCommands`.
- **Examples**: Updated
  [`clock.rs`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/examples/clock.rs#L8),
  [`clock_threaded.rs`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/examples/clock_threaded.rs#L9),
  [`dashed_circle.rs`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/examples/dashed_circle.rs#L4),
  and
  [`bezier.rs`](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/examples/bezier.rs#L4)
  to use `use turtle_lib::*;`.
-
  **[`README.md`](file:///home/dietrich/Projekte/Source/turtlers/README.md#L344)**:
  Updated trait references in the architecture outline.

---

- **Unit & Doc Tests**:
  ```bash
  cargo test --package turtle-lib
  ```
  Result: 17 unit tests passed; 34 doc-tests passed (0 failed).
- **All Examples**:
  ```bash
  cargo check --package turtle-lib --examples
  ```
  Result: Successfully compiled all 30 examples.
- **Clippy**:
  ```bash
  cargo clippy --package turtle-lib -- -Wclippy::pedantic \
  -Aclippy::cast_precision_loss -Aclippy::cast_sign_loss
  -Aclippy::cast_possible_truncation
  ```
  Result: 0 warnings in `builders.rs`.
This commit is contained in:
2026-09-19 11:45:57 +02:00
parent f117361950
commit 68593ba64d
8 changed files with 533 additions and 519 deletions
+1 -1
View File
@@ -341,7 +341,7 @@ turtle-lib/src/
├── lib.rs - Public API and TurtleApp ├── lib.rs - Public API and TurtleApp
├── state.rs - TurtleState and TurtleWorld ├── state.rs - TurtleState and TurtleWorld
├── commands.rs - TurtleCommand enum (consolidated commands) ├── commands.rs - TurtleCommand enum (consolidated commands)
├── builders.rs - Builder traits (DirectionalMovement, Turnable, etc.) ├── builders.rs - Builder traits (Movement, Rotation, Pen, Fill, Cursor, Text)
├── execution.rs - Command execution with fill support ├── execution.rs - Command execution with fill support
├── tweening.rs - Animation/tweening controller with dynamic speed ├── tweening.rs - Animation/tweening controller with dynamic speed
├── drawing.rs - Rendering with Lyon tessellation ├── drawing.rs - Rendering with Lyon tessellation
+1 -1
View File
@@ -1,7 +1,7 @@
//! Cubic Bézier curve example //! Cubic Bézier curve example
//! <https://en.wikipedia.org/wiki/B%C3%A9zier_curve> //! <https://en.wikipedia.org/wiki/B%C3%A9zier_curve>
use turtle_lib::{turtle_main, vec2}; use turtle_lib::*;
struct CubicBezier { struct CubicBezier {
point0: (f32, f32), point0: (f32, f32),
+1 -1
View File
@@ -5,7 +5,7 @@
use chrono::{Local, Timelike}; use chrono::{Local, Timelike};
use macroquad::prelude::{clear_background, is_key_pressed, next_frame, KeyCode, WHITE}; use macroquad::prelude::{clear_background, is_key_pressed, next_frame, KeyCode, WHITE};
use turtle_lib::{create_turtle_plan, vec2, DirectionalMovement, Turnable, TurtleApp}; use turtle_lib::*;
#[macroquad::main("Clock")] #[macroquad::main("Clock")]
async fn main() { async fn main() {
+1 -1
View File
@@ -6,7 +6,7 @@
use chrono::{Local, Timelike}; use chrono::{Local, Timelike};
use macroquad::prelude::{clear_background, is_key_pressed, next_frame, KeyCode, WHITE}; use macroquad::prelude::{clear_background, is_key_pressed, next_frame, KeyCode, WHITE};
use turtle_lib::{create_turtle_plan, vec2, DirectionalMovement, Turnable, TurtleApp}; use turtle_lib::*;
#[macroquad::main("Clock (Threaded)")] #[macroquad::main("Clock (Threaded)")]
async fn main() { async fn main() {
+1 -1
View File
@@ -1,7 +1,7 @@
//! Dashed circle example ported from sunjay/turtle //! Dashed circle example ported from sunjay/turtle
//! This draws a dashed circle but uses `circle_left` arcs for each segment instead of individual short lines. //! This draws a dashed circle but uses `circle_left` arcs for each segment instead of individual short lines.
use turtle_lib::{turtle_main, vec2, CurvedMovement, Turnable}; use turtle_lib::*;
#[turtle_main("Dashed Circle")] #[turtle_main("Dashed Circle")]
fn draw(turtle: &mut TurtlePlan) { fn draw(turtle: &mut TurtlePlan) {
+523 -507
View File
File diff suppressed because it is too large Load Diff
+2 -5
View File
@@ -5,13 +5,11 @@ use crate::state::{DrawCommand, TurtleParams, TurtleWorld};
use crate::tessellation; use crate::tessellation;
use macroquad::prelude::*; use macroquad::prelude::*;
/// Render the turtle world with active tween visualization. /// Render the turtle world with active tween visualization.
#[allow(clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
pub(crate) fn render_world_with_tweens(world: &TurtleWorld, zoom_level: f32) { pub(crate) fn render_world_with_tweens(world: &TurtleWorld, zoom_level: f32) {
// Update camera zoom based on current screen size to prevent stretching // Update camera zoom based on current screen size to prevent stretching
// Apply user zoom level by dividing by it (smaller zoom value = more zoomed in) // Apply user zoom level by dividing by it
let camera = Camera2D { let camera = Camera2D {
zoom: vec2( zoom: vec2(
1.0 / screen_width() * 2.0 / zoom_level, 1.0 / screen_width() * 2.0 / zoom_level,
@@ -295,8 +293,7 @@ fn draw_tween_arc(
); );
// Draw center using Lyon tessellation this helps visualizing what is done. // Draw center using Lyon tessellation this helps visualizing what is done.
if let Ok(mesh) = crate::tessellation::tessellate_circle(geom.center, 5.0, GRAY, true, 1.0) if let Ok(mesh) = crate::tessellation::tessellate_circle(geom.center, 5.0, GRAY, true, 1.0) {
{
draw_mesh(&mesh); draw_mesh(&mesh);
} }
+3 -2
View File
@@ -59,8 +59,9 @@ pub(crate) mod state;
pub(crate) mod tessellation; pub(crate) mod tessellation;
pub(crate) mod tweening; pub(crate) mod tweening;
// Re-export commonly used types pub use builders::{
pub use builders::{CurvedMovement, DirectionalMovement, Turnable, TurtlePlan, WithCommands}; Cursor, Fill, Movement, Pen, Rotation, Text, TurtlePlan, WithCommands,
};
pub use commands::{CommandQueue, TurtleCommand}; pub use commands::{CommandQueue, TurtleCommand};
pub use commands_channel::TurtleCommandSender; pub use commands_channel::TurtleCommandSender;
pub use general::{AnimationSpeed, Color, Coordinate, Degrees, Length, Precision, Radians}; pub use general::{AnimationSpeed, Color, Coordinate, Degrees, Length, Precision, Radians};