-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Leonard
committed
Sep 23, 2023
0 parents
commit d77d288
Showing
9 changed files
with
279 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
name: Rust CI | ||
|
||
on: | ||
push: | ||
branches: | ||
- master | ||
|
||
pull_request: | ||
branches: | ||
- master | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v2 | ||
|
||
- name: Set up Rust | ||
uses: actions-rs/toolchain@v1 | ||
with: | ||
toolchain: stable | ||
override: true | ||
|
||
- name: Check | ||
run: cargo check --all --examples --tests | ||
|
||
- name: Format | ||
run: cargo fmt --all -- --check | ||
|
||
- name: Clippy | ||
run: cargo clippy --workspace --examples --tests -- -D warnings |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/target | ||
/Cargo.lock | ||
.idea |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
[package] | ||
name = "dry-mods" | ||
description = "Macros to make your module management DRY" | ||
version = "0.1.0" | ||
edition = "2021" | ||
license = "MIT" | ||
repository = "https://github.com/tigerros/dry-mods" | ||
categories = ["development-tools", "development-tools:build-utils", "rust-patterns", "no-std", "no-std:no-alloc"] | ||
keywords = ["macros", "no-std", "module", "DRY", "no-alloc"] | ||
include = ["src", "README.md"] # Don't include examples in crate |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# DRY modules | ||
|
||
Don't Repeat Yourself, be DRY! | ||
That's why you should use this crate, for removing repetition and verboseness from your module declarations. | ||
|
||
Check out the docs for a guide and examples. | ||
|
||
Why this crate? | ||
- Intuitive macro syntax. | ||
- Extremely lightweight. No dependencies. | ||
- You can use it in a `no-std` or `no-alloc` context. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
pub fn bar() { | ||
println!("bar"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
pub fn foo() { | ||
println!("foo"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
mod baz { | ||
pub(crate) fn baz() { | ||
println!("baz"); | ||
} | ||
} | ||
|
||
dry_mods::mods! { | ||
// `foo` and `bar` will be defined with the `pub(crate)` visibility but the contents will be completely public. | ||
pub(crate) mod pub use foo, bar; | ||
// `baz` is totally private, but the contents are exposed in the module where `mods!` was called. | ||
// We don't use `mod` here, because `baz` is already defined. | ||
use baz; | ||
} | ||
|
||
fn main() { | ||
foo(); | ||
bar(); | ||
baz(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
mod internal1 { | ||
pub(crate) fn int1() { | ||
println!("int1"); | ||
} | ||
} | ||
|
||
mod internal2 { | ||
pub(crate) fn int2() { | ||
println!("int2"); | ||
} | ||
} | ||
|
||
dry_mods::prelude! { | ||
// `foo` and `bar` will be public modules and their contents will also be public. | ||
/// Re-exports some commonly used modules. | ||
pub mod pub use foo, bar; | ||
// `internal1` and `internal2` will only be visible within the crate. | ||
// We don't use `mod` here, because they are already defined. | ||
pub(crate) use crate::{internal1, internal2}; | ||
} | ||
|
||
fn main() { | ||
prelude::foo(); | ||
prelude::bar(); | ||
prelude::int1(); | ||
prelude::int2(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
//! Compiled examples are in the [repository](https://github.com/tigerros/dry-mods/tree/master/examples). | ||
|
||
#![warn(clippy::cargo)] | ||
#![warn(clippy::pedantic)] | ||
#![warn(clippy::style)] | ||
#![warn(clippy::nursery)] | ||
#![no_std] | ||
#![no_main] | ||
|
||
/// Flexible and powerful module declarations. | ||
/// | ||
/// # Syntax | ||
/// There's three different patterns the macro matches against: | ||
/// - Define modules and use the contents (`::*`). | ||
/// - Define modules. | ||
/// - Use the contents of modules that are already in scope. | ||
/// - Use the contents of modules that are in a root module. | ||
/// For example, `crate::{mod1, mod2}` instead of `crate::mod1, crate::mod2`. | ||
/// | ||
/// After each pattern, you can type a semicolon (`;`) and make another one! | ||
/// | ||
/// # Examples | ||
/// This showcases each of the three patterns: | ||
/// ```rs | ||
/// dry_mods::mods! { | ||
/// // `foo` and `bar` will be defined with the `pub(crate)` visibility but the contents will be completely public. | ||
/// pub(crate) mod pub use foo, bar; | ||
/// // `baz` is totally private, but the contents are exposed in the module where `mods!` was called. | ||
/// use baz; | ||
/// // `my_mod` is now a public module. | ||
/// pub mod my_mod; | ||
/// // Use the root module for crate internals. | ||
/// pub(crate) use crate::{int1, int2, int3, int4, int5}; | ||
/// } | ||
/// | ||
/// // Generates: | ||
/// | ||
/// pub(crate) mod foo; | ||
/// pub(crate) mod bar; | ||
/// pub use foo::*; | ||
/// pub use bar::*; | ||
/// use baz::*; | ||
/// pub mod my_mod; | ||
/// pub(crate) crate::{int1::*, int2::*, int3::*, int4::*, int5::*}; | ||
/// ``` | ||
#[macro_export] | ||
macro_rules! mods { | ||
() => {}; | ||
|
||
($mod_vis:vis mod $use_vis:vis use $($module:ident),+; $($rest:tt)*) => { | ||
$($mod_vis mod $module;)+ | ||
$($use_vis use $module::*;)+ | ||
::dry_mods::mods! { $($rest)* } | ||
}; | ||
|
||
($mod_vis:vis mod $($module:ident),+; $($rest:tt)*) => { | ||
$($mod_vis mod $module;)+ | ||
::dry_mods::mods! { $($rest)* } | ||
}; | ||
|
||
// No root. | ||
($use_vis:vis use $($mod_path:path),+; $($rest:tt)*) => { | ||
$($use_vis use $mod_path::*;)+ | ||
::dry_mods::mods! { $($rest)* } | ||
}; | ||
|
||
// Yes root. | ||
($use_vis:vis use $root:ident::{$($mod_path:path),+}; $($rest:tt)*) => { | ||
$($use_vis use $root::{$mod_path::*};)+ | ||
::dry_mods::mods! { $($rest)* } | ||
}; | ||
} | ||
|
||
/// Generates a `prelude` module with some uses. | ||
/// | ||
/// # Syntax | ||
/// At the start of each pattern, you can add attributes that will then be added to the `prelude` | ||
/// module. You can also write documentation! | ||
/// | ||
/// There's three different patterns the macro matches against. | ||
/// "use" means "use in the `mod prelude`". | ||
/// - Define modules in the file and use the contents (`::*`). | ||
/// This will use `super::mod_name` to get the modules in the file. | ||
/// - Use the contents of modules that are already in scope. | ||
/// - Use the contents of modules that are in a root module. | ||
/// For example, `crate::{mod1, mod2}` instead of `crate::mod1, crate::mod2`. | ||
/// | ||
/// After each pattern, you can type a semicolon (`;`) and make another one! | ||
/// | ||
/// # Examples | ||
/// This showcases each of the three patterns: | ||
/// ```rs | ||
/// mod internal1 { | ||
/// pub(crate) fn int1() {} | ||
/// } | ||
/// | ||
/// mod internal2 { | ||
/// pub(crate) fn int2() {} | ||
/// } | ||
/// | ||
/// dry_mods::prelude! { | ||
/// // `foo` and `bar` will be public modules and their contents will also be public. | ||
/// /// Re-exports some commonly used modules. | ||
/// pub mod pub use foo, bar; | ||
/// // `internal1` and `internal2` will only be visible within the crate. | ||
/// // We don't use `mod` here, because they are already defined. | ||
/// pub(crate) use crate::{internal1, internal2}; | ||
/// } | ||
/// | ||
/// // Generates: | ||
/// | ||
/// pub mod foo; | ||
/// pub mod bar; | ||
/// #[doc = " Re-exports some commonly used modules."] | ||
/// pub mod prelude { | ||
/// pub use super::foo::*; | ||
/// pub use super::bar::*; | ||
/// pub(crate) use crate::{internal1::*, internal2::* }; | ||
/// } | ||
/// ``` | ||
#[macro_export] | ||
macro_rules! prelude { | ||
() => {}; | ||
|
||
// Using modules in the prelude by prepending "U=" | ||
(U=) => {}; | ||
|
||
// No use root. | ||
(U=$vis:vis use $($mod_path:path),+; $($rest:tt)*) => { | ||
$($vis use $mod_path::*;)+ | ||
::dry_mods::prelude! { U=$($rest)* } | ||
}; | ||
|
||
// Yes use root. | ||
(U=$vis:vis use $root:ident::{$($mod_path:path),+}; $($rest:tt)*) => { | ||
$vis use $root::{$($mod_path::*,)+}; | ||
::dry_mods::prelude! { U=$($rest)* } | ||
}; | ||
|
||
// Prelude, mod and use. | ||
($(#[$attr:meta])* $mod_vis:vis mod $use_vis:vis use $($module:ident),+; $($rest:tt)*) => { | ||
$($mod_vis mod $module;)* | ||
$(#[$attr]) | ||
* | ||
$use_vis mod prelude { | ||
$($use_vis use super::$module::*;)* | ||
::dry_mods::prelude! { U=$($rest)* } | ||
} | ||
}; | ||
|
||
// Prelude, use without root. | ||
($(#[$attr:meta])* $use_vis:vis use $($mod_path:path),+; $($rest:tt)*) => { | ||
$(#[$attr]) | ||
* | ||
$use_vis mod prelude { | ||
$($use_vis use $mod_path::*;)+ | ||
::dry_mods::prelude! { U=$($rest)* } | ||
} | ||
}; | ||
|
||
// Prelude, use with root. | ||
($(#[$attr:meta])* $use_vis:vis use $root:ident::{$($mod_path:path),+}; $($rest:tt)*) => { | ||
$(#[$attr]) | ||
* | ||
$use_vis mod prelude { | ||
$($use_vis use $root::{$mod_path::*};)+ | ||
::dry_mods::prelude! { U=$($rest)* } | ||
} | ||
}; | ||
} |