From 4e73c318bcd922a01e3fabd87f497b472a7d7eee Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Thu, 6 Jul 2023 18:08:04 +0200 Subject: [PATCH 1/5] Update JS versions in `yarn.lock` (#3084) --- build.gradle.kts | 6 +- kotlin-js-store/yarn.lock | 343 +++++++++++++++++++++----------------- 2 files changed, 193 insertions(+), 156 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index cd6589fad18..7c387441774 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -127,10 +127,10 @@ apiValidation { rootProject.plugins.withType { rootProject.configure { - versions.webpackDevServer.version = "4.11.1" - versions.webpack.version = "5.75.0" + versions.webpackDevServer.version = "4.15.1" + versions.webpack.version = "5.88.1" versions.webpackCli.version = "4.10.0" - versions.karma.version = "6.4.1" + versions.karma.version = "6.4.2" versions.mocha.version = "10.2.0" } } diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock index 494d71e496b..5bd52542694 100644 --- a/kotlin-js-store/yarn.lock +++ b/kotlin-js-store/yarn.lock @@ -42,7 +42,7 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/resolve-uri@^3.0.3": +"@jridgewell/resolve-uri@3.1.0", "@jridgewell/resolve-uri@^3.0.3": version "3.1.0" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== @@ -60,12 +60,28 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/sourcemap-codec@^1.4.10": +"@jridgewell/source-map@^0.3.3": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.5.tgz#a3bb4d5c6825aab0d281268f47f6ad5853431e91" + integrity sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": version "1.4.14" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== -"@jridgewell/trace-mapping@^0.3.7", "@jridgewell/trace-mapping@^0.3.9": +"@jridgewell/trace-mapping@^0.3.17": + version "0.3.18" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz#25783b2086daf6ff1dcb53c9249ae480e4dd4cd6" + integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== + dependencies: + "@jridgewell/resolve-uri" "3.1.0" + "@jridgewell/sourcemap-codec" "1.4.14" + +"@jridgewell/trace-mapping@^0.3.9": version "0.3.14" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ== @@ -156,10 +172,10 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== -"@types/estree@^0.0.51": - version "0.0.51" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" - integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== +"@types/estree@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.1.tgz#aa22750962f3bf0e79d753d3cc067f010c95f194" + integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA== "@types/json-schema@*", "@types/json-schema@^7.0.8": version "7.0.11" @@ -183,125 +199,125 @@ dependencies: "@types/node" "*" -"@webassemblyjs/ast@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" - integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== +"@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24" + integrity sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q== dependencies: - "@webassemblyjs/helper-numbers" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" + "@webassemblyjs/helper-numbers" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" -"@webassemblyjs/floating-point-hex-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" - integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== +"@webassemblyjs/floating-point-hex-parser@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz#dacbcb95aff135c8260f77fa3b4c5fea600a6431" + integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== -"@webassemblyjs/helper-api-error@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" - integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== +"@webassemblyjs/helper-api-error@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" + integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== -"@webassemblyjs/helper-buffer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" - integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== +"@webassemblyjs/helper-buffer@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz#b66d73c43e296fd5e88006f18524feb0f2c7c093" + integrity sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA== -"@webassemblyjs/helper-numbers@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" - integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== +"@webassemblyjs/helper-numbers@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz#cbce5e7e0c1bd32cf4905ae444ef64cea919f1b5" + integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" + "@webassemblyjs/floating-point-hex-parser" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" "@xtuc/long" "4.2.2" -"@webassemblyjs/helper-wasm-bytecode@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" - integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== +"@webassemblyjs/helper-wasm-bytecode@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" + integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== -"@webassemblyjs/helper-wasm-section@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" - integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== +"@webassemblyjs/helper-wasm-section@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz#ff97f3863c55ee7f580fd5c41a381e9def4aa577" + integrity sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" -"@webassemblyjs/ieee754@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" - integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== +"@webassemblyjs/ieee754@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz#bb665c91d0b14fffceb0e38298c329af043c6e3a" + integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" - integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== +"@webassemblyjs/leb128@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz#70e60e5e82f9ac81118bc25381a0b283893240d7" + integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== dependencies: "@xtuc/long" "4.2.2" -"@webassemblyjs/utf8@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" - integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== - -"@webassemblyjs/wasm-edit@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" - integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/helper-wasm-section" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-opt" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - "@webassemblyjs/wast-printer" "1.11.1" - -"@webassemblyjs/wasm-gen@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" - integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wasm-opt@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" - integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - -"@webassemblyjs/wasm-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" - integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wast-printer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" - integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== - dependencies: - "@webassemblyjs/ast" "1.11.1" +"@webassemblyjs/utf8@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" + integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== + +"@webassemblyjs/wasm-edit@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz#c72fa8220524c9b416249f3d94c2958dfe70ceab" + integrity sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/helper-wasm-section" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-opt" "1.11.6" + "@webassemblyjs/wasm-parser" "1.11.6" + "@webassemblyjs/wast-printer" "1.11.6" + +"@webassemblyjs/wasm-gen@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz#fb5283e0e8b4551cc4e9c3c0d7184a65faf7c268" + integrity sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wasm-opt@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz#d9a22d651248422ca498b09aa3232a81041487c2" + integrity sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-parser" "1.11.6" + +"@webassemblyjs/wasm-parser@1.11.6", "@webassemblyjs/wasm-parser@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz#bb85378c527df824004812bbdb784eea539174a1" + integrity sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/ieee754" "1.11.6" + "@webassemblyjs/leb128" "1.11.6" + "@webassemblyjs/utf8" "1.11.6" + +"@webassemblyjs/wast-printer@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz#a7bf8dd7e362aeb1668ff43f35cb849f188eff20" + integrity sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A== + dependencies: + "@webassemblyjs/ast" "1.11.6" "@xtuc/long" "4.2.2" "@webpack-cli/configtest@^1.2.0": @@ -344,10 +360,10 @@ accepts@~1.3.4: mime-types "~2.1.34" negotiator "0.6.3" -acorn-import-assertions@^1.7.6: - version "1.8.0" - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" - integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== +acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== acorn@^8.5.0: version "8.7.1" @@ -359,6 +375,11 @@ acorn@^8.7.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== +acorn@^8.8.2: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== + ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" @@ -770,10 +791,10 @@ engine.io@~6.2.0: engine.io-parser "~5.0.3" ws "~8.2.3" -enhanced-resolve@^5.10.0: - version "5.10.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6" - integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ== +enhanced-resolve@^5.15.0: + version "5.15.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" + integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -788,10 +809,10 @@ envinfo@^7.7.3: resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== -es-module-lexer@^0.9.0: - version "0.9.3" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" - integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== +es-module-lexer@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.3.0.tgz#6be9c9e0b4543a60cd166ff6f8b4e9dae0b0c16f" + integrity sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA== escalade@^3.1.1: version "3.1.1" @@ -1283,10 +1304,10 @@ karma-webpack@5.0.0: minimatch "^3.0.4" webpack-merge "^4.1.5" -karma@6.4.1: - version "6.4.1" - resolved "https://registry.yarnpkg.com/karma/-/karma-6.4.1.tgz#f2253716dd3a41aaa813fa9f54b6ee047e1127d9" - integrity sha512-Cj57NKOskK7wtFWSlMvZf459iX+kpYIPXmkNUzP2WAFcA7nhr/ALn5R7sw3w+1udFDcpMx/tuB8d5amgm3ijaA== +karma@6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/karma/-/karma-6.4.2.tgz#a983f874cee6f35990c4b2dcc3d274653714de8e" + integrity sha512-C6SU/53LB31BEgRg+omznBEMY4SjHU3ricV6zBcAe1EeILKkeScr+fZXtaI5WyDbkVowJxxAI6h73NcFPmXolQ== dependencies: "@colors/colors" "1.5.0" body-parser "^1.19.0" @@ -1739,7 +1760,7 @@ safe-buffer@^5.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -schema-utils@^3.1.0, schema-utils@^3.1.1: +schema-utils@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== @@ -1748,7 +1769,16 @@ schema-utils@^3.1.0, schema-utils@^3.1.1: ajv "^6.12.5" ajv-keywords "^3.5.2" -serialize-javascript@6.0.0, serialize-javascript@^6.0.0: +schema-utils@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" + integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + +serialize-javascript@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== @@ -1762,6 +1792,13 @@ serialize-javascript@^4.0.0: dependencies: randombytes "^2.1.0" +serialize-javascript@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.1.tgz#b206efb27c3da0b0ab6b52f48d170b7996458e5c" + integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w== + dependencies: + randombytes "^2.1.0" + setprototypeof@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" @@ -1931,16 +1968,16 @@ tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -terser-webpack-plugin@^5.1.3: - version "5.3.3" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.3.tgz#8033db876dd5875487213e87c627bca323e5ed90" - integrity sha512-Fx60G5HNYknNTNQnzQ1VePRuu89ZVYWfjRAeT5rITuCY/1b08s49e5kSQwHDirKZWuoKOBRFS98EUUoZ9kLEwQ== +terser-webpack-plugin@^5.3.7: + version "5.3.9" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz#832536999c51b46d468067f9e37662a3b96adfe1" + integrity sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA== dependencies: - "@jridgewell/trace-mapping" "^0.3.7" + "@jridgewell/trace-mapping" "^0.3.17" jest-worker "^27.4.5" schema-utils "^3.1.1" - serialize-javascript "^6.0.0" - terser "^5.7.2" + serialize-javascript "^6.0.1" + terser "^5.16.8" terser@^5.0.0: version "5.17.1" @@ -1952,13 +1989,13 @@ terser@^5.0.0: commander "^2.20.0" source-map-support "~0.5.20" -terser@^5.7.2: - version "5.14.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.14.1.tgz#7c95eec36436cb11cf1902cc79ac564741d19eca" - integrity sha512-+ahUAE+iheqBTDxXhTisdA8hgvbEG1hHOQ9xmNjeUJSoi6DU/gMrKNcfZjHkyY6Alnuyc+ikYJaxxfHkT3+WuQ== +terser@^5.16.8: + version "5.18.2" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.18.2.tgz#ff3072a0faf21ffd38f99acc9a0ddf7b5f07b948" + integrity sha512-Ah19JS86ypbJzTzvUCX7KOsEIhDaRONungA4aYBjEP3JZRf4ocuDzTg4QWZnPn9DEMiMYGJPiSOy7aykoCc70w== dependencies: - "@jridgewell/source-map" "^0.3.2" - acorn "^8.5.0" + "@jridgewell/source-map" "^0.3.3" + acorn "^8.8.2" commander "^2.20.0" source-map-support "~0.5.20" @@ -2095,22 +2132,22 @@ webpack-sources@^3.2.3: resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack@5.75.0: - version "5.75.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.75.0.tgz#1e440468647b2505860e94c9ff3e44d5b582c152" - integrity sha512-piaIaoVJlqMsPtX/+3KTTO6jfvrSYgauFVdt8cr9LTHKmcq/AMd4mhzsiP7ZF/PGRNPGA8336jldh9l2Kt2ogQ== +webpack@5.88.1: + version "5.88.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.88.1.tgz#21eba01e81bd5edff1968aea726e2fbfd557d3f8" + integrity sha512-FROX3TxQnC/ox4N+3xQoWZzvGXSuscxR32rbzjpXgEzWudJFEJBpdlkkob2ylrv5yzzufD1zph1OoFsLtm6stQ== dependencies: "@types/eslint-scope" "^3.7.3" - "@types/estree" "^0.0.51" - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/wasm-edit" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" + "@types/estree" "^1.0.0" + "@webassemblyjs/ast" "^1.11.5" + "@webassemblyjs/wasm-edit" "^1.11.5" + "@webassemblyjs/wasm-parser" "^1.11.5" acorn "^8.7.1" - acorn-import-assertions "^1.7.6" + acorn-import-assertions "^1.9.0" browserslist "^4.14.5" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.10.0" - es-module-lexer "^0.9.0" + enhanced-resolve "^5.15.0" + es-module-lexer "^1.2.1" eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" @@ -2119,9 +2156,9 @@ webpack@5.75.0: loader-runner "^4.2.0" mime-types "^2.1.27" neo-async "^2.6.2" - schema-utils "^3.1.0" + schema-utils "^3.2.0" tapable "^2.1.1" - terser-webpack-plugin "^5.1.3" + terser-webpack-plugin "^5.3.7" watchpack "^2.4.0" webpack-sources "^3.2.3" From 7fbf2fbd0d1607d1412b52cc8b36a8fd2a9102bc Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Thu, 6 Jul 2023 18:12:34 +0200 Subject: [PATCH 2/5] Enable Automatic Modules for JVM (#3071) Co-authored-by: Simon Vergauwen --- arrow-libs/core/arrow-annotations/build.gradle.kts | 6 ++++++ arrow-libs/core/arrow-atomic/build.gradle.kts | 6 ++++++ arrow-libs/core/arrow-continuations/build.gradle.kts | 6 ++++++ arrow-libs/core/arrow-core/build.gradle.kts | 6 ++++++ arrow-libs/fx/arrow-fx-coroutines/build.gradle.kts | 6 ++++++ arrow-libs/fx/arrow-fx-stm/build.gradle.kts | 6 ++++++ arrow-libs/optics/arrow-optics/build.gradle.kts | 6 ++++++ arrow-libs/resilience/arrow-resilience/build.gradle.kts | 6 ++++++ 8 files changed, 48 insertions(+) diff --git a/arrow-libs/core/arrow-annotations/build.gradle.kts b/arrow-libs/core/arrow-annotations/build.gradle.kts index 4ae6d56952e..6f0336a8516 100644 --- a/arrow-libs/core/arrow-annotations/build.gradle.kts +++ b/arrow-libs/core/arrow-annotations/build.gradle.kts @@ -40,3 +40,9 @@ kotlin { } apply(from = property("ANIMALSNIFFER_MPP")) + +tasks.jar { + manifest { + attributes["Automatic-Module-Name"] = "arrow.annotations" + } +} diff --git a/arrow-libs/core/arrow-atomic/build.gradle.kts b/arrow-libs/core/arrow-atomic/build.gradle.kts index d456512a757..c4b72e9baed 100644 --- a/arrow-libs/core/arrow-atomic/build.gradle.kts +++ b/arrow-libs/core/arrow-atomic/build.gradle.kts @@ -82,3 +82,9 @@ kotlin { } } } + +tasks.jar { + manifest { + attributes["Automatic-Module-Name"] = "arrow.atomic" + } +} diff --git a/arrow-libs/core/arrow-continuations/build.gradle.kts b/arrow-libs/core/arrow-continuations/build.gradle.kts index 8ebd533bc07..43e0372889f 100644 --- a/arrow-libs/core/arrow-continuations/build.gradle.kts +++ b/arrow-libs/core/arrow-continuations/build.gradle.kts @@ -63,3 +63,9 @@ kotlin { } } } + +tasks.jar { + manifest { + attributes["Automatic-Module-Name"] = "arrow.continuations" + } +} diff --git a/arrow-libs/core/arrow-core/build.gradle.kts b/arrow-libs/core/arrow-core/build.gradle.kts index 31e7521e79c..6b682d3386a 100644 --- a/arrow-libs/core/arrow-core/build.gradle.kts +++ b/arrow-libs/core/arrow-core/build.gradle.kts @@ -75,3 +75,9 @@ kotlin { tasks.named("compileTestKotlinJvm") { kotlinOptions.freeCompilerArgs += "-Xcontext-receivers" } + +tasks.jar { + manifest { + attributes["Automatic-Module-Name"] = "arrow.core" + } +} diff --git a/arrow-libs/fx/arrow-fx-coroutines/build.gradle.kts b/arrow-libs/fx/arrow-fx-coroutines/build.gradle.kts index 3fd60251eed..1363fb4aa48 100644 --- a/arrow-libs/fx/arrow-fx-coroutines/build.gradle.kts +++ b/arrow-libs/fx/arrow-fx-coroutines/build.gradle.kts @@ -64,3 +64,9 @@ kotlin { } } } + +tasks.jar { + manifest { + attributes["Automatic-Module-Name"] = "arrow.fx.coroutines" + } +} diff --git a/arrow-libs/fx/arrow-fx-stm/build.gradle.kts b/arrow-libs/fx/arrow-fx-stm/build.gradle.kts index 94d285b5bed..3706c23e278 100644 --- a/arrow-libs/fx/arrow-fx-stm/build.gradle.kts +++ b/arrow-libs/fx/arrow-fx-stm/build.gradle.kts @@ -64,3 +64,9 @@ kotlin { } } } + +tasks.jar { + manifest { + attributes["Automatic-Module-Name"] = "arrow.fx.stm" + } +} diff --git a/arrow-libs/optics/arrow-optics/build.gradle.kts b/arrow-libs/optics/arrow-optics/build.gradle.kts index 4ce516cb736..bfa33e53eec 100644 --- a/arrow-libs/optics/arrow-optics/build.gradle.kts +++ b/arrow-libs/optics/arrow-optics/build.gradle.kts @@ -83,3 +83,9 @@ kotlin { //dependencies { // kspTest(projects.arrowOpticsKspPlugin) //} + +tasks.jar { + manifest { + attributes["Automatic-Module-Name"] = "arrow.optics" + } +} diff --git a/arrow-libs/resilience/arrow-resilience/build.gradle.kts b/arrow-libs/resilience/arrow-resilience/build.gradle.kts index 0fcfb2456d8..ed1b5ab3049 100644 --- a/arrow-libs/resilience/arrow-resilience/build.gradle.kts +++ b/arrow-libs/resilience/arrow-resilience/build.gradle.kts @@ -46,3 +46,9 @@ kotlin { } } } + +tasks.jar { + manifest { + attributes["Automatic-Module-Name"] = "arrow.resilience" + } +} From 36b40f8d2ae81fe7d496b4ff3b37368039eaab0a Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Fri, 7 Jul 2023 10:33:04 +0200 Subject: [PATCH 3/5] Serialization module (#3077) Co-authored-by: serras --- .../api/arrow-core-serialization.api | 54 +++++++++++++ .../arrow-core-serialization/build.gradle.kts | 50 +++++++++++++ .../core/serialization/EitherSerializer.kt | 62 +++++++++++++++ .../arrow/core/serialization/IorSerializer.kt | 64 ++++++++++++++++ .../NonEmptyCollectionSerializers.kt | 46 ++++++++++++ .../core/serialization/OptionSerializer.kt | 22 ++++++ .../core/serialization/ValidatedSerializer.kt | 63 ++++++++++++++++ .../arrow/core/serialization/BackAgainTest.kt | 75 +++++++++++++++++++ .../arrow/core/serialization/Generators.kt | 42 +++++++++++ build.gradle.kts | 1 + gradle.properties | 1 + gradle/libs.versions.toml | 1 + settings.gradle.kts | 3 + 13 files changed, 484 insertions(+) create mode 100644 arrow-libs/core/arrow-core-serialization/api/arrow-core-serialization.api create mode 100644 arrow-libs/core/arrow-core-serialization/build.gradle.kts create mode 100644 arrow-libs/core/arrow-core-serialization/src/commonMain/kotlin/arrow/core/serialization/EitherSerializer.kt create mode 100644 arrow-libs/core/arrow-core-serialization/src/commonMain/kotlin/arrow/core/serialization/IorSerializer.kt create mode 100644 arrow-libs/core/arrow-core-serialization/src/commonMain/kotlin/arrow/core/serialization/NonEmptyCollectionSerializers.kt create mode 100644 arrow-libs/core/arrow-core-serialization/src/commonMain/kotlin/arrow/core/serialization/OptionSerializer.kt create mode 100644 arrow-libs/core/arrow-core-serialization/src/commonMain/kotlin/arrow/core/serialization/ValidatedSerializer.kt create mode 100644 arrow-libs/core/arrow-core-serialization/src/commonTest/kotlin/arrow/core/serialization/BackAgainTest.kt create mode 100644 arrow-libs/core/arrow-core-serialization/src/commonTest/kotlin/arrow/core/serialization/Generators.kt diff --git a/arrow-libs/core/arrow-core-serialization/api/arrow-core-serialization.api b/arrow-libs/core/arrow-core-serialization/api/arrow-core-serialization.api new file mode 100644 index 00000000000..bc822411c11 --- /dev/null +++ b/arrow-libs/core/arrow-core-serialization/api/arrow-core-serialization.api @@ -0,0 +1,54 @@ +public final class arrow/core/serialization/EitherSerializer : kotlinx/serialization/KSerializer { + public fun (Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;)V + public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Larrow/core/Either; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public fun serialize (Lkotlinx/serialization/encoding/Encoder;Larrow/core/Either;)V + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V +} + +public final class arrow/core/serialization/IorSerializer : kotlinx/serialization/KSerializer { + public fun (Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;)V + public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Larrow/core/Ior; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public fun serialize (Lkotlinx/serialization/encoding/Encoder;Larrow/core/Ior;)V + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V +} + +public final class arrow/core/serialization/NonEmptyListSerializer : kotlinx/serialization/KSerializer { + public fun (Lkotlinx/serialization/KSerializer;)V + public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Larrow/core/NonEmptyList; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public fun serialize (Lkotlinx/serialization/encoding/Encoder;Larrow/core/NonEmptyList;)V + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V +} + +public final class arrow/core/serialization/NonEmptySetSerializer : kotlinx/serialization/KSerializer { + public fun (Lkotlinx/serialization/KSerializer;)V + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public fun deserialize-J9TPrxk (Lkotlinx/serialization/encoding/Decoder;)Ljava/util/Set; + public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V + public fun serialize-EvCv4gE (Lkotlinx/serialization/encoding/Encoder;Ljava/util/Set;)V +} + +public final class arrow/core/serialization/OptionSerializer : kotlinx/serialization/KSerializer { + public fun (Lkotlinx/serialization/KSerializer;)V + public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Larrow/core/Option; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public fun serialize (Lkotlinx/serialization/encoding/Encoder;Larrow/core/Option;)V + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V +} + +public final class arrow/core/serialization/ValidatedSerializer : kotlinx/serialization/KSerializer { + public fun (Lkotlinx/serialization/KSerializer;Lkotlinx/serialization/KSerializer;)V + public fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Larrow/core/Validated; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public fun serialize (Lkotlinx/serialization/encoding/Encoder;Larrow/core/Validated;)V + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V +} + diff --git a/arrow-libs/core/arrow-core-serialization/build.gradle.kts b/arrow-libs/core/arrow-core-serialization/build.gradle.kts new file mode 100644 index 00000000000..d88648d6f82 --- /dev/null +++ b/arrow-libs/core/arrow-core-serialization/build.gradle.kts @@ -0,0 +1,50 @@ +@file:Suppress("DSL_SCOPE_VIOLATION") + +plugins { + id(libs.plugins.kotlin.multiplatform.get().pluginId) + alias(libs.plugins.arrowGradleConfig.kotlin) + alias(libs.plugins.arrowGradleConfig.publish) + alias(libs.plugins.arrowGradleConfig.versioning) + alias(libs.plugins.kotest.multiplatform) + id(libs.plugins.kotlinx.serialization.get().pluginId) +} + +apply(from = property("ANIMALSNIFFER_MPP")) + +val enableCompatibilityMetadataVariant = + providers.gradleProperty("kotlin.mpp.enableCompatibilityMetadataVariant") + .orNull?.toBoolean() == true + +if (enableCompatibilityMetadataVariant) { + tasks.withType().configureEach { + exclude("**/*") + } +} + +kotlin { + sourceSets { + commonMain { + dependencies { + api(projects.arrowCore) + api(libs.kotlin.stdlibCommon) + api(libs.kotlinx.serializationCore) + } + } + if (!enableCompatibilityMetadataVariant) { + commonTest { + dependencies { + implementation(libs.kotlinx.serializationJson) + implementation(libs.kotest.frameworkEngine) + implementation(libs.kotest.assertionsCore) + implementation(libs.kotest.property) + } + } + + jvmTest { + dependencies { + runtimeOnly(libs.kotest.runnerJUnit5) + } + } + } + } +} diff --git a/arrow-libs/core/arrow-core-serialization/src/commonMain/kotlin/arrow/core/serialization/EitherSerializer.kt b/arrow-libs/core/arrow-core-serialization/src/commonMain/kotlin/arrow/core/serialization/EitherSerializer.kt new file mode 100644 index 00000000000..a89be322634 --- /dev/null +++ b/arrow-libs/core/arrow-core-serialization/src/commonMain/kotlin/arrow/core/serialization/EitherSerializer.kt @@ -0,0 +1,62 @@ +package arrow.core.serialization + +import arrow.core.Either +import arrow.core.None +import arrow.core.Option +import arrow.core.Some +import arrow.core.left +import arrow.core.none +import arrow.core.right +import kotlinx.serialization.KSerializer +import kotlinx.serialization.SerializationException +import kotlinx.serialization.descriptors.buildClassSerialDescriptor +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.CompositeDecoder +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import kotlinx.serialization.encoding.decodeStructure +import kotlinx.serialization.encoding.encodeStructure + +public class EitherSerializer( + private val errorSerializer: KSerializer, + private val elementSerializer: KSerializer, +) : KSerializer> { + + override val descriptor: SerialDescriptor = buildClassSerialDescriptor("Either") { + element("left", errorSerializer.descriptor, isOptional = true) + element("right", elementSerializer.descriptor, isOptional = true) + } + override fun serialize(encoder: Encoder, value: Either) { + encoder.encodeStructure(descriptor) { + when (value) { + is Either.Left -> encodeSerializableElement(descriptor, 0, errorSerializer, value.value) + is Either.Right -> encodeSerializableElement(descriptor, 1, elementSerializer, value.value) + } + } + } + override fun deserialize(decoder: Decoder): Either { + var leftValue: Option = none() + var rightValue: Option = none() + decoder.decodeStructure(descriptor) { + while (true) { + when (val index = decodeElementIndex(descriptor)) { + 0 -> { + leftValue = Some(decodeSerializableElement(descriptor, 0, errorSerializer)) + } + 1 -> { + rightValue = Some(decodeSerializableElement(descriptor, 1, elementSerializer)) + } + CompositeDecoder.DECODE_DONE -> break + else -> error("unexpected index: $index") + } + } + } + return when { + leftValue is None && rightValue is None -> throw SerializationException("No information found for this Either") + leftValue is Some && rightValue is Some -> throw SerializationException("Both Left and Right specified for Either") + leftValue is Some -> (leftValue as Some).value.left() + rightValue is Some -> (rightValue as Some).value.right() + else -> error("this should never happen") + } + } +} diff --git a/arrow-libs/core/arrow-core-serialization/src/commonMain/kotlin/arrow/core/serialization/IorSerializer.kt b/arrow-libs/core/arrow-core-serialization/src/commonMain/kotlin/arrow/core/serialization/IorSerializer.kt new file mode 100644 index 00000000000..8b2321093c3 --- /dev/null +++ b/arrow-libs/core/arrow-core-serialization/src/commonMain/kotlin/arrow/core/serialization/IorSerializer.kt @@ -0,0 +1,64 @@ +package arrow.core.serialization + +import arrow.core.Ior +import arrow.core.None +import arrow.core.Option +import arrow.core.Some +import arrow.core.none +import kotlinx.serialization.KSerializer +import kotlinx.serialization.SerializationException +import kotlinx.serialization.descriptors.buildClassSerialDescriptor +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.CompositeDecoder +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import kotlinx.serialization.encoding.decodeStructure +import kotlinx.serialization.encoding.encodeStructure + +public class IorSerializer( + private val errorSerializer: KSerializer, + private val elementSerializer: KSerializer, +) : KSerializer> { + + override val descriptor: SerialDescriptor = buildClassSerialDescriptor("Ior") { + element("left", errorSerializer.descriptor, isOptional = true) + element("right", elementSerializer.descriptor, isOptional = true) + } + override fun serialize(encoder: Encoder, value: Ior) { + encoder.encodeStructure(descriptor) { + when (value) { + is Ior.Left -> encodeSerializableElement(descriptor, 0, errorSerializer, value.value) + is Ior.Right -> encodeSerializableElement(descriptor, 1, elementSerializer, value.value) + is Ior.Both -> { + encodeSerializableElement(descriptor, 0, errorSerializer, value.leftValue) + encodeSerializableElement(descriptor, 1, elementSerializer, value.rightValue) + } + } + } + } + override fun deserialize(decoder: Decoder): Ior { + var leftValue: Option = none() + var rightValue: Option = none() + decoder.decodeStructure(descriptor) { + while (true) { + when (val index = decodeElementIndex(descriptor)) { + 0 -> { + leftValue = Some(decodeSerializableElement(descriptor, 0, errorSerializer)) + } + 1 -> { + rightValue = Some(decodeSerializableElement(descriptor, 1, elementSerializer)) + } + CompositeDecoder.DECODE_DONE -> break + else -> error("unexpected index: $index") + } + } + } + return when { + leftValue is None && rightValue is None -> throw SerializationException("No information found for this Ior") + leftValue is Some && rightValue is Some -> Ior.Both((leftValue as Some).value, (rightValue as Some).value) + leftValue is Some -> Ior.Left((leftValue as Some).value) + rightValue is Some -> Ior.Right((rightValue as Some).value) + else -> error("this should never happen") + } + } +} diff --git a/arrow-libs/core/arrow-core-serialization/src/commonMain/kotlin/arrow/core/serialization/NonEmptyCollectionSerializers.kt b/arrow-libs/core/arrow-core-serialization/src/commonMain/kotlin/arrow/core/serialization/NonEmptyCollectionSerializers.kt new file mode 100644 index 00000000000..6b20cff261c --- /dev/null +++ b/arrow-libs/core/arrow-core-serialization/src/commonMain/kotlin/arrow/core/serialization/NonEmptyCollectionSerializers.kt @@ -0,0 +1,46 @@ +package arrow.core.serialization + +import arrow.core.NonEmptyList +import arrow.core.NonEmptySet +import arrow.core.toNonEmptyListOrNull +import arrow.core.toNonEmptySetOrNull +import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.KSerializer +import kotlinx.serialization.SerializationException +import kotlinx.serialization.builtins.ListSerializer +import kotlinx.serialization.builtins.SetSerializer +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder + +public class NonEmptyListSerializer( + elementSerializer: KSerializer +) : KSerializer> { + private val listSerializer: KSerializer> = ListSerializer(elementSerializer) + + @OptIn(ExperimentalSerializationApi::class) + override val descriptor: SerialDescriptor = + SerialDescriptor("NonEmptyList", listSerializer.descriptor) + override fun serialize(encoder: Encoder, value: NonEmptyList) { + listSerializer.serialize(encoder, value.toList()) + } + override fun deserialize(decoder: Decoder): NonEmptyList = + listSerializer.deserialize(decoder).toNonEmptyListOrNull() + ?: throw SerializationException("expected non-empty list") +} + +public class NonEmptySetSerializer( + elementSerializer: KSerializer +) : KSerializer> { + private val setSerializer: KSerializer> = SetSerializer(elementSerializer) + + @OptIn(ExperimentalSerializationApi::class) + override val descriptor: SerialDescriptor = + SerialDescriptor("NonEmptySet", setSerializer.descriptor) + override fun serialize(encoder: Encoder, value: NonEmptySet) { + setSerializer.serialize(encoder, value.toSet()) + } + override fun deserialize(decoder: Decoder): NonEmptySet = + setSerializer.deserialize(decoder).toNonEmptySetOrNull() + ?: throw SerializationException("expected non-empty set") +} diff --git a/arrow-libs/core/arrow-core-serialization/src/commonMain/kotlin/arrow/core/serialization/OptionSerializer.kt b/arrow-libs/core/arrow-core-serialization/src/commonMain/kotlin/arrow/core/serialization/OptionSerializer.kt new file mode 100644 index 00000000000..68d1996f4ae --- /dev/null +++ b/arrow-libs/core/arrow-core-serialization/src/commonMain/kotlin/arrow/core/serialization/OptionSerializer.kt @@ -0,0 +1,22 @@ +package arrow.core.serialization + +import arrow.core.Option +import arrow.core.toOption +import kotlinx.serialization.KSerializer +import kotlinx.serialization.builtins.nullable +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder + +public class OptionSerializer( + elementSerializer: KSerializer +) : KSerializer> { + private val nullableSerializer: KSerializer = elementSerializer.nullable + + override val descriptor: SerialDescriptor = nullableSerializer.descriptor + override fun serialize(encoder: Encoder, value: Option) { + nullableSerializer.serialize(encoder, value.getOrNull()) + } + override fun deserialize(decoder: Decoder): Option = + nullableSerializer.deserialize(decoder).toOption() +} diff --git a/arrow-libs/core/arrow-core-serialization/src/commonMain/kotlin/arrow/core/serialization/ValidatedSerializer.kt b/arrow-libs/core/arrow-core-serialization/src/commonMain/kotlin/arrow/core/serialization/ValidatedSerializer.kt new file mode 100644 index 00000000000..279e93f4759 --- /dev/null +++ b/arrow-libs/core/arrow-core-serialization/src/commonMain/kotlin/arrow/core/serialization/ValidatedSerializer.kt @@ -0,0 +1,63 @@ +package arrow.core.serialization + +import arrow.core.None +import arrow.core.Option +import arrow.core.Some +import arrow.core.Validated +import arrow.core.invalid +import arrow.core.none +import arrow.core.some +import arrow.core.valid +import kotlinx.serialization.KSerializer +import kotlinx.serialization.SerializationException +import kotlinx.serialization.descriptors.buildClassSerialDescriptor +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.CompositeDecoder +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import kotlinx.serialization.encoding.decodeStructure +import kotlinx.serialization.encoding.encodeStructure + +public class ValidatedSerializer( + private val errorSerializer: KSerializer, + private val elementSerializer: KSerializer, +) : KSerializer> { + + override val descriptor: SerialDescriptor = buildClassSerialDescriptor("Validated") { + element("invalid", errorSerializer.descriptor, isOptional = true) + element("valid", elementSerializer.descriptor, isOptional = true) + } + override fun serialize(encoder: Encoder, value: Validated) { + encoder.encodeStructure(descriptor) { + when (value) { + is Validated.Invalid -> encodeSerializableElement(descriptor, 0, errorSerializer, value.value) + is Validated.Valid -> encodeSerializableElement(descriptor, 1, elementSerializer, value.value) + } + } + } + override fun deserialize(decoder: Decoder): Validated { + var invalidValue: Option = none() + var validValue: Option = none() + decoder.decodeStructure(descriptor) { + while (true) { + when (val index = decodeElementIndex(descriptor)) { + 0 -> { + invalidValue = decodeSerializableElement(descriptor, 0, errorSerializer).some() + } + 1 -> { + validValue = decodeSerializableElement(descriptor, 1, elementSerializer).some() + } + CompositeDecoder.DECODE_DONE -> break + else -> error("unexpected index: $index") + } + } + } + return when { + invalidValue is None && validValue is None -> throw SerializationException("No information found for this Either") + invalidValue is Some && validValue is Some -> throw SerializationException("Both Left and Right specified for Either") + invalidValue is Some -> (invalidValue as Some).value.invalid() + validValue is Some -> (validValue as Some).value.valid() + else -> error("this should never happen") + } + } +} diff --git a/arrow-libs/core/arrow-core-serialization/src/commonTest/kotlin/arrow/core/serialization/BackAgainTest.kt b/arrow-libs/core/arrow-core-serialization/src/commonTest/kotlin/arrow/core/serialization/BackAgainTest.kt new file mode 100644 index 00000000000..889443e7ed1 --- /dev/null +++ b/arrow-libs/core/arrow-core-serialization/src/commonTest/kotlin/arrow/core/serialization/BackAgainTest.kt @@ -0,0 +1,75 @@ +@file:UseSerializers( + EitherSerializer::class, + IorSerializer::class, + ValidatedSerializer::class, + OptionSerializer::class, + NonEmptyListSerializer::class, + NonEmptySetSerializer::class +) + +package arrow.core.serialization + +import arrow.core.Either +import arrow.core.Ior +import arrow.core.NonEmptyList +import arrow.core.NonEmptySet +import arrow.core.Option +import arrow.core.Validated +import io.kotest.core.spec.style.StringSpec +import io.kotest.property.Arb +import io.kotest.property.checkAll +import kotlinx.serialization.UseSerializers +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.encodeToJsonElement +import kotlinx.serialization.json.decodeFromJsonElement +import io.kotest.matchers.shouldBe +import io.kotest.property.arbitrary.int +import io.kotest.property.arbitrary.map +import io.kotest.property.arbitrary.string +import kotlinx.serialization.Serializable + +/* + These types are needed to "trick" the kotlinx.serialization plug-in + to use the corresponding (de)serializers for those types. + */ + +@Serializable +data class EitherInside(val thing: Either) + +@Serializable +data class IorInside(val thing: Ior) + +@Serializable +data class ValidatedInside(val thing: Validated) + +@Serializable +data class OptionInside(val thing: Option) + +@Serializable +data class NonEmptyListInside(val thing: NonEmptyList) + +@Serializable +data class NonEmptySetInside(val thing: NonEmptySet) + +inline fun StringSpec.backAgain(generator: Arb) { + "there and back again, ${T::class.simpleName}" { + checkAll(generator) { e -> + val result = Json.encodeToJsonElement(e) + val back = Json.decodeFromJsonElement(result) + back shouldBe e + } + } +} + +/** + * Checks that the result of serializing a value into JSON, + * and then deserializing it, gives back the original. + */ +class BackAgainTest : StringSpec({ + backAgain(Arb.either(Arb.string(), Arb.int()).map(::EitherInside)) + backAgain(Arb.ior(Arb.string(), Arb.int()).map(::IorInside)) + backAgain(Arb.validated(Arb.string(), Arb.int()).map(::ValidatedInside)) + backAgain(Arb.option(Arb.string()).map(::OptionInside)) + backAgain(Arb.nonEmptyList(Arb.int()).map(::NonEmptyListInside)) + backAgain(Arb.nonEmptySet(Arb.int()).map(::NonEmptySetInside)) +}) diff --git a/arrow-libs/core/arrow-core-serialization/src/commonTest/kotlin/arrow/core/serialization/Generators.kt b/arrow-libs/core/arrow-core-serialization/src/commonTest/kotlin/arrow/core/serialization/Generators.kt new file mode 100644 index 00000000000..7d2691b15e2 --- /dev/null +++ b/arrow-libs/core/arrow-core-serialization/src/commonTest/kotlin/arrow/core/serialization/Generators.kt @@ -0,0 +1,42 @@ +package arrow.core.serialization + +import arrow.core.Either +import arrow.core.Ior +import arrow.core.NonEmptyList +import arrow.core.NonEmptySet +import arrow.core.Option +import arrow.core.Validated +import arrow.core.toNonEmptySetOrNull +import arrow.core.toOption +import io.kotest.property.Arb +import io.kotest.property.arbitrary.bind +import io.kotest.property.arbitrary.choice +import io.kotest.property.arbitrary.list +import io.kotest.property.arbitrary.map +import io.kotest.property.arbitrary.orNull +import io.kotest.property.arbitrary.set +import kotlin.math.max + +fun Arb.Companion.nonEmptyList(arb: Arb, range: IntRange = 0 .. 100): Arb> = + Arb.bind(arb, Arb.list(arb, range), ::NonEmptyList) + +fun Arb.Companion.nonEmptySet(arb: Arb, range: IntRange = 0 .. 100): Arb> = + Arb.set(arb, max(range.first, 1) .. range.last).map { it.toNonEmptySetOrNull()!! } + +fun Arb.Companion.option(arb: Arb): Arb> = + arb.orNull().map { it.toOption() } + +fun Arb.Companion.either(arbE: Arb, arbA: Arb): Arb> { + val arbLeft = arbE.map { Either.Left(it) } + val arbRight = arbA.map { Either.Right(it) } + return Arb.choice(arbLeft, arbRight) +} + +fun Arb.Companion.validated(arbE: Arb, arbA: Arb): Arb> = + Arb.either(arbE, arbA).map { Validated.fromEither(it) } + +fun Arb.Companion.ior(arbA: Arb, arbB: Arb): Arb> = + arbA.alignWith(arbB) { it } + +private fun Arb.alignWith(arbB: Arb, transform: (Ior) -> R): Arb = + Arb.bind(this, arbB) { a, b -> transform(Ior.Both(a, b)) } diff --git a/build.gradle.kts b/build.gradle.kts index 7c387441774..bbd96a6c09d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -33,6 +33,7 @@ plugins { alias(libs.plugins.kotest.multiplatform) apply false alias(libs.plugins.kotlinx.kover) alias(libs.plugins.kotlin.multiplatform) apply false + alias(libs.plugins.kotlinx.serialization) apply false alias(libs.plugins.kotlin.binaryCompatibilityValidator) alias(libs.plugins.arrowGradleConfig.nexus) alias(libs.plugins.spotless) apply false diff --git a/gradle.properties b/gradle.properties index 0a4834df3fc..bce2b6e057d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -26,6 +26,7 @@ kotlin.mpp.stability.nowarn=true # https://youtrack.jetbrains.com/issue/KT-32476 kotlin.native.ignoreIncorrectDependencies=true kotlin.native.ignoreDisabledTargets=true +kotlin.native.cacheKind.linuxX64=none # https://youtrack.jetbrains.com/issue/KT-45545#focus=Comments-27-4773544.0-0 kapt.use.worker.api=false diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d7f1db63d2a..034d267ac73 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -39,6 +39,7 @@ kotlin-stdlibCommon = { module = "org.jetbrains.kotlin:kotlin-stdlib-common" } kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib" } kotlin-stdlibJS = { module = "org.jetbrains.kotlin:kotlin-stdlib-js" } kotlinx-knit = { module = "org.jetbrains.kotlinx:kotlinx-knit", version.ref = "knit" } +kotlinx-serializationCore = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "kotlinxSerialization" } kotlinx-serializationJson = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerialization" } squareup-okhttpMockWebServer = { module = "com.squareup.okhttp3:mockwebserver", version.ref = "mockWebServer" } squareup-retrofitConverterGson = { module = "com.squareup.retrofit2:converter-gson", version.ref = "retrofit" } diff --git a/settings.gradle.kts b/settings.gradle.kts index 2aa4163c3da..c1ca78fd2e7 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -43,6 +43,9 @@ project(":arrow-continuations").projectDir = file("arrow-libs/core/arrow-continu include("arrow-core-retrofit") project(":arrow-core-retrofit").projectDir = file("arrow-libs/core/arrow-core-retrofit") +include("arrow-core-serialization") +project(":arrow-core-serialization").projectDir = file("arrow-libs/core/arrow-core-serialization") + // FX include("arrow-fx-coroutines") project(":arrow-fx-coroutines").projectDir = file("arrow-libs/fx/arrow-fx-coroutines") From 896b016e1d890607231f5fe6c1fa77e0451782a1 Mon Sep 17 00:00:00 2001 From: Alejandro Serrano Date: Fri, 7 Jul 2023 12:30:27 +0200 Subject: [PATCH 4/5] Add missing docs for `Raise` operations (#3082) Co-authored-by: Simon Vergauwen --- .../kotlin/arrow/core/raise/Builders.kt | 68 +++++++++++++++- .../kotlin/arrow/core/raise/Fold.kt | 41 ++++++++++ .../kotlin/arrow/core/raise/Mappers.kt | 6 ++ .../kotlin/arrow/core/raise/Raise.kt | 38 ++++++++- .../arrow/core/raise/RaiseAccumulate.kt | 80 +++++++++++++++++++ 5 files changed, 231 insertions(+), 2 deletions(-) diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/Builders.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/Builders.kt index de970877bfe..47d9a1788ed 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/Builders.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/Builders.kt @@ -7,7 +7,6 @@ package arrow.core.raise import arrow.atomic.Atomic import arrow.atomic.updateAndGet import arrow.core.Either -import arrow.core.EmptyValue.combine import arrow.core.Ior import arrow.core.NonEmptyList import arrow.core.NonEmptySet @@ -22,18 +21,69 @@ import kotlin.experimental.ExperimentalTypeInference import kotlin.jvm.JvmMultifileClass import kotlin.jvm.JvmName +/** + * Runs a computation [block] using [Raise], and return its outcome as [Either]. + * - [Either.Right] represents success, + * - [Either.Left] represents logical failure. + * + * This function re-throws any exceptions thrown within the [Raise] block. + * + * Read more about running a [Raise] computation in the + * [Arrow docs](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#running-and-inspecting-results). + */ public inline fun either(@BuilderInference block: Raise.() -> A): Either = fold({ block.invoke(this) }, { Either.Left(it) }, { Either.Right(it) }) +/** + * Runs a computation [block] using [Raise], and return its outcome as nullable type, + * where `null` represents logical failure. + * + * This function re-throws any exceptions thrown within the [Raise] block. + * + * Read more about running a [Raise] computation in the + * [Arrow docs](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#running-and-inspecting-results). + */ public inline fun nullable(block: NullableRaise.() -> A): A? = merge { block(NullableRaise(this)) } +/** + * Runs a computation [block] using [Raise], and return its outcome as [Result]. + * + * + * Read more about running a [Raise] computation in the + * [Arrow docs](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#running-and-inspecting-results). + */ public inline fun result(block: ResultRaise.() -> A): Result = fold({ block(ResultRaise(this)) }, Result.Companion::failure, Result.Companion::failure, Result.Companion::success) +/** + * Runs a computation [block] using [Raise], and return its outcome as [Option]. + * - [Some] represents success, + * - [None] represents logical failure. + * + * This function re-throws any exceptions thrown within the [Raise] block. + * + * Read more about running a [Raise] computation in the + * [Arrow docs](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#running-and-inspecting-results). + */ public inline fun option(block: OptionRaise.() -> A): Option = fold({ block(OptionRaise(this)) }, ::identity, ::Some) +/** + * Runs a computation [block] using [Raise], and return its outcome as [Ior]. + * - [Ior.Right] represents success, + * - [Ior.Left] represents logical failure which made it impossible to continue, + * - [Ior.Both] represents that some logical failures were raised, + * but it was possible to continue until producing a final value. + * + * This function re-throws any exceptions thrown within the [Raise] block. + * + * In both [Ior.Left] and [Ior.Both] cases, if more than one logical failure + * has been raised, they are combined using [combineError]. + * + * Read more about running a [Raise] computation in the + * [Arrow docs](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#running-and-inspecting-results). + */ public inline fun ior(noinline combineError: (Error, Error) -> Error, @BuilderInference block: IorRaise.() -> A): Ior { val state: Atomic> = Atomic(None) return fold>( @@ -46,6 +96,10 @@ public inline fun ior(noinline combineError: (Error, Error) -> Error, public typealias Null = Nothing? +/** + * Implementation of [Raise] used by [nullable]. + * You should never use this directly. + */ public class NullableRaise(private val raise: Raise) : Raise by raise { @RaiseDSL public fun ensure(value: Boolean): Unit = ensure(value) { null } @@ -84,6 +138,10 @@ public class NullableRaise(private val raise: Raise) : Raise by rais } } +/** + * Implementation of [Raise] used by [result]. + * You should never use this directly. + */ public class ResultRaise(private val raise: Raise) : Raise by raise { @RaiseDSL public fun Result.bind(): A = fold(::identity) { raise(it) } @@ -117,6 +175,10 @@ public class ResultRaise(private val raise: Raise) : Raise ) } +/** + * Implementation of [Raise] used by [option]. + * You should never use this directly. + */ public class OptionRaise(private val raise: Raise) : Raise by raise { @RaiseDSL public fun Option.bind(): A = getOrElse { raise(None) } @@ -159,6 +221,10 @@ public class OptionRaise(private val raise: Raise) : Raise by raise } } +/** + * Implementation of [Raise] used by [ior]. + * You should never use this directly. + */ public class IorRaise @PublishedApi internal constructor( @PublishedApi internal val combineError: (Error, Error) -> Error, private val state: Atomic>, diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/Fold.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/Fold.kt index 1021ed3a8b7..a89b46b9ec5 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/Fold.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/Fold.kt @@ -37,6 +37,13 @@ public suspend fun Effect.fold( return fold({ invoke() }, { catch(it) }, { recover(it) }, { transform(it) }) } +/** + * `invoke` the [Effect] and [fold] the result: + * - _success_ [transform] result of [A] to a value of [B]. + * - _raised_ [recover] from `raised` value of [Error] to a value of [B]. + * + * This function re-throws any exceptions thrown within the [Effect]. + */ public suspend fun Effect.fold( recover: suspend (error: Error) -> B, transform: suspend (value: A) -> B, @@ -48,6 +55,15 @@ public suspend fun Effect.fold( return fold({ throw it }, recover, transform) } +/** + * `invoke` the [EagerEffect] and [fold] the result: + * - _success_ [transform] result of [A] to a value of [B]. + * - _raised_ [recover] from `raised` value of [Error] to a value of [B]. + * - _exception_ [catch] from [Throwable] by transforming value into [B]. + * + * This method should never be wrapped in `try`/`catch` as it will not throw any unexpected errors, + * it will only result in [CancellationException], or fatal exceptions such as `OutOfMemoryError`. + */ public inline fun EagerEffect.fold( catch: (throwable: Throwable) -> B, recover: (error: Error) -> B, @@ -61,6 +77,13 @@ public inline fun EagerEffect.fold( return fold({ invoke(this) }, catch, recover, transform) } +/** + * `invoke` the [EagerEffect] and [fold] the result: + * - _success_ [transform] result of [A] to a value of [B]. + * - _raised_ [recover] from `raised` value of [Error] to a value of [B]. + * + * This function re-throws any exceptions thrown within the [Effect]. + */ public inline fun EagerEffect.fold(recover: (error: Error) -> B, transform: (value: A) -> B): B { contract { callsInPlace(recover, AT_MOST_ONCE) @@ -69,6 +92,14 @@ public inline fun EagerEffect.fold(recover: (error: Erro return fold({ throw it }, recover, transform) } +/** + * The most general way to execute a computation using [Raise]. + * Depending on the outcome of the block, one of the two continuations is run: + * - _success_ [transform] result of [A] to a value of [B]. + * - _raised_ [recover] from `raised` value of [Error] to a value of [B]. + * + * This function re-throws any exceptions thrown within the [Raise] block. + */ @JvmName("_foldOrThrow") public inline fun fold( @BuilderInference block: Raise.() -> A, @@ -82,6 +113,16 @@ public inline fun fold( return fold(block, { throw it }, recover, transform) } +/** + * The most general way to execute a computation using [Raise]. + * Depending on the outcome of the block, one of the three continuations is run: + * - _success_ [transform] result of [A] to a value of [B]. + * - _raised_ [recover] from `raised` value of [Error] to a value of [B]. + * - _exception_ [catch] from [Throwable] by transforming value into [B]. + * + * This method should never be wrapped in `try`/`catch` as it will not throw any unexpected errors, + * it will only result in [CancellationException], or fatal exceptions such as `OutOfMemoryError`. + */ @JvmName("_fold") public inline fun fold( @BuilderInference block: Raise.() -> A, diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/Mappers.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/Mappers.kt index 4efa6d67340..c6cb52e977a 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/Mappers.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/Mappers.kt @@ -13,16 +13,19 @@ import kotlin.jvm.JvmName /** Run the [Effect] by returning [Either.Right] of [A], or [Either.Left] of [Error]. */ public suspend fun Effect.toEither(): Either = either { invoke() } +/** Run the [EagerEffect] by returning [Either.Right] of [A], or [Either.Left] of [Error]. */ public fun EagerEffect.toEither(): Either = either { invoke() } /** Run the [Effect] by returning [Validated.Valid] of [A], or [Validated.Invalid] of [Error]. */ @Deprecated(ValidatedDeprMsg, ReplaceWith("toEither()")) public suspend fun Effect.toValidated(): Validated = fold({ Validated.Invalid(it) }) { Validated.Valid(it) } +/** Run the [EagerEffect] by returning [Validated.Valid] of [A], or [Validated.Invalid] of [Error]. */ @Deprecated(ValidatedDeprMsg, ReplaceWith("toEither()")) public fun EagerEffect.toValidated(): Validated = fold({ Validated.Invalid(it) }) { Validated.Valid(it) } /** Run the [Effect] by returning [Ior.Right] of [A], or [Ior.Left] of [Error]. */ public suspend fun Effect.toIor(): Ior = fold({ Ior.Left(it) }) { Ior.Right(it) } +/** Run the [EagerEffect] by returning [Ior.Right] of [A], or [Ior.Left] of [Error]. */ public fun EagerEffect.toIor(): Ior = fold({ Ior.Left(it) }) { Ior.Right(it) } @Deprecated( @@ -45,14 +48,17 @@ public fun EagerEffect.getOrNull(): A? = getOrElse { null } /** Run the [Effect] by returning [Option] of [A], [recover] run the fallback lambda and returning its result of [Option] of [A]. */ public suspend fun Effect.toOption(recover: suspend (error: Error) -> Option): Option = fold(recover) { Some(it) } +/** Run the [EagerEffect] by returning [Option] of [A], [recover] run the fallback lambda and returning its result of [Option] of [A]. */ public inline fun EagerEffect.toOption(recover: (error: Error) -> Option): Option = fold(recover) { Some(it) } /** Run the [Effect] by returning [Result] of [A], [recover] run the fallback lambda and returning its result of [Result] of [A]. */ public suspend fun Effect.toResult(recover: suspend (error: Error) -> Result): Result = fold({ Result.failure(it) }, { recover(it) }, { Result.success(it) }) +/** Run the [EagerEffect] by returning [Result] of [A], [recover] run the fallback lambda and returning its result of [Result] of [A]. */ public inline fun EagerEffect.toResult(recover: (error: Error) -> Result): Result = fold({ Result.failure(it) }, { recover(it) }, { Result.success(it) }) /** Run the [Effect] by returning [Result] of [A], or [Result.Failure] if raised with [Throwable]. */ public suspend fun Effect.toResult(): Result = result { invoke() } +/** Run the [EagerEffect] by returning [Result] of [A], or [Result.Failure] if raised with [Throwable]. */ public fun EagerEffect.toResult(): Result = result { invoke() } diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/Raise.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/Raise.kt index fbfae26c7b7..007f6e90581 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/Raise.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/Raise.kt @@ -31,7 +31,9 @@ public annotation class RaiseDSL * * The [Raise] DSL allows you to work with _logical failures_ of type [Error]. * A _logical failure_ does not necessarily mean that the computation has failed, - * but that it has stopped or _short-circuited_. + * but that it has stopped or _short-circuited_. The Arrow website has a + * [guide](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/) + * introducing [Raise] and how to use it effectively. * * The [Raise] DSL allows you to [raise] _logical failure_ of type [Error], and you can [recover] from them. * @@ -248,6 +250,13 @@ public interface Raise { */ public operator fun EagerEffect.invoke(): A = invoke(this@Raise) + /** + * Invoke an [EagerEffect] inside `this` [Raise] context. + * Any _logical failure_ is raised in `this` [Raise] context, + * and thus short-circuits the computation. + * + * @see [recover] if you want to attempt to recover from any _logical failure_. + */ @RaiseDSL public fun EagerEffect.bind(): A = invoke(this@Raise) @@ -260,6 +269,13 @@ public interface Raise { */ public suspend operator fun Effect.invoke(): A = invoke(this@Raise) + /** + * Invoke an [Effect] inside `this` [Raise] context. + * Any _logical failure_ raised are raised in `this` [Raise] context, + * and thus short-circuits the computation. + * + * @see [recover] if you want to attempt to recover from any _logical failure_. + */ @RaiseDSL public suspend fun Effect.bind(): A = invoke(this@Raise) @@ -296,6 +312,11 @@ public interface Raise { is Either.Right -> value } + /** + * Extracts all the values in the [Map], raising every [Either.Left] + * as a _logical failure_. In other words, executed [bind] over every + * value in this [Map]. + */ public fun Map>.bindAll(): Map = mapValues { (_, a) -> a.bind() } @@ -306,14 +327,29 @@ public interface Raise { is Validated.Valid -> value } + /** + * Extracts all the values in the [Iterable], raising every [Either.Left] + * as a _logical failure_. In other words, executed [bind] over every + * value in this [Iterable]. + */ @RaiseDSL public fun Iterable>.bindAll(): List = map { it.bind() } + /** + * Extracts all the values in the [NonEmptyList], raising every [Either.Left] + * as a _logical failure_. In other words, executed [bind] over every + * value in this [NonEmptyList]. + */ @RaiseDSL public fun NonEmptyList>.bindAll(): NonEmptyList = map { it.bind() } + /** + * Extracts all the values in the [NonEmptySet], raising every [Either.Left] + * as a _logical failure_. In other words, executed [bind] over every + * value in this [NonEmptySet]. + */ @RaiseDSL public fun NonEmptySet>.bindAll(): NonEmptySet = map { it.bind() }.toNonEmptySet() diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/RaiseAccumulate.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/RaiseAccumulate.kt index ce7d09bc38a..f477e2b5306 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/RaiseAccumulate.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/RaiseAccumulate.kt @@ -27,6 +27,10 @@ import kotlin.jvm.JvmName /** * Accumulate the errors from running both [action1] and [action2] using the given [combine] function. + * + * See the Arrow docs for more information over + * [error accumulation](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#accumulating-errors) + * and how to use it in [validation](https://arrow-kt.io/learn/typed-errors/validation/). */ @RaiseDSL public inline fun Raise.zipOrAccumulate( @@ -47,6 +51,10 @@ public inline fun Raise.zipOrAccumulate( /** * Accumulate the errors from running [action1], [action2], and [action3] using the given [combine]. + * + * See the Arrow docs for more information over + * [error accumulation](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#accumulating-errors) + * and how to use it in [validation](https://arrow-kt.io/learn/typed-errors/validation/). */ @RaiseDSL public inline fun Raise.zipOrAccumulate( @@ -69,6 +77,10 @@ public inline fun Raise.zipOrAccumulate( /** * Accumulate the errors from running [action1], [action2], [action3], and [action4] using the given [combine]. + * + * See the Arrow docs for more information over + * [error accumulation](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#accumulating-errors) + * and how to use it in [validation](https://arrow-kt.io/learn/typed-errors/validation/). */ @RaiseDSL public inline fun Raise.zipOrAccumulate( @@ -93,6 +105,10 @@ public inline fun Raise.zipOrAccumulate( /** * Accumulate the errors from running [action1], [action2], [action3], [action4], and [action5] using the given [combine]. + * + * See the Arrow docs for more information over + * [error accumulation](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#accumulating-errors) + * and how to use it in [validation](https://arrow-kt.io/learn/typed-errors/validation/). */ @RaiseDSL public inline fun Raise.zipOrAccumulate( @@ -119,6 +135,10 @@ public inline fun Raise.zipOrAccumulate( /** * Accumulate the errors from running [action1], [action2], [action3], [action4], [action5], and [action6] using the given [combine]. + * + * See the Arrow docs for more information over + * [error accumulation](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#accumulating-errors) + * and how to use it in [validation](https://arrow-kt.io/learn/typed-errors/validation/). */ @RaiseDSL public inline fun Raise.zipOrAccumulate( @@ -147,6 +167,10 @@ public inline fun Raise.zipOrAccumulate( /** * Accumulate the errors from running [action1], [action2], [action3], [action4], [action5], [action6], and [action7] using the given [combine]. + * + * See the Arrow docs for more information over + * [error accumulation](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#accumulating-errors) + * and how to use it in [validation](https://arrow-kt.io/learn/typed-errors/validation/). */ @RaiseDSL public inline fun Raise.zipOrAccumulate( @@ -177,6 +201,10 @@ public inline fun Raise.zipOrAccumulate( /** * Accumulate the errors from running [action1], [action2], [action3], [action4], [action5], [action6], [action7], and [action8] using the given [combine]. + * + * See the Arrow docs for more information over + * [error accumulation](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#accumulating-errors) + * and how to use it in [validation](https://arrow-kt.io/learn/typed-errors/validation/). */ @RaiseDSL public inline fun Raise.zipOrAccumulate( @@ -209,6 +237,10 @@ public inline fun Raise.zipOrAccumulat /** * Accumulate the errors from running [action1], [action2], [action3], [action4], [action5], [action6], [action7], [action8], and [action9] using the given [combine]. + * + * See the Arrow docs for more information over + * [error accumulation](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#accumulating-errors) + * and how to use it in [validation](https://arrow-kt.io/learn/typed-errors/validation/). */ @RaiseDSL public inline fun Raise.zipOrAccumulate( @@ -241,6 +273,10 @@ public inline fun Raise.zipOrAccumu /** * Accumulate the errors from running both [action1] and [action2]. + * + * See the Arrow docs for more information over + * [error accumulation](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#accumulating-errors) + * and how to use it in [validation](https://arrow-kt.io/learn/typed-errors/validation/). */ @RaiseDSL public inline fun Raise>.zipOrAccumulate( @@ -259,6 +295,10 @@ public inline fun Raise>.zipOrAccumulate( /** * Accumulate the errors from running [action1], [action2], and [action3]. + * + * See the Arrow docs for more information over + * [error accumulation](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#accumulating-errors) + * and how to use it in [validation](https://arrow-kt.io/learn/typed-errors/validation/). */ @RaiseDSL public inline fun Raise>.zipOrAccumulate( @@ -279,6 +319,10 @@ public inline fun Raise>.zipOrAccumulate /** * Accumulate the errors from running [action1], [action2], [action3], and [action4]. + * + * See the Arrow docs for more information over + * [error accumulation](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#accumulating-errors) + * and how to use it in [validation](https://arrow-kt.io/learn/typed-errors/validation/). */ @RaiseDSL public inline fun Raise>.zipOrAccumulate( @@ -301,6 +345,10 @@ public inline fun Raise>.zipOrAccumul /** * Accumulate the errors from running [action1], [action2], [action3], [action4], and [action5]. + * + * See the Arrow docs for more information over + * [error accumulation](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#accumulating-errors) + * and how to use it in [validation](https://arrow-kt.io/learn/typed-errors/validation/). */ @RaiseDSL public inline fun Raise>.zipOrAccumulate( @@ -325,6 +373,10 @@ public inline fun Raise>.zipOrAccu /** * Accumulate the errors from running [action1], [action2], [action3], [action4], [action5], and [action6]. + * + * See the Arrow docs for more information over + * [error accumulation](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#accumulating-errors) + * and how to use it in [validation](https://arrow-kt.io/learn/typed-errors/validation/). */ @RaiseDSL public inline fun Raise>.zipOrAccumulate( @@ -351,6 +403,10 @@ public inline fun Raise>.zipOrA /** * Accumulate the errors from running [action1], [action2], [action3], [action4], [action5], [action6], and [action7]. + * + * See the Arrow docs for more information over + * [error accumulation](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#accumulating-errors) + * and how to use it in [validation](https://arrow-kt.io/learn/typed-errors/validation/). */ @RaiseDSL public inline fun Raise>.zipOrAccumulate( @@ -379,6 +435,10 @@ public inline fun Raise>.zip /** * Accumulate the errors from running [action1], [action2], [action3], [action4], [action5], [action6], [action7], and [action8]. + * + * See the Arrow docs for more information over + * [error accumulation](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#accumulating-errors) + * and how to use it in [validation](https://arrow-kt.io/learn/typed-errors/validation/). */ @RaiseDSL public inline fun Raise>.zipOrAccumulate( @@ -409,6 +469,10 @@ public inline fun Raise>. /** * Accumulate the errors from running [action1], [action2], [action3], [action4], [action5], [action6], [action7], [action8], and [action9]. + * + * See the Arrow docs for more information over + * [error accumulation](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#accumulating-errors) + * and how to use it in [validation](https://arrow-kt.io/learn/typed-errors/validation/). */ @RaiseDSL public inline fun Raise>.zipOrAccumulate( @@ -440,6 +504,10 @@ public inline fun Raise Raise.mapOrAccumulate( @@ -461,6 +529,10 @@ public inline fun Raise.mapOrAccumulate( /** * Accumulate the errors obtained by executing the [transform] over every element of [iterable]. + * + * See the Arrow docs for more information over + * [error accumulation](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#accumulating-errors) + * and how to use it in [validation](https://arrow-kt.io/learn/typed-errors/validation/). */ @RaiseDSL public inline fun Raise>.mapOrAccumulate( @@ -481,6 +553,10 @@ public inline fun Raise>.mapOrAccumulate( /** * Accumulate the errors obtained by executing the [transform] over every element of [NonEmptyList]. + * + * See the Arrow docs for more information over + * [error accumulation](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#accumulating-errors) + * and how to use it in [validation](https://arrow-kt.io/learn/typed-errors/validation/). */ @RaiseDSL public inline fun Raise>.mapOrAccumulate( @@ -490,6 +566,10 @@ public inline fun Raise>.mapOrAccumulate( /** * Accumulate the errors obtained by executing the [transform] over every element of [NonEmptySet]. + * + * See the Arrow docs for more information over + * [error accumulation](https://arrow-kt.io/learn/typed-errors/working-with-typed-errors/#accumulating-errors) + * and how to use it in [validation](https://arrow-kt.io/learn/typed-errors/validation/). */ @RaiseDSL public inline fun Raise>.mapOrAccumulate( From 1d1d54036e388d1ee70f049cbeee29bd4c08dc93 Mon Sep 17 00:00:00 2001 From: Simon Vergauwen Date: Mon, 10 Jul 2023 07:20:08 +0200 Subject: [PATCH 5/5] Add mapOrAccumulate extension in RaiseAccumulate (#3086) --- arrow-libs/core/arrow-core/api/arrow-core.api | 3 +++ .../arrow/core/raise/RaiseAccumulate.kt | 21 +++++++++++++++++++ .../arrow/core/raise/RaiseAccumulateSpec.kt | 18 ++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/raise/RaiseAccumulateSpec.kt diff --git a/arrow-libs/core/arrow-core/api/arrow-core.api b/arrow-libs/core/arrow-core/api/arrow-core.api index e6a4a7ff19a..8f2d3fc0cac 100644 --- a/arrow-libs/core/arrow-core/api/arrow-core.api +++ b/arrow-libs/core/arrow-core/api/arrow-core.api @@ -3455,6 +3455,9 @@ public final class arrow/core/raise/Raise$DefaultImpls { public class arrow/core/raise/RaiseAccumulate : arrow/core/raise/Raise { public fun (Larrow/core/raise/Raise;)V + public final fun _mapOrAccumulate (Larrow/core/NonEmptyList;Lkotlin/jvm/functions/Function2;)Larrow/core/NonEmptyList; + public final fun _mapOrAccumulate (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;)Ljava/util/List; + public final fun _mapOrAccumulate (Ljava/util/Set;Lkotlin/jvm/functions/Function2;)Ljava/util/Set; public fun attempt (Lkotlin/jvm/functions/Function2;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun bind (Larrow/core/Either;)Ljava/lang/Object; public fun bind (Larrow/core/Validated;)Ljava/lang/Object; diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/RaiseAccumulate.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/RaiseAccumulate.kt index f477e2b5306..8f85a58d77e 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/RaiseAccumulate.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/RaiseAccumulate.kt @@ -619,6 +619,27 @@ public open class RaiseAccumulate( transform: RaiseAccumulate.(A) -> B ): NonEmptySet = raise.mapOrAccumulate(this, transform) + @RaiseDSL + @JvmName("_mapOrAccumulate") + public inline fun mapOrAccumulate( + iterable: Iterable, + transform: RaiseAccumulate.(A) -> B + ): List = raise.mapOrAccumulate(iterable, transform) + + @RaiseDSL + @JvmName("_mapOrAccumulate") + public inline fun mapOrAccumulate( + list: NonEmptyList, + transform: RaiseAccumulate.(A) -> B + ): NonEmptyList = raise.mapOrAccumulate(list, transform) + + @RaiseDSL + @JvmName("_mapOrAccumulate") + public inline fun mapOrAccumulate( + set: NonEmptySet, + transform: RaiseAccumulate.(A) -> B + ): NonEmptySet = raise.mapOrAccumulate(set, transform) + @RaiseDSL override fun Iterable>.bindAll(): List = mapOrAccumulate { it.bind() } diff --git a/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/raise/RaiseAccumulateSpec.kt b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/raise/RaiseAccumulateSpec.kt new file mode 100644 index 00000000000..64584c77789 --- /dev/null +++ b/arrow-libs/core/arrow-core/src/commonTest/kotlin/arrow/core/raise/RaiseAccumulateSpec.kt @@ -0,0 +1,18 @@ +package arrow.core.raise + +import arrow.core.NonEmptyList +import arrow.core.left +import arrow.core.nonEmptyListOf +import io.kotest.core.spec.style.StringSpec +import io.kotest.matchers.shouldBe + +class RaiseAccumulateSpec : StringSpec({ + "RaiseAccumulate takes precedence over extension function" { + either, Int> { + zipOrAccumulate( + { ensure(false) { "false" } }, + { mapOrAccumulate(1..2) { ensure(false) { "$it: IsFalse" } } } + ) { _, _ -> 1 } + } shouldBe nonEmptyListOf("false", "1: IsFalse", "2: IsFalse").left() + } +})