Skip to content

Commit e8c77e9

Browse files
Update FFI to uncurried one (#38)
1 parent 183ad05 commit e8c77e9

File tree

3 files changed

+73
-86
lines changed

3 files changed

+73
-86
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ Other improvements:
1414
- Bumped CI's node version to `lts/*` (#37 by @JordanMartinez)
1515
- Updated CI `actions/checkout` and `actions/setup-nodee` to `v3` (#37 by @JordanMartinez)
1616
- Format codebase & enforce formatting in CI via purs-tidy (#37 by @JordanMartinez)
17+
- Use uncurried FFI (#38 by @JordanMartinez)
1718

1819
## [v10.0.0](https://github.com/purescript-node/purescript-node-process/releases/tag/v10.0.0) - 2022-04-29
1920

src/Node/Process.js

Lines changed: 24 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import process from "process";
2-
export { process };
32

43
export function onBeforeExit(callback) {
54
return () => {
@@ -37,34 +36,28 @@ export function onSignalImpl(signal) {
3736
};
3837
}
3938

40-
export function chdir(dir) {
41-
return () => {
42-
process.chdir(dir);
43-
};
44-
}
39+
export const nextTickImpl = (cb) => process.nextTick(cb);
40+
export const argv = () => process.argv.slice();
41+
export const execArgv = () => process.execArgv.slice();
42+
export const execPath = () => process.execPath;
43+
export const chdirImpl = (dir) => process.chdir(dir);
44+
export const cwd = () => process.cwd;
45+
export const getEnv = () => Object.assign({}, process.env);
46+
export const unsafeGetEnv = () => process.env;
47+
export const setEnvImpl = (key, val) => {
48+
process.env[key] = val;
49+
};
50+
export const unsetEnvImpl = (key) => {
51+
delete process.env[key];
52+
};
53+
export const pid = process.pid;
54+
export const platformStr = process.platform;
55+
export const exitImpl = (code) => process.exit(code);
56+
export const stdin = process.stdin;
57+
export const stdout = process.stdout;
58+
export const stderr = process.stderr;
59+
export const stdinIsTTY = process.stdinIsTTY;
60+
export const stdoutIsTTY = process.stdoutIsTTY;
61+
export const stderrIsTTY = process.stderrIsTTY;
62+
export const version = process.version;
4563

46-
export function setEnv(var_) {
47-
return val => () => {
48-
process.env[var_] = val;
49-
};
50-
}
51-
52-
export function unsetEnv(var_) {
53-
return () => {
54-
delete process.env[var_];
55-
};
56-
}
57-
58-
export function exit(code) {
59-
return () => {
60-
process.exit(code);
61-
};
62-
}
63-
64-
export function copyArray(xs) {
65-
return () => xs.slice();
66-
}
67-
68-
export function copyObject(o) {
69-
return () => Object.assign({}, o);
70-
}

src/Node/Process.purs

Lines changed: 48 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,11 @@ import Data.Posix.Signal (Signal)
3535
import Data.Posix.Signal as Signal
3636
import Effect (Effect)
3737
import Effect.Exception (Error)
38+
import Effect.Uncurried (EffectFn1, EffectFn2, runEffectFn1, runEffectFn2)
3839
import Foreign.Object as FO
3940
import Node.Platform (Platform)
4041
import Node.Platform as Platform
4142
import Node.Stream (Readable, Writable)
42-
import Unsafe.Coerce (unsafeCoerce)
43-
44-
-- YOLO
45-
foreign import process :: forall props. { | props }
46-
47-
mkEffect :: forall a. (Unit -> a) -> Effect a
48-
mkEffect = unsafeCoerce
4943

5044
-- | Register a callback to be performed when the event loop empties, and
5145
-- | Node.js is about to exit. Asynchronous calls can be made in the callback,
@@ -86,102 +80,101 @@ onSignal sig = onSignalImpl (Signal.toString sig)
8680
-- | Register a callback to run as soon as the current event loop runs to
8781
-- | completion.
8882
nextTick :: Effect Unit -> Effect Unit
89-
nextTick callback = mkEffect \_ -> process.nextTick callback
83+
nextTick cb = runEffectFn1 nextTickImpl cb
84+
85+
foreign import nextTickImpl :: EffectFn1 (Effect Unit) (Unit)
9086

91-
-- | Get an array containing the command line arguments.
92-
argv :: Effect (Array String)
93-
argv = copyArray process.argv
87+
-- | Get a copy of the array containing the command line arguments.
88+
foreign import argv :: Effect (Array String)
9489

95-
-- | Node-specific options passed to the `node` executable.
96-
execArgv :: Effect (Array String)
97-
execArgv = copyArray process.execArgv
90+
-- | Get a copy of the Node-specific options passed to the `node` executable.
91+
foreign import execArgv :: Effect (Array String)
9892

9993
-- | The absolute pathname of the `node` executable that started the
10094
-- | process.
101-
execPath :: Effect String
102-
execPath = mkEffect \_ -> process.execPath
95+
foreign import execPath :: Effect (String)
10396

10497
-- | Change the current working directory of the process. If the current
10598
-- | directory could not be changed, an exception will be thrown.
106-
foreign import chdir :: String -> Effect Unit
99+
chdir :: String -> Effect Unit
100+
chdir dir = runEffectFn1 chdirImpl dir
101+
102+
foreign import chdirImpl :: EffectFn1 (String) (Unit)
107103

108104
-- | Get the current working directory of the process.
109-
cwd :: Effect String
110-
cwd = process.cwd
105+
foreign import cwd :: Effect (String)
111106

112107
-- | Get a copy of the current environment.
113-
getEnv :: Effect (FO.Object String)
114-
getEnv = copyObject process.env
108+
-- | If you only want to look up a value without paying
109+
-- | for the overhead of the copy, use `lookupEnv`.
110+
foreign import getEnv :: Effect (FO.Object String)
111+
112+
-- | Get the current environment object without copying it.
113+
-- | Any mutations to the returned object
114+
-- | or any mutations via `unsetEnv` and `setEnv`
115+
-- | will affect all values that were obtained
116+
-- | via this function.
117+
-- | Thus, this is an internal function that is
118+
-- | not exported.
119+
foreign import unsafeGetEnv :: Effect (FO.Object String)
115120

116121
-- | Lookup a particular environment variable.
117122
lookupEnv :: String -> Effect (Maybe String)
118-
lookupEnv k = lookupMutableObject k process.env
123+
lookupEnv k = map (FO.lookup k) $ unsafeGetEnv
119124

120125
-- | Set an environment variable.
121-
foreign import setEnv :: String -> String -> Effect Unit
126+
setEnv :: String -> String -> Effect Unit
127+
setEnv key value = runEffectFn2 setEnvImpl key value
128+
129+
foreign import setEnvImpl :: EffectFn2 (String) (String) (Unit)
122130

123131
-- | Delete an environment variable.
124132
-- | Use case: to hide secret environment variable from child processes.
125-
foreign import unsetEnv :: String -> Effect Unit
133+
unsetEnv :: String -> Effect Unit
134+
unsetEnv key = runEffectFn1 unsetEnvImpl key
135+
136+
foreign import unsetEnvImpl :: EffectFn1 (String) (Unit)
126137

127-
pid :: Pid
128-
pid = process.pid
138+
foreign import pid :: Pid
129139

130140
platform :: Maybe Platform
131141
platform = Platform.fromString platformStr
132142

133-
platformStr :: String
134-
platformStr = process.platform
143+
foreign import platformStr :: String
135144

136145
-- | Cause the process to exit with the supplied integer code. An exit code
137146
-- | of 0 is normally considered successful, and anything else is considered a
138147
-- | failure.
139-
foreign import exit :: forall a. Int -> Effect a
148+
exit :: forall a. Int -> Effect a
149+
exit code = runEffectFn1 exitImpl code
150+
151+
foreign import exitImpl :: forall a. EffectFn1 (Int) (a)
140152

141153
-- | The standard input stream. Note that this stream will never emit an `end`
142154
-- | event, so any handlers attached via `onEnd` will never be called.
143-
stdin :: Readable ()
144-
stdin = process.stdin
155+
foreign import stdin :: Readable ()
145156

146157
-- | The standard output stream. Note that this stream cannot be closed; calling
147158
-- | `end` will result in an exception being thrown.
148-
stdout :: Writable ()
149-
stdout = process.stdout
159+
foreign import stdout :: Writable ()
150160

151161
-- | The standard error stream. Note that this stream cannot be closed; calling
152162
-- | `end` will result in an exception being thrown.
153-
stderr :: Writable ()
154-
stderr = process.stderr
163+
foreign import stderr :: Writable ()
155164

156165
-- | Check whether the standard input stream appears to be attached to a TTY.
157166
-- | It is a good idea to check this before processing the input data from stdin.
158-
stdinIsTTY :: Boolean
159-
stdinIsTTY = process.stdin.isTTY
167+
foreign import stdinIsTTY :: Boolean
160168

161169
-- | Check whether the standard output stream appears to be attached to a TTY.
162170
-- | It is a good idea to check this before printing ANSI codes to stdout
163171
-- | (e.g. for coloured text in the terminal).
164-
stdoutIsTTY :: Boolean
165-
stdoutIsTTY = process.stdout.isTTY
172+
foreign import stdoutIsTTY :: Boolean
166173

167174
-- | Check whether the standard error stream appears to be attached to a TTY.
168175
-- | It is a good idea to check this before printing ANSI codes to stderr
169176
-- | (e.g. for coloured text in the terminal).
170-
stderrIsTTY :: Boolean
171-
stderrIsTTY = process.stderr.isTTY
177+
foreign import stderrIsTTY :: Boolean
172178

173179
-- | Get the Node.js version.
174-
version :: String
175-
version = process.version
176-
177-
-- Utils
178-
179-
foreign import data MutableArray :: Type -> Type
180-
foreign import data MutableObject :: Type -> Type
181-
182-
foreign import copyArray :: forall a. MutableArray a -> Effect (Array a)
183-
foreign import copyObject :: forall a. MutableObject a -> Effect (FO.Object a)
184-
185-
lookupMutableObject :: forall a. String -> MutableObject a -> Effect (Maybe a)
186-
lookupMutableObject k o =
187-
mkEffect \_ -> FO.lookup k (unsafeCoerce o)
180+
foreign import version :: String

0 commit comments

Comments
 (0)