forked from richardanaya/tour_of_rust
-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathchapter_10.yaml
149 lines (107 loc) · 8.9 KB
/
chapter_10.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
- title: Chapter 10 - I/O
content_markdown: >
In computing, `I/O` is an abbreviation for `Input/Output` operation.
The `input` is what the computer and the algorithm receive and
the `output` represents the result generated based on the `input`.
Thing about `I/O` as a stream of information
A compute system without output is nearly useless.
It will always run the same code on the same data and, thus, produce the same result.
- title: Do it locally
content_markdown: >
In this chapter, the Playground will be just a code support for you :(.
Since most of the `I/O` programs are designed to compile on a local machine
(yours :) ), consider setting up a Rust environment on your personal computer and
familiarise yourself with the terminal.
Also, consider using an `IDE`, such as `VS Code` or `RustRover`
and familiarise yourself with the [terminal](https://www.youtube.com/watch?v=lZ7Kix9bjPI).
- title: Standard Input (stdin)
content_markdown: >
`Standard Input` refers to the data provided by the user for the algorithm to process.
Thus, the `input` represents what a program is being given.
Mostly, in terms of `input`, you'll work with `String` and `files`.
The Rust library `std::io` has the necessary components to interact with `I/O`
channels, such as the keyboard or any other input source.
code: >-
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=use+std%3A%3Aio%3B%0A%0Afn+main%28%29+%7B%0A++++let+mut+input+%3D+String%3A%3Anew%28%29%3B%0A%0A++++%2F%2F+the+read+will+be+stopped+by+%60%5Cn%60+character%0A++++if+let+Ok%28_%29+%3D+io%3A%3Astdin%28%29.read_line%28%26mut+input%29+%7B%0A++++++++println%21%28%22Input+text+%3A+%7B%7D%22%2C+input%29%3B%0A++++%7D%0A%7D%0A
- title: Standard Output (stdout)
content_markdown: >
Remember the first lesson? Can you notice something relevant to `I/O`?
Of course that what `println!` does is an output operation,
in fact it directs (outputs) text to `stdout` (stdout)
and it will be displayed on the screen.
If you don't want to print a new line character `\n` for you, use `print!`
code: >-
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=use+std%3A%3Aio%3B%0A%0Afn+main%28%29+%7B%0A++++let+mut+input+%3D+String%3A%3Anew%28%29%3B%0A%0A++++%2F%2F+the+read+will+be+stopped+by+%60%5Cn%60+character%0A++++if+let+Ok%28_%29+%3D+io%3A%3Astdin%28%29.read_line%28%26mut+input%29+%7B%0A++++++++println%21%28%22Input+text+%3A+%7B%7D%22%2C+input%29%3B%0A++++%7D%0A%7D%0A
- title: Standard Error (stdout)
content_markdown: >
In order to separate error reporting from common printing, you can use the `eprint!` and
`eprintln!` macros that will display text in the standard error (`stderr`) channel,
instead of `stdout`. Use this macro with an informative message.
In UNIX-like systems, such as macOS or LINUX, you can separate the two types of
output by using redirections:
- `./main > output.txt`
- `./main >> output.txt`
- `./main 2> output.txt`
- `./main 2>> output.txt`
> The commands with `2` will copy only the errors generated by the program, and the ones without `2` will discards all errors.
> The command with `>>` will add text at the end of the file, while the operator `>` will override the file.
code: >-
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=use+std%3A%3Aio%3B%0A%0Afn+main%28%29+%7B%0A++++let+mut+input+%3D+String%3A%3Anew%28%29%3B%0A%0A++++%2F%2F+the+read+will+be+stopped+by+%60%5Cn%60+character%0A++++if+let+Ok%28_%29+%3D+io%3A%3Astdin%28%29.read_line%28%26mut+input%29+%7B%0A++++++++println%21%28%22Input+text+%3A+%7B%7D%22%2C+input%29%3B%0A++++%7D%0A%7D%0A
- title: File Descriptors
content_markdown: >
Now that we know what are the basic `I/O` operations, we dive even deeper.
You've already seen before: `stdin` (standard input), `stdout` (standard output) and `stderr` (standard error).
For each of them it is associated a positive integer number, a unique identifier
for an `I/O` channel (example: file), known as a `file descriptor (fd)`.
Therefore:
- `stdin`: 0
- `stdout`: 1
- `stderr`: 2
- files
[
Working with files plays an important role in the `I/O` operations.
You've already learned to open a text file and read its content.
But how about writing data in it, as an `I/O` channel.
code: >-
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=use+std%3A%3Afs%3A%3A%7Bself%2C+File%7D%3B++++++%2F%2F+file+system%0Ause+std%3A%3Aio%3A%3A%7Bself%2C+Write%7D%3B+++++%2F%2F+input+output%0A%0Afn+main%28%29+-%3E+io%3A%3AResult%3C%28%29%3E+%7B%0A++++let+file_name+%3D+%22output.txt%22%3B%0A%0A++++%2F%2F+creates+the+file+if+it+doesn%27t+already+exists%0A++++let+mut+file+%3D+File%3A%3Acreate%28file_name%29%3F%3B%0A%0A++++let+text_to_write+%3D+%22Hello%2C+World%21%5Cn%5C%0A++++++++++++++++++++++++++++This+is+a+line+of+text.%5Cn%22%3B%0A++++file.write_all%28text_to_write.as_bytes%28%29%29%3F%3B%0A%0A++++let+absolute_path+%3D+fs%3A%3Acanonicalize%28file_name%29%3F%3B%0A++++println%21%28%22Text+has+been+written+to%3A+%7B%3A%3F%7D%22%2C+absolute_path%29%3B%0A%0A++++return+Ok%28%28%29%29%3B%0A%7D%0A
- title: System Arguments
content_markdown: >
A Rust program is able to receive `input` from the in-line arguments.
In order to do so, open a [terminal](https://www.youtube.com/watch?v=lZ7Kix9bjPI), compile it and pass the arguments to the executable in the command promt.
These arguments might be relevant files, flags and so on.
The developer must document their purpose.
If you are using LINUX or macOS, bear in mind these commands:
```bash
$ touch main.rs
$ rustc main.rs
$ ./main.rs 2 3 4 5
```
Otherwise, for Windows environment, on a PowerShell and paste them
```PowerShell
> echo. > main.rs
> rustc main.rs
> .\main.exe 2 3 4 5
```
> Notice that the first argument is the executable itself
code: >-
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=use+std%3A%3Aenv%3B+++++++%2F%2F+env+stands+for+environment%0A%0Afn+main%28%29+%7B%0A++++let+args%3A+Vec%3CString%3E+%3D+env%3A%3Aargs%28%29.collect%28%29%3B%0A++++println%21%28%22number+of+arguments+%3D+%7B%7D%22%2C+args.len%28%29%29%3B%0A++++println%21%28%22the+inline+arguments+are+%3A+%7B%3A%3F%7D%22%2C+args%29%3B%0A%7D%0A
- title: Environment Variables
content_markdown: >
You've seen that the Rust standard library grants access to the system.
Using the `std::env` module, you can do in Rust some task that might require
a UNIX terminal, such as:
- command line arguments
- printing the current working directory
- current executable path
- working with environmental variables
- working with files and directories
code: >-
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=use+std%3A%3Aenv%3B+++%2F%2F+for+interacting+with+the+system%27s+environment%0A%0Afn+main%28%29+%7B%0A%0A++++if+let+Ok%28current_dir%29+%3D+env%3A%3Acurrent_dir%28%29+%7B%0A++++++++if+let+Some%28pwd%29+%3D+current_dir.to_str%28%29+%7B%0A++++++++++++println%21%28%22The+current+working+directory+%3D+%7B%7D%22%2C+pwd%29%3B%0A++++++++%7D%0A++++%7D%0A%0A++++%2F%2F+%24+echo+%24PWD++++++%23+environment+variable%0A++++%2F%2F+if+you+don%27t+want+to+see+Seme%28...%29%2C+you+have+to+pattern+match+on+Ok%28%29%0A++++println%21%28%22The+current+working+directory+%3D+%7B%3A%3F%7D%22%2C+env%3A%3Avar%28%22PWD%22%29.ok%28%29%29%3B%0A%0A++++%2F%2F+%24+echo+%24PWD++++++%23+environment+variable%0A++++if+let+Ok%28pwd%29+%3D+env%3A%3Avar%28%22PWD%22%29+%7B%0A++++++++println%21%28%22The+current+working+directory+%3D+%7B%7D%22%2C+pwd%29%3B%0A++++%7D%0A%0A++++%2F%2F+%24+echo+%24USER+++++%23+environment+variable%0A++++if+let+Ok%28user%29+%3D+env%3A%3Avar%28%22USER%22%29+%7B%0A++++++++println%21%28%22The+current+user+is%3A+%7B%7D%22%2C+user%29%3B%0A++++%7D%0A%0A%0A++++%2F%2F+%24+echo+%24IDK++++++%23+I+suppose+you+didn%27t+set+this+variable+%3A%29%0A++++if+let+Err%28err%29+%3D+env%3A%3Avar%28%22IDK%22%29+%7B%0A++++++++eprintln%21%28%22IDK+%3A+%7B%7D%22%2C+err%29%3B%0A++++++++env%3A%3Aset_var%28%22IDK%22%2C+%22%3D+I+don%27t+know%22%29%3B%0A++++++++println%21%28%22IDK+%3D+%7B%3A%3F%7D%22%2C+env%3A%3Avar%28%22IDK%22%29.ok%28%29%29%3B%0A++++++++env%3A%3Aremove_var%28%22IDK%22%29%3B%0A++++%7D%0A%7D%0A
- title: Chapter 10 - Conclusion
content_markdown: >
Now that you know the basic of Input/Output operations, you used just two
Rust libraries along the way, and they are standard, by the way: `std::env` and `std::fs`.
Now, you can build your own file managing system, Web App or even API.
Checkout these resources:
- [Environment Variables](https://youtu.be/npsMN-tZNVs)
- [Rust API](https://youtu.be/_ccDqRTx-JU)