nulid_derive
Derive macros for types that wrap Nulid.
This crate provides procedural macros to automatically implement common traits for newtype wrappers around Nulid, eliminating boilerplate code.
Features
Core Traits
The Id derive macro automatically implements:
TryFrom<String>- Parse from owned StringTryFrom<&str>- Parse from string sliceFrom<Nulid>- Create wrapper from NulidFrom<WrapperType> for Nulid- Extract inner NulidAsRef<Nulid>- Borrow inner NulidDeref<Target = Nulid>- Direct access to all Nulid methodsDerefMut- Mutable access to inner Nulidcore::fmt::Display- Format as Base32 stringcore::fmt::Debug- Debug formattingcore::str::FromStr- Parse from string using.parse()Copy- Value semantics (automatically providesClone)PartialEqandEq- Equality comparison with other wrappersPartialEq<Nulid>- Direct equality comparison withNulidPartialOrdandOrd- Ordering comparison with other wrappersPartialOrd<Nulid>- Direct ordering comparison withNulidHash- Hashing support for collectionsDefault- Creates a default instance withNulid::ZERO
Constructor Methods
It also provides:
new()method - Creates a new instance with a freshly generatedNulidnow()method - Alias fornew()nil()method - Creates a nil/zero instancemin()method - Returns the minimum possible instancemax()method - Returns the maximum possible instancefrom_datetime(SystemTime)- Creates from specific timefrom_nanos(u128, u64)- Creates from timestamp and randomfrom_u128(u128)- Creates from raw u128from_bytes([u8; 16])- Creates from byte array
Feature-Gated Traits
When the corresponding features are enabled, additional trait implementations are automatically generated:
serde feature
Serialize- Serialization support for JSON, bincode, etc.Deserialize- Deserialization support
[]
# The 'serde' feature is automatically propagated to nulid_derive
= { = "0.5", = ["derive", "serde"] }
use Id;
use ;
// Automatically implements Serialize + Deserialize
;
chrono feature
chrono_datetime()method - Convert tochrono::DateTime<Utc>from_chrono_datetime(DateTime<Utc>)method - Create from chrono DateTime
[]
# The 'chrono' feature is automatically propagated to nulid_derive
= { = "0.5", = ["derive", "chrono"] }
use Id;
use ;
// Automatically implements chrono methods
;
uuid feature
From<uuid::Uuid>- Convert from UUIDInto<uuid::Uuid>- Convert to UUIDto_uuid()method - Convert to UUIDfrom_uuid(Uuid)method - Create from UUID
[]
# The 'uuid' feature is automatically propagated to nulid_derive
= { = "0.5", = ["derive", "uuid"] }
use Id;
use Uuid;
// Automatically implements UUID conversions
;
sqlx feature
Type<Postgres>- PostgreSQL type supportEncode<Postgres>- Encoding for PostgreSQLDecode<Postgres>- Decoding from PostgreSQLPgHasArrayType- Array type support
[]
# The 'sqlx' feature is automatically propagated to nulid_derive
= { = "0.5", = ["derive", "sqlx"] }
= { = "0.8", = ["postgres", "uuid"] }
use Id;
use PgPool;
// Automatically implements SQLx traits
;
async
postgres-types feature
FromSql- Deserialize from PostgreSQLToSql- Serialize to PostgreSQL
[]
# The 'postgres-types' feature is automatically propagated to nulid_derive
= { = "0.5", = ["derive", "postgres-types"] }
= "0.2"
use Id;
use ;
// Automatically implements ToSql + FromSql
;
// Can now be used with the postgres crate
// let row = client.query_one("SELECT id FROM users WHERE id = $1", &[&user_id])?;
proto feature
to_proto()method - Convert to protobuf messagefrom_proto(ProtoNulid)method - Create from protobuf messageFrom<WrapperType> for ProtoNulid- Convert to protobufFrom<ProtoNulid> for WrapperType- Convert from protobuf
[]
# The 'proto' feature is automatically propagated to nulid_derive
= { = "0.5", = ["derive", "proto"] }
= "0.14"
use Id;
use Nulid as ProtoNulid;
use Message;
// Automatically implements protobuf conversions
;
Feature Propagation
Important: When you enable the derive feature along with other features (like serde, uuid, sqlx, postgres-types, proto, or chrono) on the nulid crate, those features are automatically propagated to nulid_derive. You don't need to enable them separately on both crates.
# Correct - features are automatically propagated to nulid_derive
[]
= { = "0.5", = ["derive", "serde", "uuid", "sqlx"] }
# Not necessary - you don't need to enable features on nulid_derive manually
[]
= { = "0.5", = ["derive", "serde"] }
= { = "0.5", = ["serde"] } # This is redundant
This automatic propagation works for all feature-gated traits:
serde→ enablesSerializeandDeserializeimplementationschrono→ enables chronoDateTimeconversion methodsuuid→ enables UUID conversion traitssqlx→ enables SQLx PostgreSQL traitspostgres-types→ enablesFromSqlandToSqltraitsproto→ enables Protocol Buffers conversion methods
Basic Usage
Add this to your Cargo.toml:
[]
= { = "0.5", = ["derive"] }
Then use the derive macro on your wrapper types:
use ;
;
;
Direct Access to Nulid Methods
With Deref and DerefMut traits, wrapper types can directly access all Nulid methods without needing to extract or dereference the inner value:
use Id;
;
Requirements
The derive macro requires:
- The type must be a tuple struct
- It must have exactly one field
- That field must be of type
Nulid
Valid examples:
; // Private field
; // Public field
Invalid examples:
; // Multiple fields
; // Wrong type
Type Safety
Using wrapper types provides type safety by preventing accidental mixing of different ID types:
use ;
;
;
let user_id = from;
let order_id = from;
process_user; // Correct type
// process_user(order_id); // Compile error: expected UserId, found OrderId
Error Handling
All parsing methods return Result<T, nulid::Error>, allowing proper error handling:
use ;
;
match try_from
Integration with Other Traits
The derive macro works well with other derive macros and automatically provides feature-gated trait implementations:
use ;
;
// Standard traits are automatically implemented:
// Debug, Copy (Clone), PartialEq, Eq, Hash, PartialOrd, Ord
// With features enabled, additional traits are automatically implemented:
// - serde feature: Serialize, Deserialize
// - chrono feature: chrono_datetime(), from_chrono_datetime()
// - uuid feature: From<Uuid>, Into<Uuid>
// - sqlx feature: Type<Postgres>, Encode, Decode
// - postgres-types feature: FromSql, ToSql
// - proto feature: to_proto(), from_proto(), From<ProtoNulid>
Combining Multiple Features
You can enable multiple features at once to get all the trait implementations you need:
[]
= { = "0.5", = ["derive", "serde", "uuid", "sqlx", "chrono", "proto"] }
use Id;
;
// Now UserId automatically implements:
// - All core traits (Debug, Copy, PartialEq, etc.)
// - Serde traits (Serialize, Deserialize)
// - Chrono methods (chrono_datetime(), from_chrono_datetime())
// - UUID conversions (From<Uuid>, Into<Uuid>)
// - SQLx traits (Type<Postgres>, Encode, Decode)
// - Proto methods (to_proto(), from_proto())
// Plus all the constructor methods (new, nil, min, max, etc.)
Examples
See the examples directory in the nulid repository for more usage examples.
License
This project is licensed under the MIT License - see the LICENSE file for details.