git.iko.soy/rowtype-yoga/purescript-uuid
on main help sign in
Make UUIDs serialisable (#15)

* Generic encode/decode * Spago

commite6005a172435f43778d9b8dff0f8bc4abf7c6e32 authorRowan Skewes <rowan.skewes@gmail.com> dateWed 1 Apr 2020, 06:51 (7 years ago) parentb96329c
6 files changed+175−2
.gitignore+1 bower.json+3−2 packages.dhall+128 spago.dhall+18 src/Data/UUID.purs+18 test/Main.purs+7
.gitignore+1
@@ -5,3 +5,4 @@
55/.psci*
66/src/.webpack.js
77.psc-ide-port
8+/.spago/
bower.json+3−2
@@ -9,10 +9,11 @@
99 "license": "MIT",
1010 "dependencies": {
1111 "purescript-effect": "^2.0.0",
12− "purescript-maybe": "^4.0.1"
12+ "purescript-maybe": "^4.0.1",
13+ "purescript-foreign-generic": "^10.0.0"
1314 },
1415 "devDependencies": {
1516 "purescript-console": "^4.1.0",
1617 "purescript-spec": "^4.0.0"
1718 }
18−}
19+}
packages.dhallnew file+128
@@ -0,0 +1,128 @@
1+{-
2+Welcome to your new Dhall package-set!
3+
4+Below are instructions for how to edit this file for most use
5+cases, so that you don't need to know Dhall to use it.
6+
7+## Warning: Don't Move This Top-Level Comment!
8+
9+Due to how `dhall format` currently works, this comment's
10+instructions cannot appear near corresponding sections below
11+because `dhall format` will delete the comment. However,
12+it will not delete a top-level comment like this one.
13+
14+## Use Cases
15+
16+Most will want to do one or both of these options:
17+1. Override/Patch a package's dependency
18+2. Add a package not already in the default package set
19+
20+This file will continue to work whether you use one or both options.
21+Instructions for each option are explained below.
22+
23+### Overriding/Patching a package
24+
25+Purpose:
26+- Change a package's dependency to a newer/older release than the
27+ default package set's release
28+- Use your own modified version of some dependency that may
29+ include new API, changed API, removed API by
30+ using your custom git repo of the library rather than
31+ the package set's repo
32+
33+Syntax:
34+Replace the overrides' "{=}" (an empty record) with the following idea
35+The "//" or "⫽" means "merge these two records and
36+ when they have the same value, use the one on the right:"
37+-------------------------------
38+let override =
39+ { packageName =
40+ upstream.packageName // { updateEntity1 = "new value", updateEntity2 = "new value" }
41+ , packageName =
42+ upstream.packageName // { version = "v4.0.0" }
43+ , packageName =
44+ upstream.packageName // { repo = "https://www.example.com/path/to/new/repo.git" }
45+ }
46+-------------------------------
47+
48+Example:
49+-------------------------------
50+let overrides =
51+ { halogen =
52+ upstream.halogen // { version = "master" }
53+ , halogen-vdom =
54+ upstream.halogen-vdom // { version = "v4.0.0" }
55+ }
56+-------------------------------
57+
58+### Additions
59+
60+Purpose:
61+- Add packages that aren't already included in the default package set
62+
63+Syntax:
64+Replace the additions' "{=}" (an empty record) with the following idea:
65+-------------------------------
66+let additions =
67+ { package-name =
68+ { dependencies =
69+ [ "dependency1"
70+ , "dependency2"
71+ ]
72+ , repo =
73+ "https://example.com/path/to/git/repo.git"
74+ , version =
75+ "tag ('v4.0.0') or branch ('master')"
76+ }
77+ , package-name =
78+ { dependencies =
79+ [ "dependency1"
80+ , "dependency2"
81+ ]
82+ , repo =
83+ "https://example.com/path/to/git/repo.git"
84+ , version =
85+ "tag ('v4.0.0') or branch ('master')"
86+ }
87+ , etc.
88+ }
89+-------------------------------
90+
91+Example:
92+-------------------------------
93+let additions =
94+ { benchotron =
95+ { dependencies =
96+ [ "arrays"
97+ , "exists"
98+ , "profunctor"
99+ , "strings"
100+ , "quickcheck"
101+ , "lcg"
102+ , "transformers"
103+ , "foldable-traversable"
104+ , "exceptions"
105+ , "node-fs"
106+ , "node-buffer"
107+ , "node-readline"
108+ , "datetime"
109+ , "now"
110+ ]
111+ , repo =
112+ "https://github.com/hdgarrood/purescript-benchotron.git"
113+ , version =
114+ "v7.0.0"
115+ }
116+ }
117+-------------------------------
118+-}
119+
120+
121+let upstream =
122+ https://github.com/purescript/package-sets/releases/download/psc-0.13.3-20190827/packages.dhall sha256:93f6b11068b42eac6632d56dab659a151c231381e53a16de621ae6d0dab475ce
123+
124+let overrides = {=}
125+
126+let additions = {=}
127+
128+in upstream // overrides // additions
spago.dhallnew file+18
@@ -0,0 +1,18 @@
1+{-
2+Welcome to a Spago project!
3+You can edit this file as you like.
4+-}
5+{ name =
6+ "uuid"
7+, dependencies =
8+ [ "console"
9+ , "effect"
10+ , "psci-support"
11+ , "spec"
12+ , "foreign-generic"
13+ ]
14+, packages =
15+ ./packages.dhall
16+, sources =
17+ [ "src/**/*.purs", "test/**/*.purs" ]
18+}
src/Data/UUID.purs+18
@@ -9,8 +9,15 @@ module Data.UUID
99 ) where
1010
1111import Prelude
12+import Control.Monad.Except.Trans (except)
13+import Data.Either (note)
14+import Data.Generic.Rep (class Generic)
15+import Data.List.NonEmpty (singleton)
1216import Data.Maybe (Maybe(Nothing, Just))
1317import Effect (Effect)
18+import Foreign (ForeignError(..))
19+import Foreign as Foreign
20+import Foreign.Class (class Encode, class Decode)
1421
1522newtype UUID
1623 = UUID String
@@ -51,3 +58,14 @@ derive instance ordUUID :: Ord UUID
5158
5259toString :: UUID -> String
5360toString (UUID uuid) = uuid
61+
62+derive instance genericUUID :: Generic UUID _
63+
64+instance decodeUUID :: Decode UUID where
65+ decode x = Foreign.readString x >>=
66+ parseUUID
67+ >>> note (singleton $ ForeignError "Failed to parse foreign UUID")
68+ >>> except
69+
70+instance encodeUUID :: Encode UUID where
71+ encode = toString >>> Foreign.unsafeToForeign
test/Main.purs+7
@@ -1,6 +1,7 @@
11module Test.Main where
22
33import Prelude
4+import Data.Either (Either(..))
45import Data.Maybe (Maybe(..), fromJust)
56import Data.String (length)
67import Data.UUID (genUUID, genv3UUID, genv5UUID, parseUUID, toString)
@@ -8,6 +9,8 @@ import Effect (Effect)
89import Effect.Aff (launchAff_)
910import Effect.Class (liftEffect)
1011import Effect.Unsafe (unsafePerformEffect)
12+import Control.Monad.Except (runExcept)
13+import Foreign.Generic (encode, decode)
1114import Partial.Unsafe (unsafePartial)
1215import Test.Spec (it, describe)
1316import Test.Spec.Assertions (shouldEqual)
@@ -53,3 +56,7 @@ main =
5356
5457 uuid = parseUUID uuidStr
5558 showUUID `shouldEqual` (show $ unsafePartial $ fromJust uuid)
59+ it "`encode >>> decode` returns the uuid unchanged" do
60+ let
61+ uuid = unsafePerformEffect genUUID
62+ runExcept ((encode >>> decode) uuid) `shouldEqual` Right uuid