happy-rusty 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.cn.md +64 -0
- package/README.md +5 -1
- package/dist/main.cjs +40 -55
- package/dist/main.cjs.map +1 -1
- package/dist/main.mjs +35 -47
- package/dist/main.mjs.map +1 -1
- package/dist/types.d.ts +35 -33
- package/dist/types.d.ts.map +1 -1
- package/package.json +12 -22
- package/src/enum/option.ts +68 -0
- package/src/enum/result.ts +102 -0
- package/src/mod.ts +2 -0
package/README.cn.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# 在JavaScript中使用Rust特性
|
|
2
|
+
|
|
3
|
+
## 部分支持的特性
|
|
4
|
+
|
|
5
|
+
* [option](https://doc.rust-lang.org/core/option/index.html)
|
|
6
|
+
* [result](https://doc.rust-lang.org/core/result/index.html)
|
|
7
|
+
|
|
8
|
+
## 更多特性敬请期待
|
|
9
|
+
|
|
10
|
+
## 安装
|
|
11
|
+
|
|
12
|
+
通过 [JSR](https://jsr.io/@happy-js/happy-rusty) (**推荐**)
|
|
13
|
+
```
|
|
14
|
+
npx jsr add @happy-js/happy-rusty
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
或者直接使用 npm
|
|
18
|
+
```
|
|
19
|
+
npm install --save happy-rusty
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
通过 deno
|
|
23
|
+
```
|
|
24
|
+
deno add @happy-js/happy-rusty
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
通过 bun
|
|
28
|
+
```
|
|
29
|
+
bunx jsr add @happy-js/happy-rusty
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
接下来就可以在代码里引用了。
|
|
33
|
+
```ts
|
|
34
|
+
import { Some, None, Ok, Err } from '@happy-js/happy-rusty';
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 示例
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import { Some, None, Ok, Err } from '@happy-js/happy-rusty';
|
|
41
|
+
|
|
42
|
+
function judge(n: number): Option<Promise<Result<number, Error>>> {
|
|
43
|
+
if (n < 0 || n >= 1) {
|
|
44
|
+
return None;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return Some(new Promise(resolve => {
|
|
48
|
+
const r = Math.random();
|
|
49
|
+
resolve(r > n ? Ok(r) : Err(new Error('lose')));
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const res = judge(0.8);
|
|
54
|
+
if (res.isNone()) {
|
|
55
|
+
console.error('invalid number');
|
|
56
|
+
} else {
|
|
57
|
+
const result = await res.unwrap();
|
|
58
|
+
if (result.isErr()) {
|
|
59
|
+
console.assert(result.err().message === 'lose');
|
|
60
|
+
} else {
|
|
61
|
+
console.log(result.unwrap()); // must greater than 0.8
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
package/README.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="README.cn.md">[中文]</a>
|
|
3
|
+
</p>
|
|
4
|
+
|
|
1
5
|
# Use Rust features in JavaScript happily
|
|
2
6
|
|
|
3
7
|
## Partial supported
|
|
@@ -9,7 +13,7 @@
|
|
|
9
13
|
|
|
10
14
|
## Installation
|
|
11
15
|
|
|
12
|
-
Via [JSR](https://jsr.io/@happy-js/happy-rusty)(**recommand**)
|
|
16
|
+
Via [JSR](https://jsr.io/@happy-js/happy-rusty) (**recommand**)
|
|
13
17
|
```
|
|
14
18
|
npx jsr add @happy-js/happy-rusty
|
|
15
19
|
```
|
package/dist/main.cjs
CHANGED
|
@@ -1,62 +1,47 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
*/ /**
|
|
14
|
-
* option::Some type
|
|
15
|
-
*/ function $49294c54424499ce$export$9f9d0139d032da4f(value) {
|
|
16
|
-
if (value == null) throw new Error("Some value can not be null or undefined");
|
|
17
|
-
return {
|
|
18
|
-
kind: "Some",
|
|
19
|
-
isSome: ()=>true,
|
|
20
|
-
isNone: ()=>false,
|
|
21
|
-
unwrap: ()=>value
|
|
22
|
-
};
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function Some(value) {
|
|
4
|
+
if (value == null) {
|
|
5
|
+
throw new TypeError("Some value can not be null or undefined");
|
|
6
|
+
}
|
|
7
|
+
return {
|
|
8
|
+
kind: "Some",
|
|
9
|
+
isSome: () => true,
|
|
10
|
+
isNone: () => false,
|
|
11
|
+
unwrap: () => value
|
|
12
|
+
};
|
|
23
13
|
}
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
14
|
+
const None = {
|
|
15
|
+
kind: "None",
|
|
16
|
+
isSome: () => false,
|
|
17
|
+
isNone: () => true,
|
|
18
|
+
unwrap: () => {
|
|
19
|
+
throw new TypeError("None can not unwrap");
|
|
20
|
+
}
|
|
31
21
|
};
|
|
32
22
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return {
|
|
41
|
-
kind: "Ok",
|
|
42
|
-
isOk: ()=>true,
|
|
43
|
-
isErr: ()=>false,
|
|
44
|
-
unwrap: ()=>value
|
|
45
|
-
};
|
|
23
|
+
function Ok(value) {
|
|
24
|
+
return {
|
|
25
|
+
kind: "Ok",
|
|
26
|
+
isOk: () => true,
|
|
27
|
+
isErr: () => false,
|
|
28
|
+
unwrap: () => value
|
|
29
|
+
};
|
|
46
30
|
}
|
|
47
|
-
function
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
31
|
+
function Err(error) {
|
|
32
|
+
return {
|
|
33
|
+
kind: "Err",
|
|
34
|
+
isOk: () => false,
|
|
35
|
+
isErr: () => true,
|
|
36
|
+
unwrap: () => {
|
|
37
|
+
throw error;
|
|
38
|
+
},
|
|
39
|
+
err: () => error
|
|
40
|
+
};
|
|
57
41
|
}
|
|
58
42
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
43
|
+
exports.Err = Err;
|
|
44
|
+
exports.None = None;
|
|
45
|
+
exports.Ok = Ok;
|
|
46
|
+
exports.Some = Some;
|
|
62
47
|
//# sourceMappingURL=main.cjs.map
|
package/dist/main.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"
|
|
1
|
+
{"version":3,"file":"main.cjs","sources":["../src/enum/option.ts","../src/enum/result.ts"],"sourcesContent":["/**\n * @fileoverview 仿rust的[Option](https://doc.rust-lang.org/core/option/index.html)枚举,\n * 用于替代null和undefined的使用。\n */\n\n/**\n * option::Some type\n */\ninterface Some<T> {\n readonly kind: 'Some';\n readonly isSome: (this: Option<T>) => this is Some<T>;\n readonly isNone: (this: Option<T>) => this is None;\n readonly unwrap: () => T;\n}\n\n/**\n * option::None type\n */\ninterface None {\n readonly kind: 'None';\n readonly isSome: <T>(this: Option<T>) => this is Some<T>;\n readonly isNone: <T>(this: Option<T>) => this is None;\n readonly unwrap: () => never;\n}\n\n/**\n * option::Option type\n */\nexport type Option<T> = Some<T> | None;\n\n/**\n * 创建一个`Some`对象\n *\n * # Examples\n *\n * ```\n * const v = Some(10);\n * console.assert(v.unwrap() === 10);\n * ```\n *\n * @param value 被包裹的值,不能为null和undefined\n * @returns {Some}\n */\nexport function Some<T>(value: T): Option<T> {\n if (value == null) {\n throw new TypeError('Some value can not be null or undefined');\n }\n\n return {\n kind: 'Some',\n isSome: () => true,\n isNone: () => false,\n unwrap: () => value,\n } as const;\n}\n\n/**\n * `None`值是固定的\n * @constant {None}\n */\nexport const None: None = {\n kind: 'None',\n isSome: () => false,\n isNone: () => true,\n unwrap: () => {\n throw new TypeError('None can not unwrap');\n },\n} as const;","/**\n * @fileoverview 仿rust的[Result](https://doc.rust-lang.org/core/result/index.html)枚举,\n * 用于错误处理。\n */\n\n\n/**\n * result::Ok type\n */\ninterface Ok<T, E> {\n readonly kind: 'Ok';\n readonly isOk: (this: Result<T, E>) => this is Ok<T, E>;\n readonly isErr: (this: Result<T, E>) => this is Err<T, E>;\n readonly unwrap: () => T;\n}\n\n/**\n * result::Err type\n */\ninterface Err<T, E> {\n readonly kind: 'Err';\n readonly isOk: (this: Result<T, E>) => this is Ok<T, E>;\n readonly isErr: (this: Result<T, E>) => this is Err<T, E>;\n readonly unwrap: () => never;\n readonly err: () => E;\n}\n\n/**\n * result::Result type\n */\nexport type Result<T, E> = Ok<T, E> | Err<T, E>;\n\n/**\n * 创建一个`Ok`对象\n *\n * # Examples\n *\n * ```\n * const v = Ok(10);\n * console.assert(v.unwrap() === 10);\n *\nfunction judge(n: number): Option<Promise<Result<number, Error>>> {\n if (n < 0 || n >= 1) {\n return None;\n }\n\n return Some(new Promise(resolve => {\n const r = Math.random();\n resolve(r > n ? Ok(r) : Err(new Error('lose')));\n }));\n}\n\nconst res = judge(0.8);\nif (res.isNone()) {\n console.error('invalid number');\n} else {\n const result = await res.unwrap();\n if (result.isErr()) {\n console.assert(result.err().message === 'lose');\n } else {\n console.log(result.unwrap()); // must greater than 0.8\n }\n}\n *\n * ```\n *\n * @param value 被包裹的值\n * @returns {Ok}\n */\nexport function Ok<T, E>(value: T): Result<T, E> {\n return {\n kind: 'Ok',\n isOk: () => true,\n isErr: () => false,\n unwrap: () => value,\n } as const;\n}\n\n/**\n * 创建一个`Err`对象\n *\n * # Examples\n *\n * ```\n * const e = Err(new Error('unknown error'));\n * console.assert(e.err().message === 'unknown error');\n * ```\n *\n * @param error 被包裹的错误\n * @returns {Err}\n */\nexport function Err<T, E>(error: E): Result<T, E> {\n return {\n kind: 'Err',\n isOk: () => false,\n isErr: () => true,\n unwrap: () => {\n throw error;\n },\n err: () => error,\n } as const;\n}"],"names":[],"mappings":";;AA2CO,SAAS,KAAQ,KAAqB,EAAA;AACzC,EAAA,IAAI,SAAS,IAAM,EAAA;AACf,IAAM,MAAA,IAAI,UAAU,yCAAyC,CAAA,CAAA;AAAA,GACjE;AAEA,EAAO,OAAA;AAAA,IACH,IAAM,EAAA,MAAA;AAAA,IACN,QAAQ,MAAM,IAAA;AAAA,IACd,QAAQ,MAAM,KAAA;AAAA,IACd,QAAQ,MAAM,KAAA;AAAA,GAClB,CAAA;AACJ,CAAA;AAMO,MAAM,IAAa,GAAA;AAAA,EACtB,IAAM,EAAA,MAAA;AAAA,EACN,QAAQ,MAAM,KAAA;AAAA,EACd,QAAQ,MAAM,IAAA;AAAA,EACd,QAAQ,MAAM;AACV,IAAM,MAAA,IAAI,UAAU,qBAAqB,CAAA,CAAA;AAAA,GAC7C;AACJ;;ACEO,SAAS,GAAS,KAAwB,EAAA;AAC7C,EAAO,OAAA;AAAA,IACH,IAAM,EAAA,IAAA;AAAA,IACN,MAAM,MAAM,IAAA;AAAA,IACZ,OAAO,MAAM,KAAA;AAAA,IACb,QAAQ,MAAM,KAAA;AAAA,GAClB,CAAA;AACJ,CAAA;AAeO,SAAS,IAAU,KAAwB,EAAA;AAC9C,EAAO,OAAA;AAAA,IACH,IAAM,EAAA,KAAA;AAAA,IACN,MAAM,MAAM,KAAA;AAAA,IACZ,OAAO,MAAM,IAAA;AAAA,IACb,QAAQ,MAAM;AACV,MAAM,MAAA,KAAA,CAAA;AAAA,KACV;AAAA,IACA,KAAK,MAAM,KAAA;AAAA,GACf,CAAA;AACJ;;;;;;;"}
|
package/dist/main.mjs
CHANGED
|
@@ -1,54 +1,42 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
isNone: ()=>false,
|
|
12
|
-
unwrap: ()=>value
|
|
13
|
-
};
|
|
1
|
+
function Some(value) {
|
|
2
|
+
if (value == null) {
|
|
3
|
+
throw new TypeError("Some value can not be null or undefined");
|
|
4
|
+
}
|
|
5
|
+
return {
|
|
6
|
+
kind: "Some",
|
|
7
|
+
isSome: () => true,
|
|
8
|
+
isNone: () => false,
|
|
9
|
+
unwrap: () => value
|
|
10
|
+
};
|
|
14
11
|
}
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
12
|
+
const None = {
|
|
13
|
+
kind: "None",
|
|
14
|
+
isSome: () => false,
|
|
15
|
+
isNone: () => true,
|
|
16
|
+
unwrap: () => {
|
|
17
|
+
throw new TypeError("None can not unwrap");
|
|
18
|
+
}
|
|
22
19
|
};
|
|
23
20
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return {
|
|
32
|
-
kind: "Ok",
|
|
33
|
-
isOk: ()=>true,
|
|
34
|
-
isErr: ()=>false,
|
|
35
|
-
unwrap: ()=>value
|
|
36
|
-
};
|
|
21
|
+
function Ok(value) {
|
|
22
|
+
return {
|
|
23
|
+
kind: "Ok",
|
|
24
|
+
isOk: () => true,
|
|
25
|
+
isErr: () => false,
|
|
26
|
+
unwrap: () => value
|
|
27
|
+
};
|
|
37
28
|
}
|
|
38
|
-
function
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
29
|
+
function Err(error) {
|
|
30
|
+
return {
|
|
31
|
+
kind: "Err",
|
|
32
|
+
isOk: () => false,
|
|
33
|
+
isErr: () => true,
|
|
34
|
+
unwrap: () => {
|
|
35
|
+
throw error;
|
|
36
|
+
},
|
|
37
|
+
err: () => error
|
|
38
|
+
};
|
|
48
39
|
}
|
|
49
40
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
export {$a89c3c570c820c73$export$57ca7e07b341709d as None, $a89c3c570c820c73$export$9f9d0139d032da4f as Some, $e04e55a8aca8db85$export$3659d3f2d3dfceb8 as Err, $e04e55a8aca8db85$export$8146e38189b4f4dc as Ok};
|
|
41
|
+
export { Err, None, Ok, Some };
|
|
54
42
|
//# sourceMappingURL=main.mjs.map
|
package/dist/main.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"
|
|
1
|
+
{"version":3,"file":"main.mjs","sources":["../src/enum/option.ts","../src/enum/result.ts"],"sourcesContent":["/**\n * @fileoverview 仿rust的[Option](https://doc.rust-lang.org/core/option/index.html)枚举,\n * 用于替代null和undefined的使用。\n */\n\n/**\n * option::Some type\n */\ninterface Some<T> {\n readonly kind: 'Some';\n readonly isSome: (this: Option<T>) => this is Some<T>;\n readonly isNone: (this: Option<T>) => this is None;\n readonly unwrap: () => T;\n}\n\n/**\n * option::None type\n */\ninterface None {\n readonly kind: 'None';\n readonly isSome: <T>(this: Option<T>) => this is Some<T>;\n readonly isNone: <T>(this: Option<T>) => this is None;\n readonly unwrap: () => never;\n}\n\n/**\n * option::Option type\n */\nexport type Option<T> = Some<T> | None;\n\n/**\n * 创建一个`Some`对象\n *\n * # Examples\n *\n * ```\n * const v = Some(10);\n * console.assert(v.unwrap() === 10);\n * ```\n *\n * @param value 被包裹的值,不能为null和undefined\n * @returns {Some}\n */\nexport function Some<T>(value: T): Option<T> {\n if (value == null) {\n throw new TypeError('Some value can not be null or undefined');\n }\n\n return {\n kind: 'Some',\n isSome: () => true,\n isNone: () => false,\n unwrap: () => value,\n } as const;\n}\n\n/**\n * `None`值是固定的\n * @constant {None}\n */\nexport const None: None = {\n kind: 'None',\n isSome: () => false,\n isNone: () => true,\n unwrap: () => {\n throw new TypeError('None can not unwrap');\n },\n} as const;","/**\n * @fileoverview 仿rust的[Result](https://doc.rust-lang.org/core/result/index.html)枚举,\n * 用于错误处理。\n */\n\n\n/**\n * result::Ok type\n */\ninterface Ok<T, E> {\n readonly kind: 'Ok';\n readonly isOk: (this: Result<T, E>) => this is Ok<T, E>;\n readonly isErr: (this: Result<T, E>) => this is Err<T, E>;\n readonly unwrap: () => T;\n}\n\n/**\n * result::Err type\n */\ninterface Err<T, E> {\n readonly kind: 'Err';\n readonly isOk: (this: Result<T, E>) => this is Ok<T, E>;\n readonly isErr: (this: Result<T, E>) => this is Err<T, E>;\n readonly unwrap: () => never;\n readonly err: () => E;\n}\n\n/**\n * result::Result type\n */\nexport type Result<T, E> = Ok<T, E> | Err<T, E>;\n\n/**\n * 创建一个`Ok`对象\n *\n * # Examples\n *\n * ```\n * const v = Ok(10);\n * console.assert(v.unwrap() === 10);\n *\nfunction judge(n: number): Option<Promise<Result<number, Error>>> {\n if (n < 0 || n >= 1) {\n return None;\n }\n\n return Some(new Promise(resolve => {\n const r = Math.random();\n resolve(r > n ? Ok(r) : Err(new Error('lose')));\n }));\n}\n\nconst res = judge(0.8);\nif (res.isNone()) {\n console.error('invalid number');\n} else {\n const result = await res.unwrap();\n if (result.isErr()) {\n console.assert(result.err().message === 'lose');\n } else {\n console.log(result.unwrap()); // must greater than 0.8\n }\n}\n *\n * ```\n *\n * @param value 被包裹的值\n * @returns {Ok}\n */\nexport function Ok<T, E>(value: T): Result<T, E> {\n return {\n kind: 'Ok',\n isOk: () => true,\n isErr: () => false,\n unwrap: () => value,\n } as const;\n}\n\n/**\n * 创建一个`Err`对象\n *\n * # Examples\n *\n * ```\n * const e = Err(new Error('unknown error'));\n * console.assert(e.err().message === 'unknown error');\n * ```\n *\n * @param error 被包裹的错误\n * @returns {Err}\n */\nexport function Err<T, E>(error: E): Result<T, E> {\n return {\n kind: 'Err',\n isOk: () => false,\n isErr: () => true,\n unwrap: () => {\n throw error;\n },\n err: () => error,\n } as const;\n}"],"names":[],"mappings":"AA2CO,SAAS,KAAQ,KAAqB,EAAA;AACzC,EAAA,IAAI,SAAS,IAAM,EAAA;AACf,IAAM,MAAA,IAAI,UAAU,yCAAyC,CAAA,CAAA;AAAA,GACjE;AAEA,EAAO,OAAA;AAAA,IACH,IAAM,EAAA,MAAA;AAAA,IACN,QAAQ,MAAM,IAAA;AAAA,IACd,QAAQ,MAAM,KAAA;AAAA,IACd,QAAQ,MAAM,KAAA;AAAA,GAClB,CAAA;AACJ,CAAA;AAMO,MAAM,IAAa,GAAA;AAAA,EACtB,IAAM,EAAA,MAAA;AAAA,EACN,QAAQ,MAAM,KAAA;AAAA,EACd,QAAQ,MAAM,IAAA;AAAA,EACd,QAAQ,MAAM;AACV,IAAM,MAAA,IAAI,UAAU,qBAAqB,CAAA,CAAA;AAAA,GAC7C;AACJ;;ACEO,SAAS,GAAS,KAAwB,EAAA;AAC7C,EAAO,OAAA;AAAA,IACH,IAAM,EAAA,IAAA;AAAA,IACN,MAAM,MAAM,IAAA;AAAA,IACZ,OAAO,MAAM,KAAA;AAAA,IACb,QAAQ,MAAM,KAAA;AAAA,GAClB,CAAA;AACJ,CAAA;AAeO,SAAS,IAAU,KAAwB,EAAA;AAC9C,EAAO,OAAA;AAAA,IACH,IAAM,EAAA,KAAA;AAAA,IACN,MAAM,MAAM,KAAA;AAAA,IACZ,OAAO,MAAM,IAAA;AAAA,IACb,QAAQ,MAAM;AACV,MAAM,MAAA,KAAA,CAAA;AAAA,KACV;AAAA,IACA,KAAK,MAAM,KAAA;AAAA,GACf,CAAA;AACJ;;;;"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* option::Option type
|
|
3
|
+
*/
|
|
4
|
+
type Option<T> = Some<T> | None;
|
|
1
5
|
/**
|
|
2
6
|
* @fileoverview 仿rust的[Option](https://doc.rust-lang.org/core/option/index.html)枚举,
|
|
3
7
|
* 用于替代null和undefined的使用。
|
|
@@ -5,25 +9,12 @@
|
|
|
5
9
|
/**
|
|
6
10
|
* option::Some type
|
|
7
11
|
*/
|
|
8
|
-
|
|
12
|
+
interface Some<T> {
|
|
9
13
|
readonly kind: 'Some';
|
|
10
14
|
readonly isSome: (this: Option<T>) => this is Some<T>;
|
|
11
15
|
readonly isNone: (this: Option<T>) => this is None;
|
|
12
16
|
readonly unwrap: () => T;
|
|
13
17
|
}
|
|
14
|
-
/**
|
|
15
|
-
* option::None type
|
|
16
|
-
*/
|
|
17
|
-
export interface None {
|
|
18
|
-
readonly kind: 'None';
|
|
19
|
-
readonly isSome: <T>(this: Option<T>) => this is Some<T>;
|
|
20
|
-
readonly isNone: <T>(this: Option<T>) => this is None;
|
|
21
|
-
readonly unwrap: () => never;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* option::Option type
|
|
25
|
-
*/
|
|
26
|
-
export type Option<T> = Some<T> | None;
|
|
27
18
|
/**
|
|
28
19
|
* 创建一个`Some`对象
|
|
29
20
|
*
|
|
@@ -37,12 +28,26 @@ export type Option<T> = Some<T> | None;
|
|
|
37
28
|
* @param value 被包裹的值,不能为null和undefined
|
|
38
29
|
* @returns {Some}
|
|
39
30
|
*/
|
|
40
|
-
|
|
31
|
+
declare function Some<T>(value: T): Option<T>;
|
|
32
|
+
/**
|
|
33
|
+
* option::None type
|
|
34
|
+
*/
|
|
35
|
+
interface None {
|
|
36
|
+
readonly kind: 'None';
|
|
37
|
+
readonly isSome: <T>(this: Option<T>) => this is Some<T>;
|
|
38
|
+
readonly isNone: <T>(this: Option<T>) => this is None;
|
|
39
|
+
readonly unwrap: () => never;
|
|
40
|
+
}
|
|
41
41
|
/**
|
|
42
42
|
* `None`值是固定的
|
|
43
43
|
* @constant {None}
|
|
44
44
|
*/
|
|
45
|
-
|
|
45
|
+
declare const None: None;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* result::Result type
|
|
49
|
+
*/
|
|
50
|
+
type Result<T, E> = Ok<T, E> | Err<T, E>;
|
|
46
51
|
/**
|
|
47
52
|
* @fileoverview 仿rust的[Result](https://doc.rust-lang.org/core/result/index.html)枚举,
|
|
48
53
|
* 用于错误处理。
|
|
@@ -50,26 +55,12 @@ export const None: None;
|
|
|
50
55
|
/**
|
|
51
56
|
* result::Ok type
|
|
52
57
|
*/
|
|
53
|
-
|
|
58
|
+
interface Ok<T, E> {
|
|
54
59
|
readonly kind: 'Ok';
|
|
55
60
|
readonly isOk: (this: Result<T, E>) => this is Ok<T, E>;
|
|
56
61
|
readonly isErr: (this: Result<T, E>) => this is Err<T, E>;
|
|
57
62
|
readonly unwrap: () => T;
|
|
58
63
|
}
|
|
59
|
-
/**
|
|
60
|
-
* result::Err type
|
|
61
|
-
*/
|
|
62
|
-
export interface Err<T, E> {
|
|
63
|
-
readonly kind: 'Err';
|
|
64
|
-
readonly isOk: (this: Result<T, E>) => this is Ok<T, E>;
|
|
65
|
-
readonly isErr: (this: Result<T, E>) => this is Err<T, E>;
|
|
66
|
-
readonly unwrap: () => never;
|
|
67
|
-
readonly err: () => E;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* result::Result type
|
|
71
|
-
*/
|
|
72
|
-
export type Result<T, E> = Ok<T, E> | Err<T, E>;
|
|
73
64
|
/**
|
|
74
65
|
* 创建一个`Ok`对象
|
|
75
66
|
*
|
|
@@ -107,7 +98,17 @@ if (res.isNone()) {
|
|
|
107
98
|
* @param value 被包裹的值
|
|
108
99
|
* @returns {Ok}
|
|
109
100
|
*/
|
|
110
|
-
|
|
101
|
+
declare function Ok<T, E>(value: T): Result<T, E>;
|
|
102
|
+
/**
|
|
103
|
+
* result::Err type
|
|
104
|
+
*/
|
|
105
|
+
interface Err<T, E> {
|
|
106
|
+
readonly kind: 'Err';
|
|
107
|
+
readonly isOk: (this: Result<T, E>) => this is Ok<T, E>;
|
|
108
|
+
readonly isErr: (this: Result<T, E>) => this is Err<T, E>;
|
|
109
|
+
readonly unwrap: () => never;
|
|
110
|
+
readonly err: () => E;
|
|
111
|
+
}
|
|
111
112
|
/**
|
|
112
113
|
* 创建一个`Err`对象
|
|
113
114
|
*
|
|
@@ -121,6 +122,7 @@ export function Ok<T, E>(value: T): Result<T, E>;
|
|
|
121
122
|
* @param error 被包裹的错误
|
|
122
123
|
* @returns {Err}
|
|
123
124
|
*/
|
|
124
|
-
|
|
125
|
+
declare function Err<T, E>(error: E): Result<T, E>;
|
|
125
126
|
|
|
127
|
+
export { Err, None, Ok, type Option, type Result, Some };
|
|
126
128
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"
|
|
1
|
+
{"version":3,"file":"types.d.ts","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
package/package.json
CHANGED
|
@@ -3,40 +3,32 @@
|
|
|
3
3
|
"description": "Porting some excellent design implementations from Rust to JavaScript.",
|
|
4
4
|
"author": "jiang115jie@gmail.com",
|
|
5
5
|
"license": "GPL-3.0",
|
|
6
|
-
"version": "1.0.
|
|
6
|
+
"version": "1.0.5",
|
|
7
7
|
"source": "./src/mod.ts",
|
|
8
8
|
"main": "./dist/main.cjs",
|
|
9
9
|
"module": "./dist/main.mjs",
|
|
10
10
|
"types": "./dist/types.d.ts",
|
|
11
11
|
"exports": "./src/mod.ts",
|
|
12
|
-
"targets": {
|
|
13
|
-
"main": {
|
|
14
|
-
"isLibrary": true
|
|
15
|
-
},
|
|
16
|
-
"module": {
|
|
17
|
-
"isLibrary": true
|
|
18
|
-
}
|
|
19
|
-
},
|
|
20
12
|
"files": [
|
|
21
13
|
"LICENSE",
|
|
22
14
|
"README.md",
|
|
15
|
+
"README.cn.md",
|
|
23
16
|
"package.json",
|
|
17
|
+
"src",
|
|
24
18
|
"dist"
|
|
25
19
|
],
|
|
26
20
|
"sideEffects": false,
|
|
27
21
|
"scripts": {
|
|
28
|
-
"clean": "npx rimraf .parcel-cache dist",
|
|
29
22
|
"check": "npx tsc --noEmit",
|
|
30
23
|
"lint": "npx eslint src/",
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"test": "npx jest",
|
|
24
|
+
"prebuild": "npx rimraf dist && npm run check && npm run lint",
|
|
25
|
+
"build": "npx rollup --config rollup.config.mjs",
|
|
26
|
+
"test": "bun test",
|
|
35
27
|
"prepublishOnly": "npm run build"
|
|
36
28
|
},
|
|
37
29
|
"repository": {
|
|
38
30
|
"type": "git",
|
|
39
|
-
"url": "https://github.com/JiangJie/happy-rusty.git"
|
|
31
|
+
"url": "git+https://github.com/JiangJie/happy-rusty.git"
|
|
40
32
|
},
|
|
41
33
|
"keywords": [
|
|
42
34
|
"rust",
|
|
@@ -50,15 +42,13 @@
|
|
|
50
42
|
],
|
|
51
43
|
"devDependencies": {
|
|
52
44
|
"@jest/globals": "^29.7.0",
|
|
53
|
-
"@
|
|
54
|
-
"@
|
|
55
|
-
"@typescript-eslint/eslint-plugin": "^7.7.1",
|
|
56
|
-
"@typescript-eslint/parser": "^7.7.1",
|
|
45
|
+
"@typescript-eslint/eslint-plugin": "^7.8.0",
|
|
46
|
+
"@typescript-eslint/parser": "^7.8.0",
|
|
57
47
|
"eslint": "^8.57.0",
|
|
58
|
-
"jest": "^29.7.0",
|
|
59
|
-
"parcel": "^2.12.0",
|
|
60
48
|
"rimraf": "^5.0.5",
|
|
61
|
-
"
|
|
49
|
+
"rollup": "^4.17.2",
|
|
50
|
+
"rollup-plugin-dts": "^6.1.0",
|
|
51
|
+
"rollup-plugin-esbuild": "^6.1.1",
|
|
62
52
|
"typescript": "^5.4.5"
|
|
63
53
|
}
|
|
64
54
|
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview 仿rust的[Option](https://doc.rust-lang.org/core/option/index.html)枚举,
|
|
3
|
+
* 用于替代null和undefined的使用。
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* option::Some type
|
|
8
|
+
*/
|
|
9
|
+
interface Some<T> {
|
|
10
|
+
readonly kind: 'Some';
|
|
11
|
+
readonly isSome: (this: Option<T>) => this is Some<T>;
|
|
12
|
+
readonly isNone: (this: Option<T>) => this is None;
|
|
13
|
+
readonly unwrap: () => T;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* option::None type
|
|
18
|
+
*/
|
|
19
|
+
interface None {
|
|
20
|
+
readonly kind: 'None';
|
|
21
|
+
readonly isSome: <T>(this: Option<T>) => this is Some<T>;
|
|
22
|
+
readonly isNone: <T>(this: Option<T>) => this is None;
|
|
23
|
+
readonly unwrap: () => never;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* option::Option type
|
|
28
|
+
*/
|
|
29
|
+
export type Option<T> = Some<T> | None;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* 创建一个`Some`对象
|
|
33
|
+
*
|
|
34
|
+
* # Examples
|
|
35
|
+
*
|
|
36
|
+
* ```
|
|
37
|
+
* const v = Some(10);
|
|
38
|
+
* console.assert(v.unwrap() === 10);
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @param value 被包裹的值,不能为null和undefined
|
|
42
|
+
* @returns {Some}
|
|
43
|
+
*/
|
|
44
|
+
export function Some<T>(value: T): Option<T> {
|
|
45
|
+
if (value == null) {
|
|
46
|
+
throw new TypeError('Some value can not be null or undefined');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
kind: 'Some',
|
|
51
|
+
isSome: () => true,
|
|
52
|
+
isNone: () => false,
|
|
53
|
+
unwrap: () => value,
|
|
54
|
+
} as const;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* `None`值是固定的
|
|
59
|
+
* @constant {None}
|
|
60
|
+
*/
|
|
61
|
+
export const None: None = {
|
|
62
|
+
kind: 'None',
|
|
63
|
+
isSome: () => false,
|
|
64
|
+
isNone: () => true,
|
|
65
|
+
unwrap: () => {
|
|
66
|
+
throw new TypeError('None can not unwrap');
|
|
67
|
+
},
|
|
68
|
+
} as const;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview 仿rust的[Result](https://doc.rust-lang.org/core/result/index.html)枚举,
|
|
3
|
+
* 用于错误处理。
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* result::Ok type
|
|
9
|
+
*/
|
|
10
|
+
interface Ok<T, E> {
|
|
11
|
+
readonly kind: 'Ok';
|
|
12
|
+
readonly isOk: (this: Result<T, E>) => this is Ok<T, E>;
|
|
13
|
+
readonly isErr: (this: Result<T, E>) => this is Err<T, E>;
|
|
14
|
+
readonly unwrap: () => T;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* result::Err type
|
|
19
|
+
*/
|
|
20
|
+
interface Err<T, E> {
|
|
21
|
+
readonly kind: 'Err';
|
|
22
|
+
readonly isOk: (this: Result<T, E>) => this is Ok<T, E>;
|
|
23
|
+
readonly isErr: (this: Result<T, E>) => this is Err<T, E>;
|
|
24
|
+
readonly unwrap: () => never;
|
|
25
|
+
readonly err: () => E;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* result::Result type
|
|
30
|
+
*/
|
|
31
|
+
export type Result<T, E> = Ok<T, E> | Err<T, E>;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* 创建一个`Ok`对象
|
|
35
|
+
*
|
|
36
|
+
* # Examples
|
|
37
|
+
*
|
|
38
|
+
* ```
|
|
39
|
+
* const v = Ok(10);
|
|
40
|
+
* console.assert(v.unwrap() === 10);
|
|
41
|
+
*
|
|
42
|
+
function judge(n: number): Option<Promise<Result<number, Error>>> {
|
|
43
|
+
if (n < 0 || n >= 1) {
|
|
44
|
+
return None;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return Some(new Promise(resolve => {
|
|
48
|
+
const r = Math.random();
|
|
49
|
+
resolve(r > n ? Ok(r) : Err(new Error('lose')));
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const res = judge(0.8);
|
|
54
|
+
if (res.isNone()) {
|
|
55
|
+
console.error('invalid number');
|
|
56
|
+
} else {
|
|
57
|
+
const result = await res.unwrap();
|
|
58
|
+
if (result.isErr()) {
|
|
59
|
+
console.assert(result.err().message === 'lose');
|
|
60
|
+
} else {
|
|
61
|
+
console.log(result.unwrap()); // must greater than 0.8
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
*
|
|
65
|
+
* ```
|
|
66
|
+
*
|
|
67
|
+
* @param value 被包裹的值
|
|
68
|
+
* @returns {Ok}
|
|
69
|
+
*/
|
|
70
|
+
export function Ok<T, E>(value: T): Result<T, E> {
|
|
71
|
+
return {
|
|
72
|
+
kind: 'Ok',
|
|
73
|
+
isOk: () => true,
|
|
74
|
+
isErr: () => false,
|
|
75
|
+
unwrap: () => value,
|
|
76
|
+
} as const;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* 创建一个`Err`对象
|
|
81
|
+
*
|
|
82
|
+
* # Examples
|
|
83
|
+
*
|
|
84
|
+
* ```
|
|
85
|
+
* const e = Err(new Error('unknown error'));
|
|
86
|
+
* console.assert(e.err().message === 'unknown error');
|
|
87
|
+
* ```
|
|
88
|
+
*
|
|
89
|
+
* @param error 被包裹的错误
|
|
90
|
+
* @returns {Err}
|
|
91
|
+
*/
|
|
92
|
+
export function Err<T, E>(error: E): Result<T, E> {
|
|
93
|
+
return {
|
|
94
|
+
kind: 'Err',
|
|
95
|
+
isOk: () => false,
|
|
96
|
+
isErr: () => true,
|
|
97
|
+
unwrap: () => {
|
|
98
|
+
throw error;
|
|
99
|
+
},
|
|
100
|
+
err: () => error,
|
|
101
|
+
} as const;
|
|
102
|
+
}
|
package/src/mod.ts
ADDED