Skip to content

Commit ca08bc8

Browse files
author
nejc
committed
docs: update documentation and add comprehensive examples
- Add comprehensive_example.php demonstrating all library features - Update README.md with new features and development tools - Update CHANGELOG.md to version 2.0.0 with breaking changes - Document algebraic data types, Laravel integration, and benchmarks - Add migration guide for breaking changes - Include examples for all major features and use cases
1 parent afe6b54 commit ca08bc8

File tree

3 files changed

+332
-6
lines changed

3 files changed

+332
-6
lines changed

CHANGELOG.md

Lines changed: 73 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,77 @@
11
# Changelog
22

3-
All notable changes to `php-datatypes` will be documented in this file
3+
All notable changes to `php-datatypes` will be documented in this file.
44

5-
## 1.0.0 - 201X-XX-XX
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
67

7-
- initial release
8+
## [2.0.0] - 2024-12-19
9+
10+
### Added
11+
- PHP 8.4 compatibility and CI testing
12+
- PHPStan static analysis configuration (level 9)
13+
- `Dictionary::toArray()`, `isEmpty()`, and `getAll()` methods
14+
- Benchmark suite for performance testing
15+
- `Option<T>` type for nullable values
16+
- `Result<T, E>` type for error handling
17+
- Mutation testing with Infection
18+
- Laravel integration (validation rules, service provider)
19+
- PHPStorm metadata for better IDE support
20+
- Comprehensive example demonstrating all features
21+
22+
### Changed
23+
- **BREAKING:** All concrete datatype classes are now `final` to prevent inheritance issues
24+
- **BREAKING:** All methods now have explicit return types for better type safety
25+
- **BREAKING:** All Laravel validation rules and casts are now `final`
26+
- Updated minimum PHP version requirement to ^8.4
27+
- Enhanced CI workflow to test PHP 8.4
28+
- Improved code quality with static analysis
29+
- Enhanced parameter type declarations throughout the codebase
30+
31+
### Fixed
32+
- Missing serialization methods in Dictionary class
33+
- Missing return types in various methods
34+
- Parameter type declarations for better type safety
35+
36+
### Migration Guide
37+
38+
If you were extending any datatype classes, you'll need to use composition instead:
39+
40+
**Before (v1.x):**
41+
```php
42+
class MyCustomInt8 extends Int8 {
43+
// custom implementation
44+
}
45+
```
46+
47+
**After (v2.0):**
48+
```php
49+
class MyCustomInt8 {
50+
private Int8 $int8;
51+
52+
public function __construct(int $value) {
53+
$this->int8 = new Int8($value);
54+
}
55+
56+
public function getValue(): int {
57+
return $this->int8->getValue();
58+
}
59+
60+
// delegate other methods as needed
61+
}
62+
```
63+
64+
## [1.0.0] - 2024-12-19
65+
66+
### Added
67+
- Initial release with comprehensive type system
68+
- Scalar types: Int8, Int16, Int32, Int64, Int128, UInt8, UInt16, UInt32, UInt64, UInt128
69+
- Floating point types: Float32, Float64
70+
- Boolean, Char, and Byte types
71+
- Composite types: Arrays, Structs, Unions, Lists, Dictionaries
72+
- String types: AsciiString, Utf8String, EmailString, and 20+ specialized string types
73+
- Vector types: Vec2, Vec3, Vec4
74+
- Serialization support: JSON, XML, Binary
75+
- Comprehensive test suite (592 tests, 1042 assertions)
76+
- Helper functions for all types
77+
- Type-safe operations with overflow/underflow protection

README.md

Lines changed: 86 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,13 @@ PHP Datatypes is designed to address the challenges of modern PHP development, w
4242
## Features
4343
- **Strict Scalar Types:** Signed/unsigned integers (Int8, UInt8, etc.), floating points (Float32, Float64), booleans, chars, and bytes
4444
- **Composite Types:** Structs, arrays, unions, lists, dictionaries, and more
45+
- **Algebraic Data Types:** Option<T> for nullable values, Result<T, E> for error handling
4546
- **Type-safe Operations:** Arithmetic, validation, and conversion with built-in safeguards
46-
- **Serialization:** Easy conversion to/from array, JSON, and XML
47-
- **Laravel Integration:** Ready for use in modern PHP frameworks
47+
- **Serialization:** Easy conversion to/from array, JSON, XML, and binary formats
48+
- **Laravel Integration:** Validation rules, Eloquent casts, form requests, and service provider
49+
- **Performance Benchmarks:** Built-in benchmarking suite to compare with native PHP types
50+
- **Static Analysis:** PHPStan level 9 configuration for maximum code quality
51+
- **Mutation Testing:** Infection configuration for comprehensive test coverage
4852
- **Extensible:** Easily define your own types and validation rules
4953

