#竞争 #Windows #范围

bin+lib cargo-equip

Cargo 子命令,用于将您的代码打包成一个 .rs 文件进行竞技编程

39 个不稳定版本

0.20.1 2023年8月6日
0.19.0 2022年3月26日
0.18.1 2021年12月23日
0.18.0 2021年9月7日
0.9.0 2020年11月27日

#200Cargo 插件

MIT/Apache

205KB
4.5K SLoC

cargo-equip

CI codecov dependency status Crates.io Crates.io

日语

Cargo 子命令,用于将您的代码打包成一个 .rs 文件进行竞技编程。

近期更新

请参阅 CHANGELOG.md发布 了解最近更新。

功能

cargo-equip 可以

  • 打包多个包
  • 只打包使用过的包
  • 排除某些包 (--exclude-{atcoder, codingame}-crates)
  • 展开过程宏
  • 保留 #[macro_export] 宏的作用域
  • 解析 #[cfg(..)]
  • 移除注释和文档注释 (--remove)
  • 压缩代码 (--minify)
  • 并检查输出

示例

平方根模 - 库检查器

[package]
name = "library-checker"
version = "0.0.0"
edition = "2018"

[dependencies]
ac-library-rs-parted-modint = { git = "https://github.com/qryxip/ac-library-rs-parted" }
proconio = { version = "0.4.3", features = ["derive"] }
qryxip-competitive-tonelli-shanks = { git = "https://github.com/qryxip/competitive-programming-library" }
# ...
use acl_modint::ModInt;
use proconio::{fastout, input};
use tonelli_shanks::ModIntBaseExt as _;

#[fastout]
fn main() {
    input! {
        yps: [(u32, u32)],
    }

    for (y, p) in yps {
        ModInt::set_modulus(p);
        if let Some(x) = ModInt::new(y).sqrt() {
            println!("{}", x);
        } else {
            println!("-1");
        }
    }
}

mod sub {
    // You can also `use` the crate in submodules.

    #[allow(unused_imports)]
    use proconio::input as _;
}

 cargo equip \
>       --remove docs `# Remove doc comments` \
>       --minify libs `# Minify each library` \
>       --bin sqrt_mod `# Specify the bin crate` | xsel -b

提交信息 #59239 - 库检查器

兼容

安装

首先安装 nightly 工具链和 cargo-udeps

 rustup update nightly
 cargo install cargo-udeps

从 Crates.io

 cargo install cargo-equip

master 分支

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

GitHub 发布

发布

用法

在编写用于打包的库时,请遵循以下约定。

  1. package.edition 设置为 "2018"

    "2015" 不受支持。

  2. lib包中不要使用过程宏。

    你可以使用它们,但不能调用。

  3. 在宏中使用$crate代替crate

    cargo-equip将宏中的$crate替换为$crate::extern_crate_name_in_main_crate。宏中的crate标识符不会被修改。

  4. 尽可能不要使用绝对路径。

    cargo-equip将crate替换为crate::extern_crate_name_in_main_crate,并将pub(crate)替换为pub(in crate::extern_crate_name_in_main_crate)

    然而,我无法保证这会很好地工作。使用self::super::代替crate::

    -use crate::foo::Foo;
    +use super::foo::Foo;
    
  5. 如果可能,不要使用glob导入

    cargo-equip将glob导入作为extern预导入#[macro_use]的替代。

  6. 尽可能将它们分成小的单独包。

    cargo-equip不会搜索"项目之间的依赖关系"。

    在AtCoder以外的网站上,将你的库拆分成小的包以适应64KiB。

    .
    ├── a
       ├── Cargo.toml
       └── src
           └── lib.rs
    ├── b
       ├── Cargo.toml
       └── src
           └── lib.rs
    
    

当你准备好你的库包后,将它们添加到[dependencies]bin/example中。如果你使用工具自动生成包,请将其添加到其模板中。

如果你想使用rust-lang-ja/ac-library-rs,请使用qryxip/ac-library-rs-parted

