cargo-equip

CI codecov unsafe forbidden Crates.io Crates.io

English

競技プログラミング用にRustコードを一つの.rsファイルにバンドルするCargoサブコマンドです。

Point Add Range Sum - Library-Cheker

lib

toml [package.metadata.cargo-equip-lib.mod-dependencies] "algebraic" = [] "fenwick" = ["algebraic"] "input" = [] "output" = []

bin

toml [dependencies] __lib = { package = "lib", path = "/path/to/lib" }

```rust

[cfgattr(cargoequip, cargo_equip::equip)]

use ::__lib::{fenwick::AdditiveFenwickTree, input, output};

use std::io::Write as _;

fn main() { input! { n: usize, q: usize, r#as: [i64; n], }

let mut fenwick = AdditiveFenwickTree::new(n);

for (i, a) in r#as.into_iter().enumerate() {
    fenwick.plus(i, &a);
}

output::buf_print(|out| {
    macro_rules! println(($($tt:tt)*) => (writeln!(out, $($tt)*).unwrap()));
    for _ in 0..q {
        input!(kind: u32);
        match kind {
            0 => {
                input!(p: usize, x: i64);
                fenwick.plus(p, &x);
            }
            1 => {
                input!(l: usize, r: usize);
                println!("{}", fenwick.query(l..r));
            }
            _ => unreachable!(),
        }
    }
});

} ```

console $ cargo equip --oneline mods --rustfmt --check -o ./bundled.rs Bundling code Checking cargo-equip-check-output-b6yi355fkyhc37tj v0.1.0 (/tmp/cargo-equip-check-output-b6yi355fkyhc37tj) Finished dev [unoptimized + debuginfo] target(s) in 0.18s

https://judge.yosupo.jp/submission/21202

インストール

Crates.io

console $ cargo install cargo-equip

master

console $ cargo install --git https://github.com/qryxip/cargo-equip

GitHub Releases

バイナリでの提供もしています。

使い方

まずライブラリをこのように横に広く作ってください。 深さ2以上のモジュールはinline module (mod { .. })として書いてください。

src ├── a.rs ├── b.rs ├── c.rs └── lib.rs

rust // src/lib.rs pub mod a; pub mod b; pub mod c;

次にライブラリのCargo.tomlpackage.metadataにモジュールの依存関係を手で書いてください。 欠けている場合はwarningと共にすべてのモジュールを展開します。

使う側で指定できるようにすることも考えています

toml [package.metadata.cargo-equip-lib.mod-dependencies] "a" = [] "b" = ["a"] "c" = ["a"]

そしてbin側の準備として、バンドルしたいライブラリをdependenciesに加えてください。

toml [dependencies] __my_lib = { package = "my_lib", path = "/path/to/my_lib" }

ただしこの際、ライブラリは誤って直接使わないようにリネームしておくことを強く推奨します。 直接使った場合cargo-equipはそれについて何も操作しません。

準備ができたらこのようにライブラリをuseします。

```rust

[cfgattr(cargoequip, cargo_equip::equip)]

use ::_mylib::{b::B, c::C}; ```

useのパスにはleading colon (::)を付けてください。

```

[cfgattr(cargoequip, cargo_equip::equip)]

use ::_mylib::{b::B, c::C}; ^^ ```

パスの1つ目のsegmentから展開するべきライブラリを決定します。 leading colonを必須としているのはこのためです。

```

[cfgattr(cargoequip, cargo_equip::equip)]

use ::_mylib::{b::B, c::C}; ^^^^^^^^ ```

パスの2つ目のsegmentから使用しているモジュールを判定します。 これらのモジュールと、先程書いたmod-dependenciesで繋がっているモジュールが展開されます。

```

[cfgattr(cargoequip, cargo_equip::equip)]

use ::_mylib::{b::B, c::C}; ^ ^ ```

パスの3つ目以降のsegmentはuse self::$name::{ .. }として展開されます。

```

[cfgattr(cargoequip, cargo_equip::equip)]

use ::_mylib::{b::B, c::C}; ^ ^ ```

コードが書けたらcargo equipで展開します。 --bin {binの名前}--src {binのファイルパス}binを指定してください。 パッケージ内のbinが一つの場合は省略できます。 ただしdefault-runには未対応です。

console $ cargo equip --bin "$name"

コードはこのように展開されます。

``rust //! # Bundled libraries //! //! ## [mylib]({ a link to Crates.io or the repository }) //! //! ### Modules //! //! -::mylib::a$crate::a //! -::mylib::b$crate::b //! -::mylib::c$crate::c`

/#[cfg_attr(cargo_equip, cargo_equip::equip)] use ::__my_lib::{b::B, c::C};/

fn main() { todo!(); }

// The following code was expanded by cargo-equip.

use self::b::B; use self::c::C;

// bcで使われているとmod-dependenciesに記述されているため、展開される mod a { // .. }

mod b { // .. }

mod c { // .. } ```

モジュールの階層が変わらないため、各ファイルの中身を手を加えずにそのまま展開します。 そのため壊れにくくなっているはずです。 多分。

またライブラリ内の#[macro_export]しているマクロですが、マクロ名と同名のモジュールに入れておくと自然な形で使えると思います。

```rust // input.rs

[macro_export]

macrorules! input { ($($tt:tt)*) => { compileerror!("TODO") }; } ```

```rust

[cfgattr(cargoequip, cargo_equip::equip)]

use ::_mylib::input; ```

オプション

--oneline

--oneline modsで展開後の各モジュールをそれぞれ一行に折り畳みます。 --oneline allでコード全体を一行に折り畳みます。

トークン列を" "区切りで出力しているだけなので、minificationではありません。

--rustfmt

出力をRustfmtでフォーマットします。

--check

バンドルしたコードを出力する前にtarget directoryを共有した一時パッケージを作り、それの上でcargo checkします。

console $ cargo equip --check -o /dev/null Bundling code Checking cargo-equip-check-output-r3cw9cy0swqb5yac v0.1.0 (/tmp/cargo-equip-check-output-r3cw9cy0swqb5yac) Finished dev [unoptimized + debuginfo] target(s) in 0.18s

ライセンス

MIT or Apache-2.0のデュアルライセンスです。