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