[dependencies]
ac-library-rs-parted             = { git = "https://github.com/qryxip/ac-library-rs-parted" }
ac-library-rs-parted-convolution = { git = "https://github.com/qryxip/ac-library-rs-parted" }
ac-library-rs-parted-dsu         = { git = "https://github.com/qryxip/ac-library-rs-parted" }
ac-library-rs-parted-fenwicktree = { git = "https://github.com/qryxip/ac-library-rs-parted" }
ac-library-rs-parted-lazysegtree = { git = "https://github.com/qryxip/ac-library-rs-parted" }
ac-library-rs-parted-math        = { git = "https://github.com/qryxip/ac-library-rs-parted" }
ac-library-rs-parted-maxflow     = { git = "https://github.com/qryxip/ac-library-rs-parted" }
ac-library-rs-parted-mincostflow = { git = "https://github.com/qryxip/ac-library-rs-parted" }
ac-library-rs-parted-modint      = { git = "https://github.com/qryxip/ac-library-rs-parted" }
ac-library-rs-parted-scc         = { git = "https://github.com/qryxip/ac-library-rs-parted" }
ac-library-rs-parted-segtree     = { git = "https://github.com/qryxip/ac-library-rs-parted" }
ac-library-rs-parted-string      = { git = "https://github.com/qryxip/ac-library-rs-parted" }
ac-library-rs-parted-twosat      = { git = "https://github.com/qryxip/ac-library-rs-parted" }

二进制文件/示例的约束条件是

  1. 如果你使用proc-macro包,请确保宏名称是唯一的。

    如果你在过程宏名称上遇到困难,你可以使用#[macor_use].导入它们。

  2. 如果可能,不要使用glob导入。

    cargo-equip也会像在库中做的那样插入glob导入。

    pub use __cargo_equip::prelude::*;
    
    //
    
    pub mod __cargo_equip {
        pub mod crates {
            //
        }
        //
    
        pub(crate) prelude {
            pub use crate::__cargo_equip::crates::*;
        }
    }
    
use input::input;
use mic::answer;
use partition_point::RangeBoundsExt as _;

#[answer(join("\n"))]
fn main() -> _ {
    input! {
        a: [u64],
    }
    a.into_iter()
        .map(|a| (1u64..1_000_000_000).partition_point(|ans| ans.pow(2) < a))
}

然后执行cargo-equip

 cargo equip --bin "$name"

解析#[cfg()]

默认情况下,cargo-equip

  1. 移除 #[cfg(always_true_predicate)](例如:cfg(feature = "enabled-feature"))。
  2. 移除带有 #[cfg(always_false_preducate)](例如:cfg(test)cfg(feature = "disable-feature"))的项目。

谓词将根据此规则进行评估。

  • testfalse
  • proc_macrofalse
  • cargo_equiptrue
  • feature:对已启用的功能为 true
  • 否则:未知
#[allow(dead_code)]
pub mod a {
    pub struct A;

    #[cfg(test)]
    mod tests {
        #[test]
        fn it_works() {
            assert_eq!(2 + 2, 4);
        }
    }
}

#[allow(dead_code)]
pub mod a {
    pub struct A;
}

检查输出

默认情况下,cargo-equip 创建一个与当前目标目录共享的临时包,并在输出之前执行 cargo check

    Checking cargo-equip-check-output-6j2i3j3tgtugeaqm v0.1.0 (/tmp/cargo-equip-check-output-6j2i3j3tgtugeaqm)
    Finished dev [unoptimized + debuginfo] target(s) in 0.11s

展开过程宏

cargo-equip 可以展开过程宏。

use memoise::memoise;
use proconio_derive::fastout;

#[fastout]
fn main() {
    for i in 0..=10 {
        println!("{}", fib(i));
    }
}

#[memoise(n <= 10)]
fn fib(n: i64) -> i64 {
    if n == 0 || n == 1 {
        return n;
    }
    fib(n - 1) + fib(n - 2)
}
  • proc-macro 包需要使用 Rust 1.48.0+ 编译。如果活动工具链的版本低于 1.48.0,则 cargo-equip 会找到替代工具链并使用它来编译 proc-macro
  • 使用 pub use $name::*; 重导出的过程宏也可以展开。

选项

--remove<REMOVE>...

移除

  • 文档注释(//! ../// ../** .. */#[doc = ".."])使用 --remove docs
  • 注释(// ../* .. */)使用 --remove comments
#[allow(dead_code)]
pub mod a {
    //! A.

    /// A.
    pub struct A; // aaaaa
}

#[allow(dead_code)]
pub mod a {
    pub struct A;
}

--minify<MINIFY>

精简

  • 使用 --minify lib 对每个展开的库进行精简。
  • 使用 --minify all 对整个代码进行精简。

请注意,精简功能尚不完整。可能会插入不必要的空格。

--no-resolve-cfgs

不要解析 #[cfg()]

--no-rustfmt

不要格式化输出。

--no-check

不要检查输出。

许可证

MIT或Apache-2.0双许可。

依赖项

~14–25MB
~345K SLoC