Data Modeling Capstone
Nested Order Summary
Aggregate Child Records
Nested structs can represent parent and child records, while methods keep aggregate calculations near the data.
Program
Play the program to choose a quantity and compute an order total from its line items.
nested_order_summary.rs
Replay: real traced execution (multi-file project)
struct LineItem {
name: &'static str,
quantity: u32,
price: u32,
}
struct Order {
id: u32,
items: Vec<LineItem>,
}
impl Order {
fn total(&self) -> u32 {
self.items.iter().map(|item| item.quantity * item.price).sum()
}
}
fn main() {
let quantity = 2;
let order = Order {
id: 7,
items: vec![
LineItem { name: "book", quantity, price: 15 },
LineItem { name: "pen", quantity: 3, price: 2 },
],
};
let first = order.items[0].name;
let total = order.total();
println!("order={} first={} total={}", order.id, first, total);
}
struct LineItem {
name: &'static str,
quantity: u32,
price: u32,
}
struct Order {
id: u32,
items: Vec<LineItem>,
}
impl Order {
fn total(&self) -> u32 {
self.items.iter().map(|item| item.quantity * item.price).sum()
}
}
fn main() {
let quantity = 1;
let order = Order {
id: 7,
items: vec![
LineItem { name: "book", quantity, price: 15 },
LineItem { name: "pen", quantity: 3, price: 2 },
],
};
let first = order.items[0].name;
let total = order.total();
println!("order={} first={} total={}", order.id, first, total);
}
struct LineItem {
name: &'static str,
quantity: u32,
price: u32,
}
struct Order {
id: u32,
items: Vec<LineItem>,
}
impl Order {
fn total(&self) -> u32 {
self.items.iter().map(|item| item.quantity * item.price).sum()
}
}
fn main() {
let quantity = 4;
let order = Order {
id: 7,
items: vec![
LineItem { name: "book", quantity, price: 15 },
LineItem { name: "pen", quantity: 3, price: 2 },
],
};
let first = order.items[0].name;
let total = order.total();
println!("order={} first={} total={}", order.id, first, total);
}
quantity ← 2, order ← (empty), first ← "book", order.items[0].name ← "book"
18fn main() {19 let quantit→ 2y = 2; //@quantity=2, 1, 420 let orde→ (empty)r = Order {21 id: 7,22 items: vec![23 LineItem { name: "book", quantity, price: 15 },24 LineItem { name: "pen", quantity: 3, price: 2 },25 ],26 };27 let firs→ "book"t = order.items[0].nam→ "book"e;28 let total = order.total();29 println!("order={} first={} total={}", order.id, first, total);values this step(empty)order.items[0]total ← 36
27 let first = order.items[0].name;28 let tota→ 36l = order.total();29 println!("order={} first={} total={}", order.id, first, total);30}outputorder=7 first=book total=36
quantity ← 1, order ← (empty), first ← "book", order.items[0].name ← "book"
18fn main() {19 let quantit→ 1y = 1;20 let orde→ (empty)r = Order {21 id: 7,22 items: vec![23 LineItem { name: "book", quantity, price: 15 },24 LineItem { name: "pen", quantity: 3, price: 2 },25 ],26 };27 let firs→ "book"t = order.items[0].nam→ "book"e;28 let total = order.total();29 println!("order={} first={} total={}", order.id, first, total);values this step(empty)order.items[0]total ← 21
27 let first = order.items[0].name;28 let tota→ 21l = order.total();29 println!("order={} first={} total={}", order.id, first, total);30}outputorder=7 first=book total=21
quantity ← 4, order ← (empty), first ← "book", order.items[0].name ← "book"
18fn main() {19 let quantit→ 4y = 4;20 let orde→ (empty)r = Order {21 id: 7,22 items: vec![23 LineItem { name: "book", quantity, price: 15 },24 LineItem { name: "pen", quantity: 3, price: 2 },25 ],26 };27 let firs→ "book"t = order.items[0].nam→ "book"e;28 let total = order.total();29 println!("order={} first={} total={}", order.id, first, total);values this step(empty)order.items[0]total ← 66
27 let first = order.items[0].name;28 let tota→ 66l = order.total();29 println!("order={} first={} total={}", order.id, first, total);30}outputorder=7 first=book total=66
nested structs
`Order` owns a vector of `LineItem` child records.
method
`total` keeps aggregate behavior attached to the model it summarizes.
aggregation
The iterator multiplies each quantity by price, then sums the line totals.