pxid
Prefixed Globally Unique Identifier
[![Crates.io](https://img.shields.io/crates/v/pxid.svg)](https://crates.io/crates/pxid)
[![Documentation](https://docs.rs/pxid/badge.svg)](https://docs.rs/pxid)
![Build](https://github.com/EstebanBorai/pxid/workflows/build/badge.svg)
![Clippy](https://github.com/EstebanBorai/pxid/workflows/clippy/badge.svg)
![Formatter](https://github.com/EstebanBorai/pxid/workflows/fmt/badge.svg)
## Motivation
Extend the [rs/xid][1] implementation by adding capability to have
a prefix and at the same time have a `u16` type support by fitting prefix bits.
This library is inspired in Stripe IDs which have a friendly notation and are
very short IDs. These IDs are prefixed with a maximum of 4 bytes belonging to
the entity behind them.
## Usage
```rust
use pxid::Pxid;
fn main() -> Result<(), Box> {
// Given that some of the dependencies to build
// an instance of the Pxid may fail.
// - Getting current timestamp
// - Getting machine id
// - Getting process id
//
// A `Result` is returned.
let id = Pxid::new("acct".as_bytes())?;
println!("{}", id); // acct_9m4e2mr0ui3e8a215n4g
}
```
To improve memory usage (reduce allocations), and reuse dependencies required,
the `Factory` struct can also be used to build `Pxid` instances.
This is the recommended way to build `Pxid` instances, given that resources are
initialized once, and then reused.
```rust
use pxid::Factory;
fn main() -> Result<(), Box> {
let factory = Factory::new_without_prefix()?;
let id = factory.with_prefix("acct");
println!("{}", id); // acct_9m4e2mr0ui3e8a215n4g
let factory_with_prefix = Factory::new("acct")?;
let id = factory_with_prefix.generate();
println!("{}", id); // acct_9m4e2mr0ui3e8a215n4g
}
```
### GraphQL Support
You can use `Pxid` on GraphQL via the `async-graphql` crate.
Make sure the `graphql` feature is enabled and import `Pxid` for GraphQL.
```rust
use async_graphql::{Context, InputObject, Result, SimpleObject};
use pxid::graphql::Pxid;
// -- snip --
#[derive(Debug, InputObject)]
pub struct PostCreateInput {
pub title: String,
pub content: String,
pub parent_id: Option,
}
impl PostCreate {
pub async fn exec(ctx: &Context<'_>, input: PostCreateInput) -> Result {
// -- snip --
```
> Check out the full example [here][2].
## Layout
A prefixed XID fits nicely on a 16 bytes slice thanks to its packed data format.
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
Prefix |
Timestamp |
Machine ID |
Process ID |
Counter |
For a total of 16 bytes.
The prefix allows up to 4 UTF-8 Characters, this allows the ID to provide some
context about its scope.
```txt
acct_9m4e2mr0ui3e8a215n4g
ordr_9m4e2mr0ui3e8a215n4g
usr_9m4e2mr0ui3e8a215n4g
```
This way IDs are not only even harder to collide, but they also provides a bit
of context on record association.
## License
This project is licensed under the MIT License
[1]: https://github.com/rs/xid
[2]: https://github.com/whizzes/gabble/blob/ca10e295ce1386dd15a8f91f968e7aa8085287c4/crates/server/src/graphql/modules/post/mutation/post_create.rs