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.

quantity
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);
}
  1. 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]
  2. 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
  1. 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]
  2. 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
  1. 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]
  2. 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.