The `Id`, `Name`, and `Path` value objects are not only message-related
concerns, they're part of the core of the library, hence it makes sense
to place them at the root namespace.
Currently, we’re using scalar values to trace paths. The problem with
that approach is that we can’t create a reliable hierarchy with them, as
we can’t know for sure when a path is the same for different rules. By
using an object, we can easily compare and create a parent-child
relationship with it.
While making these changes, I deemed it necessary to also create objects
to handle Name and Id, which makes the code simpler and more robust. By
having Name and Path, we can create specific stringifiers that allow us
to customise how we render those values.
I didn’t manage to make those changes atomically, which is why this
commit makes so many changes. I found myself moving back and forth, and
making all those changes at once was the best solution I found.
Because of how the validation engine works now [1], there's no reason to
keep adding names to each rule. Instead, create a single rule that
handles naming rules with a few other accessories. This change is not
necessarily simple, but it shrinks the `Rule` interface, and it's more
aligned with how the library works right now.
Personally, I think this API is much more straightforward than the
`setName()` method, as it's way more explicit about which rule we're
naming. Because of this change, the behaviour changed slightly, but it's
for the best.
Because of this change, I managed to remove a lot of code, but
unfortunately, it's quite a big-bang commit. It would be too complicated
to make it atomic since names are an intrinsic part of the library.
[1]: 238f2d506a