Skip to content

Commit

Permalink
Implement new methods to manipulate buffers
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastienfilion committed Dec 4, 2020
1 parent e4fcb0d commit 766716d
Show file tree
Hide file tree
Showing 24 changed files with 366 additions and 157 deletions.
160 changes: 80 additions & 80 deletions README.md

Large diffs are not rendered by default.

13 changes: 8 additions & 5 deletions library/Buffer.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { factorizeType } from "https://deno.land/x/[email protected]/library/factories.js";
import { $$type } from "https://deno.land/x/[email protected]/library/Symbols.js";
import Task from "https://deno.land/x/[email protected]/library/Task.js";

export const Buffer = factorizeType("Buffer", [ "raw" ]);
import { curry } from "https://x.nest.land/[email protected]/source/index.js";
import { factorizeType } from "https://deno.land/x/[email protected]/library/factories.js";
import { $$type } from "https://deno.land/x/[email protected]/library/Symbols.js";
import Task from "https://deno.land/x/[email protected]/library/Task.js";

/**
* The `Buffer` is the most basic type; it only has one attribute which is a typed array named "raw".
Expand All @@ -22,6 +21,8 @@ export const Buffer = factorizeType("Buffer", [ "raw" ]);
* ```
*/

export const Buffer = factorizeType("Buffer", [ "raw" ]);

