1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
//! Compact, human-readable unique IDs — grain-sized, yet enough for a lifetime.
//!
//! For a language agnostic specification of the grain-id format, see [SPECS.md](https://github.com/fluo10/grain-id/blob/main/SPECS.md)
//!
//! # Quick Start
//! ```rust
//! use grain_id::GrainId;
//!
//! let id = GrainId::random();
//! println!("{}", id); // e.g. "123abcd"
//! ```
//!
//! # Why grain-id?
//!
//! Traditional identifier systems face challenges in distributed environments:
//!
//! - **Sequential numbers** (like GitHub issue numbers) cause collisions in distributed systems
//! - **UUIDs** are too long and not human-friendly
//! - **Short hashes** (like Git commit hashes) lack standardization
//!
//! grain-id bridges the gap between human readability and technical requirements.
//!
//! # Installation
//!
//! Add this to your `Cargo.toml`:
//! ```toml
//! [dependencies]
//! grain-id = "0.14.1"
//!
//! # With optional features
//! grain-id = { version = "0.15.0", features = ["arbitrary", "serde", "rusqlite", "sea-orm", "prost", "schemars"] }
//! ```
//!
//! ## For no_std Environments
//!
//! This crate support `no_std`.
//! For `no_std` environment, you'll need to disable default features.
//! ```toml
//! [dependencies]
//! grain-id = { version = "0.14.1", default-features = false }
//! ```
//!
//! # Features
//!
//! - **Human-friendly**: Easy to read, type, and communicate
//! - **Collision-resistant**: Sufficient entropy for personal distributed systems
//! - **Compact**: Shorter than UUIDs while maintaining uniqueness
//! - **Type-safe**: Rust implementation with strong typing
//! - **Multiple integrations**: Support for serde, rusqlite, sea-orm, and protobuf
//!
//! ## Optional Feature Flags
//!
//! - `arbitrary`: `arbitrary::Arbitrary` support for fuzzing tests.
//! - `digest`: Hash-based [`GrainId`] generation via [`digest::Digest`] trait.
//! - `serde`: Serialization/deserialization support
//! - `rusqlite`: SQLite database integration
//! - `sea-orm`: SeaORM ORM integration
//! - `prost`: Protocol Buffers support
//! - `schemars`: JSON Schema support
//!
//! # Examples
//! ```rust
//! use grain_id::GrainId;
//! # fn main() -> Result<(), grain_id::Error> {
//! // Generate random grain-id
//! let grain_id = GrainId::random();
//!
//! // e.g. `123abcd`
//! println!("'{}'", grain_id);
//!
//! // Parse from string
//! let valid_id: GrainId = "012atvw".parse()?;
//!
//! // When decoding from BASE32, ambiguous characters (1/l/I, 0/o, v/u) are treated as 1, 0 and v respectively, so they do not cause errors.
//! let also_valid_id: GrainId = "ol2atuw".parse()?;
//! assert_eq!(valid_id, also_valid_id);
//!
//! // Convert to/from integer
//! let num: u64 = valid_id.into();
//! let id_from_int: GrainId = num.try_into()?;
//! assert_eq!(valid_id, id_from_int);
//!
//! // Lossy conversion from oversized int is allowed.
//! let id_from_overflowed_int = GrainId::from_u64_lossy(GrainId::CAPACITY + num);
//! assert_eq!(valid_id, id_from_overflowed_int);
//!
//! # Ok(())
//! # }
//! ```
extern crate core as std;
/// Provides constants and private functions about encoding/decoding alphabet.
///
/// This module implements encoding and decoding character based on [Crockford's Base32](https://www.crockford.com/base32.html) with following exceptions:
///
/// - The letter `u` (`U`) is decoded to 27, same as `v`.
/// - Characters are separated by hyphens every three characters (triplet) during encoding.
/// During decoding, hyphens may be omitted or replaced with underscores.
pub use GrainId;
pub use Error;
pub use GrainIdPrefix;
/// Provides message types generated by prost-build.
/// Alias of [`proto::GrainId`]
pub type GrainIdProto = GrainId;
/// Alias of [`proto::GrainIdPrefix`]
pub type GrainIdPrefixProto = GrainIdPrefix;