Skip to content

Commit 2afabd9

Browse files
committed
Cleaning up Node.FS.Perms a bit more
* More instances: Eq, Ord * Better Show instances * Ensure permsFromString (permsToString x) == Just x
1 parent 0b3fe98 commit 2afabd9

File tree

4 files changed

+153
-90
lines changed

4 files changed

+153
-90
lines changed

README.md

Lines changed: 60 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -190,18 +190,36 @@ newtype Perm
190190
A `Perm` value specifies what is allowed to be done with a particular
191191
file by a particular class of user — that is, whether it is
192192
readable, writable, and/or executable. It has a semigroup instance, which
193-
allows you to combine permissions; for example, `r <> w` means "readable
194-
and writable".
193+
allows you to combine permissions; for example, `read <> write` means
194+
"readable and writable".
195195

196-
#### `Perms`
196+
#### `eqPerm`
197197

198198
``` purescript
199-
newtype Perms
199+
instance eqPerm :: Eq Perm
200+
```
201+
202+
203+
#### `ordPerm`
204+
205+
``` purescript
206+
instance ordPerm :: Ord Perm
207+
```
208+
209+
210+
#### `showPerm`
211+
212+
``` purescript
213+
instance showPerm :: Show Perm
214+
```
215+
216+
217+
#### `semigroupPerm`
218+
219+
``` purescript
220+
instance semigroupPerm :: Semigroup Perm
200221
```
201222

202-
A `Perms` value includes all the permissions information about a
203-
particular file or directory, by storing a `Perm` value for each of the
204-
file owner, the group, and others.
205223

206224
#### `none`
207225

@@ -212,26 +230,26 @@ none :: Perm
212230
No permissions. This is the identity of the `Semigroup` operation `(<>)`
213231
for `Perm`.
214232

215-
#### `r`
233+
#### `read`
216234

217235
``` purescript
218-
r :: Perm
236+
read :: Perm
219237
```
220238

221239
The "readable" permission.
222240

223-
#### `w`
241+
#### `write`
224242

225243
``` purescript
226-
w :: Perm
244+
write :: Perm
227245
```
228246

229247
The "writable" permission.
230248

231-
#### `x`
249+
#### `execute`
232250

233251
``` purescript
234-
x :: Perm
252+
execute :: Perm
235253
```
236254

237255
The "executable" permission.
@@ -244,10 +262,34 @@ all :: Perm
244262

245263
All permissions: readable, writable, and executable.
246264

247-
#### `semigroupPerm`
265+
#### `Perms`
248266

249267
``` purescript
250-
instance semigroupPerm :: Semigroup Perm
268+
newtype Perms
269+
```
270+
271+
A `Perms` value includes all the permissions information about a
272+
particular file or directory, by storing a `Perm` value for each of the
273+
file owner, the group, and any other users.
274+
275+
#### `eqPerms`
276+
277+
``` purescript
278+
instance eqPerms :: Eq Perms
279+
```
280+
281+
282+
#### `ordPerms`
283+
284+
``` purescript
285+
instance ordPerms :: Ord Perms
286+
```
287+
288+
289+
#### `showPerms`
290+
291+
``` purescript
292+
instance showPerms :: Show Perms
251293
```
252294

253295

@@ -259,16 +301,16 @@ permsFromString :: String -> Maybe Perms
259301

260302
Attempt to parse a `Perms` value from a `String` containing an octal
261303
integer. For example,
262-
`permsFromString "644" == Just (mkPerms (r <> w) r r)`.
304+
`permsFromString "0644" == Just (mkPerms (read <> write) read read)`.
263305

264306
#### `mkPerms`
265307

266308
``` purescript
267309
mkPerms :: Perm -> Perm -> Perm -> Perms
268310
```
269311

270-
Create a `Perms` value. The arguments represent the user's, group's, and
271-
others' permission sets, respectively.
312+
Create a `Perms` value. The arguments represent the owner's, group's, and
313+
other users' permission sets, respectively.
272314

273315
#### `permsToString`
274316

@@ -289,20 +331,6 @@ permsToInt :: Perms -> Int
289331

290332
Convert a `Perms` value to an `Int`, via `permsToString`.
291333

292-
#### `showPerm`
293-
294-
``` purescript
295-
instance showPerm :: Show Perm
296-
```
297-
298-
299-
#### `showPerms`
300-
301-
``` purescript
302-
instance showPerms :: Show Perms
303-
```
304-
305-
306334

307335
## Module Node.FS.Stats
308336

src/Node/FS/Async.purs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ mkdir :: forall eff. FilePath
227227
-> Callback eff Unit
228228
-> Eff (fs :: FS | eff) Unit
229229

230-
mkdir = flip mkdir' $ mkPerms (r <> w <> x) (r <> w <> x) (r <> w <> x)
230+
mkdir = flip mkdir' $ mkPerms all all all
231231

232232
-- |
233233
-- Makes a new directory with the specified permissions.

src/Node/FS/Perms.purs