Buffer.prototype.ap = Buffer.prototype["fantasy-land/ap"] = function (container) {

return Buffer.of(container.raw(this.raw));
Expand Down Expand Up @@ -92,4 +93,6 @@ Buffer.prototype.map = Buffer.prototype["fantasy-land/map"] = function (unaryFun

Buffer.of = Buffer.prototype.of = Buffer.prototype["fantasy-land/of"] = buffer => Buffer(buffer);

export const factorizeBuffer = curry(Buffer);

export default Buffer;
2 changes: 1 addition & 1 deletion library/Buffer_test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { assert, assertEquals } from "https://deno.land/std@0.70.0/testing/asserts.ts";
import { assert, assertEquals } from "https://deno.land/std@0.79.0/testing/asserts.ts";

import Buffer from "./Buffer.js";

Expand Down
6 changes: 3 additions & 3 deletions library/Directory.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { factorizeType } from "https://deno.land/x/functional@v1.0.0/library/factories.js";
import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js";
import { factorizeType } from "https://deno.land/x/functional@v1.2.1/library/factories.js";
import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js";

import { $$type } from "https://deno.land/x/functional@v1.0.0/library/Symbols.js";
import { $$type } from "https://deno.land/x/functional@v1.2.1/library/Symbols.js";

/**
* The `Directory` type represents a directory on the file system. It is the only type with the same shape as `URL`.
Expand Down
2 changes: 1 addition & 1 deletion library/Directory_test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { assert, assertEquals } from "https://deno.land/std@0.70.0/testing/asserts.ts";
import { assert, assertEquals } from "https://deno.land/std@0.79.0/testing/asserts.ts";

import Directory from "./Directory.js";

Expand Down
6 changes: 3 additions & 3 deletions library/File.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { factorizeType } from "https://deno.land/x/functional@v1.0.0/library/factories.js";
import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js";
import { factorizeType } from "https://deno.land/x/functional@v1.2.1/library/factories.js";
import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js";

import { $$type } from "https://deno.land/x/functional@v1.0.0/library/Symbols.js";
import { $$type } from "https://deno.land/x/functional@v1.2.1/library/Symbols.js";

/**
* The `File` type extends the `Resource` type. It represents a file with a path.
Expand Down
4 changes: 2 additions & 2 deletions library/FileSystemCollection.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { factorizeType } from "https://deno.land/x/functional@v1.0.0/library/factories.js";
import { factorizeType } from "https://deno.land/x/functional@v1.2.1/library/factories.js";

import { $$value } from "https://deno.land/x/functional@v1.0.0/library/Symbols.js";
import { $$value } from "https://deno.land/x/functional@v1.2.1/library/Symbols.js";

/**
* The `FileSystemCollection` is represents a collection of `Location`, namely of `Directory` and `File`. This of it
Expand Down
2 changes: 1 addition & 1 deletion library/FileSystemCollection_test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { assertEquals } from "https://deno.land/std@0.70.0/testing/asserts.ts";
import { assertEquals } from "https://deno.land/std@0.79.0/testing/asserts.ts";

import FileSystemCollection from "./FileSystemCollection.js";
import File from "./File.js";
Expand Down
2 changes: 1 addition & 1 deletion library/File_test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { assert, assertEquals } from "https://deno.land/std@0.70.0/testing/asserts.ts";
import { assert, assertEquals } from "https://deno.land/std@0.79.0/testing/asserts.ts";

import File from "./File.js";

Expand Down
2 changes: 1 addition & 1 deletion library/Request.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { curry } from "https://x.nest.land/[email protected]/source/index.js";

import { factorizeType } from "https://deno.land/x/functional@v1.0.0/library/factories.js";
import { factorizeType } from "https://deno.land/x/functional@v1.2.1/library/factories.js";

/**
* The `Request` represent a HTTP request.
Expand Down
2 changes: 1 addition & 1 deletion library/Request_test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { assert, assertEquals } from "https://deno.land/std@0.65.0/testing/asserts.ts";
import { assert, assertEquals } from "https://deno.land/std@0.79.0/testing/asserts.ts";

import Request from "./Request.js";

Expand Down
9 changes: 6 additions & 3 deletions library/Resource.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { factorizeType } from "https://deno.land/x/[email protected]/library/factories.js";
import Task from "https://deno.land/x/[email protected]/library/Task.js";
import { curry } from "https://x.nest.land/[email protected]/source/index.js";
import { factorizeType } from "https://deno.land/x/[email protected]/library/factories.js";
import Task from "https://deno.land/x/[email protected]/library/Task.js";

import { $$type } from "https://deno.land/x/functional@v1.0.0/library/Symbols.js";
import { $$type } from "https://deno.land/x/functional@v1.2.1/library/Symbols.js";

/**
* The `Resource` type extends the `Buffer` type. It represents a system resource with a handle, eg: STDOUT, STDIN or a
Expand Down Expand Up @@ -103,4 +104,6 @@ Resource.prototype.map = Resource.prototype["fantasy-land/map"] = function (unar

Resource.of = Resource.prototype.of = Resource.prototype["fantasy-land/of"] = raw => Resource(raw, 0);

export const factorizeResource = curry(Resource);

export default Resource;
2 changes: 1 addition & 1 deletion library/Resource_test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { assert, assertEquals } from "https://deno.land/std@0.70.0/testing/asserts.ts";
import { assert, assertEquals } from "https://deno.land/std@0.79.0/testing/asserts.ts";

import Resource from "./Resource.js";

Expand Down
2 changes: 1 addition & 1 deletion library/Response.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { curry } from "https://x.nest.land/[email protected]/source/index.js";

import { factorizeSumType } from "https://deno.land/x/functional@v1.0.0/library/factories.js";
import { factorizeSumType } from "https://deno.land/x/functional@v1.2.1/library/factories.js";

/**
* The `Response` represent a HTTP response.
Expand Down
2 changes: 1 addition & 1 deletion library/Response_test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { assert, assertEquals } from "https://deno.land/std@0.65.0/testing/asserts.ts";
import { assert, assertEquals } from "https://deno.land/std@0.79.0/testing/asserts.ts";

import Response from "./Response.js";

Expand Down
6 changes: 3 additions & 3 deletions library/URL.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { factorizeType } from "https://deno.land/x/functional@v1.0.0/library/factories.js";
import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js";
import { factorizeType } from "https://deno.land/x/functional@v1.2.1/library/factories.js";
import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js";

import { $$type } from "https://deno.land/x/functional@v1.0.0/library/Symbols.js";
import { $$type } from "https://deno.land/x/functional@v1.2.1/library/Symbols.js";

/**
* The `URL` type represents an URL; either of a location on the file system or on a remote server.
Expand Down
2 changes: 1 addition & 1 deletion library/browser_safe.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { apply, lift } from "https://x.nest.land/[email protected]/source/index.js";

import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js";
import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js";

import Request from "./Request.js";
import Response from "./Response.js";
Expand Down
8 changes: 4 additions & 4 deletions library/browser_safe_test.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { assert } from "https://deno.land/std@0.70.0/testing/asserts.ts";
import { serve } from "https://deno.land/std@0.74.0/http/server.ts";
import { assert } from "https://deno.land/std@0.79.0/testing/asserts.ts";
import { serve } from "https://deno.land/std@0.79.0/http/server.ts";
import { fetch } from "./browser_safe.js";

import Either from "https://deno.land/x/functional@v1.0.0/library/Either.js";
import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js";
import Either from "https://deno.land/x/functional@v1.2.1/library/Either.js";
import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js";
import Request from "./Request.js";

const startAsyncIterator = async (state, server, callback) => {
Expand Down
83 changes: 56 additions & 27 deletions library/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ import {
ensureSymlink as _ensureSymlink,
exists as _exists,
move as _move
} from "https://deno.land/std@0.70.0/fs/mod.ts";
import { curry } from "https://x.nest.land/[email protected]/source/index.js";
import Either from "https://deno.land/x/functional@v1.0.0/library/Either.js"
import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"
} from "https://deno.land/std@0.79.0/fs/mod.ts";
import { compose, curry } from "https://x.nest.land/[email protected]/source/index.js";
import Either from "https://deno.land/x/functional@v1.2.1/library/Either.js"
import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"
import Buffer from "./Buffer.js";
import Directory from "./Directory.js";
import File from "./File.js";
import Resource from "./Resource.js";
import { coerceAsReader, coerceAsWriter } from "./utilities.js";
import { coerceAsReader, coerceAsWriter, factorizeUint8Array } from "./utilities.js";

// chdir :: Directory a -> Task e Directory a
export const chdir = directory => Directory.isOrThrow(directory)
Expand All @@ -32,10 +32,10 @@ export const chown = curry(
.map(_ => File(file.path, file.raw, file.rid))
);

// close :: File a -> Task e File a
export const close = file => File.isOrThrow(file)
&& Task.wrap(_ => Deno.close(file.rid) || Promise.resolve(undefined))
.map(_ => File(file.path, file.raw, file.rid));
// close :: Resource a -> Task e Resource a
export const close = resource => Resource.isOrThrow(resource)
&& Task.wrap(_ => Deno.close(resource.rid) || Promise.resolve(undefined))
.map(_ => resource.constructor.from({ ...resource }));

// copy :: Options -> Buffer a -> Buffer b -> Task e Buffer a
export const copy = curry(
Expand Down Expand Up @@ -75,18 +75,18 @@ export const ensureSymlink = directory => Directory.isOrThrow(directory)
&& Task.wrap(_ => _ensureSymlink(directory.path))
.map(_ => Directory(directory.path));

// exists :: Location a -> Task null Location a
export const exists = location => {
if (!Directory.is(location) && !File.is(location)) {
throw new Error(`Expected a Directory or a File but got a "${typeof location}"`);
// exists :: URL a -> Task null URL a
export const exists = url => {
if (!Directory.is(url) && !File.is(url)) {
throw new Error(`Expected a Directory or a File but got a "${typeof url}"`);
}

return Task.wrap(_ => _exists(location.path))
return Task.wrap(_ => _exists(url.path))
.map(
fileExists => {
if (!fileExists) return Either.Left(null);

return location.constructor.from({ ...location });
return url.constructor.from({ ...url });
}
)
};
Expand All @@ -98,11 +98,11 @@ export const mkdir = curry(
.map(_ => Directory(directory.path))
);

// move :: Options -> String -> Location a -> Task e Location b
// move :: Options -> String -> URL a -> Task e URL b
export const move = curry(
(options, destinationPath, location) => location.hasOwnProperty("path")
&& Task.wrap(_ => _move(location.path, destinationPath))
.map(_ => location.constructor.from({ ...location, path: destinationPath }))
(options, destinationPath, url) => url.hasOwnProperty("path")
&& Task.wrap(_ => _move(url.path, destinationPath))
.map(_ => url.constructor.from({ ...url, path: destinationPath }))
);

// open :: Options -> File a -> Task e File a
Expand All @@ -121,6 +121,34 @@ export const read = resource => {
.map(_ => resource.constructor.from({ ...resource, raw: _buffer }))
};

// readLine :: Resource a -> Task e Resource a
export const readLine = resource => Task.wrap(async _ => {
let _accumulatorBuffer = new Uint8Array(1024);
let index = 0;
let _buffer = new Uint8Array(1);
let reachedCL = false;

while (await Deno.read(resource.rid, _buffer)) {
_accumulatorBuffer[index++] = _buffer[0];
if (reachedCL && _buffer[0] === 10) break;
reachedCL = _buffer[0] === 13;
_buffer = new Uint8Array(1);
}

return resource.constructor.from({ ...resource, raw: _accumulatorBuffer.slice(0, index) });
});

// readNBytes :: Number -> Resource a -> Task e Resource a
export const readNBytes = curry(
compose(
read,
(n, resource) => resource.constructor.from({ ...resource, raw: factorizeUint8Array(n) })
)
);

// readOneByte :: Resource a -> Task e Resource a
export const readOneByte = readNBytes(1);

// readAll :: Resource a -> Task e Resource a
export const readAll = resource => Resource.isOrThrow(resource)
&& Task.wrap(_ => Deno.readAll(coerceAsReader(resource)))
Expand All @@ -131,18 +159,18 @@ export const readFile = file => File.isOrThrow(file)
&& Task.wrap(_ => Deno.readFile(file.path))
.map(_buffer => File(file.path, _buffer, file.rid));

// remove :: Options -> Location a -> Task e Location a
// remove :: Options -> URL a -> Task e URL a
export const remove = curry(
(options, location) => location.hasOwnProperty("path")
&& Task.wrap(_ => Deno.remove(location.path, options))
.map(_ => location.constructor.from({ ...location }))
(options, url) => url.hasOwnProperty("path")
&& Task.wrap(_ => Deno.remove(url.path, options))
.map(_ => url.constructor.from({ ...url }))
);

// rename :: String -> Location a -> Task e Location b
// rename :: String -> URL a -> Task e URL b
export const rename = curry(
(destinationPath, location) => location.hasOwnProperty("path")
&& Task.wrap(_ => Deno.rename(location.path, destinationPath))
.map(_ => location.constructor.from({ ...location, path: destinationPath }))
(destinationPath, url) => url.hasOwnProperty("path")
&& Task.wrap(_ => Deno.rename(url.path, destinationPath))
.map(_ => url.constructor.from({ ...url, path: destinationPath }))
);

// write :: Resource a -> Task e Resource a
Expand All @@ -164,3 +192,4 @@ export const writeFile = curry(
&& Task.wrap(_ => Deno.writeFile(file.path, file.raw, options))
.map(_ => file.constructor.from({ ...file }))
);

37 changes: 32 additions & 5 deletions library/fs_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import {
replace,
trim
} from "https://x.nest.land/[email protected]/source/index.js";
import { assert, assertEquals } from "https://deno.land/std@0.70.0/testing/asserts.ts";
import { assert, assertEquals } from "https://deno.land/std@0.79.0/testing/asserts.ts";
import {
emptyDir as _emptyDir,
ensureDir as _ensureDir
} from "https://deno.land/std@0.70.0/fs/mod.ts";
import Either from "https://deno.land/x/functional@v1.0.0/library/Either.js"
import Task from "https://deno.land/x/functional@v1.0.0/library/Task.js"
} from "https://deno.land/std@0.79.0/fs/mod.ts";
import Either from "https://deno.land/x/functional@v1.2.1/library/Either.js"
import Task from "https://deno.land/x/functional@v1.2.1/library/Task.js"
import {
chdir,
chmod,
Expand All @@ -37,6 +37,7 @@ import {
read,
readAll,
readFile,
readNBytes,
remove,
rename,
write,
Expand All @@ -47,7 +48,7 @@ import Buffer from "./Buffer.js";
import Directory from "./Directory.js";
import File from "./File.js";

import { $$value } from "https://deno.land/x/functional@v1.0.0/library/Symbols.js";
import { $$value } from "https://deno.land/x/functional@v1.2.1/library/Symbols.js";

Deno.test(
"Integration: chdir",
Expand Down Expand Up @@ -515,6 +516,32 @@ Deno.test(
}
);

Deno.test(
"Integration: readNBytes",
async () => {
await _ensureDir(`${Deno.cwd()}/dump`);
await Deno.writeTextFile(`${Deno.cwd()}/dump/hoge`, "ABCDE");
const _file = await Deno.open(`${Deno.cwd()}/dump/hoge`, { read: true, write: true });

const containerA = readNBytes(5, File(`${Deno.cwd()}/dump/hoge`, new Uint8Array([]), _file.rid));
const promise = containerA.run();

assert(Task.is(containerA));
assert(promise instanceof Promise);

const containerB = await promise;

assert(Either.Right.is(containerB));
assertEquals(
containerB.toString(),
`Either.Right(File("${Deno.cwd()}/dump/hoge", 65,66,67,68,69, ${_file.rid}))`
);

await Deno.remove(`${Deno.cwd()}/dump/hoge`);
Deno.close(_file.rid);
}
);

Deno.test(
"Integration: readFile",
async () => {
Expand Down
2 changes: 1 addition & 1 deletion library/network.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Connection } from "./Resource.js";
import Task from "https://deno.land/x/functional@v1.0.0/library/Task";
import Task from "https://deno.land/x/functional@v1.2.1/library/Task";

// connect :: Connection a -> Task e Connection a
export const connect = connection => Connection.isOrThrow(connection)
Expand Down
Loading

0 comments on commit 766716d

Please sign in to comment.