5054
## Installation
@@ -134,6 +138,60 @@ $result = $int1->add($int2); // Performs addition
134138
echo $result->getValue(); // 80
135139
```
136140

141+
### Algebraic Data Types
142+
#### Option Type for Nullable Values
143+
```php
144+
use Nejcc\PhpDatatypes\Composite\Option;
145+
146+
$someValue = Option::some("Hello");
147+
$noneValue = Option::none();
148+
149+
$processed = $someValue
150+
->map(fn($value) => strtoupper($value))
151+
->unwrapOr("DEFAULT");
152+
153+
echo $processed; // "HELLO"
154+
```
155+
156+
#### Result Type for Error Handling
157+
```php
158+
use Nejcc\PhpDatatypes\Composite\Result;
159+
160+
$result = Result::try(function () {
161+
return new Int8(42);
162+
});
163+
164+
if ($result->isOk()) {
165+
echo $result->unwrap()->getValue(); // 42
166+
} else {
167+
echo "Error: " . $result->unwrapErr();
168+
}
169+
```
170+
171+
### Laravel Integration
172+
#### Validation Rules
173+
```php
174+
// In your form request
175+
public function rules(): array
176+
{
177+
return [
178+
'age' => ['required', 'int8'],
179+
'user_id' => ['required', 'uint8'],
180+
'balance' => ['required', 'float32'],
181+
];
182+
}
183+
```
184+
185+
#### Eloquent Casts
186+
```php
187+
// In your model
188+
protected $casts = [
189+
'age' => Int8Cast::class,
190+
'user_id' => 'uint8',
191+
'balance' => 'float32',
192+
];
193+
```
194+
137195
## Roadmap
138196

139197
```md
@@ -193,13 +251,38 @@ Data Types
193251
└── Channel
194252
```
195253

196-
## Testing
254+
## Development Tools
197255

256+
### Testing
198257
Run the test suite with:
199258
```bash
200259
composer test
201260
```
202261

262+
### Static Analysis
263+
Run PHPStan for static analysis:
264+
```bash
265+
composer phpstan
266+
```
267+
268+
### Mutation Testing
269+
Run Infection for mutation testing:
270+
```bash
271+
composer infection
272+
```
273+
274+
### Performance Benchmarks
275+
Run performance benchmarks:
276+
```bash
277+
composer benchmark
278+
```
279+
280+
### Code Style
281+
Run Laravel Pint for code formatting:
282+
```bash
283+
vendor/bin/pint
284+
```
285+
203286
## Changelog
204287

205288
Please see [CHANGELOG](CHANGELOG.md) for details on recent changes.

examples/comprehensive_example.php

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
require_once __DIR__ . '/../vendor/autoload.php';
6+
7+
use Nejcc\PhpDatatypes\Scalar\Integers\Signed\Int8;
8+
use Nejcc\PhpDatatypes\Scalar\Integers\Signed\Int32;
9+
use Nejcc\PhpDatatypes\Scalar\Integers\Unsigned\UInt8;
10+
use Nejcc\PhpDatatypes\Scalar\FloatingPoints\Float32;
11+
use Nejcc\PhpDatatypes\Composite\Option;
12+
use Nejcc\PhpDatatypes\Composite\Result;
13+
use Nejcc\PhpDatatypes\Composite\Dictionary;
14+
use Nejcc\PhpDatatypes\Composite\Struct\Struct;
15+
use Nejcc\PhpDatatypes\Composite\Union\UnionType;
16+
17+
echo "=== PHP Datatypes Comprehensive Example ===\n\n";
18+
19+
// 1. Scalar Types
20+
echo "1. Scalar Types:\n";
21+
echo "---------------\n";
22+
23+
$int8 = new Int8(42);
24+
$int32 = new Int32(1000);
25+
$uint8 = new UInt8(200);
26+
$float32 = new Float32(3.14159);
27+
28+
echo "Int8: " . $int8->getValue() . "\n";
29+
echo "Int32: " . $int32->getValue() . "\n";
30+
echo "UInt8: " . $uint8->getValue() . "\n";
31+
echo "Float32: " . $float32->getValue() . "\n\n";
32+
33+
// 2. Arithmetic Operations
34+
echo "2. Arithmetic Operations:\n";
35+
echo "------------------------\n";
36+
37+
$result = $int8->add(new Int8(10));
38+
echo "Int8(42) + Int8(10) = " . $result->getValue() . "\n";
39+
40+
$result = $int32->multiply(new Int32(2));
41+
echo "Int32(1000) * Int32(2) = " . $result->getValue() . "\n\n";
42+
43+
// 3. Option Type
44+
echo "3. Option Type:\n";
45+
echo "--------------\n";
46+
47+
$someValue = Option::some("Hello World");
48+
$noneValue = Option::none();
49+
50+
echo "Some value: " . $someValue . "\n";
51+
echo "None value: " . $noneValue . "\n";
52+
53+
$processed = $someValue
54+
->map(fn($value) => strtoupper($value))
55+
->unwrapOr("DEFAULT");
56+
57+
echo "Processed: " . $processed . "\n\n";
58+
59+
// 4. Result Type
60+
echo "4. Result Type:\n";
61+
echo "--------------\n";
62+
63+
$successResult = Result::ok("Operation successful");
64+
$errorResult = Result::err("Something went wrong");
65+
66+
echo "Success: " . $successResult . "\n";
67+
echo "Error: " . $errorResult . "\n";
68+
69+
$safeResult = Result::try(function () {
70+
return new Int8(50);
71+
});
72+
73+
if ($safeResult->isOk()) {
74+
echo "Safe operation result: " . $safeResult->unwrap()->getValue() . "\n";
75+
} else {
76+
echo "Safe operation failed: " . $safeResult->unwrapErr() . "\n";
77+
}
78+
79+
echo "\n";
80+
81+
// 5. Dictionary
82+
echo "5. Dictionary:\n";
83+
echo "-------------\n";
84+
85+
$dict = new Dictionary([
86+
'name' => 'John Doe',
87+
'age' => 30,
88+
'email' => 'john@example.com'
89+
]);
90+
91+
echo "Dictionary size: " . $dict->size() . "\n";
92+
echo "Name: " . $dict->get('name') . "\n";
93+
echo "Keys: " . implode(', ', $dict->getKeys()) . "\n\n";
94+
95+
// 6. Struct
96+
echo "6. Struct:\n";
97+
echo "----------\n";
98+
99+
$userStruct = new Struct([
100+
'id' => ['type' => 'int', 'nullable' => false],
101+
'name' => ['type' => 'string', 'nullable' => false],
102+
'email' => ['type' => 'string', 'nullable' => true],
103+
], [
104+
'id' => 1,
105+
'name' => 'Jane Doe',
106+
'email' => 'jane@example.com'
107+
]);
108+
109+
echo "User ID: " . $userStruct->get('id') . "\n";
110+
echo "User Name: " . $userStruct->get('name') . "\n";
111+
echo "User Email: " . $userStruct->get('email') . "\n\n";
112+
113+
// 7. Union Type
114+
echo "7. Union Type:\n";
115+
echo "-------------\n";
116+
117+
$union = new UnionType([
118+
'string' => 'string',
119+
'int' => 'int',
120+
'float' => 'float'
121+
]);
122+
123+
$union->setValue('string', 'Hello Union');
124+
echo "Union active type: " . $union->getActiveType() . "\n";
125+
echo "Union value: " . $union->getValue() . "\n";
126+
127+
$union->setValue('int', 42);
128+
echo "Union active type: " . $union->getActiveType() . "\n";
129+
echo "Union value: " . $union->getValue() . "\n\n";
130+
131+
// 8. Helper Functions
132+
echo "8. Helper Functions:\n";
133+
echo "-------------------\n";
134+
135+
$int8Helper = int8(75);
136+
$uint8Helper = uint8(150);
137+
$float32Helper = float32(2.71828);
138+
$someHelper = some("Helper function");
139+
$okHelper = ok("Success");
140+
141+
echo "Int8 helper: " . $int8Helper->getValue() . "\n";
142+
echo "UInt8 helper: " . $uint8Helper->getValue() . "\n";
143+
echo "Float32 helper: " . $float32Helper->getValue() . "\n";
144+
echo "Some helper: " . $someHelper . "\n";
145+
echo "Ok helper: " . $okHelper . "\n\n";
146+
147+
// 9. Serialization
148+
echo "9. Serialization:\n";
149+
echo "----------------\n";
150+
151+
$json = $userStruct->toJson();
152+
echo "Struct JSON: " . $json . "\n";
153+
154+
$xml = $userStruct->toXml();
155+
echo "Struct XML: " . substr($xml, 0, 100) . "...\n\n";
156+
157+
// 10. Error Handling
158+
echo "10. Error Handling:\n";
159+
echo "------------------\n";
160+
161+
try {
162+
$invalidInt8 = new Int8(1000); // This will throw OutOfRangeException
163+
} catch (\OutOfRangeException $e) {
164+
echo "Caught OutOfRangeException: " . $e->getMessage() . "\n";
165+
}
166+
167+
try {
168+
$overflow = $int8->add(new Int8(100)); // This will throw OverflowException
169+
} catch (\OverflowException $e) {
170+
echo "Caught OverflowException: " . $e->getMessage() . "\n";
171+
}
172+
173+
echo "\n=== Example Complete ===\n";

0 commit comments

Comments
 (0)