Lines changed: 91 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,113 @@
11
module Node.FS.Perms
2-
( permsFromString
3-
, permsToString
4-
, permsToInt
2+
( Perm()
53
, none
6-
, r
7-
, w
8-
, x
4+
, read
5+
, write
6+
, execute
97
, all
10-
, mkPerms
118
, Perms()
12-
, Perm()
9+
, mkPerms
10+
, permsFromString
11+
, permsToString
12+
, permsToInt
1313
) where
1414

1515
import Global (readInt)
16+
import Data.Array () -- for Semigroup and Functor instances
1617
import Data.Maybe (Maybe(..))
17-
import Data.Char (Char(), charString)
18-
import Data.String (toCharArray)
18+
import Data.Char (Char(), charString, fromCharCode)
19+
import Data.String (toCharArray, joinWith, drop, charAt)
1920
import Data.Int (Int(), fromNumber, toNumber)
2021

2122
-- | A `Perm` value specifies what is allowed to be done with a particular
2223
-- | file by a particular class of user &mdash; that is, whether it is
2324
-- | readable, writable, and/or executable. It has a semigroup instance, which
24-
-- | allows you to combine permissions; for example, `r <> w` means "readable
25-
-- | and writable".
25+
-- | allows you to combine permissions; for example, `read <> write` means
26+
-- | "readable and writable".
2627
newtype Perm = Perm { r :: Boolean, w :: Boolean, x :: Boolean }
2728

28-
-- | A `Perms` value includes all the permissions information about a
29-
-- | particular file or directory, by storing a `Perm` value for each of the
30-
-- | file owner, the group, and others.
31-
newtype Perms = Perms { u :: Perm, g :: Perm, o :: Perm }
29+
instance eqPerm :: Eq Perm where
30+
(==) (Perm { r = r1, w = w1, x = x1 }) (Perm { r = r2, w = w2, x = x2 }) =
31+
r1 == r2 && w1 == w2 && x1 == x2
32+
(/=) x y = not (x == y)
33+
34+
instance ordPerm :: Ord Perm where
35+
compare (Perm { r = r1, w = w1, x = x1 }) (Perm { r = r2, w = w2, x = x2 }) =
36+
compare [r1, w1, x1] [r2, w2, x2]
37+
38+
instance showPerm :: Show Perm where
39+
show p | p == none = "none"
40+
show p | p == all = "all"
41+
show (Perm { r = r, w = w, x = x }) =
42+
joinWith " <> " ps
43+
where
44+
ps =
45+
(if r then ["read"] else []) <>
46+
(if w then ["write"] else []) <>
47+
(if x then ["execute"] else [])
48+
49+
instance semigroupPerm :: Semigroup Perm where
50+
(<>) (Perm { r = r0, w = w0, x = x0 }) (Perm { r = r1, w = w1, x = x1 }) =
51+
Perm { r: r0 || r1, w: w0 || w1, x: x0 || x1 }
52+
53+
-- | Create a `Perm` value. The arguments represent the readable, writable, and
54+
-- | executable permissions, in that order.
55+
mkPerm :: Boolean -> Boolean -> Boolean -> Perm
56+
mkPerm r w x = Perm { r: r, w: w, x: x }
3257

3358
-- | No permissions. This is the identity of the `Semigroup` operation `(<>)`
3459
-- | for `Perm`.
3560
none :: Perm
3661
none = Perm { r: false, w: false, x: false }
3762

3863
-- | The "readable" permission.
39-
r :: Perm
40-
r = Perm { r: true, w: false, x: false }
64+
read :: Perm
65+
read = Perm { r: true, w: false, x: false }
4166

4267
-- | The "writable" permission.
43-
w :: Perm
44-
w = Perm { r: false, w: true, x: false }
68+
write :: Perm
69+
write = Perm { r: false, w: true, x: false }
4570

4671
-- | The "executable" permission.
47-
x :: Perm
48-
x = Perm { r: false, w: false, x: true }
72+
execute :: Perm
73+
execute = Perm { r: false, w: false, x: true }
4974

5075
-- | All permissions: readable, writable, and executable.
5176
all :: Perm
52-
all = r <> w <> x
77+
all = read <> write <> execute
5378

54-
instance semigroupPerm :: Semigroup Perm where
55-
(<>) (Perm { r = r0, w = w0, x = x0 }) (Perm { r = r1, w = w1, x = x1 }) =
56-
Perm { r: r0 || r1, w: w0 || w1, x: x0 || x1 }
79+
-- | A `Perms` value includes all the permissions information about a
80+
-- | particular file or directory, by storing a `Perm` value for each of the
81+
-- | file owner, the group, and any other users.
82+
newtype Perms = Perms { u :: Perm, g :: Perm, o :: Perm }
83+
84+
instance eqPerms :: Eq Perms where
85+
(==) (Perms { u = u1, g = g1, o = o1 }) (Perms { u = u2, g = g2, o = o2 }) =
86+
u1 == u2 && g1 == g2 && o1 == o2
87+
(/=) x y = not (x == y)
88+
89+
instance ordPerms :: Ord Perms where
90+
compare (Perms { u = u1, g = g1, o = o1 }) (Perms { u = u2, g = g2, o = o2 }) =
91+
compare [u1, g1, o1] [u2, g2, o2]
92+
93+
instance showPerms :: Show Perms where
94+
show (Perms { u = u, g = g, o = o }) =
95+
"mkPerms " <> joinWith " " (f <$> [u, g, o])
96+
where
97+
f perm = "(" <> show perm <> ")"
5798

5899
-- | Attempt to parse a `Perms` value from a `String` containing an octal
59100
-- | integer. For example,
60-
-- | `permsFromString "644" == Just (mkPerms (r <> w) r r)`.
101+
-- | `permsFromString "0644" == Just (mkPerms (read <> write) read read)`.
61102
permsFromString :: String -> Maybe Perms
62-
permsFromString = _perms <<< toCharArray
103+
permsFromString = _perms <<< toCharArray <<< dropPrefix zeroChar
63104
where
105+
zeroChar = fromCharCode 48
106+
107+
dropPrefix x xs
108+
| charAt 0 xs == Just x = drop 1 xs
109+
| otherwise = xs
110+
64111
_perms [u, g, o] =
65112
mkPerms <$> permFromChar u
66113
<*> permFromChar g
@@ -71,22 +118,17 @@ permFromChar :: Char -> Maybe Perm
71118
permFromChar = _perm <<< charString
72119
where
73120
_perm "0" = Just $ none
74-
_perm "1" = Just $ x
75-
_perm "2" = Just $ w
76-
_perm "3" = Just $ w <> x
77-
_perm "4" = Just $ r
78-
_perm "5" = Just $ r <> x
79-
_perm "6" = Just $ r <> w
80-
_perm "7" = Just $ r <> w <> x
121+
_perm "1" = Just $ execute
122+
_perm "2" = Just $ write
123+
_perm "3" = Just $ write <> execute
124+
_perm "4" = Just $ read
125+
_perm "5" = Just $ read <> execute
126+
_perm "6" = Just $ read <> write
127+
_perm "7" = Just $ read <> write <> execute
81128
_perm _ = Nothing
82129

83-
-- | Create a `Perm` value. The arguments represent the readable, writable, and
84-
-- | executable permissions, in that order.
85-
mkPerm :: Boolean -> Boolean -> Boolean -> Perm
86-
mkPerm r w x = Perm { r: r, w: w, x: x }
87-
88-
-- | Create a `Perms` value. The arguments represent the user's, group's, and
89-
-- | others' permission sets, respectively.
130+
-- | Create a `Perms` value. The arguments represent the owner's, group's, and
131+
-- | other users' permission sets, respectively.
90132
mkPerms :: Perm -> Perm -> Perm -> Perms
91133
mkPerms u g o = Perms { u: u, g: g, o: o }
92134

@@ -96,10 +138,11 @@ mkPerms u g o = Perms { u: u, g: g, o: o }
96138
-- | * `permToInt w == 2`
97139
-- | * `permToInt (r <> w) == 6`
98140
permToInt :: Perm -> Int
99-
permToInt (Perm { r = r, w = w, x = x }) = fromNumber $
100-
(if r then 4 else 0)
101-
+ (if w then 2 else 0)
102-
+ (if x then 1 else 0)
141+
permToInt (Perm { r = r, w = w, x = x }) =
142+
fromNumber $
143+
(if r then 4 else 0)
144+
+ (if w then 2 else 0)
145+
+ (if x then 1 else 0)
103146

104147
-- | Convert a `Perm` to an octal string, via `permToInt`.
105148
permToString :: Perm -> String
@@ -116,14 +159,6 @@ permsToString (Perms { u = u, g = g, o = o }) =
116159
++ permToString g
117160
++ permToString o
118161

162+
-- | Convert a `Perms` value to an `Int`, via `permsToString`.
119163
permsToInt :: Perms -> Int
120-
permsToInt p = fromNumber $ readInt 8 $ permsToString p
121-
122-
instance showPerm :: Show Perm where
123-
show (Perm { r = r, w = w, x = x }) =
124-
(if r then "r" else "-")
125-
++ (if w then "w" else "-")
126-
++ (if x then "x" else "-")
127-
128-
instance showPerms :: Show Perms where
129-
show (Perms { u = u, g = g, o = o }) = show u ++ show g ++ show o
164+
permsToInt = fromNumber <<< readInt 8 <<< permsToString

src/Node/FS/Sync.purs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ rmdir file = mkEff $ \_ -> runFn1
247247
mkdir :: forall eff. FilePath
248248
-> Eff (fs :: FS, err :: Exception | eff) Unit
249249

250-
mkdir = flip mkdir' $ mkPerms (r <> w <> x) (r <> w <> x) (r <> w <> x)
250+
mkdir = flip mkdir' $ mkPerms all all all
251251

252252
-- |
253253
-- Makes a new directory with the specified permissions.

0 commit comments

Comments
 (0)