ruff/crates/ruff_python_stdlib/src/identifiers.rs
konsti 1df7e9831b
Replace .map_or(false, $closure) with .is_some_and(closure) (#6244)
**Summary**
[Option::is_some_and](https://doc.rust-lang.org/stable/std/option/enum.Option.html#method.is_some_and)
and
[Result::is_ok_and](https://doc.rust-lang.org/std/result/enum.Result.html#method.is_ok_and)
are new methods is rust 1.70. I find them way more readable than
`.map_or(false, ...)`.

The changes are `s/.map_or(false,/.is_some_and(/g`, then manually
switching to `is_ok_and` where the value is a Result rather than an
Option.

**Test Plan** n/a^
2023-08-01 19:29:42 +02:00

112 lines
3.3 KiB
Rust

use crate::keyword::is_keyword;
/// Returns `true` if a string is a valid Python identifier (e.g., variable
/// name).
pub fn is_identifier(name: &str) -> bool {
// Is the first character a letter or underscore?
let mut chars = name.chars();
if !chars.next().is_some_and(|c| c.is_alphabetic() || c == '_') {
return false;
}
// Are the rest of the characters letters, digits, or underscores?
if !chars.all(|c| c.is_alphanumeric() || c == '_') {
return false;
}
// Is the identifier a keyword?
if is_keyword(name) {
return false;
}
true
}
/// Returns `true` if a string is a private identifier, such that, when the
/// identifier is defined in a class definition, it will be mangled prior to
/// code generation.
///
/// See: <https://docs.python.org/3.5/reference/expressions.html?highlight=mangling#index-5>.
pub fn is_mangled_private(id: &str) -> bool {
id.starts_with("__") && !id.ends_with("__")
}
/// Returns `true` if a string is a PEP 8-compliant module name (i.e., consists of lowercase
/// letters, numbers, underscores, and is not a keyword).
pub fn is_module_name(name: &str) -> bool {
// Is the first character a letter or underscore?
let mut chars = name.chars();
if !chars
.next()
.is_some_and(|c| c.is_ascii_lowercase() || c == '_')
{
return false;
}
// Are the rest of the characters letters, digits, or underscores?
if !chars.all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || c == '_') {
return false;
}
// Is the identifier a keyword?
if is_keyword(name) {
return false;
}
true
}
/// Returns `true` if a string appears to be a valid migration file name (e.g., `0001_initial.py`).
pub fn is_migration_name(name: &str) -> bool {
// Are characters letters, digits, or underscores?
if !name
.chars()
.all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || c == '_')
{
return false;
}
// Is the identifier a keyword?
if is_keyword(name) {
return false;
}
true
}
#[cfg(test)]
mod tests {
use crate::identifiers::{is_migration_name, is_module_name};
#[test]
fn module_name() {
assert!(is_module_name("_abc"));
assert!(is_module_name("a"));
assert!(is_module_name("a_b_c"));
assert!(is_module_name("abc"));
assert!(is_module_name("abc0"));
assert!(is_module_name("abc_"));
assert!(!is_module_name("0001_initial"));
assert!(!is_module_name("0abc"));
assert!(!is_module_name("a-b-c"));
assert!(!is_module_name("a_B_c"));
assert!(!is_module_name("class"));
assert!(!is_module_name("δ"));
}
#[test]
fn migration_name() {
assert!(is_migration_name("0001_initial"));
assert!(is_migration_name("0abc"));
assert!(is_migration_name("_abc"));
assert!(is_migration_name("a"));
assert!(is_migration_name("a_b_c"));
assert!(is_migration_name("abc"));
assert!(is_migration_name("abc0"));
assert!(is_migration_name("abc_"));
assert!(!is_migration_name("a-b-c"));
assert!(!is_migration_name("a_B_c"));
assert!(!is_migration_name("class"));
assert!(!is_migration_name("δ"));
}
}