A Cargo subcommand to bundle your code into one .rs file for competitive programming.
See CHANGELOG.md or Releases for recent updates.
cargo-equip can
- bundle multiple crates,
- bundle only used crates,
- exclude certain crates (
--exclude-{atcoder, codingame}-crates), - expand procedural macros,
- preserve scopes for
#[macro_export]ed macros, - resolve
#[cfg(..)], - remove comments and doc comments (
--remove), - minify code (
--minify), - and check the output.
[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 -bSubmit Info #59239 - Library-Checker
- fixedbitset 0.4.0
- lazy_static 1.4.0
- maplit 1.0.2
- memoise 0.3.2
- multimap 0.8.3
- permutohedron 0.2.4
- proconio 0.4.3
- rustc-hash 1.1.0
- smallvec 1.6.1
- strsim 0.10.0
- whiteread 0.5.0
Install a nightly toolchain and cargo-udeps first.
❯ rustup update nightly❯ cargo install cargo-udeps❯ cargo install cargo-equip❯ cargo install cargo-equip --git https://github.com/qryxip/cargo-equipFollow these constrants when you writing libraries to bundle.
-
Set
package.editionto"2018"."2015"is not supported. -
Do not use procedural macros in
libcrates.You can
pub usethem, but cannot call. -
Use
$crateinstead ofcratein macros.cargo-equip replaces
$crateinmacro_rules!with$crate::extern_crate_name_in_main_crate.crateidentifiers inmacro_rules!are not modified. -
Do not use absolute path as possible.
cargo-equip replaces
cratewithcrate::extern_crate_name_in_main_crateandpub(crate)withpub(in crate::extern_crate_name_in_main_crate).However I cannot ensure this works well. Use
self::andsuper::instead ofcrate::.-use crate::foo::Foo; +use super::foo::Foo;
-
If possible, do not use glob import.
cargo-equip inserts glob imports as substitutes for extern prelude and
#[macro_use]. -
Split into small separate crates as possible.
cargo-equip does not search "dependencies among items".
On a website other except AtCoder, Split your library into small crates to fit in 64KiB.
. ├── a │ ├── Cargo.toml │ └── src │ └── lib.rs ├── b │ ├── Cargo.toml │ └── src │ └── lib.rs ⋮
When you finish preparing your library crates, add them to [dependencies] of the bin/example.
If you generate packages automatically with a tool, add them to its template.
If you want to use rust-lang-ja/ac-library-rs, use qryxip/ac-library-rs-parted instead.
[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" }The constraints for bins/examples are:
-
If you use
proc-macrocrates, make sure the macro names unique.If you have trouble about procedural macro names, you can import them with
#[macor_use]. -
If possible, do not use glob import.
cargo-equip also inserts glob imports as it does into libraries.
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))
}Then execute cargo-equip.
❯ cargo equip --bin "$name"By default, cargo-equip
- Removes
#[cfg(always_true_predicate)](e.g.cfg(feature = "enabled-feature")). - Removes items with
#[cfg(always_false_preducate)](e.g.cfg(test),cfg(feature = "disable-feature")).
Predicates are evaluated according to this rule.
test:falseproc_macro:falsecargo_equip:truefeature:truefor those enabled- Otherwise: unknown
#[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;
}By default, cargo-equip creates a temporary package that shares the current target directory and execute cargo check before outputting.
Checking cargo-equip-check-output-6j2i3j3tgtugeaqm v0.1.0 (/tmp/cargo-equip-check-output-6j2i3j3tgtugeaqm)
Finished dev [unoptimized + debuginfo] target(s) in 0.11scargo-equip can expand procedural macros.
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-macrocrates need to be compile with Rust 1.48.0+. If version of the active toolchain is less than 1.48.0, cargo-equip finds an alternative toolchain and uses it for compilingproc-macros.- procedural macros re-exported with
pub use $name::*;are also able to be expanded.
Removes
- doc comments (
//! ..,/// ..,/** .. */,#[doc = ".."]) with--remove docs. - comments (
// ..,/* .. */) with--remove comments.
#[allow(dead_code)]
pub mod a {
//! A.
/// A.
pub struct A; // aaaaa
}↓
#[allow(dead_code)]
pub mod a {
pub struct A;
}Minifies
- each expaned library with
--minify lib. - the whole code with
--minify all.
Not that the minification function is incomplete. Unnecessary spaces may be inserted.
Do not resolve #[cfg(…)].
Do not format the output.
Do not check the output.
Dual-licensed under MIT or Apache-2.0.