1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//! A trait for Strings and &str's to check if a string is a reserved keyword,
//! and convert it to a safe non-keyword if so.
//!
//! Only strict and reserved keywords are checked against; weak keywords are not included.
//!
//! You can add this dependency with:
//!
//! ```toml
//! [dependencies]
//! check_keyword = "0.1.1"
//! ```
//!
//! # Examples
//!
//! ```
//! use check_keyword::CheckKeyword;
//! let keyword = "match";
//!
//! assert!(keyword.is_keyword());
//! assert_eq!(keyword.to_safe(), "r#match");
//!
//! // There's also a self-consuming version if you want
//! assert_eq!(keyword.into_safe(), "r#match");
//! ```
//!
//! # Rust Editions
//!
//! By default, the keywords added in Rust Edition 2018 are included in the list of checked keywords.
//! This can be disabled with `default-features = false` in your Cargo.toml.
//!
//! ```toml
//! [dependencies]
//! check_keyword = { version = "0.1.1", default-features = false }
//! ```
//!
//! Future Rust editions may add new keywords, and this crate will be updated to reflect that.
//! (Or you can create an issue on github if I don't.)
mod strings;

#[macro_use] mod arr_macro;

pub trait CheckKeyword {
    /// The type returned by [to_safe](Keywords::to_safe) and [into_safe](Keywords::into_safe). Currently this is [String]
    /// for both the [String] and [&str] implementations, but future implementations might not return
    /// Strings.
    type SafeOutput;

    /// Checks if `self` is a keyword.
    fn is_keyword(&self) -> bool;

    /// Creates a new instance of [SafeOutput](Self::SafeOutput). If it is not a keyword, the contents are unchanged.
    /// If is is a keyword, "r#" is prepended to it.
    fn to_safe(&self) -> Self::SafeOutput;

    /// Identical to [to_safe](Keywords::to_safe), but it consumes `self`.
    fn into_safe(self) -> Self::SafeOutput;
}

arr!(static KEYWORDS: [&'static str; _] = [

    // STRICT, 2015

    "as",
    "break",
    "const",
    "continue",
    "crate",
    "else",
    "enum",
    "extern",
    "false",
    "fn",
    "for",
    "if",
    "impl",
    "in",
    "let",
    "loop",
    "match",
    "mod",
    "move",
    "mut",
    "pub",
    "ref",
    "return",
    "self",
    "Self",
    "static",
    "struct",
    "super",
    "trait",
    "true",
    "type",
    "unsafe",
    "use",
    "where",
    "while",

    // STRICT, 2018

    #[cfg(feature = "2018")] "async",
    #[cfg(feature = "2018")] "await",
    #[cfg(feature = "2018")] "dyn",

    // RESERVED, 2015

    "abstract",
    "become",
    "box",
    "do",
    "final",
    "macro",
    "override",
    "priv",
    "typeof",
    "unsized",
    "virtual",
    "yield",

    // RESERVED, 2018

    #[cfg(feature = "2018")] "try"

]);

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn array_length() {
        println!("{}", KEYWORDS.len());
    }
}