Skip to content

Commit

Permalink
Merge pull request #20 from lyonnee/pref_view
Browse files Browse the repository at this point in the history
添加和修改ferris的渲染
  • Loading branch information
lispking authored May 17, 2024
2 parents 9fff91b + 6ea93e1 commit 590881e
Show file tree
Hide file tree
Showing 17 changed files with 94 additions and 26 deletions.
4 changes: 2 additions & 2 deletions book.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ title = "Effective Rust 中文版"

[output.html]
default-theme = "rust"
additional-css = [ "style/css/ferris.css" ]
additional-js = [ "style/js/tongji.js" ]
additional-css = ["style/css/ferris.css"]
additional-js = ["style/js/tongji.js","style/js/ferris.js"]
8 changes: 4 additions & 4 deletions src/chapter_1/builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ let dizzy = Details {

还有一个更普遍的问题:仅当所有的字段类型都实现了 `Default` trait 的时候,结构体才能使用自动派生的 `Default` 实现。如果有任何一个字段不满足,那么 `derive` 就会失败了:

<div class="ferris"><img src="../images/does_not_compile.svg" width="75" height="75" /></div>
<div class="ferris"><img src="../images/ferris/does_not_compile.svg" width="75" height="75" /></div>

```rust
#[derive(Debug, Default)]
Expand Down Expand Up @@ -151,7 +151,7 @@ pub fn build(self) -> Details {

总而言之,这让构造器的使用者拥有了更符合工程学的体验:

<div class="ferris"><img src="../images/does_not_compile.svg" width="75" height="75" /></div>
<div class="ferris"><img src="../images/ferris/does_not_compile.svg" width="75" height="75" /></div>

```rust
let also_bob = DetailsBuilder::new(
Expand Down Expand Up @@ -221,7 +221,7 @@ let bob = builder.build();
构造器的性质带来的另一个问题是你只能构造一个最终对象,对同一个构造器重复调用 `build()` 函数来创建多个实例会违反编译器的检查规则,如同你能想到的那样:
<div class="ferris"><img src="../images/does_not_compile.svg" width="75" height="75" /></div>
<div class="ferris"><img src="../images/ferris/does_not_compile.svg" width="75" height="75" /></div>
```rust
let smithy = DetailsBuilder::new(
Expand Down Expand Up @@ -274,7 +274,7 @@ let bob = builder.build();
然而,这个版本的实现使得构造器的构造方法和它的 `setter` 函数无法被链式调用:
<div class="ferris"><img src="../images/does_not_compile.svg" width="75" height="75" /></div>
<div class="ferris"><img src="../images/ferris/does_not_compile.svg" width="75" height="75" /></div>
```rust
let builder = DetailsBuilder::new(
Expand Down
6 changes: 2 additions & 4 deletions src/chapter_1/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,7 @@ pub fn first_line(filename: &str) -> Result<String, MyError> {

将子错误信息编码为 [trait 对象]避免了为每种可能性都有一个`枚举`变体的需要,但擦除了特定基础错误类型的细节。接收此类对象的调用者将能够访问 `Error` 特征及其特征约束的方法 —— `source()``Display::fmt()``Debug::fmt()`,依次类推 —— 但不会知道子错误原始的静态类型:


<div class="ferris"><img src="../images/not_desired_behavior.svg" width="75" height="75" /></div>
<div class="ferris"><img src="../images/ferris/not_desired_behavior.svg" width="75" height="75" /></div>

```rust
#[derive(Debug)]
Expand All @@ -273,8 +272,7 @@ impl std::fmt::Display for WrappedError {

这意味着可以从一个内部的 `WrappedError` 创建一个 `WrappedError`,因为 `WrappedError` 实现了 `Error`,并且这与 `From` 的泛反射实现冲突:


<div class="ferris"><img src="../images/does_not_compile.svg" width="75" height="75" /></div>
<div class="ferris"><img src="../images/ferris/does_not_compile.svg" width="75" height="75" /></div>

```rust
impl Error for WrappedError {}
Expand Down
2 changes: 1 addition & 1 deletion src/chapter_1/transform.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ struct InputData {

这个结构上的一个方法尝试将有效载荷传递给一个加密函数,该函数的签名是 `(&[u8]) -> Vec<u8>`,如果简单地尝试获取一个引用,则会失败:

<div class="ferris"><img src="../images/does_not_compile.svg" width="75" height="75" /></div>
<div class="ferris"><img src="../images/ferris/does_not_compile.svg" width="75" height="75" /></div>

```rust
impl InputData {
Expand Down
4 changes: 2 additions & 2 deletions src/chapter_1/use-types-2.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ println!("op = {:p}", op);
这段代码无法编译!

<div class="ferris"><img src="../images/does_not_compile.svg" width="75" height="75" /></div>
<div class="ferris"><img src="../images/ferris/does_not_compile.svg" width="75" height="75" /></div>

```rust
let op1 = sum;
Expand Down Expand Up @@ -130,7 +130,7 @@ assert_eq!(data, vec![3, 4, 5,]);

这段代码无法编译!

<div class="ferris"><img src="../images/does_not_compile.svg" width="75" height="75" /></div>
<div class="ferris"><img src="../images/ferris/does_not_compile.svg" width="75" height="75" /></div>

```rust
let amount_to_add = 3;
Expand Down
4 changes: 2 additions & 2 deletions src/chapter_1/use-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ error[E0308]: mismatched types
Rust 枚举的类型安全性在 `match` 表达式中继续体现出以下这段代码无法编译:

<div class="ferris"><img src="../images/does_not_compile.svg" width="75" height="75" /></div>
<div class="ferris"><img src="../images/ferris/does_not_compile.svg" width="75" height="75" /></div>

```rust
let msg = match code {
Expand Down Expand Up @@ -199,7 +199,7 @@ pub enum SchedulerState {

当一个字段或参数何时有效需要通过注释来解释时,这就是一个明显的迹象表明这种情况没有发生:

<div class="ferris"><img src="../images/not_desired_behavior.svg" width="75" height="75" /></div>
<div class="ferris"><img src="../images/ferris/not_desired_behavior.svg" width="75" height="75" /></div>

```rust
struct DisplayProps {
Expand Down
5 changes: 2 additions & 3 deletions src/chapter_2/impl-drop-for-RAII.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ class ThreadSafeInt {
如果修改程序以在错误发生时提前退出函数,将会导致互斥锁保持锁定状态:
<div class="ferris"><img src="../images/not_desired_behavior.svg" width="75" height="75" /></div>
<div class="ferris"><img src="../images/ferris/not_desired_behavior.svg" width="75" height="75" /></div>
```C++
// C++ code
Expand Down Expand Up @@ -156,7 +155,7 @@ error[E0040]: explicit use of destructor method

在这里,我们需要了解一些技术细节。请注意, `Drop::drop` 方法的签名是 `drop(&mut self)` 而不是 `drop(self)` :它接收的是对象的可变引用,而不是将对象移动到方法中。如果 `Drop::drop` 像普通方法那样运行,就意味着对象在方法执行后仍然可用——尽管它的所有内部状态已经被清理完毕,资源也已释放!

<div class="ferris"><img src="../images/does_not_compile.svg" width="75" height="75" /></div>
<div class="ferris"><img src="../images/ferris/does_not_compile.svg" width="75" height="75" /></div>

```rust
{
Expand Down
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
File renamed without changes
11 changes: 7 additions & 4 deletions src/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,16 @@ Rust 的安全性也导致完全没有标题为“绝不…”的条目。如果
5. **异步 Rust**:关于使用 Rust 异步机制的建议。
6. **超出标准 Rust**:关于在超出 Rust 标准安全环境工作时的建议。

<!-- 隐藏的锚点 -->
<a id="ferris"></a>
尽管“**概念**”部分可以说是比“**类型**”部分更基础,但它故意放在第二位,以便从开始到结束阅读的读者可以先建立一些信心。
以下标记,借用了 [Rust 书]中的 Ferris,用于标识在某些方面不正确的代码。

| Ferris | 含义 |
| ------------------------------------------------------------ | ---------------------------- |
| <img src="./images/does_not_compile.svg" style="zoom:5%;" /> | 这段代码无法编译! |
| <img src="./images/not_desired_behavior.svg" style="zoom:5%;" /> | 这段代码没有产生期望的行为。 |

| Ferris | 含义 |
| ----------------------------------------------------------------------- | ---------------------------- |
| <img src="./images/ferris/does_not_compile.svg" style="zoom:5%;" /> | 这段代码无法编译! |
| <img src="./images/ferris/not_desired_behavior.svg" style="zoom:5%;" /> | 这段代码没有产生期望的行为。 |

## 致谢

Expand Down
8 changes: 4 additions & 4 deletions style/css/ferris.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
body.light .does_not_compile,
body.light .panics,
body.light .not_desired_behaviour,
body.light .not_desired_behavior,
body.rust .does_not_compile,
body.rust .panics,
body.rust .not_desired_behavior {
Expand All @@ -9,13 +9,13 @@ body.rust .not_desired_behavior {

body.coal .does_not_compile,
body.coal .panics,
body.coal .not_desired_behaviour,
body.coal .not_desired_behavior,
body.navy .does_not_compile,
body.navy .panics,
body.navy .not_desired_behaviour,
body.navy .not_desired_behavior,
body.ayu .does_not_compile,
body.ayu .panics,
body.ayu .not_desired_behaviour {
body.ayu .not_desired_behavior {
background: #501f21;
}

Expand Down
68 changes: 68 additions & 0 deletions style/js/ferris.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
var ferrisTypes = [
{
attr: 'does_not_compile',
title: 'This code does not compile!'
},
{
attr: 'panics',
title: 'This code panics!'
},
{
attr: 'not_desired_behavior',
title: 'This code does not produce the desired behavior.'
}
]

document.addEventListener('DOMContentLoaded', () => {
for (var ferrisType of ferrisTypes) {
attachFerrises(ferrisType)
}
})


function attachFerrises(type) {
var elements = document.getElementsByClassName(type.attr)

for (var codeBlock of elements) {
var lines = codeBlock.innerText.replace(/\n$/, '').split(/\n/).length
var size = 'large'
if (lines < 4) {
size = 'small'
}

var container = prepareFerrisContainer(codeBlock, size == 'small')
container.appendChild(createFerris(type, size))
}
}

function prepareFerrisContainer(element, useButtons) {
var foundButtons = element.parentElement.querySelector('.buttons')
if (useButtons && foundButtons) {
return foundButtons
}

var div = document.createElement('div')
div.classList.add('ferris-container')

element.parentElement.insertBefore(div, element)

return div
}


function createFerris(type, size) {
var a = document.createElement('a')
var a = document.createElement('a')
a.setAttribute('href', '../intro.html#ferris')
a.setAttribute('target', '_blank')

var images = document.createElement('images')
images.setAttribute('src', 'images/ferris/' + type.attr + '.svg')
images.setAttribute('title', type.title)
images.classList.add('ferris')
images.classList.add('ferris-' + size)

a.appendChild(images)

return a
}

0 comments on commit 590881e

Please sign in to comment.