# Scoped IDs
[](https://crates.io/crates/dmv)
[](https://docs.rs/dmv)

This crate implements the idea of identifiers whose uniqueness is tied to a specific "scope", allowing for a common [`Id`] type generic over the scope where each individual instantiation can only inter-operate with its own instantiation.
## Common Use
To create a new id-scope that is attached to a specific type, you can use the [`Dmv`] derive macro:
```rust
#[derive(Dmv)]
struct Foo {
// ...
}
```
The above snippet would expand to:
```rust
#[derive(Hash)]
struct FooScope;
impl Scope for FooScope {}
type FooId = Id<FooScope>;
struct Foo {
// ...
}
```
Note that the visibility of the item being derived is inherited to the scope and ID alias. E.g. if you have `pub(super) struct Bar;`, it would generate `pub(super) BarScope;` and `pub(super) type BarId = ...`.
For a use-case that grants more control, there is also available the [`scope!`] macro demonstrated here:
```rust
dmv::scope!{ pub FooScope } // generates a struct with visibility `pub` and ident `FooScope`
type FooId = dmv::Id<FooScope>;
struct Foo {
sid: FooId,
gid: dmv::GlobalId,
}
dmv::scope!{ pub(super) BarScope } // generates a struct with visibility `pub(super)` and ident `BarScope`
type BarId = dmv::Id<BarScope>;
struct Bar {
sid: BarId,
gid: dmv::GlobalId,
}
```
In the example above, the `sid` members of both `Foo` and `Bar` are different types and cannot be directly operated with each other, and the `gid` members are of the same type and are therefore interoperable.
[`Id`]: https://docs.rs/dmv/*/dmv/identity/struct.Id.html
[`Dmv`]: https://docs.rs/dmv/*/dmv/derive.Dmv.html
[`scope!`]: https://docs.rs/dmv/*/dmv/macro.scope.html