Expand description

This crate provides tools to provide type safety for types that you use as identifier types. In general, the identifier fields between structs aren’t interchangeable, even if they are the same type.

Enter TypedId, a container struct that is generic over your ID type and the type that ID belongs to. TypedId implements many useful traits to make using TypeId identical to using the underlying ID type, but with a layer of type safety to prevent mistakes that can occur when work with multiple ID types. This layer only exists at compile time, so there is no added bloat or performance hit at runtime. Let’s see that TypedId can do.

use typed_id::TypedId;
// The ID type for our Customer struct
pub type CustomerId = TypedId<u32, Customer>;
// The ID type for our Order struct
pub type OrderId = TypedId<u32, Order>;

pub struct Customer {
    id: CustomerId,
    orders: Vec<OrderId>,
    /* Likely more fields */
}

pub struct Order {
    id: OrderId,
    /* Likely more fields */
}

impl Customer {
    pub fn has_order(&self, o_id: OrderId) -> bool {
        self.orders.iter().find(|&o| *o == o_id).is_some()
    }
}

let id = 42;

// Convert the id to a typed id
let mut customer = Customer { id: id.into(), orders: Vec::new() };
let order = Order { id: id.into() };

customer.orders.push(order.id);

// We can cast typed ids back to `u32`'s if needed
assert_eq!(id, *customer.id);
assert_eq!(id, *order.id);

// This will *not* compile
// We *can't* directly compare typed ids, they are different types
// assert_eq!(id, customer.id);
// assert_eq!(id, order.id);
// assert_eq!(order.id, customer.id);

// Nor can we mistake a `u32` or a different typed id for an `OrderId`
// assert!(customer.has_order(id));

// Instead, we must have an `OrderId` or explicitly convert an id to an `OrderId`
assert!(customer.has_order(order.id));
assert!(customer.has_order(id.into()));
assert!(customer.has_order(customer.id.convert()));

Macros

A macro to shorthand the creation of TypeId aliases.

Structs

A generic type-checked wrapper around a generic identifier type