Skip to content

Commit 5e122ea

Browse files
Add FFI for access, copyFile, mkdtemp
1 parent 2a88704 commit 5e122ea

File tree

6 files changed

+138
-13
lines changed

6 files changed

+138
-13
lines changed

src/Node/FS/Async.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
export {
2+
access as accessImpl,
3+
copyFile as copyFileImpl,
4+
mkdtemp as mkdtempImpl,
25
rename as renameImpl,
36
truncate as truncateImpl,
47
chown as chownImpl,
@@ -22,4 +25,4 @@ export {
2225
read as readImpl,
2326
write as writeImpl,
2427
close as closeImpl
25-
} from "fs";
28+
} from "node:fs";

src/Node/FS/Async.purs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
module Node.FS.Async
22
( Callback(..)
3+
, access
4+
, access'
5+
, copyFile
6+
, copyFile'
7+
, mkdtemp
8+
, mkdtemp'
39
, rename
410
, truncate
511
, chown
@@ -45,10 +51,11 @@ import Data.Nullable (Nullable, toMaybe, toNullable)
4551
import Data.Time.Duration (Milliseconds(..))
4652
import Effect (Effect)
4753
import Effect.Exception (Error)
48-
import Effect.Uncurried (EffectFn2, EffectFn3, EffectFn4, EffectFn6, mkEffectFn2, runEffectFn2, runEffectFn3, runEffectFn4, runEffectFn6)
54+
import Effect.Uncurried (EffectFn1, EffectFn2, EffectFn3, EffectFn4, EffectFn6, mkEffectFn1, mkEffectFn2, runEffectFn2, runEffectFn3, runEffectFn4, runEffectFn6)
4955
import Node.Buffer (Buffer, size)
50-
import Node.Encoding (Encoding)
56+
import Node.Encoding (Encoding(..), encodingToNode)
5157
import Node.FS (FileDescriptor, ByteCount, FilePosition, BufferLength, BufferOffset, FileMode, FileFlags, SymlinkType, fileFlagsToNode, symlinkTypeToNode)
58+
import Node.FS.Constants (AccessMode, CopyMode, defaultAccessMode, defaultCopyMode)
5259
import Node.FS.Perms (Perms, permsToString, all, mkPerms)
5360
import Node.FS.Stats (StatsObj, Stats(..))
5461
import Node.Path (FilePath)
@@ -63,6 +70,31 @@ handleCallback cb = mkEffectFn2 \err a -> case toMaybe err of
6370
-- | Type synonym for callback functions.
6471
type Callback a = Either Error a -> Effect Unit
6572

73+
access :: FilePath -> (Maybe Error -> Effect Unit) -> Effect Unit
74+
access path = access' path defaultAccessMode
75+
76+
access' :: FilePath -> AccessMode -> (Maybe Error -> Effect Unit) -> Effect Unit
77+
access' path mode cb = runEffectFn3 accessImpl path mode $ mkEffectFn1 \err -> do
78+
cb $ toMaybe err
79+
80+
foreign import accessImpl :: EffectFn3 FilePath AccessMode (EffectFn1 (Nullable Error) Unit) Unit
81+
82+
copyFile :: FilePath -> FilePath -> Callback Unit -> Effect Unit
83+
copyFile src dest = copyFile' src dest defaultCopyMode
84+
85+
copyFile' :: FilePath -> FilePath -> CopyMode -> Callback Unit -> Effect Unit
86+
copyFile' src dest mode cb = runEffectFn4 copyFileImpl src dest mode (handleCallback cb)
87+
88+
foreign import copyFileImpl :: EffectFn4 FilePath FilePath CopyMode (JSCallback Unit) Unit
89+
90+
mkdtemp :: String -> Callback String -> Effect Unit
91+
mkdtemp prefix = mkdtemp' prefix UTF8
92+
93+
mkdtemp' :: String -> Encoding -> Callback String -> Effect Unit
94+
mkdtemp' prefix encoding cb = runEffectFn3 mkdtempImpl prefix (encodingToNode encoding) (handleCallback cb)
95+
96+
foreign import mkdtempImpl :: EffectFn3 FilePath String (JSCallback String) Unit
97+
6698
foreign import renameImpl :: EffectFn3 FilePath FilePath (JSCallback Unit) Unit
6799
foreign import truncateImpl :: EffectFn3 FilePath Int (JSCallback Unit) Unit
68100
foreign import chownImpl :: EffectFn4 FilePath Int Int (JSCallback Unit) Unit

src/Node/FS/Constants.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { constants } from "node:fs";
2+
3+
export const f_OK = constants.F_OK;
4+
5+
export const r_OK = constants.R_OK;
6+
7+
export const w_OK = constants.W_OK;
8+
9+
export const x_OK = constants.X_OK;
10+
11+
export const copyFile_EXCL = constants.COPYFILE_EXCL;
12+
13+
export const copyFile_FICLONE = constants.COPYFILE_FICLONE;
14+
15+
export const copyFile_FICLONE_FORCE = constants.COPYFILE_FICLONE_FORCE;
16+
17+
export const appendCopyMode = (l, r) => l | r;

src/Node/FS/Constants.purs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
module Node.FS.Constants where
2+
3+
import Prelude
4+
5+
import Data.Function.Uncurried (Fn2, runFn2)
6+
7+
-- | the mode parameter passed to `access` and `accessSync`.
8+
foreign import data AccessMode :: Type
9+
10+
-- | the file is visible to the calling process.
11+
-- | This is useful for determining if a file exists, but says nothing about rwx permissions. Default if no mode is specified.
12+
foreign import f_OK :: AccessMode
13+
14+
-- | the file can be read by the calling process.
15+
foreign import r_OK :: AccessMode
16+
17+
-- | the file can be written by the calling process.
18+
foreign import w_OK :: AccessMode
19+
20+
-- | the file can be executed by the calling process. This has no effect on Windows (will behave like fs.constants.F_OK).
21+
foreign import x_OK :: AccessMode
22+
23+
defaultAccessMode = f_OK :: AccessMode
24+
25+
foreign import data CopyMode :: Type
26+
27+
foreign import copyFile_EXCL :: CopyMode
28+
foreign import copyFile_FICLONE :: CopyMode
29+
foreign import copyFile_FICLONE_FORCE :: CopyMode
30+
31+
defaultCopyMode = copyFile_EXCL :: CopyMode
32+
33+
foreign import appendCopyMode :: Fn2 CopyMode CopyMode CopyMode
34+
35+
instance Semigroup CopyMode where
36+
append l r = runFn2 appendCopyMode l r

src/Node/FS/Sync.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
export {
1+
export {
2+
accessSync as accessImpl,
3+
copyFileSync as copyFileImpl,
4+
mkdtempSync as mkdtempImpl,
25
renameSync as renameSyncImpl,
36
truncateSync as truncateSyncImpl,
47
chownSync as chownSyncImpl,
@@ -24,4 +27,4 @@ export {
2427
writeSync as writeSyncImpl,
2528
fsyncSync as fsyncSyncImpl,
2629
closeSync as closeSyncImpl
27-
} from "fs";
30+
} from "node:fs";

src/Node/FS/Sync.purs

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
module Node.FS.Sync
2-
( rename
2+
( access
3+
, access'
4+
, copyFile
5+
, copyFile'
6+
, mkdtemp
7+
, mkdtemp'
8+
, rename
39
, truncate
410
, chown
511
, chmod
@@ -37,20 +43,48 @@ module Node.FS.Sync
3743

3844
import Prelude
3945

40-
import Effect (Effect)
4146
import Data.DateTime (DateTime)
42-
import Data.Time.Duration (Milliseconds(..))
4347
import Data.DateTime.Instant (fromDateTime, unInstant)
44-
import Data.Nullable (Nullable(), toNullable)
48+
import Data.Either (blush)
4549
import Data.Int (round)
4650
import Data.Maybe (Maybe(..))
51+
import Data.Nullable (Nullable, toNullable)
52+
import Data.Time.Duration (Milliseconds(..))
53+
import Effect (Effect)
54+
import Effect.Exception (Error, try)
4755
import Effect.Uncurried (EffectFn1, EffectFn2, EffectFn3, EffectFn5, runEffectFn1, runEffectFn2, runEffectFn3, runEffectFn5)
48-
import Node.Buffer (Buffer(), size)
49-
import Node.Encoding (Encoding)
56+
import Node.Buffer (Buffer, size)
57+
import Node.Encoding (Encoding(..), encodingToNode)
5058
import Node.FS (FileDescriptor, ByteCount, FilePosition, BufferLength, BufferOffset, FileMode, FileFlags, SymlinkType, fileFlagsToNode, symlinkTypeToNode)
51-
import Node.FS.Stats (StatsObj, Stats(..))
52-
import Node.Path (FilePath())
59+
import Node.FS.Constants (AccessMode, CopyMode, defaultAccessMode, defaultCopyMode)
5360
import Node.FS.Perms (Perms, permsToString, all, mkPerms)
61+
import Node.FS.Stats (StatsObj, Stats(..))
62+
import Node.Path (FilePath)
63+
64+
access :: FilePath -> Effect (Maybe Error)
65+
access = flip access' defaultAccessMode
66+
67+
access' :: FilePath -> AccessMode -> Effect (Maybe Error)
68+
access' path mode = do
69+
map blush $ try $ runEffectFn2 accessImpl path mode
70+
71+
foreign import accessImpl :: EffectFn2 FilePath AccessMode (Maybe Error)
72+
73+
copyFile :: FilePath -> FilePath -> Effect Unit
74+
copyFile src dest = runEffectFn3 copyFileImpl src dest defaultCopyMode
75+
76+
copyFile' :: FilePath -> FilePath -> CopyMode -> Effect Unit
77+
copyFile' src dest mode = runEffectFn3 copyFileImpl src dest mode
78+
79+
foreign import copyFileImpl :: EffectFn3 FilePath FilePath CopyMode Unit
80+
81+
mkdtemp :: String -> Effect String
82+
mkdtemp prefix = mkdtemp' prefix UTF8
83+
84+
mkdtemp' :: String -> Encoding -> Effect String
85+
mkdtemp' prefix encoding = runEffectFn2 mkdtempImpl prefix (encodingToNode encoding)
86+
87+
foreign import mkdtempImpl :: EffectFn2 String String String
5488

5589
foreign import renameSyncImpl :: EffectFn2 FilePath FilePath Unit
5690
foreign import truncateSyncImpl :: EffectFn2 FilePath Int Unit

0 commit comments

Comments
 (0)