add generator support
This commit is contained in:
parent
9e3b6a59cb
commit
fd83139ed5
36
README.md
36
README.md
|
@ -66,5 +66,41 @@ if (parseStatus.Of(SyntaxError)) {
|
|||
}
|
||||
```
|
||||
|
||||
## Handle functions:
|
||||
|
||||
Grip can also handle functions:
|
||||
|
||||
```javascript
|
||||
const [result, status] = grip(() => "ok");
|
||||
// result = "ok"
|
||||
|
||||
const [result1, status1] = grip(() => {
|
||||
if (1) throw new Error("error")
|
||||
});
|
||||
// result1 = null
|
||||
// status.Of(Error) = true
|
||||
```
|
||||
|
||||
## Handle generators
|
||||
|
||||
Generators can be handled using the `Iter()` method:
|
||||
|
||||
```javascript
|
||||
const res = grip(async function* () {
|
||||
for (let i = 0; i < 3; i++) {
|
||||
if (i == 2) throw new Error("2");
|
||||
yield i;
|
||||
}
|
||||
});
|
||||
for await (let [value, status] of res.Iter()) {
|
||||
if (status.Of(Error)) {
|
||||
// handle error properly
|
||||
break;
|
||||
}
|
||||
// typeof value === "number"
|
||||
console.log(value)
|
||||
}
|
||||
```
|
||||
|
||||
## License
|
||||
MIT
|
||||
|
|
48
dist/grip.js
vendored
48
dist/grip.js
vendored
|
@ -67,13 +67,57 @@ class Result extends Array {
|
|||
Fail() {
|
||||
return this[1].Fail();
|
||||
}
|
||||
Of(impl) {
|
||||
return this[1].Of(impl);
|
||||
Of(cls) {
|
||||
return this[1].Of(cls);
|
||||
}
|
||||
Iter() {
|
||||
const value = this.value;
|
||||
const that = this;
|
||||
if (typeof value !== "object" && !(typeof value[Symbol.iterator] === "function" || typeof value[Symbol.asyncIterator] === "function")) {
|
||||
return {
|
||||
async* [Symbol.asyncIterator]() {
|
||||
yield new Result(that.value, that.status);
|
||||
},
|
||||
*[Symbol.iterator]() {
|
||||
yield new Result(that.value, that.status);
|
||||
}
|
||||
};
|
||||
}
|
||||
return {
|
||||
async* [Symbol.asyncIterator]() {
|
||||
yield* asyncIterator(value);
|
||||
},
|
||||
*[Symbol.iterator]() {
|
||||
yield* iterator(value);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
var promise = (result) => {
|
||||
return result.then((res) => new Result(res, new Ok)).catch((err) => new Result(null, Err.fromCatch(err)));
|
||||
};
|
||||
var iterator = function* (iter) {
|
||||
try {
|
||||
let data = iter.next();
|
||||
while (!data.done) {
|
||||
yield new Result(data.value, new Ok);
|
||||
data = iter.next();
|
||||
}
|
||||
} catch (e) {
|
||||
yield new Result(null, Err.fromCatch(e));
|
||||
}
|
||||
};
|
||||
var asyncIterator = async function* (iter) {
|
||||
try {
|
||||
let data = await iter.next();
|
||||
while (!data.done) {
|
||||
yield new Result(data.value, new Ok);
|
||||
data = await iter.next();
|
||||
}
|
||||
} catch (e) {
|
||||
yield new Result(null, Err.fromCatch(e));
|
||||
}
|
||||
};
|
||||
export {
|
||||
grip,
|
||||
Ok,
|
||||
|
|
32
grip.test.ts
32
grip.test.ts
|
@ -63,3 +63,35 @@ test("fetch json", async () => {
|
|||
expect(jsonStatus.Of(SyntaxError)).toBe(true);
|
||||
expect(json === null).toBe(true);
|
||||
});
|
||||
|
||||
test("function*", async () => {
|
||||
const res = grip(function* () {
|
||||
for (let i = 0; i < 3; i++) {
|
||||
if (i == 2) throw new Error("2");
|
||||
yield i;
|
||||
}
|
||||
});
|
||||
expect(res.Ok()).toBe(true);
|
||||
for (let [value, status] of res.Iter()) {
|
||||
if (status.Of(Error)) {
|
||||
break;
|
||||
}
|
||||
expect(value).toBeTypeOf("number");
|
||||
}
|
||||
});
|
||||
|
||||
test("async function*", async () => {
|
||||
const res = grip(async function* () {
|
||||
for (let i = 0; i < 3; i++) {
|
||||
if (i == 2) throw new Error("2");
|
||||
yield i;
|
||||
}
|
||||
});
|
||||
expect(res.Ok()).toBe(true);
|
||||
for await (let [value, status] of res.Iter()) {
|
||||
if (status.Of(Error)) {
|
||||
break;
|
||||
}
|
||||
expect(value).toBeTypeOf("number");
|
||||
}
|
||||
});
|
||||
|
|
62
grip.ts
62
grip.ts
|
@ -69,13 +69,45 @@ class Result<T> extends Array<T | Status> implements IResult<T> {
|
|||
Fail() {
|
||||
return (this[1] as Status).Fail();
|
||||
}
|
||||
Of(impl: any) {
|
||||
return (this[1] as Status).Of(impl);
|
||||
Of(cls: any) {
|
||||
return (this[1] as Status).Of(cls);
|
||||
}
|
||||
Iter() {
|
||||
const value = this.value;
|
||||
const that = this;
|
||||
if (
|
||||
typeof value !== "object" &&
|
||||
!(
|
||||
typeof (value as any)[Symbol.iterator] === "function" ||
|
||||
typeof (value as any)[Symbol.asyncIterator] === "function"
|
||||
)
|
||||
) {
|
||||
return {
|
||||
async *[Symbol.asyncIterator]() {
|
||||
yield new Result(that.value, that.status) as SafeResult<T>;
|
||||
},
|
||||
*[Symbol.iterator]() {
|
||||
yield new Result(that.value, that.status) as SafeResult<T>;
|
||||
},
|
||||
};
|
||||
}
|
||||
return {
|
||||
async *[Symbol.asyncIterator]() {
|
||||
yield* asyncIterator<T>(value as AsyncGenerator);
|
||||
},
|
||||
*[Symbol.iterator]() {
|
||||
yield* iterator<T>(value as Generator);
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
type Unwrap<T> =
|
||||
T extends Promise<infer U>
|
||||
T extends AsyncGenerator<infer U>
|
||||
? U
|
||||
: T extends Generator<infer U>
|
||||
? U
|
||||
: T extends Promise<infer U>
|
||||
? U
|
||||
: T extends (...args: any) => Promise<infer U>
|
||||
? U
|
||||
|
@ -110,3 +142,27 @@ const promise = <T>(result: Promise<T>) => {
|
|||
.then((res) => new Result(res, new Ok()))
|
||||
.catch((err) => new Result(null, Err.fromCatch(err))) as Promise<Result<T>>;
|
||||
};
|
||||
|
||||
const iterator = function* <T>(iter: Generator) {
|
||||
try {
|
||||
let data = iter.next();
|
||||
while (!data.done) {
|
||||
yield new Result<T>(data.value as T, new Ok()) as SafeResult<T>;
|
||||
data = iter.next();
|
||||
}
|
||||
} catch (e) {
|
||||
yield new Result<T>(null as T, Err.fromCatch(e)) as SafeResult<T>;
|
||||
}
|
||||
};
|
||||
|
||||
const asyncIterator = async function* <T>(iter: AsyncGenerator) {
|
||||
try {
|
||||
let data = await iter.next();
|
||||
while (!data.done) {
|
||||
yield new Result<T>(data.value as T, new Ok()) as SafeResult<T>;
|
||||
data = await iter.next();
|
||||
}
|
||||
} catch (e) {
|
||||
yield new Result<T>(null as T, Err.fromCatch(e)) as SafeResult<T>;
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue