chore(rust): Strongly type Rust NamingStyles (#2602)
* standardise json formatting
* add file association for schema files
* install eslint packages
* add eslint config
* remove tslint
* eslint autofix
* update eslint rules, eslintignore
* add lint:fix script
* update eslint rules, eslintignore
* add lint:fix script
* add import rules
* add import rules
* update import rules
* reduce excess style rules
* downgrade remaining to warnings
* fix enum values
fixup! fix enum values
* add all missing accessibility modifiers
fixup! add all missing accessibility modifiers
fixup! add all missing accessibility modifiers
* fix nullish errors
* update import rules
* fix all require imports
* fix all imports
* reduce excess style rules
* fix any types
fixup! fix any types
fixup! fix any types
* fix misc errors
* downgrade remaining to warnings
* return types
* fix types errors
* fix json import for test tsconfig
* auto lint fix
* fix lint errors in extension
* fix lint errors in Elixir
* make ref.pushElement public
* fix misc
* fix accidental public in CSharp raw text get
* fix new lint errors
* Merge branch 'refactor/imports/languages'
* strongly type Rust naming styles
* fix typo
* unify emitDeriveHeader for Rust
* ♻️
This commit is contained in:
@ -25,7 +25,7 @@ import { type RenderContext } from "../../Renderer";
|
||||
import { EnumOption, type Option, StringOption, getOptionValues } from "../../RendererOptions";
|
||||
import { type NamingStyle } from "../../support/Strings";
|
||||
import { TargetLanguage } from "../../TargetLanguage";
|
||||
import { type FixMeOptionsType, type FixMeOptionsAnyType } from "../../types";
|
||||
import { type FixMeOptionsAnyType, type FixMeOptionsType } from "../../types";
|
||||
|
||||
import { CJSONRenderer } from "./CJSONRenderer";
|
||||
|
||||
|
@ -16,11 +16,12 @@ import { keywords } from "./constants";
|
||||
import { type rustOptions } from "./language";
|
||||
import {
|
||||
Density,
|
||||
type NamingStyleKey,
|
||||
Visibility,
|
||||
camelNamingFunction,
|
||||
getPreferedNamingStyle,
|
||||
getPreferredNamingStyle,
|
||||
listMatchingNamingStyles,
|
||||
nameToNamingStyle,
|
||||
nameWithNamingStyle,
|
||||
namingStyles,
|
||||
rustStringEscape,
|
||||
snakeNamingFunction
|
||||
@ -121,12 +122,12 @@ export class RustRenderer extends ConvenienceRenderer {
|
||||
private emitRenameAttribute(
|
||||
propName: Name,
|
||||
jsonName: string,
|
||||
defaultNamingStyle: string,
|
||||
preferedNamingStyle: string
|
||||
defaultNamingStyle: NamingStyleKey,
|
||||
preferedNamingStyle: NamingStyleKey
|
||||
): void {
|
||||
const escapedName = rustStringEscape(jsonName);
|
||||
const name = namingStyles[defaultNamingStyle].fromParts(this.sourcelikeToString(propName).split(" "));
|
||||
const styledName = nameToNamingStyle(name, preferedNamingStyle);
|
||||
const styledName = nameWithNamingStyle(name, preferedNamingStyle);
|
||||
const namesDiffer = escapedName !== styledName;
|
||||
if (namesDiffer) {
|
||||
this.emitLine('#[serde(rename = "', escapedName, '")]');
|
||||
@ -168,7 +169,7 @@ export class RustRenderer extends ConvenienceRenderer {
|
||||
|
||||
// Set the default naming style on the struct
|
||||
const defaultStyle = "snake_case";
|
||||
const preferedNamingStyle = getPreferedNamingStyle(Object.values(propertiesNamingStyles).flat(), defaultStyle);
|
||||
const preferedNamingStyle = getPreferredNamingStyle(Object.values(propertiesNamingStyles).flat(), defaultStyle);
|
||||
if (preferedNamingStyle !== defaultStyle) {
|
||||
this.emitLine(`#[serde(rename_all = "${preferedNamingStyle}")]`);
|
||||
}
|
||||
@ -240,7 +241,7 @@ export class RustRenderer extends ConvenienceRenderer {
|
||||
|
||||
// Set the default naming style on the enum
|
||||
const defaultStyle = "PascalCase";
|
||||
const preferedNamingStyle = getPreferedNamingStyle(Object.values(enumCasesNamingStyles).flat(), defaultStyle);
|
||||
const preferedNamingStyle = getPreferredNamingStyle(Object.values(enumCasesNamingStyles).flat(), defaultStyle);
|
||||
if (preferedNamingStyle !== defaultStyle) {
|
||||
this.emitLine(`#[serde(rename_all = "${preferedNamingStyle}")]`);
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ interface NamingStyle {
|
||||
toParts: NameToParts;
|
||||
}
|
||||
|
||||
export const namingStyles: Record<string, NamingStyle> = {
|
||||
export const namingStyles = {
|
||||
snake_case: {
|
||||
regex: /^[a-z][a-z0-9]*(_[a-z0-9]+)*$/,
|
||||
toParts: (name: string): string[] => name.split("_"),
|
||||
@ -80,7 +80,11 @@ export const namingStyles: Record<string, NamingStyle> = {
|
||||
toParts: (name: string): string[] => [name],
|
||||
fromParts: (parts: string[]): string => parts.map(p => p.toUpperCase()).join("")
|
||||
}
|
||||
};
|
||||
} as const;
|
||||
|
||||
namingStyles satisfies Record<string, NamingStyle>;
|
||||
|
||||
export type NamingStyleKey = keyof typeof namingStyles;
|
||||
|
||||
const isAsciiLetterOrUnderscoreOrDigit = (codePoint: number): boolean => {
|
||||
if (!isAscii(codePoint)) {
|
||||
@ -132,13 +136,13 @@ const standardUnicodeRustEscape = (codePoint: number): string => {
|
||||
|
||||
export const rustStringEscape = utf32ConcatMap(escapeNonPrintableMapper(isPrintable, standardUnicodeRustEscape));
|
||||
|
||||
export function getPreferedNamingStyle(namingStyleOccurences: string[], defaultStyle: string): string {
|
||||
export function getPreferredNamingStyle(namingStyleOccurences: string[], defaultStyle: NamingStyleKey): NamingStyleKey {
|
||||
const occurrences = Object.fromEntries(Object.keys(namingStyles).map(key => [key, 0]));
|
||||
namingStyleOccurences.forEach(style => ++occurrences[style]);
|
||||
const max = Math.max(...Object.values(occurrences));
|
||||
const preferedStyles = Object.entries(occurrences)
|
||||
.filter(([_style, num]) => num === max)
|
||||
.map(([style, _num]) => style);
|
||||
const preferedStyles = Object.entries(occurrences).flatMap(([style, num]) =>
|
||||
num === max ? [style] : []
|
||||
) as NamingStyleKey[];
|
||||
if (preferedStyles.includes(defaultStyle)) {
|
||||
return defaultStyle;
|
||||
}
|
||||
@ -146,13 +150,13 @@ export function getPreferedNamingStyle(namingStyleOccurences: string[], defaultS
|
||||
return preferedStyles[0];
|
||||
}
|
||||
|
||||
export function listMatchingNamingStyles(name: string): string[] {
|
||||
return Object.entries(namingStyles)
|
||||
.filter(([_, { regex }]) => regex.test(name))
|
||||
.map(([namingStyle, _]) => namingStyle);
|
||||
export function listMatchingNamingStyles(name: string): NamingStyleKey[] {
|
||||
return Object.entries(namingStyles).flatMap(([namingStyleKey, { regex }]) =>
|
||||
regex.test(name) ? [namingStyleKey] : []
|
||||
) as NamingStyleKey[];
|
||||
}
|
||||
|
||||
export function nameToNamingStyle(name: string, style: string): string {
|
||||
export function nameWithNamingStyle(name: string, style: NamingStyleKey): string {
|
||||
if (namingStyles[style].regex.test(name)) {
|
||||
return name;
|
||||
}
|
||||
|
@ -10,7 +10,8 @@
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"outDir": "dist",
|
||||
"baseUrl": "src"
|
||||
"baseUrl": "src",
|
||||
"resolveJsonModule": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
|
Reference in New Issue
Block a user