5

Write Cleaner, More Maintainable Rust Code with PhantomData

 2 weeks ago
source link: https://aayushyavajpayee.substack.com/p/coming-soon
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Write Cleaner, More Maintainable Rust Code with PhantomData

Solving the Redundancy Problem: How PhantomData Saves the Day in Rust

I recently encountered a problem while working on an invoice generation project. I found myself dealing with duplicated code when modeling invoice lines with two types of quantities: billed quantity and free quantity. In this blog post, I'll share my experience of using PhantomData to reduce code duplication and improve the overall structure of my code.

The Problem

In my invoice line struct, I wanted to have two separate types for quantities: BilledLineQuantity for billed quantities and FreeLineQuantity for free quantities. The reason for this was to enforce specific validations and ensure that the quantities were always valid. However, this led to a significant amount of duplicated code between the two types.

Initial Approach

I started by defining the BilledLineQuantity and FreeLineQuantity structs separately, each with their own implementations:

https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1f0724e7-e15b-472e-80f2-6ef2795cd4a1_1766x2096.png

The problem with this approach was that most of the methods for handling quantities, such as getting the numeric value or performing unit of measure conversions, were the same for both types. This resulted in a lot of duplicated code.

Thanks for reading Aayushya’s Substack! Subscribe for free to receive new posts and support my work.

Introducing PhantomData

To reduce code duplication, I decided to use PhantomData. PhantomData is a zero-sized type that can be used to mark generic type parameters and provide type-level information without affecting the runtime behaviour.

I created a BaseLineQuantity<T> struct that contained the common fields and methods for both BilledLineQuantity and FreeLineQuantity:

https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcb360de4-85b2-42b9-b58c-5014afc1c76c_1384x972.png

The phantom field of type PhantomData<T> is used to differentiate between the two types.

Refactoring with PhantomData

With the BaseLineQuantity<T> struct in place, I defined two marker types: FreeLineQuantityTag and BilledLineQuantityTag. These types serve as tags to distinguish between the two quantities:

pub struct FreeLineQuantityTag; 
pub struct BilledLineQuantityTag;

Next, I defined FreeLineQuantity and BilledLineQuantity as type aliases of BaseLineQuantity<T> with their respective tags:

pub type FreeLineQuantity = BaseLineQuantity<FreeLineQuantityTag>;
pub type BilledLineQuantity = BaseLineQuantity<BilledLineQuantityTag>;

Finally, I implemented the new method for each type, enforcing the specific validations:

https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff5754eac-1969-4131-bff5-c15dd9f01f3c_1686x1118.png
struct InvoiceLine {
    billed_quantity: BilledLineQuantity,
    free_quantity: FreeLineQuantity,
    // other fields
}

By leveraging PhantomData, I was able to reduce code duplication and improve the overall structure of my invoice line implementation. PhantomData allowed me to create a generic BaseLineQuantity<T> struct that encapsulated the common fields and methods, while still maintaining type-specific validations through the use of marker types.

This experience taught me the value of using advanced Rust features like PhantomData to solve real-world problems. It's a powerful tool that can help in creating more maintainable and expressive code.

I hope this blog post has provided you with insights into how PhantomData can be used to reduce code duplication in Rust

Thanks for reading Aayushya’s Substack! Subscribe for free to receive new posts and support my work.

Share

Leave a comment


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK