Skip to content
This repository was archived by the owner on Jan 24, 2025. It is now read-only.

Commit f34fb08

Browse files
authored
Minor grammar fixes to deserialize instruction data (#336)
1 parent c811fae commit f34fb08

File tree

1 file changed

+46
-48
lines changed

1 file changed

+46
-48
lines changed

content/courses/native-onchain-development/deserialize-instruction-data.md

Lines changed: 46 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,9 @@ description:
1414

1515
## Summary
1616

17-
- Most programs support **multiple discrete instruction handlers** - you decide
18-
when writing your program what these instruction handlers are and what data
19-
must accompany them when writing your program what these instruction handlers
20-
are and what data
21-
- Rust **enums** are often used to represent discrete program instruction
17+
- Most programs support **multiple discrete instruction handlers** (sometimes
18+
just referred to as 'instructions') - these are functions inside your program
19+
- Rust **enums** are often used to represent each instruction handler
2220
- You can use the `borsh` crate and the `derive` attribute to provide Borsh
2321
deserialization and serialization functionality to Rust structs
2422
- Rust `match` expressions help create conditional code paths based on the
@@ -27,18 +25,18 @@ description:
2725
## Lesson
2826

2927
One of the most basic elements of a Solana program is the logic for handling
30-
instruction data. Most programs support multiple related functions and use
31-
differences in instruction data to determine which code path to execute. For
32-
example, two different data formats in the instruction data passed to the
33-
program may represent instructions for creating a new piece of data vs deleting
34-
the same piece of data.
28+
instruction data. Most programs support multiple functions, also called
29+
instruction handlers. For example, a program may have different instruction
30+
handlers for creating a new piece of data versus deleting the same piece of
31+
data. Programs use differences in instruction data to determine which
32+
instruction handler to execute.
3533

3634
Since instruction data is provided to your program's entry point as a byte
3735
array, it's common to create a Rust data type to represent instructions in a way
3836
that's more usable throughout your code. This lesson will walk through how to
3937
set up such a type, how to deserialize the instruction data into this format,
40-
and how to execute the proper code path based on the instruction passed into the
41-
program's entry point.
38+
and how to execute the proper instruction handler based on the instruction
39+
passed into the program's entry point.
4240

4341
### Rust basics
4442

@@ -53,10 +51,10 @@ Variable assignment in Rust happens with the `let` keyword.
5351
let age = 33;
5452
```
5553

56-
Variables in Rust by default are immutable, meaning a variable's value cannot be
57-
changed once it has been set. To create a variable that we'd like to change at
58-
some point in the future, we use the `mut` keyword. Defining a variable with
59-
this keyword means that the value stored in it can change.
54+
By default, variables in Rust are immutable, meaning a variable's value cannot
55+
be changed once it has been set. To create a variable that we'd like to change
56+
at some point in the future, we use the `mut` keyword. Defining a variable with
57+
this keyword means that its stored value can change.
6058

6159
```rust
6260
// compiler will throw error
@@ -68,15 +66,15 @@ let mut mutable_age = 33;
6866
mutable_age = 34;
6967
```
7068

71-
The Rust compiler guarantees that immutable variables truly cannot change so
72-
that you don’t have to keep track of it yourself. This makes your code easier to
73-
reason through and simplifies debugging.
69+
The Rust compiler guarantees that immutable variables cannot change, so you
70+
don’t have to keep track of it yourself. This makes your code easier to reason
71+
through and simplifies debugging.
7472

7573
#### Structs
7674

7775
A struct, or structure, is a custom data type that lets you package together and
7876
name multiple related values that make up a meaningful group. Each piece of data
79-
in a struct can be of different types and each has a name associated with it.
77+
in a struct can be of different types, and each has a name associated with it.
8078
These pieces of data are called **fields**. They behave similarly to properties
8179
in other languages.
8280

@@ -117,8 +115,8 @@ enum LightStatus {
117115
}
118116
```
119117

120-
The `LightStatus` enum has two possible variants in this situation: it's either
121-
`On` or `Off`.
118+
The `LightStatus` enum has two possible variants in this situation: it's
119+
either`On` or `Off`.
122120

123121
You can also embed values into enum variants, similar to adding fields to a
124122
struct.
@@ -139,10 +137,10 @@ requires also setting the value of `color`.
139137

140138
#### Match statements
141139

142-
Match statements are very similar to `switch` statements in C/C++. The `match`
143-
statement allows you to compare a value against a series of patterns and then
144-
execute code based on which pattern matches the value. Patterns can be made of
145-
literal values, variable names, wildcards, and more. The match statement must
140+
Match statements are very similar to `switch` statements in other languages. The
141+
`match` statement allows you to compare a value against a series of patterns and
142+
then execute code based on which pattern matches the value. Patterns can be made
143+
of literal values, variable names, wildcards, and more. The match statement must
146144
include all possible scenarios, otherwise the code will not compile.
147145

148146
```rust
@@ -206,9 +204,9 @@ example.answer();
206204
#### Traits and attributes
207205

208206
You won't be creating your own traits or attributes at this stage, so we won't
209-
provide an in depth explanation of either. However, you will be using the
207+
provide an in-depth explanation of either. However, you will be using the
210208
`derive` attribute macro and some traits provided by the `borsh` crate, so it's
211-
important you have a high level understanding of each.
209+
important you have a high-level understanding of each.
212210

213211
Traits describe an abstract interface that types can implement. If a trait
214212
defines a function `bark()` and a type then adopts that trait, the type must
@@ -227,10 +225,10 @@ concrete example of this shortly.
227225

228226
Now that we've covered the Rust basics, let's apply them to Solana programs.
229227

230-
More often than not, programs will have more than one function. For example, you
231-
may have a program that acts as the backend for a note-taking app. Assume this
232-
program accepts instructions for creating a new note, updating an existing note,
233-
and deleting an existing note.
228+
More often than not, programs will have more than one instruction handler. For
229+
example, you may have a program that acts as the backend for a note-taking app.
230+
Assume this program accepts instructions for creating a new note, updating an
231+
existing note, and deleting an existing note.
234232

235233
Since instructions have discrete types, they're usually a great fit for an enum
236234
data type.
@@ -293,18 +291,18 @@ accepts the instruction data as an argument and returns the appropriate instance
293291
of the enum with the deserialized data.
294292

295293
It's standard practice to structure your program to expect the first byte (or
296-
other fixed number of bytes) to be an identifier for which instruction the
297-
program should run. This could be an integer or a string identifier. For this
298-
example, we'll use the first byte and map integers 0, 1, and 2 to instructions
299-
create, update, and delete, respectively.
294+
other fixed number of bytes) to be an identifier for which instruction handler
295+
the program should run. This could be an integer or a string identifier. For
296+
this example, we'll use the first byte and map integers 0, 1, and 2 to the
297+
instruction handlers for create, update, and delete, respectively.
300298

301299
```rust
302300
impl NoteInstruction {
303301
// Unpack inbound buffer to associated Instruction
304302
// The expected format for input is a Borsh serialized vector
305303
pub fn unpack(input: &[u8]) -> Result<Self, ProgramError> {
306304
// Take the first byte as the variant to
307-
// determine which instruction to execute
305+
// determine which instruction handler to execute
308306
let (&variant, rest) = input.split_first().ok_or(ProgramError::InvalidInstructionData)?;
309307
// Use the temporary payload struct to deserialize
310308
let payload = NoteInstructionPayload::try_from_slice(rest).unwrap();
@@ -380,7 +378,7 @@ pub fn process_instruction(
380378
For simple programs where there are only one or two instructions to execute, it
381379
may be fine to write the logic inside the match statement. For programs with
382380
many different possible instructions to match against, your code will be much
383-
more readable if the logic for each instruction is written in a separate
381+
more readable if the logic for each instruction handler is written in a separate
384382
function and simply called from inside the `match` statement.
385383

386384
### Program file structure
@@ -391,11 +389,11 @@ important to maintain a project structure that remains readable and extensible.
391389
This involves encapsulating code into functions and data structures as we've
392390
done so far. But it also involves grouping related code into separate files.
393391

394-
For example, a good portion of the code we've worked through so far has to do
395-
with defining and deserializing instructions. That code should live in its own
396-
file rather than be written in the same file as the entry point. By doing so, we
397-
would then have 2 files, one with the program entry point and the other with the
398-
instruction code:
392+
For example, a good portion of the code we've worked through so far involves
393+
defining and deserializing instructions. That code should live in its own file
394+
rather than be written in the same file as the entry point. By doing so, we
395+
would then have two files, one with the program entry point and the other with
396+
the instruction handler:
399397

400398
- **lib.rs**
401399
- **instruction.rs**
@@ -541,11 +539,11 @@ pub mod instruction;
541539
use instruction::{MovieInstruction};
542540
```
543541

544-
Next, let's define a new function `add_movie_review` that takes as arguments
542+
Next, let's define a new function `add_movie_review` that takes the arguments
545543
`program_id`, `accounts`, `title`, `rating`, and `description`. It should also
546-
return an instance of `ProgramResult` Inside this function, let's simply log our
547-
values for now and we'll revisit the rest of the implementation of the function
548-
in the next lesson.
544+
return an instance of `ProgramResult`. Inside this function, let's simply log
545+
our values for now and we'll revisit the rest of the implementation of the
546+
function in the next lesson.
549547

550548
```rust
551549
pub fn add_movie_review(
@@ -596,7 +594,7 @@ instruction data passed in when a transaction is submitted!
596594
Build and deploy your program from Solana Program just like in the last lesson.
597595
If you haven't changed the program ID since going through the last lesson, it
598596
will automatically deploy to the same ID. If you'd like it to have a separate
599-
address you can generate a new program ID from the playground before deploying.
597+
address, you can generate a new program ID from the playground before deploying.
600598

601599
You can test your program by submitting a transaction with the right instruction
602600
data. For that, feel free to use

0 commit comments

Comments
 (0)