diff --git a/CHANGELOG.md b/CHANGELOG.md index c415930..155fdab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,18 @@ All notable changes to this project are documented here. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased] + +### Added +- **String parsing** — `Quantity::parse('100 km/h')`, `Quantity::parse('5 ft 3 in')` + (multi-segment inputs of the same dimension are summed). +- **`Quantity::humanize()`** — auto-selects the most readable unit (e.g. `1500 m` → `1.5 km`). +- **Many more units** — speed (`km/h`, `mph`, `kn`), data (`KB`…`TiB`, `bit`), force (`N`), + energy (`J`, `kWh`, `cal`), power (`W`, `hp`), pressure (`Pa`, `bar`, `psi`), frequency + (`Hz`…`GHz`), angle (`rad`, `deg`), plus more length/mass/time/area/volume units. +- **Laravel integration** — auto-discovered `UnitServiceProvider` and an Eloquent + `AsQuantity` cast; register custom units via `config/unit.php`. + ## [1.1.0] - 2026-07-10 ### Added diff --git a/README.md b/README.md index 6ef2953..d0e9cef 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,22 @@ echo Quantity::of(32, '°F')->to('°C')->format(1); // "0.0 °C" echo Quantity::of(25, '°C')->to('K')->format(2); // "298.15 K" ``` +### Parsing strings + +```php +echo Quantity::parse('100 km/h')->to('mph')->format(2); // "62.14 mph" +echo Quantity::parse('-40 °C')->to('°F')->format(1); // "-40.0 °F" +echo Quantity::parse('5 ft 3 in')->to('cm')->format(2); // "160.02 cm" (segments summed) +``` + +### Humanize (auto-pick the best unit) + +```php +echo Quantity::of(1500, 'm')->humanize(); // "1.5 km" +echo Quantity::of(2500000, 'B')->humanize(); // "2.5 MB" +echo Quantity::of(5400, 's')->humanize(); // "1.5 h" +``` + ### Comparison ```php @@ -152,17 +168,61 @@ Quantity::of(5, 'kg')->add(Quantity::of(3, 's')); // InvalidArgumentException | Dimension | Units | | --- | --- | -| Length | `mm`, `cm`, `m`, `km`, `in`, `ft` | -| Mass | `mg`, `g`, `kg` | -| Time | `s`, `min`, `h` | -| Area | `cm²`, `m²` | -| Volume | `mL`, `L`, `m³` | +| Length | `mm`, `cm`, `m`, `km`, `in`, `ft`, `yd`, `mi` | +| Mass | `mg`, `g`, `kg`, `t`, `lb`, `oz` | +| Time | `ms`, `s`, `min`, `h`, `d`, `wk` | +| Area | `cm²`, `m²`, `km²`, `ft²`, `ha`, `acre` | +| Volume | `mL`, `L`, `m³`, `gal` | | Temperature | `°C`, `°F`, `K` | +| Speed | `m/s`, `km/h`, `mph`, `kn` | +| Data | `bit`, `B`, `KB`, `MB`, `GB`, `TB`, `KiB`, `MiB`, `GiB`, `TiB` | +| Force | `N`, `kN` | +| Energy | `J`, `kJ`, `cal`, `kcal`, `Wh`, `kWh` | +| Power | `W`, `kW`, `hp` | +| Pressure | `Pa`, `kPa`, `bar`, `atm`, `psi` | +| Frequency | `Hz`, `kHz`, `MHz`, `GHz` | +| Angle | `rad`, `deg`, `grad`, `turn` | Need more? [Open an issue](https://github.com/khaledalam/unit/issues) or register your own. --- +## Laravel integration + +The package ships a service provider (auto-discovered) and an Eloquent cast. Store a +quantity in a single column and get a `Quantity` back on access: + +```php +use Illuminate\Database\Eloquent\Model; +use KhaledAlam\Unit\Laravel\AsQuantity; + +class Parcel extends Model +{ + protected function casts(): array + { + return ['weight' => AsQuantity::class]; + } +} + +$parcel->weight = Quantity::of(2.5, 'kg'); // stored as "2.5 kg" +$parcel->weight->to('g'); // 2500 g +$parcel->weight = '5 ft 3 in'; // strings are parsed on the way in +``` + +Register app-specific units via `config/unit.php`: + +```php +return [ + 'units' => [ + new \KhaledAlam\Unit\Unit('furlong', 'fur', 201.168, new \KhaledAlam\Unit\Dimension(['L' => 1])), + ], +]; +``` + +> Requires `illuminate/database` (already present in any Laravel app). + +--- + ## Examples Runnable scripts live in [`examples/`](examples): diff --git a/composer.json b/composer.json index b8d1164..dfedf87 100644 --- a/composer.json +++ b/composer.json @@ -22,6 +22,7 @@ }, "autoload": { "psr-4": { + "KhaledAlam\\Unit\\Laravel\\": "src/Laravel", "KhaledAlam\\Unit\\": "src/Unit" }, "files": [ @@ -46,7 +47,11 @@ "require-dev": { "phpunit/phpunit": "^11.4", "phpstan/phpstan": "^2.0", - "friendsofphp/php-cs-fixer": "^3.64" + "friendsofphp/php-cs-fixer": "^3.64", + "illuminate/database": "^11.0 || ^12.0" + }, + "suggest": { + "illuminate/database": "For the Laravel service provider and Eloquent 'AsQuantity' cast." }, "scripts": { "test": "phpunit --configuration phpunit.xml.dist --testsuite=unit", @@ -54,6 +59,13 @@ "cs": "php-cs-fixer fix --dry-run --diff", "cs-fix": "php-cs-fixer fix" }, + "extra": { + "laravel": { + "providers": [ + "KhaledAlam\\Unit\\Laravel\\UnitServiceProvider" + ] + } + }, "config": { "sort-packages": true }, diff --git a/docs/index.html b/docs/index.html index 5401653..6f627bd 100644 --- a/docs/index.html +++ b/docs/index.html @@ -172,14 +172,26 @@