The Screen Struct
Part of the Object Oriented Programming section of Coddy's Rust journey — lesson 52 of 61.
Challenge
EasyNow 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: YourDrawtrait from previous challenges.text_field.rs: YourTextFieldcomponent that printsText: {content}.button.rs: YourButtoncomponent that printsButton: {label} (width: {width}).screen.rs: Create aScreenstruct that holds a public fieldcomponentsof typeVec<Box<dyn Draw>>. Implement anewassociated function that creates an empty screen, and anaddmethod that takes aBox<dyn Draw>and adds it to the components vector.main.rs: Bring all modules together. Create aScreen, add aTextFieldand aButtonto it, then iterate through the screen's components and calldraw()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
1Methods and Behavior
Intro Implementation BlocksThe Self ParameterMutable MethodsAssociated FunctionsMultiple Implementation BlocksMethod ChainingRecap - Rectangle Actions4Project: Virtual Pet
Defining the PetFeeding the Pet7Standard Traits
The Debug TraitThe Display TraitClone and CopyEquality TraitsRecap - Printable Point10Project: Document System
The Draw TraitText Component2Encapsulation and Modules
Modules BasicsThe Public KeywordPrivate FieldsGettersSettersRecap - Secure Locker5Generics
Generic StructsGeneric MethodsMultiple Generic TypesGeneric FunctionsRecap - Coordinate Point8Traits as Bounds
Trait Bounds SyntaxMultiple BoundsThe Where ClauseReturning Types with TraitsRecap - Generic Printer11Design Patterns in Rust
Newtype PatternCompositionThe Drop TraitFrom and IntoRecap - Smart Pointer Mock