Skip to content

Commit

Permalink
Native enums
Browse files Browse the repository at this point in the history
  • Loading branch information
Vorlias committed Dec 26, 2021
1 parent 5001a8e commit 43307e2
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 87 deletions.
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,6 @@
"@rbxts/snapdragon": "2.0.0-beta.1",
"@rbxts/string-utils": "^1.0.3",
"@rbxts/t": "^1.3.5",
"@rbxts/zirconium": "^1.0.4"
"@rbxts/zirconium": "^1.1.0-beta.0"
}
}
62 changes: 20 additions & 42 deletions src/Class/ZirconEnum.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ZrObjectUserdata } from "@rbxts/zirconium/out/Data/Userdata";
import { ZrEnum } from "@rbxts/zirconium/out/Data/Enum";
import { ZirconEnumItem } from "./ZirconEnumItem";
import { ZirconValidator } from "./ZirconTypeValidator";

Expand All @@ -12,45 +12,27 @@ export type ZirconEnumValidator<K extends string> = ZirconValidator<
>;

/**
* High level Enum wrapper for Zircon
* An extension of the `ZrEnum` class for Zircon
*/
export class ZirconEnum<K extends string> extends ZrObjectUserdata<readonly ZirconEnumItem[]> {
private name: string;
public constructor(name: string, private members: K[]) {
super(members.map((member, i) => new ZirconEnumItem(this, i, member)));
this.name = name;
}

/**
* Gets the values of this EnumType
* @returns The enum value
*/
public GetEnumItems() {
return this.value();
}

/**
* Gets the name of this EnumType
* @returns
*/
public GetName() {
return this.name;
export class ZirconEnum<K extends string> extends ZrEnum {
public constructor(name: string, members: K[]) {
super(members, name);
}

/**
* Returns whether or not the specified value is an ZirconEnumItem of this type
* @returns
*/
public Is(value: ZirconEnumItem<any>): value is ZirconEnumItem<ZirconEnum<K>, K> {
return this.value().includes(value);
public is(value: ZirconEnumItem<any>): value is ZirconEnumItem<ZirconEnum<K>, K> {
return this.getItems().includes(value);
}

/**
* Gets an enum item value by key
* @param key The key
*/
public GetItem<TKey extends K>(key: TKey) {
return this.value().find((k) => k.GetName() === key)! as ZirconEnumItem<ZirconEnum<K>, TKey>;
public getItem<TKey extends K>(key: TKey) {
return this.getItems().find((k) => k.getName() === key)! as ZirconEnumItem<ZirconEnum<K>, TKey>;
}

/**
Expand All @@ -60,10 +42,10 @@ export class ZirconEnum<K extends string> extends ZrObjectUserdata<readonly Zirc
* @param value The enum item
* @param matches The matches
*/
public Match<R>(value: ZirconEnumItem, matches: EnumMatchTree<ZirconEnum<K>, K, R> & { _?: () => R }): R {
for (const member of this.value()) {
public match<R>(value: ZirconEnumItem, matches: EnumMatchTree<ZirconEnum<K>, K, R> & { _?: () => R }): R {
for (const member of this.getItems()) {
if (member === value) {
return matches[member.GetName() as K](value as ZirconEnumItem<ZirconEnum<K>, K>);
return matches[member.getName() as K](value as ZirconEnumItem<ZirconEnum<K>, K>);
}
}

Expand All @@ -73,36 +55,32 @@ export class ZirconEnum<K extends string> extends ZrObjectUserdata<readonly Zirc
throw `Invalid match`;
}

public GetMemberType(): ZirconEnumValidator<K> {
public getMemberType(): ZirconEnumValidator<K> {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const thisRef = this;
return {
Validate(value): value is ZirconEnumItem<ZirconEnum<K>, K> | string {
print("validate", value, thisRef.value());
print("validate", value, thisRef.getItems());
return (
(typeIs(value, "string") &&
thisRef.value().find((f) => f.GetName().lower() === value.lower()) !== undefined) ||
(typeIs(value, "number") && thisRef.value().find((f) => f.GetId() === value) !== undefined) ||
(value instanceof ZirconEnumItem && (value.GetEnumType() as ZirconEnum<any>) === thisRef)
thisRef.getItems().find((f) => f.getName().lower() === value.lower()) !== undefined) ||
(typeIs(value, "number") && thisRef.getItems().find((f) => f.getValue() === value) !== undefined) ||
(value instanceof ZirconEnumItem && (value.getEnum() as ZirconEnum<any>) === thisRef)
);
},
Transform(value) {
if (typeIs(value, "string")) {
return thisRef.value().find((v) => v.GetName().lower() === value.lower())! as ZirconEnumItem<
return thisRef.getItems().find((v) => v.getName().lower() === value.lower())! as ZirconEnumItem<
ZirconEnum<K>,
K
>;
} else if (typeIs(value, "number")) {
return thisRef.value().find((v) => v.GetId() === value)! as ZirconEnumItem<ZirconEnum<K>, K>;
return thisRef.getItems().find((v) => v.getValue() === value)! as ZirconEnumItem<ZirconEnum<K>, K>;
} else {
return value as ZirconEnumItem<ZirconEnum<K>, K>;
}
},
Type: "ZirconEnum[" + this.members.join(" | ") + "]",
Type: "ZirconEnum[" + this.getEnumName() + "]",
};
}

public toString() {
return `[Enum '` + this.name + "']";
}
}
42 changes: 7 additions & 35 deletions src/Class/ZirconEnumItem.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,23 @@
import { ZrEnumItem } from "@rbxts/zirconium/out/Data/Enum";
import { ZrObjectUserdata } from "@rbxts/zirconium/out/Data/Userdata";
import { ZirconEnum, EnumMatchTree } from "./ZirconEnum";

/**
* High level enum item wrapper for Zircon
* An extension of the `ZrEnumItem` class for Zircon.
*/

export class ZirconEnumItem<
TParent extends ZirconEnum<string> = ZirconEnum<string>,
K extends string = string
> extends ZrObjectUserdata<K> {
public constructor(private enumParent: TParent, private id: number, private name: K) {
super(name);
}

/**
* Gets the numeric value of this enum
* @returns The numeric value
*/
public GetId() {
return this.id;
}

/**
* Gets the string literal value of this enum
* @returns The value
*/
public GetName() {
return this.name;
}

/**
* Gets the Enum of this EnumItem
* @returns The Enum
*/
public GetEnumType() {
return this.enumParent as TParent;
> extends ZrEnumItem {
public constructor(private enumParent: TParent, id: number, name: K) {
super(enumParent, id, name);
}

/**
* Performs a match against this enum value - similar to `match` in Rust.
* @param matches The matches to check against
*/
public Match<R>(matches: EnumMatchTree<TParent, K, R>) {
return matches[this.GetName()](this);
}

public toString() {
return tostring(this.enumParent) + "::[EnumItem '" + this.name + "']";
public match<R>(matches: EnumMatchTree<TParent, K, R>) {
return matches[this.getName() as K](this);
}
}
2 changes: 1 addition & 1 deletion src/Class/ZirconFunctionBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class ZirconFunctionBuilder<V extends ZirconValidator<unknown, unknown>[]
if (typeIs(argValidator, "string")) {
validator = BuiltInValidators[argValidator as keyof BuiltInValidators];
} else if (argValidator instanceof ZirconEnum) {
validator = argValidator.GetMemberType();
validator = argValidator.getMemberType();
} else {
validator = argValidator;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Services/DispatchService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export namespace ZirconDispatchService {
const Registry = GetCommandService("RegistryService");
return Promise.defer<ZrScript>((resolve, reject) => {
const [mainScript] = Registry.GetScriptContextsForPlayer(player);
const source = mainScript.parseSource(text, ZrScriptVersion.Zr2021);
const source = mainScript.parseSource(text, ZrScriptVersion.Zr2022);
if (source.isOk()) {
resolve(mainScript.createScript(source.okValue));
} else {
Expand Down

0 comments on commit 43307e2

Please sign in to comment.