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
14 changes: 14 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/tests export-ignore
/vendor export-ignore

/README.md export-ignore
/LICENSE export-ignore
/Makefile export-ignore
/phpmd.xml export-ignore
/phpunit.xml export-ignore
/phpstan.neon.dist export-ignore
/infection.json.dist export-ignore

/.github export-ignore
/.gitignore export-ignore
/.gitattributes export-ignore
25 changes: 25 additions & 0 deletions .github/workflows/auto-assign.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Auto assign issues and pull requests

on:
issues:
types:
- opened
pull_request:
types:
- opened

jobs:
run:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- name: Assign issues and pull requests
uses: gustavofreze/auto-assign@1.1.4
with:
assignees: '${{ secrets.ASSIGNEES }}'
github_token: '${{ secrets.GITHUB_TOKEN }}'
allow_self_assign: 'true'
allow_no_assignees: 'true'
assignment_options: 'ISSUE,PULL_REQUEST'
49 changes: 49 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: CI

on:
pull_request:

permissions:
contents: read

env:
PHP_VERSION: '8.3'

jobs:
auto-review:
name: Auto review
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Configure PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ env.PHP_VERSION }}

- name: Install dependencies
run: composer update --no-progress --optimize-autoloader

- name: Run review
run: composer review

tests:
name: Tests
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Use PHP ${{ env.PHP_VERSION }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ env.PHP_VERSION }}

- name: Install dependencies
run: composer update --no-progress --optimize-autoloader

- name: Run tests
run: composer tests
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*.lock
.phpunit.*
.idea/

/vendor/
/report
38 changes: 38 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
ifeq ($(OS),Windows_NT)
PWD := $(shell cd)
else
PWD := $(shell pwd -L)
endif

ARCH := $(shell uname -m)
PLATFORM :=

ifeq ($(ARCH),arm64)
PLATFORM := --platform=linux/amd64
endif

DOCKER_RUN = docker run ${PLATFORM} --rm -it --net=host -v ${PWD}:/app -w /app gustavofreze/php:8.3

.PHONY: configure test test-file test-no-coverage review show-reports clean

configure:
@${DOCKER_RUN} composer update --optimize-autoloader

test:
@${DOCKER_RUN} composer tests

test-file:
@${DOCKER_RUN} composer test-file ${FILE}

test-no-coverage:
@${DOCKER_RUN} composer tests-no-coverage

review:
@${DOCKER_RUN} composer review

show-reports:
@sensible-browser report/coverage/coverage-html/index.html report/coverage/mutation-report.html

clean:
@sudo chown -R ${USER}:${USER} ${PWD}
@rm -rf report vendor .phpunit.cache .lock
177 changes: 175 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,175 @@
# mapper
Allows mapping data between different formats, such as JSON, arrays, and DTOs, providing flexibility in transforming and serializing information.
# Mapper

