Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions src/Abstract/BaseStruct.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace Nejcc\PhpDatatypes\Abstract;

use InvalidArgumentException;
use Nejcc\PhpDatatypes\Interfaces\StructInterface;

abstract class BaseStruct implements StructInterface
{
/**
* @var array<string, array{type: string, value: mixed}>
*/
protected array $fields = [];

/**
* Add a new field to the struct.
*
* @param string $name The name of the field.
* @param string $type The expected type of the field.
* @return void
*/
protected function addField(string $name, string $type): void
{
if (isset($this->fields[$name])) {
throw new InvalidArgumentException("Field '$name' already exists in the struct.");
}

$this->fields[$name] = [
'type' => $type,
'value' => null
];
}

/**
* Check if the type is nullable (e.g., `?string`).
*
* @param string $type The field type.
* @return bool True if the type is nullable, false otherwise.
*/
protected function isNullable(string $type): bool
{
return str_starts_with($type, '?');
}

/**
* Strip the nullable symbol (`?`) from a type.
*
* @param string $type The field type.
* @return string The base type.
*/
protected function stripNullable(string $type): string
{
return ltrim($type, '?');
}
}
100 changes: 5 additions & 95 deletions src/Composite/Struct/Struct.php
Original file line number Diff line number Diff line change
@@ -1,72 +1,26 @@
<?php

declare(strict_types=1);

namespace Nejcc\PhpDatatypes\Composite\Struct;

use InvalidArgumentException;
use Nejcc\PhpDatatypes\Abstract\BaseStruct;

final class Struct
final class Struct extends BaseStruct
{
/**

* @var string
*/
public string $name;
/**
* The array that stores field definitions and their values.
*
* @var array<string, array{type: string, value: mixed}>
*/
private array $fields;

/**
* Struct constructor.
*
* Initializes the struct with the provided fields and types.
*
* @param array<string, string> $fields Array of field names and their expected types.
*/
public function __construct(array $fields)
{
$this->fields = [];
foreach ($fields as $name => $type) {
$this->addField($name, $type);
}
}

/**

* Add a new field to the struct.
*
* Adds a field to the struct with its specified type and initializes it with a null value.
*
* @param string $name The name of the field.
* @param string $type The expected type of the field.
* @return void
*/
private function addField(string $name, string $type): void
{
if (isset($this->fields[$name])) {
throw new InvalidArgumentException("Field '$name' already exists in the struct.");
}

$this->fields[$name] = [
'type' => $type,
'value' => null
];
}

/**
* Set the value of a field, ensuring it matches the expected type.
*
* Validates that the provided value matches the expected type of the field.
*
* @param string $name The field name.
* @param mixed $value The value to set.
* @return void
*
* @throws InvalidArgumentException if the field doesn't exist or the value type doesn't match.
* {@inheritDoc}
*/
public function set(string $name, mixed $value): void
{
Expand All @@ -85,7 +39,6 @@ public function set(string $name, mixed $value): void

$baseType = $this->stripNullable($expectedType);

// Strict type check with class inheritance support
if ($actualType !== $baseType && !is_subclass_of($value, $baseType)) {
throw new InvalidArgumentException("Field '$name' expects type '$expectedType', but got '$actualType'.");
}
Expand All @@ -94,14 +47,7 @@ public function set(string $name, mixed $value): void
}

/**
* Get the value of a field.
*
* Retrieves the value of the field, throwing an exception if the field doesn't exist.
*
* @param string $name The field name.
* @return mixed The field value.
*
* @throws InvalidArgumentException if the field doesn't exist.
* {@inheritDoc}
*/
public function get(string $name): mixed
{
Expand All @@ -113,50 +59,16 @@ public function get(string $name): mixed
}

/**

* Get all fields in the struct.
*
* Returns the entire set of fields in the struct along with their types and values.
*
* @return array<string, array{type: string, value: mixed}> The fields with their respective types and values.

* {@inheritDoc}
*/
public function getFields(): array
{
return $this->fields;
}

/**
* Check if the type is nullable (e.g., `?string`).
*
* Determines if the field type allows null values.
*
* @param string $type The field type.
* @return bool True if the type is nullable, false otherwise.
*/
private function isNullable(string $type): bool
{
return str_starts_with($type, '?');
}

/**
* Strip the nullable symbol (`?`) from a type.
*
* Removes the nullable marker from the type to check the base type.
*
* @param string $type The field type.
* @return string The base type.
*/
private function stripNullable(string $type): string
{
return ltrim($type, '?');
}

/**
* Magic method for accessing fields like object properties.
*
* This method allows accessing fields as if they were public properties.
*
* @param string $name The field name.
* @return mixed The field value.
*
Expand All @@ -170,8 +82,6 @@ public function __get(string $name): mixed
/**
* Magic method for setting fields like object properties.
*
* This method allows setting fields as if they were public properties.
*
* @param string $name The field name.
* @param mixed $value The field value.
* @return void
Expand Down
30 changes: 30 additions & 0 deletions src/Interfaces/StructInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

namespace Nejcc\PhpDatatypes\Interfaces;

interface StructInterface
{
/**
* Set the value of a field.
*
* @param string $name The field name.
* @param mixed $value The value to set.
* @return void
*/
public function set(string $name, mixed $value): void;

/**
* Get the value of a field.
*
* @param string $name The field name.
* @return mixed The field value.
*/
public function get(string $name): mixed;

/**
* Get all fields in the struct.
*
* @return array<string, array{type: string, value: mixed}> The fields with their respective types and values.
*/
public function getFields(): array;
}
Loading