Skip to content

Commit d4c266d

Browse files
author
nejc
committed
feat: add string types and abstractions
1 parent 947ddb3 commit d4c266d

File tree

5 files changed

+410
-359
lines changed

5 files changed

+410
-359
lines changed

examples/char_operations.php

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
<?php
2+
3+
require_once __DIR__ . '/../vendor/autoload.php';
4+
5+
use Nejcc\PhpDatatypes\Scalar\Char;
6+
7+
/**
8+
* Example 1: Basic Char Operations
9+
*/
10+
echo "Example 1: Basic Char Operations\n";
11+
echo "============================\n";
12+
13+
try {
14+
// Create Char instances
15+
$char1 = new Char('A');
16+
$char2 = new Char('b');
17+
18+
echo "Char 1: " . $char1->getValue() . "\n";
19+
echo "Char 2: " . $char2->getValue() . "\n";
20+
21+
// Convert to string
22+
echo "Char 1 as string: " . (string)$char1 . "\n";
23+
24+
// Case conversion
25+
echo "Char 1 to lowercase: " . $char1->toLowerCase()->getValue() . "\n";
26+
echo "Char 2 to uppercase: " . $char2->toUpperCase()->getValue() . "\n";
27+
} catch (\Exception $e) {
28+
echo "Error: " . $e->getMessage() . "\n";
29+
}
30+
31+
/**
32+
* Example 2: Character Type Checking
33+
*/
34+
echo "\nExample 2: Character Type Checking\n";
35+
echo "==============================\n";
36+
37+
try {
38+
$letter = new Char('A');
39+
$digit = new Char('5');
40+
$symbol = new Char('@');
41+
42+
echo "Is 'A' a letter? " . ($letter->isLetter() ? "Yes" : "No") . "\n";
43+
echo "Is 'A' uppercase? " . ($letter->isUpperCase() ? "Yes" : "No") . "\n";
44+
echo "Is 'A' lowercase? " . ($letter->isLowerCase() ? "Yes" : "No") . "\n";
45+
46+
echo "\nIs '5' a digit? " . ($digit->isDigit() ? "Yes" : "No") . "\n";
47+
echo "Is '5' a letter? " . ($digit->isLetter() ? "Yes" : "No") . "\n";
48+
49+
echo "\nIs '@' a letter? " . ($symbol->isLetter() ? "Yes" : "No") . "\n";
50+
echo "Is '@' a digit? " . ($symbol->isDigit() ? "Yes" : "No") . "\n";
51+
} catch (\Exception $e) {
52+
echo "Error: " . $e->getMessage() . "\n";
53+
}
54+
55+
/**
56+
* Example 3: ASCII Operations
57+
*/
58+
echo "\nExample 3: ASCII Operations\n";
59+
echo "========================\n";
60+
61+
try {
62+
$char = new Char('A');
63+
64+
// Get ASCII code
65+
$ascii = $char->toAscii();
66+
echo "ASCII code of 'A': " . $ascii . "\n";
67+
68+
// Create Char from ASCII
69+
$newChar = Char::fromAscii($ascii);
70+
echo "Char from ASCII " . $ascii . ": " . $newChar->getValue() . "\n";
71+
72+
// Try some other ASCII values
73+
$space = Char::fromAscii(32);
74+
echo "ASCII 32 (space): '" . $space->getValue() . "'\n";
75+
76+
$newline = Char::fromAscii(10);
77+
echo "ASCII 10 (newline): '" . $newline->getValue() . "'\n";
78+
} catch (\Exception $e) {
79+
echo "Error: " . $e->getMessage() . "\n";
80+
}
81+
82+
/**
83+
* Example 4: Character Comparison
84+
*/
85+
echo "\nExample 4: Character Comparison\n";
86+
echo "===========================\n";
87+
88+
try {
89+
$char1 = new Char('A');
90+
$char2 = new Char('A');
91+
$char3 = new Char('B');
92+
93+
echo "Is 'A' equal to 'A'? " . ($char1->equals($char2) ? "Yes" : "No") . "\n";
94+
echo "Is 'A' equal to 'B'? " . ($char1->equals($char3) ? "Yes" : "No") . "\n";
95+
96+
// Compare ASCII values
97+
echo "ASCII of 'A': " . $char1->toAscii() . "\n";
98+
echo "ASCII of 'B': " . $char3->toAscii() . "\n";
99+
} catch (\Exception $e) {
100+
echo "Error: " . $e->getMessage() . "\n";
101+
}
102+
103+
/**
104+
* Example 5: Error Handling
105+
*/
106+
echo "\nExample 5: Error Handling\n";
107+
echo "======================\n";
108+
109+
try {
110+
// Try to create a Char with multiple characters
111+
$invalidChar = new Char('AB');
112+
} catch (\InvalidArgumentException $e) {
113+
echo "Error creating Char with multiple characters: " . $e->getMessage() . "\n";
114+
}
115+
116+
try {
117+
// Try to create a Char from invalid ASCII
118+
$invalidAscii = Char::fromAscii(300);
119+
} catch (\InvalidArgumentException $e) {
120+
echo "Error creating Char from invalid ASCII: " . $e->getMessage() . "\n";
121+
}
122+
123+
/**
124+
* Example 6: Character Transformation Chain
125+
*/
126+
echo "\nExample 6: Character Transformation Chain\n";
127+
echo "=====================================\n";
128+
129+
try {
130+
$char = new Char('a');
131+
132+
echo "Original: " . $char->getValue() . "\n";
133+
echo "To uppercase: " . $char->toUpperCase()->getValue() . "\n";
134+
echo "Back to lowercase: " . $char->toUpperCase()->toLowerCase()->getValue() . "\n";
135+
echo "ASCII code: " . $char->toAscii() . "\n";
136+
echo "Back to char: " . Char::fromAscii($char->toAscii())->getValue() . "\n";
137+
} catch (\Exception $e) {
138+
echo "Error: " . $e->getMessage() . "\n";
139+
}

