GithubHelp home page GithubHelp logo

bag's People

Contributors

dependabot[bot] avatar dshafik avatar elazar avatar raphaelstolt avatar theofidry avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

bag's Issues

[RFC] Bag-less Value Objects

Currently in order to create Bag value objects you must extend the \Bag\Bag class. This requirement limits where you can use Bag value objects — you cannot simply add Value Object behavior to an existing value-object-like class. This is intended as an alternative way to use Bag.

We can solve this in two ways:

Composition using BagInterface and AsBag Trait

The first approach is more type-safe, by creating a BagInterface we enforce Bag-like UX on any class that wishes to be a Bag Value Object. Primarily this means enforcing the following methods:

interface BagInterface
{
    public static function from(mixed $values): BagInterface;

    public static function rules(): array;

    public static function collect(iterable $values = []): Collection;

    public static function validate(LaravelCollection|array $values): bool;

    public function with(mixed ...$values): BagInterface;

    public function get(?string $key = null): mixed;

    public function getRaw(?string $key = null): mixed;

    public function unwrapped(): array;

    public function toArray(): array;

    public function jsonSerialize(): array;

    public function toJson($options = 0): string;
}

We can then provide the implementation using the AsBag trait, meaning that to implement Bag functionality in any object, you can do the following:

use Bag\Contracts\BagInterface;
use Bag\Traits\AsBag;

readonly class MyValue implements BagInterface {
    use AsBag;

    public function __construct(…) { }
}

and the default Bag class can simply be the following to continue allowing the existing extend Bag UX:

readonly class Bag implements Arrayable, Jsonable, JsonSerializable, Castable, BagInterface
{
    use AsBag;
}

Bag::make()

Alternatively, we can implement a Bag::make() method with the following signature:

/**
 * @template T of object
 * @param class-string<T> $className
 * @return T
 */
public static function make(string $className, mixed $values): object;

This would then resolve the constructor arguments for $className and create a new instance. In addition static methods such as Bag::validate() and Bag::collect() can be updated to support objects that don't extend Bag.

However, with() is an instance method and the alternative to this to re-use Bag::make() and pass in the original value object values along with the new changes.

To enable support for features such as Hidden, we would also need to implement output functions such as toArray(), and toJson()/jsonSerialize(), which would either need to make heavy of (slow) reflection, or wrap around those functions in the underlying object.

Discussion

With the interface-and-trait implementation the resulting class has all the functionality and UX of Bag value objects, however it still requires you to update your existing class definition. The Bag::make() option requires less changes to the class, although you can opt-in to features using the attributes for features like casting or validation.

The primary downfall of the Bag::make() implementation is that the pipeline must be changed from working on Bag objects and instead just use object instead, losing any type safety in the process.

It should be noted that both of these solutions and the original extend Bag solution can co-exist, however there are concerns about complicating the UX by being too flexible.

Class "BagServiceProvider" not found

Describe the bug
Attempting to install Bag via the CLI leards to In ProviderRepository.php line 206: Class "BagServiceProvider" not found

To Reproduce

composer require dshafik/bag

Expected behavior

System (please complete the following information):

  • OS: macOS
  • PHP Version: 8.2
  • Bag Version: dev?

Additional context
Laravel 11.0.6, brand new install, I do need to change stability in composer to to "dev" order to get this far

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.