sync_code/lib.rs
1//! Synchronize code blocks between different files.
2//!
3//! It can replace `macros` in certain scenarios.
4//! For example, when your code isn’t duplicated many times but the design is
5//! relatively complex (e.g., involving generics), using `sync-code` instead
6//! of a `macro` will give you much better readability and easier maintenance.
7//! Features like Go-to-definition and intelligent auto-completion also work
8//! properly without using `macros`.
9//!
10//! # Usage
11//! Run command:
12//! ```shell
13//! cargo add --build sync-code
14//! ```
15//!
16//! `build.rs`:
17//! ```rust
18//! fn main() {
19//! sync_code::Builder::new()
20//! .add("src/target1.rs", "src/source1.rs")
21//! .add("src/target2.rs", "src/source2.rs")
22//! .sync();
23//! }
24//!
25//! ```
26//!
27//! `your_code.rs`:
28//! ```rust
29//! // $sync block_name
30//!
31//! fn code_you_want_to_sync() {
32//! }
33//!
34//! // $sync end
35//! ```
36
37#![allow(clippy::needless_doctest_main)]
38mod sync;
39
40use std::path::Path;
41use sync::Sync;
42
43#[derive(Default)]
44pub struct Builder {
45 table: Vec<Sync>,
46}
47
48impl Builder {
49 pub fn new() -> Self {
50 Self::default()
51 }
52
53 pub fn add<P: AsRef<Path>>(mut self, file: P, dep_file: P) -> Self {
54 println!("cargo:rerun-if-changed={}", dep_file.as_ref().display());
55 self.table.push(Sync::new(
56 file.as_ref().to_path_buf(),
57 dep_file.as_ref().to_path_buf(),
58 ));
59 self
60 }
61
62 pub fn sync(&mut self) {
63 println!("Start syncing code ... {}", self.table.len());
64 for sync in &self.table {
65 sync.sync();
66 }
67 }
68}