Skip to content

최신 예제로 배우는 러스트로 업데이트 (#7) #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 34 additions & 11 deletions .github/workflows/gh-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,46 @@ on:
push:
branches:
- main
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

jobs:
deploy:
runs-on: ubuntu-18.04
build:
#runs-on: ubuntu-18.04 # deprecated
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Checkout
uses: actions/checkout@v2

- name: Setup mdBook
uses: peaceiris/actions-mdbook@v1
uses: peaceiris/actions-mdbook@v2
with:
mdbook-version: '0.4.6'
# mdbook-version: 'latest'
# mdbook-version: '0.4.6'
mdbook-version: 'latest'

- run: mdbook build
- name: Build Rust by Example
run: mdbook build

- name: Deploy
uses: peaceiris/actions-gh-pages@v3
- name: Upload artifact
#uses: peaceiris/actions-gh-pages@v3
#with:
# github_token: ${{ secrets.GITHUB_TOKEN }}
# publish_dir: ./book
uses: actions/upload-pages-artifact@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./book
path: ./book

deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
4 changes: 2 additions & 2 deletions book.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[book]
title = "예제로 배우는 러스트 (Rust by Example) 한국어판"
description = "A description"
author = "The Rust Community"
description = "예제로 배우는 러스트 (Rust by Example)의 한국어판입니다."
author = "러스트 한국 커뮤니티"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/rust-kr/ org의 이름과 일치시키는 편이 좋겠습니다.

Suggested change
author = "러스트 한국 커뮤니티"
author = "한국 러스트 사용자 그룹"


[output.html.playpen]
editable = true
Expand Down
9 changes: 7 additions & 2 deletions src-en/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,14 @@
- [match](flow_control/match.md)
- [Destructuring](flow_control/match/destructuring.md)
- [tuples](flow_control/match/destructuring/destructure_tuple.md)
- [arrays/slices](flow_control/match/destructuring/destructure_slice.md)
- [enums](flow_control/match/destructuring/destructure_enum.md)
- [pointers/ref](flow_control/match/destructuring/destructure_pointers.md)
- [structs](flow_control/match/destructuring/destructure_structures.md)
- [Guards](flow_control/match/guard.md)
- [Binding](flow_control/match/binding.md)
- [if let](flow_control/if_let.md)
- [let-else](flow_control/let_else.md)
- [while let](flow_control/while_let.md)

- [Functions](fn.md)
Expand Down Expand Up @@ -154,10 +156,12 @@

- [Error handling](error.md)
- [`panic`](error/panic.md)
- [`abort` & `unwind`](error/abort_unwind.md)
- [`Option` & `unwrap`](error/option_unwrap.md)
- [Unpacking options with `?`](error/option_unwrap/question_mark.md)
- [Combinators: `map`](error/option_unwrap/map.md)
- [Combinators: `and_then`](error/option_unwrap/and_then.md)
- [Defaults: `or`, `or_else`, `get_or_insert`, `get_or_insert_with`](error/option_unwrap/defaults.md)
- [`Result`](error/result.md)
- [`map` for `Result`](error/result/result_map.md)
- [aliases for `Result`](error/result/result_alias.md)
Expand Down Expand Up @@ -193,7 +197,7 @@
- [File I/O](std_misc/file.md)
- [`open`](std_misc/file/open.md)
- [`create`](std_misc/file/create.md)
- [`read lines`](std_misc/file/read_lines.md)
- [`read_lines`](std_misc/file/read_lines.md)
- [Child processes](std_misc/process.md)
- [Pipes](std_misc/process/pipe.md)
- [Wait](std_misc/process/wait.md)
Expand All @@ -209,10 +213,11 @@
- [Dev-dependencies](testing/dev_dependencies.md)

- [Unsafe Operations](unsafe.md)
- [Inline assembly](unsafe/asm.md)

- [Compatibility](compatibility.md)
- [Raw identifiers](compatibility/raw_identifiers.md)

- [Meta](meta.md)
- [Documentation](meta/doc.md)
- [Playpen](meta/playpen.md)
- [Playground](meta/playground.md)
36 changes: 33 additions & 3 deletions src-en/attribute.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,38 @@ can be used to/for:
* link to a foreign library
* mark functions as unit tests
* mark functions that will be part of a benchmark
* [attribute like macros][macros]

When attributes apply to a whole crate, their syntax is `#![crate_attribute]`,
and when they apply to a module or item, the syntax is `#[item_attribute]`
(notice the missing bang `!`).
Attributes look like `#[outer_attribute]` or `#![inner_attribute]`,
with the difference between them being where they apply.

* `#[outer_attribute]` applies to the [item][item] immediately
following it. Some examples of items are: a function, a module
declaration, a constant, a structure, an enum. Here is an example
where attribute `#[derive(Debug)]` applies to the struct
`Rectangle`:

```rust
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
```

* `#![inner_attribute]` applies to the enclosing [item][item] (typically a
module or a crate). In other words, this attribute is interpreted as
applying to the entire scope in which it's placed. Here is an example
where `#![allow(unused_variables)]` applies to the whole crate (if
placed in `main.rs`):

```rust
#![allow(unused_variables)]

fn main() {
let x = 3; // This would normally warn about an unused variable.
}
```

Attributes can take arguments with different syntaxes:

Expand All @@ -35,4 +63,6 @@ Attributes can have multiple values and can be separated over multiple lines, to

[cfg]: attribute/cfg.md
[crate]: attribute/crate.md
[item]: https://doc.rust-lang.org/stable/reference/items.html
[lint]: https://en.wikipedia.org/wiki/Lint_%28software%29
[macros]: https://doc.rust-lang.org/book/ch19-06-macros.html#attribute-like-macros
2 changes: 2 additions & 0 deletions src-en/attribute/cfg.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ While the former enables conditional compilation, the latter conditionally
evaluates to `true` or `false` literals allowing for checks at run-time. Both
utilize identical argument syntax.

`cfg!`, unlike `#[cfg]`, does not remove any code and only evaluates to true or false. For example, all blocks in an if/else expression need to be valid when `cfg!` is used for the condition, regardless of what `cfg!` is evaluating.

```rust,editable
// This function only gets compiled if the target OS is linux
#[cfg(target_os = "linux")]
Expand Down
6 changes: 3 additions & 3 deletions src-en/cargo/conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ foo
└── my_other_bin.rs
```

To tell `cargo` to compile or run this binary as opposed to the default or other
binaries, we just pass `cargo` the `--bin my_other_bin` flag, where `my_other_bin`
is the name of the binary we want to work with.
To tell `cargo` to only compile or run this binary, we just pass `cargo` the
`--bin my_other_bin` flag, where `my_other_bin` is the name of the binary we
want to work with.

In addition to extra binaries, `cargo` supports [more features] such as
benchmarks, tests, and examples.
Expand Down
25 changes: 14 additions & 11 deletions src-en/cargo/deps.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ To create a new Rust project,
# A binary
cargo new foo

# OR A library
cargo new --lib foo
# A library
cargo new --lib bar
```

For the rest of this chapter, let's assume we are making a binary, rather than
Expand All @@ -21,14 +21,19 @@ a library, but all of the concepts are the same.
After the above commands, you should see a file hierarchy like this:

```txt
foo
├── Cargo.toml
└── src
└── main.rs
.
├── bar
│ ├── Cargo.toml
│ └── src
│ └── lib.rs
└── foo
├── Cargo.toml
└── src
└── main.rs
```

The `main.rs` is the root source file for your new project -- nothing new there.
The `Cargo.toml` is the config file for `cargo` for this project (`foo`). If you
The `main.rs` is the root source file for your new `foo` project -- nothing new there.
The `Cargo.toml` is the config file for `cargo` for this project. If you
look inside it, you should see something like this:

```toml
Expand Down Expand Up @@ -56,8 +61,7 @@ lots of great packages on [crates.io](https://crates.io) (the official Rust
package registry). One popular choice is [clap](https://crates.io/crates/clap).
As of this writing, the most recent published version of `clap` is `2.27.1`. To
add a dependency to our program, we can simply add the following to our
`Cargo.toml` under `[dependencies]`: `clap = "2.27.1"`. And of course, `extern
crate clap` in `main.rs`, just like normal. And that's it! You can start using
`Cargo.toml` under `[dependencies]`: `clap = "2.27.1"`. And that's it! You can start using
`clap` in your program.

`cargo` also supports [other types of dependencies][dependencies]. Here is just
Expand Down Expand Up @@ -87,6 +91,5 @@ rebuilds what it has not already built, similar to `make`).

Voila! That's all there is to it!


[manifest]: https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html
102 changes: 95 additions & 7 deletions src-en/cargo/test.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

As we know testing is integral to any piece of software! Rust has first-class
support for unit and integration testing ([see this
chapter](https://doc.rust-lang.org/book/ch11-00-testing.html) in
TRPL).
chapter](https://doc.rust-lang.org/book/ch11-00-testing.html) in TRPL).

From the testing chapters linked above, we see how to write unit tests and
integration tests. Organizationally, we can place unit tests in the modules they
Expand All @@ -14,12 +13,19 @@ foo
├── Cargo.toml
├── src
│ └── main.rs
│ └── lib.rs
└── tests
├── my_test.rs
└── my_other_test.rs
```

Each file in `tests` is a separate integration test.
Each file in `tests` is a separate
[integration test](https://doc.rust-lang.org/book/ch11-03-test-organization.html#integration-tests),
i.e. a test that is meant to test your library as if it were being called from a dependent
crate.

The [Testing][testing] chapter elaborates on the three different testing styles:
[Unit][unit_testing], [Doc][doc_testing], and [Integration][integration_testing].

`cargo` naturally provides an easy way to run all of your tests!

Expand All @@ -35,13 +41,13 @@ $ cargo test
Finished dev [unoptimized + debuginfo] target(s) in 0.89 secs
Running target/debug/deps/blah-d3b32b97275ec472

running 3 tests
running 4 tests
test test_bar ... ok
test test_baz ... ok
test test_foo_bar ... ok
test test_foo ... ok

test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
```

You can also run tests whose name matches a pattern:
Expand All @@ -64,5 +70,87 @@ test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out
```

One word of caution: Cargo may run multiple tests concurrently, so make sure
that they don't race with each other. For example, if they all output to a
file, you should make them write to different files.
that they don't race with each other.

One example of this concurrency causing issues is if two tests output to a
file, such as below:

```rust
#[cfg(test)]
mod tests {
// Import the necessary modules
use std::fs::OpenOptions;
use std::io::Write;

// This test writes to a file
#[test]
fn test_file() {
// Opens the file ferris.txt or creates one if it doesn't exist.
let mut file = OpenOptions::new()
.append(true)
.create(true)
.open("ferris.txt")
.expect("Failed to open ferris.txt");

// Print "Ferris" 5 times.
for _ in 0..5 {
file.write_all("Ferris\n".as_bytes())
.expect("Could not write to ferris.txt");
}
}

// This test tries to write to the same file
#[test]
fn test_file_also() {
// Opens the file ferris.txt or creates one if it doesn't exist.
let mut file = OpenOptions::new()
.append(true)
.create(true)
.open("ferris.txt")
.expect("Failed to open ferris.txt");

// Print "Corro" 5 times.
for _ in 0..5 {
file.write_all("Corro\n".as_bytes())
.expect("Could not write to ferris.txt");
}
}
}
```

Although the intent is to get the following:

```shell
$ cat ferris.txt
Ferris
Ferris
Ferris
Ferris
Ferris
Corro
Corro
Corro
Corro
Corro
```

What actually gets put into `ferris.txt` is this:

```shell
$ cargo test test_file && cat ferris.txt
Corro
Ferris
Corro
Ferris
Corro
Ferris
Corro
Ferris
Corro
Ferris
```

[testing]: ../testing.md
[unit_testing]: ../testing/unit_testing.md
[integration_testing]: ../testing/integration_testing.md
[doc_testing]: ../testing/doc_testing.md
2 changes: 1 addition & 1 deletion src-en/compatibility.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Compatibility

The Rust language is fastly evolving, and because of this certain compatibility
The Rust language is evolving rapidly, and because of this certain compatibility
issues can arise, despite efforts to ensure forwards-compatibility wherever
possible.

Expand Down
Loading