-
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
0 parents
commit b13233b
Showing
15 changed files
with
396 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,56 @@ | ||
name: Lints | ||
on: | ||
push: | ||
branches: [ master ] | ||
|
||
pull_request: | ||
branches: [ master ] | ||
|
||
jobs: | ||
check: | ||
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 --workspace --examples --tests | ||
check-formatting: | ||
needs: [ check ] | ||
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: Format | ||
run: cargo fmt --all -- --check | ||
clippy: | ||
needs: [ check ] | ||
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: Clippy | ||
run: cargo clippy --workspace --examples --tests -- --warn clippy::pedantic --warn clippy::nursery --deny 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,29 @@ | ||
name: Tests | ||
|
||
on: | ||
push: | ||
branches: [ master ] | ||
|
||
pull_request: | ||
branches: [ master ] | ||
|
||
jobs: | ||
test: | ||
needs: [ check ] | ||
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 --workspace --examples --tests | ||
|
||
- name: Test | ||
run: cargo test --workspace |
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,14 @@ | ||
[package] | ||
name = "type-path" | ||
version = "0.1.0" | ||
edition = "2021" | ||
authors = ["Leonard. D <tigerros.gh@gmail.com>"] | ||
description = "Get the string array representation of a Rust type path" | ||
license = "MIT" | ||
repository = "https://github.com/tigerros/type-path" | ||
keywords = ["reflection", "macros", "no-std"] | ||
categories = ["rust-patterns", "no-std"] | ||
include = ["src/lib.rs", "README.md"] | ||
|
||
[dev-dependencies] | ||
trybuild = "1.0.0" |
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,16 @@ | ||
[![tests badge]](https://github.com/tigerros/type-path/actions/workflows/tests.yml) | ||
[![lints badge]](https://github.com/tigerros/type-path/actions/workflows/lints.yml) | ||
[![docs.rs badge]](https://docs.rs/type-path/) | ||
[![crates.io badge]](https://crates.io/crates/type-path) | ||
[![license badge]](https://github.com/tigerros/type-path/blob/master/LICENSE) | ||
|
||
A tiny crate for getting the string array representation of a Rust type path, with type validation. | ||
Everything happens at compile-time. | ||
|
||
Check out the docs for everything else! | ||
|
||
[tests badge]: https://img.shields.io/github/actions/workflow/status/tigerros/type-path/tests.yml?label=tests&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1MTIgNTEyIj48IS0tISBGb250IEF3ZXNvbWUgUHJvIDYuNC4yIGJ5IEBmb250YXdlc29tZSAtIGh0dHBzOi8vZm9udGF3ZXNvbWUuY29tIExpY2Vuc2UgLSBodHRwczovL2ZvbnRhd2Vzb21lLmNvbS9saWNlbnNlIChDb21tZXJjaWFsIExpY2Vuc2UpIENvcHlyaWdodCAyMDIzIEZvbnRpY29ucywgSW5jLiAtLT48cGF0aCBmaWxsPSIjRkZGRkZGIiBkPSJNMzQyLjYgOS40Yy0xMi41LTEyLjUtMzIuOC0xMi41LTQ1LjMgMHMtMTIuNSAzMi44IDAgNDUuM2w5LjQgOS40TDI4LjEgMzQyLjZDMTAuMSAzNjAuNiAwIDM4NSAwIDQxMC41VjQxNmMwIDUzIDQzIDk2IDk2IDk2aDUuNWMyNS41IDAgNDkuOS0xMC4xIDY3LjktMjguMUw0NDggMjA1LjNsOS40IDkuNGMxMi41IDEyLjUgMzIuOCAxMi41IDQ1LjMgMHMxMi41LTMyLjggMC00NS4zbC0zMi0zMi05Ni05Ni0zMi0zMnpNMjA1LjMgMjU2TDM1MiAxMDkuMyA0MDIuNyAxNjBsLTk2IDk2SDIwNS4zeiIvPjwvc3ZnPg== | ||
[lints badge]: https://img.shields.io/github/actions/workflow/status/tigerros/type-path/lints.yml?label=lints&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1NzYgNTEyIj48IS0tISBGb250IEF3ZXNvbWUgUHJvIDYuNC4yIGJ5IEBmb250YXdlc29tZSAtIGh0dHBzOi8vZm9udGF3ZXNvbWUuY29tIExpY2Vuc2UgLSBodHRwczovL2ZvbnRhd2Vzb21lLmNvbS9saWNlbnNlIChDb21tZXJjaWFsIExpY2Vuc2UpIENvcHlyaWdodCAyMDIzIEZvbnRpY29ucywgSW5jLiAtLT48cGF0aCBmaWxsPSIjRkZGRkZGIiBkPSJNMTEyIDBDOTkuMSAwIDg3LjQgNy44IDgyLjUgMTkuN2wtNjYuNyAxNjAtMTMuMyAzMmMtNi44IDE2LjMgLjkgMzUgMTcuMiA0MS44czM1LS45IDQxLjgtMTcuMkw2Ni43IDIyNGg5MC43bDUuMSAxMi4zYzYuOCAxNi4zIDI1LjUgMjQgNDEuOCAxNy4yczI0LTI1LjUgMTcuMi00MS44bC0xMy4zLTMyLTY2LjctMTYwQzEzNi42IDcuOCAxMjQuOSAwIDExMiAwem0xOC43IDE2MEg5My4zTDExMiAxMTUuMiAxMzAuNyAxNjB6TTI1NiAzMnY5NiA5NmMwIDE3LjcgMTQuMyAzMiAzMiAzMmg4MGM0NC4yIDAgODAtMzUuOCA4MC04MGMwLTIzLjEtOS44LTQzLjgtMjUuNC01OC40YzYtMTEuMiA5LjQtMjQgOS40LTM3LjZjMC00NC4yLTM1LjgtODAtODAtODBIMjg4Yy0xNy43IDAtMzIgMTQuMy0zMiAzMnptOTYgNjRIMzIwVjY0aDMyYzguOCAwIDE2IDcuMiAxNiAxNnMtNy4yIDE2LTE2IDE2em0tMzIgNjRoMzIgMTZjOC44IDAgMTYgNy4yIDE2IDE2cy03LjIgMTYtMTYgMTZIMzIwVjE2MHpNNTY2LjYgMzEwLjZjMTIuNS0xMi41IDEyLjUtMzIuOCAwLTQ1LjNzLTMyLjgtMTIuNS00NS4zIDBMMzUyIDQzNC43bC03My40LTczLjRjLTEyLjUtMTIuNS0zMi44LTEyLjUtNDUuMyAwcy0xMi41IDMyLjggMCA0NS4zbDk2IDk2YzEyLjUgMTIuNSAzMi44IDEyLjUgNDUuMyAwbDE5Mi0xOTJ6Ii8+PC9zdmc+ | ||
[docs.rs badge]: https://img.shields.io/docsrs/type-path?logo=docs.rs&label=docs.rs | ||
[crates.io badge]: https://img.shields.io/crates/v/type-path?logo=rust | ||
[license badge]: https://img.shields.io/crates/l/type-path |
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,131 @@ | ||
#![no_std] | ||
|
||
//! # Guide | ||
//! | ||
//! The crate has just one macro: [`type_path!`](type_path). Check it out for syntax and returning details. | ||
//! | ||
//! You might be wondering why we're using an absolute path in the following example: | ||
//! | ||
//! ```rust | ||
//! use type_path::type_path; | ||
//! assert_eq!(type_path!(::std::io::BufWriter), ["::", "std", "io", "BufWriter"]); | ||
//! ``` | ||
//! | ||
//! It's because macros have no way of knowing the scope of the given item. | ||
//! | ||
//! If it wasn't required, the following would happen, because macros only have access to the literal `Result` tokens, | ||
//! and no type information/scope etc. | ||
//! | ||
//! ```rust,ignore | ||
//! # use type_path::type_path; | ||
//! use std::io::Result; | ||
//! assert_eq!(type_path!(Result), ["Result"]); | ||
//! ``` | ||
//! | ||
//! Now, the reliability aspect is gone, because even though the type exists, | ||
//! `"Result"` is extremely generic and almost certainly not what you want. | ||
//! | ||
//! You can also have an "everything" path (although you probably won't use this a lot): | ||
//! | ||
//! ```rust | ||
//! # use type_path::type_path; | ||
//! assert_eq!(type_path!(::std::io::*), ["::", "std", "io", "*"]); | ||
//! ``` | ||
//! | ||
//! This doesn't compile, since `BufWrirer` doesn't exist: | ||
//! | ||
//! ```compile_fail,E0432 | ||
//! # use type_path::type_path; | ||
//! type_path!(::std::io::BufWrirer); | ||
//! ``` | ||
//! | ||
//! # Why? | ||
//! - **Reliability**: | ||
//! The [`type_path!`](type_path) macro will check if the path you entered is valid, at compile time. | ||
//! With other approaches, you can't be sure that the path is valid. | ||
//! - No dependencies. | ||
//! - You can use it in a no-std environment, | ||
|
||
const WHITESPACE: u8 = b'\t' | b'\n' | b'\r' | b' '; | ||
|
||
const fn bytes_trim_start(mut this: &[u8]) -> &[u8] { | ||
loop { | ||
match this { | ||
[WHITESPACE, rem @ ..] => this = rem, | ||
_ => return this, | ||
} | ||
} | ||
} | ||
|
||
const fn bytes_trim_end(mut this: &[u8]) -> &[u8] { | ||
loop { | ||
match this { | ||
[rem @ .., WHITESPACE] => this = rem, | ||
_ => return this, | ||
} | ||
} | ||
} | ||
|
||
const fn bytes_trim(this: &[u8]) -> &[u8] { | ||
bytes_trim_start(bytes_trim_end(this)) | ||
} | ||
|
||
/// **This is not intended to be used outside of this crate!** | ||
/// It's public because [`type_path!`](type_path) includes it in the expansion. | ||
/// | ||
/// Trims a string at compile time. | ||
#[doc(hidden)] | ||
#[must_use] | ||
pub const fn trim(this: &str) -> &str { | ||
let trimmed = bytes_trim(this.as_bytes()); | ||
|
||
// Safety: bytes_trim only removes ascii bytes | ||
unsafe { core::str::from_utf8_unchecked(trimmed) } | ||
} | ||
|
||
/// **This is not intended to be used outside of this crate!** | ||
/// | ||
/// Macro with one empty pattern `() => {};`. | ||
/// Used for enforcing that a meta variable (e.g., `$foo:tt`) is empty. | ||
#[macro_export] | ||
macro_rules! empty { | ||
() => {}; | ||
} | ||
|
||
/// # Syntax | ||
/// | ||
/// *Ignore the macro source. It might be confusing and not helpful.* | ||
/// | ||
/// There's 3 patterns: | ||
/// | ||
/// - `::` prefix, with 1+ [identifiers] separated by `::`. E.g., `::path::to::Item`. | ||
/// This is an absolute path and will be resolved from the root of your project, regardless of scope. | ||
/// - Same as the first pattern, but with a `crate` prefix. | ||
/// Use this when you need to use types from the current crate. | ||
/// - Same as the first pattern, but ending in `::*`. E.g., `::path::to::prelude::*`. | ||
/// | ||
/// # Returns | ||
/// | ||
/// `[&'static str; N]`, where `N` is the amount of segments in the path, and `&str` is the segment. | ||
/// | ||
/// The first item in the string array will be `"::"` or `"crate"`, depending on which prefix you use. | ||
/// | ||
/// [identifiers]: https://doc.rust-lang.org/reference/identifiers.html "Rust identifier reference" | ||
#[macro_export] | ||
#[allow(clippy::crate_in_macro_def)] | ||
macro_rules! type_path { | ||
|
||
(::$($segment:ident):: +$(::*$($empty:tt)? )?) => {{ | ||
#[allow(unused_imports)] | ||
use :: $($segment)::+ $(::* $($crate::empty!($empty))?)?; | ||
|
||
["::", $($crate::trim(stringify!($segment))),+ $(, "*" $($crate::empty!($empty))?)?] | ||
}}; | ||
|
||
(crate::$($segment:ident):: +$(::*$($empty:tt)? )?) => {{ | ||
#[allow(unused_imports)] | ||
use crate :: $($segment)::+ $(::* $($crate::empty!($empty))?)?; | ||
|
||
["crate", $($crate::trim(stringify!($segment))),+ $(, "*" $($crate::empty!($empty))?)?] | ||
}}; | ||
} |
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,5 @@ | ||
use type_path::type_path; | ||
|
||
fn main() { | ||
type_path!(std::io::BufWriter); | ||
} |
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 @@ | ||
error: no rules expected the token `std` | ||
--> tests/compile-fail/no_root_prefix.rs:4:16 | ||
| | ||
4 | type_path!(std::io::BufWriter); | ||
| ^^^ no rules expected this token in macro call | ||
| | ||
note: while trying to match `::` | ||
--> src/lib.rs | ||
| | ||
| (::$($segment:ident):: +$(::*$($empty:tt)? )?) => {{ | ||
| ^^ |
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,5 @@ | ||
use type_path::type_path; | ||
|
||
const ITER_REPEAT_PATH: &[&str; 4] = type_path!(::std::iter::repeat); | ||
|
||
fn main() {} |
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,7 @@ | ||
error[E0308]: mismatched types | ||
--> tests/compile-fail/slice_instead_of_array.rs:3:38 | ||
| | ||
3 | const ITER_REPEAT_PATH: &[&str; 4] = type_path!(::std::iter::repeat); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&[&str; 4]`, found `[&str; 4]` | ||
| | ||
= note: this error originates in the macro `type_path` (in Nightly builds, run with -Z macro-backtrace for more info) |
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,5 @@ | ||
use type_path::type_path; | ||
|
||
fn main() { | ||
type_path!(::std::io::BufWrirer); | ||
} |
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 @@ | ||
error[E0432]: unresolved import `std::io::BufWrirer` | ||
--> tests/compile-fail/unresolved_path.rs:4:5 | ||
| | ||
4 | type_path!(::std::io::BufWrirer); | ||
| ^^^^^^^^^^^^^^^^^^^^^^---------^ | ||
| | | | ||
| | help: a similar name exists in the module: `BufWriter` | ||
| no `BufWrirer` in `io` | ||
| | ||
= note: this error originates in the macro `type_path` (in Nightly builds, run with -Z macro-backtrace for more info) |
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,5 @@ | ||
use type_path::type_path; | ||
|
||
const ITER_REPEAT_PATH: [&str; 3] = type_path!(::std::iter::repeat); | ||
|
||
fn main() {} |
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,9 @@ | ||
error[E0308]: mismatched types | ||
--> tests/compile-fail/wrong_array_length.rs:3:37 | ||
| | ||
3 | const ITER_REPEAT_PATH: [&str; 3] = type_path!(::std::iter::repeat); | ||
| - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected an array with a fixed size of 3 elements, found one with 4 elements | ||
| | | ||
| help: consider specifying the actual array length: `4` | ||
| | ||
= note: this error originates in the macro `type_path` (in Nightly builds, run with -Z macro-backtrace for more info) |
Oops, something went wrong.