src/Abstract/AbstractChar.php

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Nejcc\PhpDatatypes\Abstract;
5+
6+
/**
7+
* Abstract base for Char-like types (single character).
8+
*/
9+
abstract class AbstractChar
10+
{
11+
/**
12+
* @var string
13+
*/
14+
protected string $value;
15+
16+
/**
17+
* @param string $value
18+
* @throws \InvalidArgumentException
19+
*/
20+
public function __construct(string $value)
21+
{
22+
if (strlen($value) !== 1) {
23+
throw new \InvalidArgumentException('Char must be a single character.');
24+
}
25+
$this->value = $value;
26+
}
27+
28+
public function getValue(): string
29+
{
30+
return $this->value;
31+
}
32+
33+
public function toUpperCase(): static
34+
{
35+
return new static(strtoupper($this->value));
36+
}
37+
38+
public function toLowerCase(): static
39+
{
40+
return new static(strtolower($this->value));
41+
}
42+
43+
public function isLetter(): bool
44+
{
45+
return ctype_alpha($this->value);
46+
}
47+
48+
public function isDigit(): bool
49+
{
50+
return ctype_digit($this->value);
51+
}
52+
53+
public function isUpperCase(): bool
54+
{
55+
return ctype_upper($this->value);
56+
}
57+
58+
public function isLowerCase(): bool
59+
{
60+
return ctype_lower($this->value);
61+
}
62+
63+
public function isWhitespace(): bool
64+
{
65+
return ctype_space($this->value);
66+
}
67+
68+
public function getNumericValue(): int
69+
{
70+
return $this->isDigit() ? (int)$this->value : -1;
71+
}
72+
73+
public function equals(self $char): bool
74+
{
75+
return $this->value === $char->getValue();
76+
}
77+
78+
public function toAscii(): int
79+
{
80+
return ord($this->value);
81+
}
82+
83+
public static function fromAscii(int $ascii): static
84+
{
85+
if ($ascii < 0 || $ascii > 255) {
86+
throw new \InvalidArgumentException('ASCII value must be between 0 and 255.');
87+
}
88+
return new static(chr($ascii));
89+
}
90+
91+
public function __toString(): string
92+
{
93+
return $this->value;
94+
}
95+
}

0 commit comments

Comments
 (0)