Hello! Welcome back.
In the last module, we established a strong foundation in Rust's ownership system, mastering the concepts of moving, borrowing, and cloning. These rules are what make Rust safe and efficient, but they are primarily about how we manage memory. Now, it's time to start building the actual logic of our chess game.
This lesson marks the beginning of that process. We will learn how to define our own custom data types using structs and enums. These are the fundamental building blocks in Rust for modeling real-world concepts. By the end of this lesson, you'll have created the very first data structures for our chess game, representing the pieces themselves.

1. Structs: Grouping Related Data
Think about any object in a game, like a player character, an item, or in our case, a chess piece. These objects have a collection of properties or attributes. A struct (short for structure) is Rust's way of grouping these related properties into a single, named type.
If you've used C, structs will feel familiar. In Java, you can think of them as simple classes that only contain data fields (we'll add behavior later).
To get a clear picture of how to define and use structs, let's watch a short video.
The 'Let's Get Rusty' channel has a great introduction to structs. This segment will cover the basic syntax, how to create an instance of a struct, and how to access its data.
Watch from the beginning (00:18) to 04:46. Pay attention to the struct keyword for definition, the curly brace {} syntax for instantiation, and the dot . notation for accessing fields.
As the video demonstrated, the concept is straightforward:
- You define a
structwith a name and a set of named fields, each with its own type. - You create an instance of that struct by providing values for each field.
- You access the data in those fields using dot notation (e.g.,
user1.email).
Now, let's apply this to our chess game. How might we represent a single piece on the board? A piece has two fundamental properties: its type (Pawn, Rook, etc.) and its color (White or Black). We can't fully define this yet, but we can see how a struct would be the right tool to hold these two properties together.
2. Enums: Representing a Set of Choices
What about the color or the type of a piece? A piece's color can only be White or Black. Its type can only be one of Pawn, Rook, Knight, Bishop, Queen, or King. This is a classic "either/or" scenario where a value must be one of a fixed set of possibilities.
This is exactly what enums (enumerations) are for. An enum allows you to define a type by listing all its possible variants.
Since you're interested in games, a great analogy comes from the DEV Community article "Structs and Enums in Rust". In a Mario game, a power-up could be an enum with variants like SuperMushroom, FireFlower, or Starman. Mario can only have one of these at a time.
Structs and Enums in Rust - DEV Community
To understand enums with a gaming-themed example, read this section from the article by Sonu Bardai on DEV Community.
Read the section titled 'Enum1, Enum2, Enum3' (the actual content starts with 'Enums, short for enumerations...'). Focus on how the PowerUp enum is defined and how an instance of it is created.
Rust's enums are more powerful than in languages like C, as they can also hold data. Let's see a video that explains this.
Enums and Pattern Matching in Rust
This video from 'Let's Get Rusty' introduces enums and their more advanced capabilities.
Watch from 00:39 to 03:51. The first part covers the basic enum definition. The second part is crucial, as it shows how enum variants can store data, making them incredibly flexible.
With enums, we now have the perfect tool to define our piece properties:
// Represents the type of a piece
enum PieceKind {
Pawn,
Rook,
Knight,
Bishop,
Queen,
King,
}
// Represents the color of a piece
enum PieceColor {
White,
Black,
}
These definitions are clean, type-safe, and clearly express our intent. You can't accidentally create a PieceColor::Green.
3. Hands-On: Modeling Our First Chess Piece
Now we can combine these two concepts to create our first data structure for the chess game. A chess piece is a single entity that has a color and a kind. Therefore, a struct is the right tool to group these properties, and our enums are the right tools for the properties themselves.
This is a common and effective pattern in Rust. A developer on Stack Overflow asked a similar question about how to model a chess board, and the answer provides a perfect illustration of this design.
How best to use traits vs enums when describing a chess board
Let's read the accepted answer to a Stack Overflow question on this very topic. It recommends a simple and powerful model that we will adopt for our project.
Read the first two code blocks in the accepted answer (starting with 'I think the simplest possible model...'). Notice how it defines a Piece struct that contains PieceKind and PieceColor enums.
Following this excellent advice, let's put it all together.
Your turn!
- Open your
rust_chessproject and replace the contents ofsrc/main.rswith the following code. - Read through it to see how
structandenumwork together. - Run the code with
cargo run.
// In src/main.rs
// An enum to represent the six types of chess pieces.
enum PieceKind {
Pawn,
Rook,
Knight,
Bishop,
Queen,
King,
}
// An enum to represent the two piece colors.
enum PieceColor {
White,
Black,
}
// A struct to represent a single chess piece.
// It groups the kind and color together.
struct Piece {
kind: PieceKind,
color: PieceColor,
}
fn main() {
// Let's create an instance of a piece: a white king.
let white_king = Piece {
kind: PieceKind::King,
color: PieceColor::White,
};
// Let's create another one: a black pawn.
let black_pawn = Piece {
kind: PieceKind::Pawn,
color: PieceColor::Black,
};
// We can't print these structs to the console yet.
// If you try to do println!("{:?}", white_king); you'll get a compiler error.
// We will learn how to make them printable in a future lesson!
println!("Successfully defined and created instances of our chess piece data structures!");
}
When you run this, it will simply print the success message. But don't be fooled by the simple output! You have just laid the foundational data model for your entire chess game using core Rust features.
Conclusion
In this lesson, we took a major step towards building our chess application. We moved from the abstract rules of ownership to the concrete task of data modeling.
Key Takeaways:
- Structs are used to group related data into a named, custom type. They are ideal for representing objects with multiple attributes (e.g., a
Piecethat has akindand acolor). - Enums are used to define a type that can have one of several possible variants. They are perfect for representing a fixed set of choices (e.g.,
PieceColorcan only beWhiteorBlack). - Combining structs and enums is a powerful pattern in Rust for creating clear, expressive, and safe data models.
Our Piece struct is currently just a passive data container. It doesn't do anything. In our next lesson, we will learn how to attach behavior to our structs and enums using impl blocks. This will allow us to define methods, bringing our data structures to life.