minor improvements

This commit is contained in:
Anton Nesterov 2024-10-18 00:51:30 +02:00
parent 635d2aea06
commit 61e63987d1
No known key found for this signature in database
GPG key ID: 59121E8AE2851FB5
4 changed files with 37 additions and 37 deletions

View file

@ -11,10 +11,12 @@ It makes the control flow similar to that of Golang, but doesn't force you to ma
Instead of returning a nullish error, Grip always returns a consistent status object:
```javascript
const [value, status] = grip(callable)
const [value, status] = grip(callable) // or {value, status}
if (status.of(MySpecificError)) {
// handle specific error
}
if (status.fail()) {
// handle any error
}
@ -24,13 +26,15 @@ The call result is better than tuple:
```javascript
const result = grip(callable)
if (result.fail()) {
// handle any error
}
if (result.of(MySpecificError)) {
// handle specific error
}
if (result.fail()) {
// handle any error
}
console.log(result.value) // result[0]
```
@ -51,7 +55,7 @@ The result can be hadled as either an object or a tuple.
import { grip } from '@nesterow/grip';
```
## Handle result as an object:
## Handle result as an object
The result can be handled as an object: `{value, status, Ok(), Fail(), Of(type)}`
@ -60,7 +64,7 @@ const res = await grip(
fetch('https://api.example.com')
);
if (res.Fail()) {
if (res.fail()) {
// handle error
return;
}
@ -69,14 +73,14 @@ const json = await grip(
res.value.json()
);
if (json.Of(SyntaxError)) {
if (json.of(SyntaxError)) {
// handle parse error
return;
}
```
## Handle result as a tuple:
## Handle result as a tuple
The result can also be received as a tuple if you want to handle errors in Go'ish style:
@ -84,7 +88,7 @@ The result can also be received as a tuple if you want to handle errors in Go'is
const [res, fetchStatus] = await grip(
fetch('https://api.example.com')
);
if (fetchStatus.Fail()) {
if (fetchStatus.fail()) {
// handle error
return;
}
@ -92,13 +96,13 @@ if (fetchStatus.Fail()) {
const [json, parseStatus] = await grip(
res.json()
);
if (parseStatus.Of(SyntaxError)) {
if (parseStatus.of(SyntaxError)) {
// handle parse error
return;
}
```
## Handle functions:
## Handle functions
Grip can also handle functions:
@ -124,8 +128,8 @@ const res = grip(async function* () {
yield i;
}
});
for await (let [value, status] of res.Iter()) {
if (status.Of(Error)) {
for await (let [value, status] of res.iter()) {
if (status.of(Error)) {
// handle error properly
break;
}

8
dist/grip.js vendored
View file

@ -123,8 +123,12 @@ class Result extends Array {
return this.Iter();
}
}
var promise = (result) => {
return result.then((res) => new Result(res, new Ok)).catch((err) => new Result(null, Err.fromCatch(err)));
var promise = async (result) => {
try {
return new Result(await result, new Ok);
} catch (err) {
return new Result(null, Err.fromCatch(err));
}
};
var iterator = function* (iter) {
try {

View file

@ -89,7 +89,7 @@ test("async function*", async () => {
});
expect(res.Ok()).toBe(true);
for await (let [value, status] of res.Iter()) {
if (status.Of(Error)) {
if (status.of(Error)) {
break;
}
expect(value).toBeTypeOf("number");

34
grip.ts
View file

@ -2,13 +2,10 @@ interface Status {
message?: string;
cause?: any;
Ok(): boolean;
/* alias Ok */
ok(): boolean;
Fail(): boolean;
/* alias Fail */
fail(): boolean;
Of(cls: any): boolean;
/* alias Of */
of(cls: any): boolean;
}
@ -16,21 +13,18 @@ export class Err extends Error {
Ok() {
return false;
}
/* alias Ok */
ok() {
return this.Ok();
}
Fail() {
return true;
}
/* alias Fail */
fail() {
return this.Fail();
}
Of(cls: any) {
return this.cause instanceof cls || this instanceof cls;
}
/* alias Of */
of(cls: any) {
return this.Of(cls);
}
@ -46,21 +40,18 @@ export class Ok {
Ok() {
return true;
}
/* alias Ok */
ok() {
return this.Ok();
}
Fail() {
return false;
}
/* alias Fail */
fail() {
return this.Fail();
}
Of(cls: any) {
return this instanceof cls;
}
/* alias Of */
of(cls: any) {
return this.Of(cls);
}
@ -96,21 +87,18 @@ class Result<T> extends Array<T | Status> implements IResult<T> {
Ok() {
return (this[1] as Status).Ok();
}
/* alias Ok */
ok() {
return this.Ok();
}
Fail() {
return (this[1] as Status).Fail();
}
/* alias Fail */
fail() {
return this.Fail();
}
Of(cls: any) {
return (this[1] as Status).Of(cls);
}
/* alias Of */
of(cls: any) {
return this.Of(cls);
}
@ -142,7 +130,6 @@ class Result<T> extends Array<T | Status> implements IResult<T> {
},
};
}
/* alias Iter */
iter() {
return this.Iter();
}
@ -168,7 +155,7 @@ export type SafeResult<T> =
? Promise<Result<Unwrap<T>>>
: Result<Unwrap<T>>;
export function grip<T>(action: T): SafeResult<T> {
export function grip<T>(action: T) {
if (action instanceof Promise) {
return promise<T>(action) as SafeResult<T>;
}
@ -179,14 +166,19 @@ export function grip<T>(action: T): SafeResult<T> {
}
return new Result<T>(result, new Ok()) as SafeResult<T>;
} catch (err: any) {
return new Result<T>(null as any, Err.fromCatch(err)) as SafeResult<T>;
return new Result<T>(
null as never,
Err.fromCatch(err),
) as SafeResult<never>;
}
}
const promise = <T>(result: Promise<T>) => {
return result
.then((res) => new Result(res, new Ok()))
.catch((err) => new Result(null, Err.fromCatch(err))) as Promise<Result<T>>;
const promise = async <T>(result: Promise<T>) => {
try {
return new Result(await result, new Ok());
} catch (err) {
return new Result<never>(null as never, Err.fromCatch(err));
}
};
const iterator = function* <T>(iter: Generator) {
@ -197,7 +189,7 @@ const iterator = function* <T>(iter: Generator) {
data = iter.next();
}
} catch (e) {
yield new Result<T>(null as T, Err.fromCatch(e)) as SafeResult<T>;
yield new Result<T>(null as never, Err.fromCatch(e)) as SafeResult<never>;
}
};
@ -209,6 +201,6 @@ const asyncIterator = async function* <T>(iter: AsyncGenerator) {
data = await iter.next();
}
} catch (e) {
yield new Result<T>(null as T, Err.fromCatch(e)) as SafeResult<T>;
yield new Result<T>(null as T, Err.fromCatch(e)) as SafeResult<never>;
}
};