🧊

Rustのモジュールとディレクトリの関係のおさらい

Rust 2018 Editionです。

Rustのモジュールの使い方 2018 Edition版 | κeenのHappy Hacκing Blog

なおこちらの偉大な先人の記事がスッと頭に入る人は、このメモを読む必要ないです。

こういうディレクトリ構造にしたかった

RustでReact的なコードが書ける`yew`を試してたとき、無性にディレクトリ構造を整理したくなって。

.
├── app.rs
├── component
│   └── header.rs
└── main.rs

JavaScriptでやってるときと同じような感じにしたい。

ただ愚直にこう配置しても、Rustではパスが通せずコンパイルできなかった。

冒頭の記事を読み直したり、あれこれ野良リポジトリを漁ったりした結果、できたのがコレ。

こうする

.
├── app.rs
├── component
│   ├── header.rs
│   └── mod.rs
└── main.rs

もしくは、

.
├── app.rs
├── component
│   └── header.rs
├── component.rs
└── main.rs

ディレクトリを切っただけでは何も起こらないので、それを指し示す存在が必要。

上の例だと`mod.rs`がそれ、下の例だと`component.rs`がそれで、結果的には同じ。
`mod.rs`は2015 Editionの遺産だそうですが、ディレクトリにすべてしまっちゃいたい場合はこれしかなさそう。

`component/mod.rs`にはこう書く。

// component/mod.rs
pub mod header;

`component`ディレクトリ配下のものをよしなにexportする。

`main.rs`が重要

ここから辿れないものは、ファイルとして存在していようとも、コンパイルできない。

// main.rs
mod app;
mod component;

fn main() {
    yew::start_app::<app::App>();
}

`mod component`が重要。
こうしておかないと、`app.rs`から`component`配下が参照できない。

`app.rs`にはこう書く。

// app.rs
use crate::component::header::Header;

// ...

impl Component for App {

// ...

  fn view(&self) -> Html {
    // ...

    html! {
      <div>
        <Header />
      </div>
    }
  }
}

`crate::`で、このプロジェクトのルートから辿ることができる。

`lib.rs`を置いてもいい

上の例で`main.rs`に書いてたものを、`lib.rs`を作って書くこともできる!

// lib.rs
mod app;
mod component;

pub use app::App;

こうすると、`App`だけをexportできる!

`main.rs`はこうなる。

// main.rs
use yew_todo::App;

fn main() {
    yew::start_app::<App>();
}

`yew_todo`のところは、`cargo new`するときに指定した実際のプロジェクト名。