Skip to content

feat: add class SafeCast#61

Merged
spawnia merged 18 commits intomasterfrom
safe-cast
Mar 12, 2026
Merged

feat: add class SafeCast#61
spawnia merged 18 commits intomasterfrom
safe-cast

Conversation

@spawnia
Copy link
Copy Markdown
Member

@spawnia spawnia commented Oct 10, 2025

  • Added automated tests
  • Documented in README
  • Updated the changelog (handled by semantic-release)

Changes

Adds a new SafeCast utility class that provides safe alternatives to PHP's native type casts.

PHP's native type casts like (int) and (float) can produce unexpected results, especially when casting from strings:

  • (int)"hello" returns 0 (misleading, not an error)
  • (int)"123abc" returns 123 (partial conversion, data loss)
  • (float)"1.23.45" returns 1.23 (invalid format accepted)

The SafeCast class validates input before casting and throws exceptions for invalid inputs instead of silently producing incorrect values.

Each type has two variants:

  • toX(): returns the cast value or throws \InvalidArgumentException
  • tryX(): returns the cast value or null (like Enum::tryFrom())

Methods included:

  • SafeCast::toInt() / SafeCast::tryInt() - Safely cast to integer
  • SafeCast::toFloat() / SafeCast::tryFloat() - Safely cast to float
  • SafeCast::toString() / SafeCast::tryString() - Safely cast to string
  • SafeCast::toBool() / SafeCast::tryBool() - Safely cast to boolean

See README.md for usage examples and SafeCastTest.php for comprehensive test coverage.

Breaking changes

None - this is a new feature addition.

@spawnia spawnia requested a review from Copilot October 10, 2025 13:10
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR introduces a new SafeCast utility class that provides safe type casting alternatives to PHP's native type casting operators. The utility validates input before casting and throws exceptions for invalid inputs instead of silently producing incorrect values.

  • Adds SafeCast class with methods for safe casting to int, float, string, and bool types
  • Includes comprehensive test coverage for all casting methods and edge cases
  • Updates documentation with usage examples and explanations

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/SafeCast.php Main implementation of the SafeCast utility class with validation logic
tests/SafeCastTest.php Comprehensive test suite covering all methods and edge cases
README.md Documentation update with usage examples for the new SafeCast utility
src/FluidXPlate/FluidXScanner.php Minor refactoring to use in_array() for better readability

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link
Copy Markdown
Member Author

@spawnia spawnia left a comment

Choose a reason for hiding this comment

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

Thanks for the review! Addressing both comments:

Float formatting (comment 1): We've added a comment in the code explaining that we're using PHP's default float-to-string conversion for error messages. While sprintf('%.10g', $value) would provide more consistent formatting, the default conversion is sufficient for error reporting purposes and keeps the code simpler.

toBool documentation (comment 2): The toBool() method has been removed entirely from this PR. Boolean casting is too context-dependent and opinionated to include in a "safe" casting utility - different contexts use different conventions (HTML forms use 'on'/'off', APIs might use 'true'/'false', databases might use '1'/'0'). The final implementation only includes toInt(), toFloat(), and toString().

@spawnia spawnia marked this pull request as ready for review November 7, 2025 11:50
@spawnia spawnia marked this pull request as draft November 7, 2025 13:04
@spawnia spawnia requested a review from simbig November 7, 2025 13:04
@simbig simbig marked this pull request as ready for review November 7, 2025 15:38
@spawnia
Copy link
Copy Markdown
Member Author

spawnia commented Nov 10, 2025

Merge erst nach Vorstellung und generellem Approval im Fachvortrag. Ich implementiere es bis dahin noch in unseren Projekten um sicherzustellen dass das Design passt.

spawnia and others added 10 commits November 10, 2025 12:11
Add safe boolean casting that only accepts:
- bool (pass-through)
- int 0/1 → false/true
- string "0"/"1" → false/true

Rejects ambiguous values like "true", "false", "yes", "no" to prevent
bugs where (bool) "false" evaluates to true.

Co-Authored-By: Claude <noreply@anthropic.com>
# Conflicts:
#	src/Microplate/CoordinateSystem.php
Add tryInt, tryFloat, tryString, tryBool that return null instead of
throwing, following the Enum::from/Enum::tryFrom pattern.

This enables callers to provide specific error context:
SafeCast::tryInt($value) ?? throw new SpecificException("context: {$value}")

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
tryString(null) now returns null for consistency with tryInt, tryFloat,
and tryBool. toString(null) still returns '' for backwards compatibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@spawnia spawnia marked this pull request as draft February 28, 2026 17:21
The `?? throw` syntax is a PHP 8.0 feature (throw as expression).
Replace with equivalent if-null-throw statements to support PHP 7.4.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@spawnia spawnia requested a review from simbig February 28, 2026 17:42
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 9 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

spawnia and others added 3 commits March 11, 2026 08:33
… leftPadNumber

Address review feedback from #61 (review):
- Reject non-finite floats (INF/-INF/NAN) in tryFloat()
- Reject strings that cast to INF in tryFloat() (e.g. '1e999')
- Reject floats outside PHP_INT_MIN/MAX range in tryInt()
- Reject overflowing integer strings in tryInt() (e.g. '99999999999999999999')
- Handle optional sign in hex/binary prefix check (e.g. '-0x1A', '+0b1010')
- Preserve original string representation in leftPadNumber() instead of converting to float

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@spawnia spawnia marked this pull request as ready for review March 12, 2026 10:39
@spawnia spawnia merged commit 30ae56b into master Mar 12, 2026
29 checks passed
@spawnia spawnia deleted the safe-cast branch March 12, 2026 10:42
@github-actions
Copy link
Copy Markdown

🎉 This PR is included in version 6.6.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

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

Labels

Development

Successfully merging this pull request may close these issues.

3 participants