[![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)

* [Overview](#overview)
* [Installation](#installation)
* [How to use](#how-to-use)
* [License](#license)
* [Contributing](#contributing)

<div id='overview'></div>

## Overview

Allows mapping data between different formats, such as JSON, arrays, and DTOs, providing flexibility in transforming and
serializing information.

<div id='installation'></div>

## Installation

```bash
composer require tiny-blocks/mapper
```

<div id='how-to-use'></div>

## How to use

### Object

The library exposes available behaviors through the `ObjectMapper` interface, and the implementation of these behaviors
through the `ObjectMappability` trait.

#### Create an object from an iterable

You can map data from an iterable (such as an array) into an object. Here's how to map a `Shipping` object from an
iterable:

```php
<?php

declare(strict_types=1);

namespace Example;

use TinyBlocks\Mapper\ObjectMappability;
use TinyBlocks\Mapper\ObjectMapper;

final readonly class Shipping implements ObjectMapper
{
use ObjectMappability;

public function __construct(public int $id, public ShippingAddresses $addresses)
{
}
}
```

Next, define a `ShippingAddresses` class that is iterable:

```php
<?php

declare(strict_types=1);

namespace Example;

use ArrayIterator;use IteratorAggregate;use TinyBlocks\Mapper\ObjectMappability;use TinyBlocks\Mapper\ObjectMapper;use Traversable;

final class ShippingAddresses implements ObjectMapper, IteratorAggregate
{
use ObjectMappability;

/**
* @var \TinyBlocks\Mapper\Models\ShippingAddress[] $elements
*/
private iterable $elements;

public function __construct(iterable $elements = [])
{
$this->elements = is_array($elements) ? $elements : iterator_to_array($elements);
}

public function getIterator(): Traversable
{
return new ArrayIterator($this->elements);
}
}

```

Now you can map data into a `Shipping` object using `fromIterable`:

```php
<?php

use Example\Shipping;

$shipping = Shipping::fromIterable(iterable: [
'id' => PHP_INT_MAX,
'addresses' => [
[
'city' => 'New York',
'state' => 'NY',
'street' => '5th Avenue',
'number' => 717,
'country' => 'US'
]
]
]);
```

#### Map object to array

Once the object is created, you can easily convert it into an array representation.

```php
$shipping->toArray();
```

This will output the following array:

```php
[
'id' => 9223372036854775807,
'addresses' => [
[
'city' => 'New York',
'state' => 'NY',
'street' => '5th Avenue',
'number' => 717,
'country' => 'US'
]
]
]
```

#### Map object to JSON

Similarly, you can convert the object into a JSON representation.

```php
$shipping->toJson();
```

This will produce the following JSON:

```json
{
"id": 9223372036854775807,
"addresses": [
{
"city": "New York",
"state": "NY",
"street": "5th Avenue",
"number": 717,
"country": "US"
}
]
}
```

<div id='license'></div>

## License

Mapper is licensed under [MIT](LICENSE).

<div id='contributing'></div>

## Contributing

Please follow the [contributing guidelines](https://github.com/tiny-blocks/tiny-blocks/blob/main/CONTRIBUTING.md) to
contribute to the project.
76 changes: 76 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
{
"name": "tiny-blocks/mapper",
"type": "library",
"license": "MIT",
"homepage": "https://github.com/tiny-blocks/mapper",
"description": "Allows mapping data between different formats, such as JSON, arrays, and DTOs, providing flexibility in transforming and serializing information.",
"prefer-stable": true,
"minimum-stability": "stable",
"keywords": [
"psr",
"dto",
"json",
"array",
"object",
"mapper",
"tiny-blocks"
],
"authors": [
{
"name": "Gustavo Freze de Araujo Santos",
"homepage": "https://github.com/gustavofreze"
}
],
"support": {
"issues": "https://github.com/tiny-blocks/mapper/issues",
"source": "https://github.com/tiny-blocks/mapper"
},
"config": {
"sort-packages": true,
"allow-plugins": {
"infection/extension-installer": true
}
},
"autoload": {
"psr-4": {
"TinyBlocks\\Mapper\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"TinyBlocks\\Mapper\\": "tests/"
}
},
"require": {
"php": "^8.3",
"tiny-blocks/collection": "^1.8"
},
"require-dev": {
"phpmd/phpmd": "^2.15",
"phpstan/phpstan": "^1",
"phpunit/phpunit": "^11",
"infection/infection": "^0",
"squizlabs/php_codesniffer": "^3.11"
},
"scripts": {
"test": "phpunit --configuration phpunit.xml tests",
"phpcs": "phpcs --standard=PSR12 --extensions=php ./src",
"phpmd": "phpmd ./src text phpmd.xml --suffixes php --ignore-violations-on-exit",
"phpstan": "phpstan analyse -c phpstan.neon.dist --quiet --no-progress",
"test-file": "phpunit --configuration phpunit.xml --no-coverage --filter",
"mutation-test": "infection --only-covered --threads=max --logger-html=report/coverage/mutation-report.html --coverage=report/coverage",
"test-no-coverage": "phpunit --configuration phpunit.xml --no-coverage tests",
"review": [
"@phpcs",
"@phpmd",
"@phpstan"
],
"tests": [
"@test",
"@mutation-test"
],
"tests-no-coverage": [
"@test-no-coverage"
]
}
}
Loading
Loading