Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@
],
"dependencies": {
"purescript-datetime": "^0.9.0",
"purescript-exceptions": "^0.3.0",
"purescript-foreign": "^0.7.0",
"purescript-node-buffer": "^0.2.0",
"purescript-node-path": "^0.4.0",
"purescript-unsafe-coerce": "^0.1.0",
"purescript-nullable": "~0.2.1"
"purescript-nullable": "~0.2.1",
"purescript-node-streams": "~0.3.0",
"purescript-exceptions": "~0.3.3"
},
"devDependencies": {
"purescript-console": "~0.1.1"
Expand Down
95 changes: 95 additions & 0 deletions docs/Node/FS/Stream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
## Module Node.FS.Stream

#### `createWriteStream`

``` purescript
createWriteStream :: forall eff. FilePath -> Eff (fs :: FS | eff) (Writable () (fs :: FS | eff))
```

Create a Writable stream which writes data to the specified file, using
the default options.

#### `fdCreateWriteStream`

``` purescript
fdCreateWriteStream :: forall eff. FileDescriptor -> Eff (fs :: FS | eff) (Writable () (fs :: FS | eff))
```

Create a Writable stream which writes data to the specified file
descriptor, using the default options.

#### `WriteStreamOptions`

``` purescript
type WriteStreamOptions = { flags :: FileFlags, perms :: Perms }
```

#### `defaultWriteStreamOptions`

``` purescript
defaultWriteStreamOptions :: WriteStreamOptions
```

#### `createWriteStreamWith`

``` purescript
createWriteStreamWith :: forall eff. WriteStreamOptions -> FilePath -> Eff (fs :: FS | eff) (Writable () (fs :: FS | eff))
```

Like `createWriteStream`, but allows you to pass options.

#### `fdCreateWriteStreamWith`

``` purescript
fdCreateWriteStreamWith :: forall eff. WriteStreamOptions -> FileDescriptor -> Eff (fs :: FS | eff) (Writable () (fs :: FS | eff))
```

Like `fdCreateWriteStream`, but allows you to pass options.

#### `createReadStream`

``` purescript
createReadStream :: forall eff. FilePath -> Eff (fs :: FS | eff) (Readable () (fs :: FS | eff))
```

Create a Readable stream which reads data to the specified file, using
the default options.

#### `fdCreateReadStream`

``` purescript
fdCreateReadStream :: forall eff. FileDescriptor -> Eff (fs :: FS | eff) (Readable () (fs :: FS | eff))
```

Create a Readable stream which reads data to the specified file
descriptor, using the default options.

#### `ReadStreamOptions`

``` purescript
type ReadStreamOptions = { flags :: FileFlags, perms :: Perms, autoClose :: Boolean }
```

#### `defaultReadStreamOptions`

``` purescript
defaultReadStreamOptions :: ReadStreamOptions
```

#### `createReadStreamWith`

``` purescript
createReadStreamWith :: forall eff. ReadStreamOptions -> FilePath -> Eff (fs :: FS | eff) (Readable () (fs :: FS | eff))
```

Create a Readable stream which reads data from the specified file.

#### `fdCreateReadStreamWith`

``` purescript
fdCreateReadStreamWith :: forall eff. ReadStreamOptions -> FileDescriptor -> Eff (fs :: FS | eff) (Readable () (fs :: FS | eff))
```

Create a Readable stream which reads data from the specified file descriptor.


2 changes: 0 additions & 2 deletions src/Node/FS/Async.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

// module Node.FS.Async

exports.fs = require('fs');

exports.handleCallbackImpl = function (left, right, f) {
return function (err, value) {
if (err) {
Expand Down
3 changes: 2 additions & 1 deletion src/Node/FS/Async.purs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ foreign import handleCallbackImpl ::
handleCallback :: forall eff a. (Callback eff a) -> JSCallback a
handleCallback cb = runFn3 handleCallbackImpl Left Right cb

foreign import fs ::
fs ::
{ rename :: Fn3 FilePath FilePath (JSCallback Unit) Unit
, truncate :: Fn3 FilePath Int (JSCallback Unit) Unit
, chown :: Fn4 FilePath Int Int (JSCallback Unit) Unit
Expand All @@ -85,6 +85,7 @@ foreign import fs ::
, write :: Fn6 FileDescriptor Buffer BufferOffset BufferLength (Nullable FilePosition) (JSCallback ByteCount) Unit
, close :: Fn2 FileDescriptor (JSCallback Unit) Unit
}
fs = unsafeRequireFS

-- | Type synonym for callback functions.
type Callback eff a = Either Error a -> Eff (fs :: FS | eff) Unit
Expand Down
4 changes: 4 additions & 0 deletions src/Node/FS/Internal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
"use strict";
// module Node.FS.Internal

exports.unsafeRequireFS = require("fs");
2 changes: 2 additions & 0 deletions src/Node/FS/Internal.purs
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ import Unsafe.Coerce

mkEff :: forall e a. (Unit -> a) -> Eff e a
mkEff = unsafeCoerce

foreign import unsafeRequireFS :: forall props. { | props }
144 changes: 144 additions & 0 deletions src/Node/FS/Stream.purs
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
module Node.FS.Stream
( createWriteStream
, fdCreateWriteStream
, WriteStreamOptions()
, defaultWriteStreamOptions
, createWriteStreamWith
, fdCreateWriteStreamWith
, createReadStream
, fdCreateReadStream
, ReadStreamOptions()
, defaultReadStreamOptions
, createReadStreamWith
, fdCreateReadStreamWith
) where

import Prelude
import Data.Maybe (Maybe(..))
import Data.Function
import Data.Nullable
import Control.Monad.Eff
import Node.Stream (Readable(), Writable())
import Node.Path (FilePath())

import Node.FS
import Node.FS.Perms (Perms())
import Node.FS.Perms as Perms
import Node.FS.Internal

fs ::
{ createReadStream :: forall eff opts. Fn2 (Nullable FilePath) { | opts } (Readable () (fs :: FS | eff))
, createWriteStream :: forall eff opts. Fn2 (Nullable FilePath) { | opts } (Writable () (fs :: FS | eff))
}
fs = unsafeRequireFS

readWrite :: Perms
readWrite = Perms.mkPerms rw rw rw
where
rw = Perms.read + Perms.write

null :: forall a. Nullable a
null = toNullable Nothing

nonnull :: forall a. a -> Nullable a
nonnull = toNullable <<< Just

-- | Create a Writable stream which writes data to the specified file, using
-- | the default options.
createWriteStream :: forall eff.
FilePath
-> Eff (fs :: FS | eff) (Writable () (fs :: FS | eff))
createWriteStream = createWriteStreamWith defaultWriteStreamOptions

-- | Create a Writable stream which writes data to the specified file
-- | descriptor, using the default options.
fdCreateWriteStream :: forall eff.
FileDescriptor
-> Eff (fs :: FS | eff) (Writable () (fs :: FS | eff))
fdCreateWriteStream = fdCreateWriteStreamWith defaultWriteStreamOptions

type WriteStreamOptions =
{ flags :: FileFlags
, perms :: Perms
}

defaultWriteStreamOptions :: WriteStreamOptions
defaultWriteStreamOptions =
{ flags: W
, perms: readWrite
}

-- | Like `createWriteStream`, but allows you to pass options.
createWriteStreamWith :: forall eff.
WriteStreamOptions
-> FilePath
-> Eff (fs :: FS | eff) (Writable () (fs :: FS | eff))
createWriteStreamWith opts file = mkEff $ \_ -> runFn2
fs.createWriteStream (nonnull file)
{ mode: Perms.permsToInt opts.perms
, flags: fileFlagsToNode opts.flags
}

-- | Like `fdCreateWriteStream`, but allows you to pass options.
fdCreateWriteStreamWith :: forall eff.
WriteStreamOptions
-> FileDescriptor
-> Eff (fs :: FS | eff) (Writable () (fs :: FS | eff))
fdCreateWriteStreamWith opts fd = mkEff $ \_ -> runFn2
fs.createWriteStream null
{ fd
, mode: Perms.permsToInt opts.perms
, flags: fileFlagsToNode opts.flags
}

-- | Create a Readable stream which reads data to the specified file, using
-- | the default options.
createReadStream :: forall eff.
FilePath
-> Eff (fs :: FS | eff) (Readable () (fs :: FS | eff))
createReadStream = createReadStreamWith defaultReadStreamOptions

-- | Create a Readable stream which reads data to the specified file
-- | descriptor, using the default options.
fdCreateReadStream :: forall eff.
FileDescriptor
-> Eff (fs :: FS | eff) (Readable () (fs :: FS | eff))
fdCreateReadStream = fdCreateReadStreamWith defaultReadStreamOptions

type ReadStreamOptions =
{ flags :: FileFlags
, perms :: Perms
, autoClose :: Boolean
}

defaultReadStreamOptions :: ReadStreamOptions
defaultReadStreamOptions =
{ flags: R
, perms: readWrite
, autoClose: true
}

-- | Create a Readable stream which reads data from the specified file.
createReadStreamWith :: forall eff.
ReadStreamOptions
-> FilePath
-> Eff (fs :: FS | eff) (Readable () (fs :: FS | eff))
createReadStreamWith opts file = mkEff $ \_ -> runFn2
fs.createReadStream (nonnull file)
{ mode: Perms.permsToInt opts.perms
, flags: fileFlagsToNode opts.flags
, autoClose: opts.autoClose
}

-- | Create a Readable stream which reads data from the specified file descriptor.
fdCreateReadStreamWith :: forall eff.
ReadStreamOptions
-> FileDescriptor
-> Eff (fs :: FS | eff) (Readable () (fs :: FS | eff))
fdCreateReadStreamWith opts fd = mkEff $ \_ -> runFn2
fs.createReadStream null
{ fd
, mode: Perms.permsToInt opts.perms
, flags: fileFlagsToNode opts.flags
, autoClose: opts.autoClose
}
17 changes: 0 additions & 17 deletions src/Node/FS/Sync.js

This file was deleted.

4 changes: 3 additions & 1 deletion src/Node/FS/Sync.purs
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,14 @@ import Data.Int (round)
import Data.Maybe (Maybe(..))
import Node.Buffer (Buffer(), BUFFER(), size)
import Node.Encoding

import Node.FS
import Node.FS.Stats
import Node.Path (FilePath())
import Node.FS.Perms
import Node.FS.Internal

foreign import fs ::
fs ::
{ renameSync :: Fn2 FilePath FilePath Unit
, truncateSync :: Fn2 FilePath Int Unit
, chownSync :: Fn3 FilePath Int Int Unit
Expand All @@ -73,6 +74,7 @@ foreign import fs ::
, fsyncSync :: Fn1 FileDescriptor Unit
, closeSync :: Fn1 FileDescriptor Unit
}
fs = unsafeRequireFS

-- | Renames a file.
rename :: forall eff. FilePath
Expand Down
2 changes: 2 additions & 0 deletions test/Main.purs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ module Test.Main where
import Prelude
import qualified Test as Test
import qualified TestAsync as TestAsync
import Test.Streams as Streams

main = do
Test.main
TestAsync.main
Streams.main
38 changes: 38 additions & 0 deletions test/Streams.purs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
module Test.Streams where

import Prelude
import Data.Maybe
import Data.Either
import Control.Apply ((*>))
import Control.Bind ((=<<))
import Control.Monad.Eff
import Control.Monad.Eff.Exception
import Control.Monad.Eff.Console (log)
import Node.Encoding
import Node.Buffer as Buffer
import Node.Path as Path
import Node.Stream as Stream
import Unsafe.Coerce

import Node.FS
import Node.FS.Stats
import Node.FS.Stream
import Node.FS.Sync as Sync

main = do
let fp = Path.concat

log "Testing streams"

r <- createReadStream (fp ["test", "Streams.purs"])
w <- createWriteStream (fp ["tmp", "Streams.purs"])

Stream.pipe r w

Stream.onEnd r do
src <- Sync.readTextFile UTF8 (fp ["test", "Streams.purs"])
dst <- Sync.readTextFile UTF8 (fp ["tmp", "Streams.purs"])

if src == dst
then log "all good"
else log "not good"