3.9 KiB
3.9 KiB
please refactor each of the objects in the the chosen folder to use builder paradigm, see below for an example we always start from root object, each file e.g. product.rs corresponds to a root object, the rootobject is what is stored in the DB, the rest are sub objects which are children of the root object
✅ Step 1: Define your struct
#[derive(Debug)]
pub enum ProductType {
Service,
// Other variants...
}
#[derive(Debug)]
pub enum ProductStatus {
Available,
Unavailable,
// Other variants...
}
#[derive(Debug)]
pub struct Product {
id: u32,
name: String,
description: String,
price: f64,
product_type: ProductType,
category: String,
status: ProductStatus,
max_amount: u32,
validity_days: u32,
}
✅ Step 2: Create a builder
pub struct ProductBuilder {
id: Option<u32>,
name: Option<String>,
description: Option<String>,
price: Option<f64>,
product_type: Option<ProductType>,
category: Option<String>,
status: Option<ProductStatus>,
max_amount: Option<u32>,
validity_days: Option<u32>,
}
impl ProductBuilder {
pub fn new() -> Self {
Self {
id: None,
name: None,
description: None,
price: None,
product_type: None,
category: None,
status: None,
max_amount: None,
validity_days: None,
}
}
pub fn id(mut self, id: u32) -> Self {
self.id = Some(id);
self
}
pub fn name<S: Into<String>>(mut self, name: S) -> Self {
self.name = Some(name.into());
self
}
pub fn description<S: Into<String>>(mut self, description: S) -> Self {
self.description = Some(description.into());
self
}
pub fn price(mut self, price: f64) -> Self {
self.price = Some(price);
self
}
pub fn product_type(mut self, product_type: ProductType) -> Self {
self.product_type = Some(product_type);
self
}
pub fn category<S: Into<String>>(mut self, category: S) -> Self {
self.category = Some(category.into());
self
}
pub fn status(mut self, status: ProductStatus) -> Self {
self.status = Some(status);
self
}
pub fn max_amount(mut self, max_amount: u32) -> Self {
self.max_amount = Some(max_amount);
self
}
pub fn validity_days(mut self, validity_days: u32) -> Self {
self.validity_days = Some(validity_days);
self
}
pub fn build(self) -> Result<Product, &'static str> {
Ok(Product {
id: self.id.ok_or("id is required")?,
name: self.name.ok_or("name is required")?,
description: self.description.ok_or("description is required")?,
price: self.price.ok_or("price is required")?,
product_type: self.product_type.ok_or("type is required")?,
category: self.category.ok_or("category is required")?,
status: self.status.ok_or("status is required")?,
max_amount: self.max_amount.ok_or("max_amount is required")?,
validity_days: self.validity_days.ok_or("validity_days is required")?,
})
}
}
✅ Step 3: Use it like this
let product = ProductBuilder::new()
.id(1)
.name("Premium Service")
.description("Our premium service offering")
.price(99.99)
.product_type(ProductType::Service)
.category("Services")
.status(ProductStatus::Available)
.max_amount(100)
.validity_days(30)
.build()
.expect("Failed to build product");
This way:
- You don’t need to remember the order of parameters.
- You get readable, self-documenting code.
- It’s easier to provide defaults or optional values if you want later.
Want help generating this automatically via a macro or just want it shorter? I can show you a derive macro to do that too.