Menu
Coddy logo textTech

The Screen Struct

Part of the Object Oriented Programming section of Coddy's Rust journey — lesson 52 of 61.

challenge icon

Challenge

Easy

Now it's time to bring all your UI components together! You'll create a Screen struct that can hold a collection of different drawable components using trait objects. This is where the power of Vec<Box<dyn Draw>> really shines—one collection that manages multiple component types.

You'll add a new module to your growing project:

  • draw.rs: Your Draw trait from previous challenges.
  • text_field.rs: Your TextField component that prints Text: {content}.
  • button.rs: Your Button component that prints Button: {label} (width: {width}).
  • screen.rs: Create a Screen struct that holds a public field components of type Vec<Box<dyn Draw>>. Implement a new associated function that creates an empty screen, and an add method that takes a Box<dyn Draw> and adds it to the components vector.
  • main.rs: Bring all modules together. Create a Screen, add a TextField and a Button to it, then iterate through the screen's components and call draw() on each one.

Your Screen needs to store trait objects, so you'll use the dyn keyword with your Draw trait. The add method should take &mut self since it modifies the components vector.

The following inputs will be provided:

  • First line: the text field's content
  • Second line: the button's label
  • Third line: the button's width (as a number)

Your output should display each component on its own line, in the order they were added:

Text: Hello
Button: Click Me (width: 80)

Try it yourself

mod draw;
mod text_field;
mod button;
mod screen;

use draw::Draw;
use text_field::TextField;
use button::Button;
use screen::Screen;

pub struct Label {
    pub text: String,
}

impl Draw for Label {
    fn draw(&self) {
        println!("{}", self.text);
    }
}

fn main() {
    let mut input1 = String::new();
    std::io::stdin().read_line(&mut input1).expect("Failed to read line");
    let content = input1.trim().to_string();

    let mut input2 = String::new();
    std::io::stdin().read_line(&mut input2).expect("Failed to read line");
    let label = input2.trim().to_string();

    let mut input3 = String::new();
    std::io::stdin().read_line(&mut input3).expect("Failed to read line");
    let width: u32 = input3.trim().parse().expect("Failed to parse width");

    // TODO: Create a Screen using Screen::new()
    // TODO: Add a TextField wrapped in Box::new() to the screen
    // TODO: Add a Button wrapped in Box::new() to the screen
    // TODO: Iterate over screen.components and call draw() on each component
}

All lessons in Object Oriented Programming