diff --git a/docs/rules/rust_style.md b/docs/rules/rust_style.md index 8efa16c2..d4cbfdae 100644 --- a/docs/rules/rust_style.md +++ b/docs/rules/rust_style.md @@ -24,7 +24,6 @@ Of note: let firstName = "Ichigo"; const obj1 = { lastName: "Hoshimiya" }; const obj2 = { firstName }; -const { lastName } = obj1; function doSomething() {} function foo({ camelCase = "default value" }) {} @@ -33,7 +32,6 @@ class snake_case_class {} class camelCaseClass {} class Also_Not_Valid_Class {} -import { camelCased } from "external-module.js"; export * as camelCased from "mod.ts"; enum snake_case_enum { @@ -66,6 +64,7 @@ const __my_private_variable = "Hoshimiya"; const my_private_variable_ = "Hoshimiya"; const obj1 = { "lastName": "Hoshimiya" }; // if an object key is wrapped in quotation mark, then it's valid const obj2 = { "firstName": firstName }; +const { lastName } = obj1; //valid, because one has no control over the identifier const { lastName: last_name } = obj; function do_something() {} // function declarations must be snake_case but... @@ -74,6 +73,7 @@ function foo({ camelCase: snake_case = "default value" }) {} class PascalCaseClass {} +import { camelCased } from "external-module.js"; //valid, because one has no control over the identifier import { camelCased as not_camel_cased } from "external-module.js"; export * as not_camel_cased from "mod.ts"; diff --git a/src/rules/rust_style.rs b/src/rules/rust_style.rs index 37ecd34c..20a43f33 100644 --- a/src/rules/rust_style.rs +++ b/src/rules/rust_style.rs @@ -1344,6 +1344,28 @@ mod tests { r#"const SCREAMING_SNAKE_CASE = 42;"#, r#"class FooBar { static snake_case = 42; }"#, r#"class FooBar { static SCREAMING_SNAKE_CASE = 42; }"#, + + r#"class STILL_VALID_CLASS {}"#,// considered UpperCamelCased + + //doc test cases: + r#"let first_name = "Ichigo";"#, + r#"const FIRST_NAME = "Ichigo";"#, + r#"const __my_private_variable = "Hoshimiya";"#, + r#"const my_private_variable_ = "Hoshimiya";"#, + r#"const obj1 = { "lastName": "Hoshimiya" }; // if an object key is wrapped in quotation mark, then it's valid"#, + r#"const obj2 = { "firstName": firstName };"#, + r#"const { lastName } = obj1; //valid, because one has no control over the identifier"#,// valid, see #1187 + r#"const { lastName: last_name } = obj;"#, + r#"function do_something() {} // function declarations must be snake_case but..."#, + r#"doSomething(); // ...camel_case function calls are allowed"#, + r#"function foo({ camelCase: snake_case = "default value" }) {}"#, + r#"class PascalCaseClass {}"#, + r#"import { camelCased } from "external-module.js"; //valid, because one has no control over the identifier"#,// valid, see #1187 + r#"import { camelCased as not_camel_cased } from "external-module.js";"#, + r#"export * as not_camel_cased from "mod.ts";"#, + r#"enum PascalCaseEnum { PascalCaseVariant }"#, + r#"type PascalCaseType = { some_property: number };"#, + r#"interface PascalCaseInterface { some_property: number; }"#, }; } @@ -1917,6 +1939,132 @@ mod tests { hint: "Consider renaming `UpperCamelCased` to `upper_camel_cased` or `UPPER_CAMEL_CASED`", } ], + //doc test cases: + r#"let firstName = "Ichigo";"#: [ + { + col: 4, + message: "Identifier 'firstName' is not in rust style.", + hint: "Consider renaming `firstName` to `first_name`", + }, + ], + r#"const obj1 = { lastName: "Hoshimiya" };"#: [ + { + col: 15, + message: "Identifier 'lastName' is not in rust style.", + hint: "Consider renaming `lastName` to `last_name`, or wrapping it in quotation mark like `\"lastName\"`", + }, + ], + r#"const obj2 = { firstName };"#: [ + { + col: 15, + message: "Identifier 'firstName' is not in rust style.", + hint: "Consider writing `first_name: firstName` or `\"firstName\": firstName`", + }, + ], + r#"function doSomething() {}"#: [ + { + col: 9, + message: "Identifier 'doSomething' is not in rust style.", + hint: "Consider renaming `doSomething` to `do_something`", + }, + ], + r#"function foo({ camelCase = "default value" }) {}"#: [ + { + col: 15, + message: "Identifier 'camelCase' is not in rust style.", + hint: "Consider renaming `camelCase` to `camel_case`", + }, + ], + r#"class snake_case_class {}"#: [ + { + col: 6, + message: "Identifier 'snake_case_class' is not in rust style.", + hint: "Consider renaming `snake_case_class` to `SnakeCaseClass`", + }, + ], + r#"class camelCaseClass {}"#: [ + { + col: 6, + message: "Identifier 'camelCaseClass' is not in rust style.", + hint: "Consider renaming `camelCaseClass` to `CamelCaseClass`", + }, + ], + r#"class Also_Not_Valid_Class {}"#: [ + { + col: 6, + message: "Identifier 'Also_Not_Valid_Class' is not in rust style.", + hint: "Consider renaming `Also_Not_Valid_Class` to `ALSO_NOT_VALID_CLASS`", + }, + ], + r#"export * as camelCased from "mod.ts";"#: [ + { + col: 12, + message: "Identifier 'camelCased' is not in rust style.", + hint: "Consider renaming `camelCased` to `camel_cased`", + }, + ], + r#"enum snake_case_enum { snake_case_variant }"#: [ + { + col: 5, + message: "Identifier 'snake_case_enum' is not in rust style.", + hint: "Consider renaming `snake_case_enum` to `SnakeCaseEnum`", + }, + { + col: 23, + message: "Identifier 'snake_case_variant' is not in rust style.", + hint: "Consider renaming `snake_case_variant` to `SnakeCaseVariant`", + }, + ], + r#"enum camelCasedEnum { camelCasedVariant }"#: [ + { + col: 5, + message: "Identifier 'camelCasedEnum' is not in rust style.", + hint: "Consider renaming `camelCasedEnum` to `CamelCasedEnum`", + }, + { + col: 22, + message: "Identifier 'camelCasedVariant' is not in rust style.", + hint: "Consider renaming `camelCasedVariant` to `CamelCasedVariant`", + }, + ], + r#"type snake_case_type = { some_property: number };"#: [ + { + col: 5, + message: "Identifier 'snake_case_type' is not in rust style.", + hint: "Consider renaming `snake_case_type` to `SnakeCaseType`", + }, + ], + r#"type camelCasedType = { someProperty: number };"#: [ + { + col: 5, + message: "Identifier 'camelCasedType' is not in rust style.", + hint: "Consider renaming `camelCasedType` to `CamelCasedType`", + }, + { + col: 24, + message: "Identifier 'someProperty' is not in rust style.", + hint: "Consider renaming `someProperty` to `some_property`, or wrapping it in quotation mark like `\"someProperty\"`", + }, + ], + r#"interface snake_case_interface { some_property: number; }"#: [ + { + col: 10, + message: "Identifier 'snake_case_interface' is not in rust style.", + hint: "Consider renaming `snake_case_interface` to `SnakeCaseInterface`", + }, + ], + r#"interface camelCasedInterface { someProperty: number; }"#: [ + { + col: 10, + message: "Identifier 'camelCasedInterface' is not in rust style.", + hint: "Consider renaming `camelCasedInterface` to `CamelCasedInterface`", + }, + { + col: 32, + message: "Identifier 'someProperty' is not in rust style.", + hint: "Consider renaming `someProperty` to `some_property`, or wrapping it in quotation mark like `\"someProperty\"`", + }, + ], }; } } diff --git a/www/static/docs.json b/www/static/docs.json index 0bdc3a1f..736030d0 100644 --- a/www/static/docs.json +++ b/www/static/docs.json @@ -644,7 +644,7 @@ }, { "code": "rust_style", - "docs": "Enforces the use of Rust-style naming conventions, see\nhttps://rust-lang.github.io/api-guidelines/naming.html\n\nConsistency in a code base is key for readability and maintainability. This rule\nis useful for deno projects that call rust functions via FFI. It attempts to\nunify naming conventions and enforces declarations and object property names\nwhich you create to be\\\nin UpperCamelCase/PascalCase for classes, types, interfaces,\\\nin snake_case for functions, methods, variables\\\nand in SCREAMING_SNAKE_CASE for static class properties and constants.\n\nOf note:\n\n- `_` is allowed at the start or end of a variable\n- All uppercase variable names (e.g. constants) may have `_` in their name\n- If you have to use a camelCase key in an object for some reasons, wrap it in\n quotation mark\n- This rule also applies to variables imported or exported via ES modules, but\n not to object properties of those variables\n\n### Invalid:\n\n```typescript\nlet firstName = \"Ichigo\";\nconst obj1 = { lastName: \"Hoshimiya\" };\nconst obj2 = { firstName };\nconst { lastName } = obj1;\n\nfunction doSomething() {}\nfunction foo({ camelCase = \"default value\" }) {}\n\nclass snake_case_class {}\nclass camelCaseClass {}\nclass Also_Not_Valid_Class {}\n\nimport { camelCased } from \"external-module.js\";\nexport * as camelCased from \"mod.ts\";\n\nenum snake_case_enum {\n snake_case_variant,\n}\n\nenum camelCasedEnum {\n camelCasedVariant,\n}\n\ntype snake_case_type = { some_property: number };\n\ntype camelCasedType = { someProperty: number };\n\ninterface snake_case_interface {\n some_property: number;\n}\n\ninterface camelCasedInterface {\n someProperty: number;\n}\n```\n\n### Valid:\n\n```typescript\nlet first_name = \"Ichigo\";\nconst FIRST_NAME = \"Ichigo\";\nconst __my_private_variable = \"Hoshimiya\";\nconst my_private_variable_ = \"Hoshimiya\";\nconst obj1 = { \"lastName\": \"Hoshimiya\" }; // if an object key is wrapped in quotation mark, then it's valid\nconst obj2 = { \"firstName\": firstName };\nconst { lastName: last_name } = obj;\n\nfunction do_something() {} // function declarations must be snake_case but...\ndoSomething(); // ...camel_case function calls are allowed\nfunction foo({ camelCase: snake_case = \"default value\" }) {}\n\nclass PascalCaseClass {}\n\nimport { camelCased as not_camel_cased } from \"external-module.js\";\nexport * as not_camel_cased from \"mod.ts\";\n\nenum PascalCaseEnum {\n PascalCaseVariant,\n}\n\ntype PascalCaseType = { some_property: number };\n\ninterface PascalCaseInterface {\n some_property: number;\n}\n```\n", + "docs": "Enforces the use of Rust-style naming conventions, see\nhttps://rust-lang.github.io/api-guidelines/naming.html\n\nConsistency in a code base is key for readability and maintainability. This rule\nis useful for deno projects that call rust functions via FFI. It attempts to\nunify naming conventions and enforces declarations and object property names\nwhich you create to be\\\nin UpperCamelCase/PascalCase for classes, types, interfaces,\\\nin snake_case for functions, methods, variables\\\nand in SCREAMING_SNAKE_CASE for static class properties and constants.\n\nOf note:\n\n- `_` is allowed at the start or end of a variable\n- All uppercase variable names (e.g. constants) may have `_` in their name\n- If you have to use a camelCase key in an object for some reasons, wrap it in\n quotation mark\n- This rule also applies to variables imported or exported via ES modules, but\n not to object properties of those variables\n\n### Invalid:\n\n```typescript\nlet firstName = \"Ichigo\";\nconst obj1 = { lastName: \"Hoshimiya\" };\nconst obj2 = { firstName };\n\nfunction doSomething() {}\nfunction foo({ camelCase = \"default value\" }) {}\n\nclass snake_case_class {}\nclass camelCaseClass {}\nclass Also_Not_Valid_Class {}\n\nexport * as camelCased from \"mod.ts\";\n\nenum snake_case_enum {\n snake_case_variant,\n}\n\nenum camelCasedEnum {\n camelCasedVariant,\n}\n\ntype snake_case_type = { some_property: number };\n\ntype camelCasedType = { someProperty: number };\n\ninterface snake_case_interface {\n some_property: number;\n}\n\ninterface camelCasedInterface {\n someProperty: number;\n}\n```\n\n### Valid:\n\n```typescript\nlet first_name = \"Ichigo\";\nconst FIRST_NAME = \"Ichigo\";\nconst __my_private_variable = \"Hoshimiya\";\nconst my_private_variable_ = \"Hoshimiya\";\nconst obj1 = { \"lastName\": \"Hoshimiya\" }; // if an object key is wrapped in quotation mark, then it's valid\nconst obj2 = { \"firstName\": firstName };\nconst { lastName } = obj1; //valid, because one has no control over the identifier\nconst { lastName: last_name } = obj;\n\nfunction do_something() {} // function declarations must be snake_case but...\ndoSomething(); // ...camel_case function calls are allowed\nfunction foo({ camelCase: snake_case = \"default value\" }) {}\n\nclass PascalCaseClass {}\n\nimport { camelCased } from \"external-module.js\"; //valid, because one has no control over the identifier\nimport { camelCased as not_camel_cased } from \"external-module.js\";\nexport * as not_camel_cased from \"mod.ts\";\n\nenum PascalCaseEnum {\n PascalCaseVariant,\n}\n\ntype PascalCaseType = { some_property: number };\n\ninterface PascalCaseInterface {\n some_property: number;\n}\n```\n", "tags": [] }, {