{"id":21040310,"url":"https://github.com/exoticknight/rust-option","last_synced_at":"2025-05-15T16:33:12.557Z","repository":{"id":38985157,"uuid":"161189355","full_name":"exoticknight/rust-option","owner":"exoticknight","description":"brings Option / Result / match from Rust to Javascript","archived":false,"fork":false,"pushed_at":"2023-01-05T18:28:57.000Z","size":405,"stargazers_count":24,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-03T14:03:58.047Z","etag":null,"topics":["javascript","option","result","rust","rust-option","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/exoticknight.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-12-10T14:42:44.000Z","updated_at":"2025-03-23T23:53:10.000Z","dependencies_parsed_at":"2023-02-04T10:15:58.928Z","dependency_job_id":null,"html_url":"https://github.com/exoticknight/rust-option","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exoticknight%2Frust-option","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exoticknight%2Frust-option/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exoticknight%2Frust-option/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exoticknight%2Frust-option/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/exoticknight","download_url":"https://codeload.github.com/exoticknight/rust-option/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254377412,"owners_count":22061134,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["javascript","option","result","rust","rust-option","typescript"],"created_at":"2024-11-19T13:46:05.427Z","updated_at":"2025-05-15T16:33:12.319Z","avatar_url":"https://github.com/exoticknight.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rust-option\n[![Build Status](https://travis-ci.org/exoticknight/rust-option.svg?branch=master)](https://travis-ci.org/exoticknight/rust-option)\n[![codecov](https://codecov.io/gh/exoticknight/rust-option/branch/master/graph/badge.svg)](https://codecov.io/gh/exoticknight/rust-option)\n![license](https://img.shields.io/npm/l/rust-option.svg)\n\nbrings Option / Result / match from Rust to Javascript\n\n## Install\n\n```bash\nnpm i -S rust-option\n```\n\n## Usage\n\nNearly all methods are similar to the [Option][option] and [Result][result]\n\n\u003e this lib will not implement all methods from Rust's Option and Result, see [Note](#Note)\n\n```javascript\nimport {\n  Some,\n  None,\n  Ok,\n  Err,\n\n  match,\n} from 'rust-option'\n\nlet x = Some(2)\nlet y = None\nlet z = Ok(1)\nlet w = Err('error')\n\n// Note: matches are exhaustive\nlet ret = match(x, [\n  [Some(2), theX =\u003e 'match and get the 2'],\n  [None, () =\u003e 'should not match None'],\n  [Ok, () =\u003e 'should not match Ok'],\n  [Err('error'), () =\u003e 'should not match Err(\\'error\\')'],\n  // function is not a must\n  [Some(2), 'something'],\n  // the 'default' match must be function\n  (arg) =\u003e 'should not match default',\n])\n// ret is 'match and get the Some(2)'\n```\n\nSee more examples in [Test][test] and [Examples][examples].\n\n[option]: https://doc.rust-lang.org/std/option/enum.Option.html\n[result]: https://doc.rust-lang.org/std/result/enum.Result.html\n[test]: https://github.com/exoticknight/rust-option/tree/master/test\n[Examples]: #examples\n\n## Test\n\n```bash\nnpm test\n```\n\n## The `match` function\n\n`match` function provides match syntax similar to Rust, but in JavaScript way.\n\nequal(===) considered to be match\n\n```javascript\nmatch(1, [\n  [1, () =\u003e console.log('match')],\n  () =\u003e console.log('not match ')\n])\n```\n\nhandle type match\n\n```javascript\nmatch(1, [\n  [Number, (x) =\u003e console.log(x)],\n  () =\u003e console.log('not match ')\n])\n```\n\nmore matches\n\n**value**|**match**\n-----|-----\n1|1, Number\nNaN|NaN, Number\n'yeah'|'yeah', 'ea', String\nfalse|false, Boolean\nfunction f(){}|Function\nnew Date('2000-01-01')|new Date('2000-01-01'), Date\n[1,2,4]|Array\n/foo/|RegExp\nnew Set|Set\nnew Map|Map\nnew WeakMap|WeakMap\nnew WeakSet|WeakSet\nSymbol.iterator|Symbol\narguments|Arguments\nnew Error|Error\n{a:1, b:2 }|object, {a: 1}, {a: Number}\nSome(1)|Some(1),Some\nOk(1)|Ok(1),Ok\nErr(1)|Err(1),Err\nNone|None\nSome({a:1, b:2 })|Some(object),Some({a: 1}),Some\n\n\u003cbr\u003e\n\n**given**|**value**|**match**\n-----|-----|-----\nclass A {}|new A|A\nclass B extends A {}|new B|A,B\n\n\u003cbr\u003e\n\nnon-exhaustive match throws Error\n\n```javascript\n// this will throws 'non-exhaustive patterns' Error\nmatch(x, [\n  [None, () =\u003e console.log('not match None')],\n])\n```\n\ndefault branch can get the matchee\n\n```javascript\nmatch(x, [\n  m =\u003e console.log('default match get Some(2) as parameter')\n])\n```\n\nhandle nested match\n\n```javascript\nlet z = Ok(x)\nlet w = Err('error')\n\nmatch(z, [\n  [Ok(Some(2)), () =\u003e console.log('match and get Some(2)')],\n  [w, () =\u003e console.log('not match Err')],\n  // the 'default' match\n  () =\u003e console.log('not match default'),\n])\n```\n\n## the ?\n\nuse `.$` instead of ?\n\n```javascript\nOk(1).$ === 1  // similar to Ok(1).unwrap() and Ok(1)?\n\ntry {\n  Err('I am Err').$\n} catch (err) {\n  err.message === 'I am Err'\n}\n\nSome(1).$ === 1  // similar to Some(1).unwrap() and Some(1)?\n\ntry {\n  None.$\n} catch (err) {\n  err instanceof NoneError\n}\n```\n\n## more helper functions\n\n### makeMatch\n\n```typescript\nmakeMatch\u003cT\u003e(branches:(((x:any)=\u003eT) | [any, T | ((x?:any)=\u003eT)])[], deep:boolean=false):(opt:any)=\u003eT;\n```\n\nactually,\n\n```javascript\nmatch(x, [\n  () =\u003e 'x'\n])\n```\n\nis\n\n```javascript\nmakeMatch([\n  () =\u003e 'x'\n])(x)\n```\n\n### equal\n\nso you can not just use `===` or `==` to compare Option and Result, but the Option and Result itself provides an API call 'equal' for that.\n\n```javascript\n// equal\nSome(1).equal(Some(1))\n\n// deepEqual\nOk({a: 1}).equal(Ok({a: 1}), true)\n```\n\n### optionify / resultify\n\nawait a function and make its output or Error to be Option or Result.\n\n```javascript\nconst content = await resultify(() =\u003e Promise.resolve('content'))()\n\nmatch(content, [\n  [Ok, c =\u003e c],\n  [Err, 'nothing']\n])\n```\n\n### optionifySync / resultifySync\n\nwrap a function and make its output or Error to be Option or Result.\n\n```javascript\nconst content = resultifySync(fs.statSync)('./f')\n\nmatch(content, [\n  [Ok, c =\u003e c],\n  [Err, 'nothing']\n])\n```\n\n## deepEqual\n\ndeepEqual in Javascript is not a piece of cake.\n\ndeepEqual in this lib is provided by [lodash.isequal][lodash.isequal].\n\n```javascript\nimport {\n  Some\n} from 'rust-option'\n\nlet ox = Some({foo: 1})\nlet oy = Some({foo: 1})\nox.equal(oy)  // false\nox.equal(oy, true)  // true\n```\n\n[lodash.isequal]: https://www.npmjs.com/package/lodash.isequal\n\n\u003ca name=\"#examples\"\u003e\u003c/a\u003e\n## Examples\n\nan [examples](https://stackblitz.com/edit/react-ts-6xdhsg?file=index.tsx) with React on StackBlitz.\n\n\u003ca name=\"#Note\"\u003e\u003c/a\u003e\n## Note\n\nUnlike Rust, JavaScript doesn't have the 'Ownership' feature, so some API like 'as_ref ' is not necessary.\n\n## implement for Option\n\n- [x] isSome\n- [x] isNone\n- [x] expect\n- [x] unwrap\n- [x] unwrapOr\n- [x] unwrapOrElse\n- [x] map\n- [x] mapOr\n- [x] mapOrElse\n- [x] okOr\n- [x] okOrElse\n- [x] and\n- [x] andThen\n- [x] filter\n- [x] or\n- [x] orElse\n- [x] xor\n- [x] transpose\n- [x] ?\n\n## not implement for Option\n\n```text\nas_ref\nas_mut\nas_pin_ref\nas_pin_mut\niter\niter_mut\nget_or_insert\nget_or_insert_with\ntake\nreplace\ncloned\nunwrap_or_default\nderef\n```\n\n## implement for Result\n\n- [x] isOk\n- [x] isErr\n- [x] ok\n- [x] err\n- [x] map\n- [x] mapOrElse\n- [x] mapErr\n- [x] and\n- [x] andThen\n- [x] or\n- [x] orElse\n- [x] unwrapOr\n- [x] unwrapOrElse\n- [x] unwrap\n- [x] expect\n- [x] unwrapErr\n- [x] expectErr\n- [x] transpose\n- [x] ?\n\n## not implement for Result\n\n```text\nas_ref\nas_mut\niter\niter_mut\nunwrap_or_default\nderef_ok\nderef_err\nderef\n```\n\n## License\n\nMIT","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexoticknight%2Frust-option","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fexoticknight%2Frust-option","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexoticknight%2Frust-option/lists"}