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: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@

- Requires `innmind/filesystem:~8.0`
- Requires `innmind/time-continuum:~4.1`
- `Innmind\Encoding\Tar\Encode::_invoke()` now only returns a file content

### Removed

- Ability to Gzip (de)compress a `File` or a `Sequence` of chunks

## 1.1.0 - 2024-06-26

Expand Down
5 changes: 3 additions & 2 deletions documentation/use_cases/compressed_at_rest.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ $response = $serverRequest
->files()
->under('tsv')
->get('users')
->map(static fn($file) => $file->rename(Name::of('users.tsv'))
->map(static fn($file) => $file->content()
->map(Gzip::compress())
->map(static fn($content) => File::named('users.tsv.gz', $content))
->map(
static fn($file) => $os
->filesystem()
Expand All @@ -47,7 +48,7 @@ $response = $serverRequest
(new ResponseSender($os->clock()))($response);
```

This code will take any file uploaded in the key `tsv[users]`, gzip it and write it in the `path/to/stored/data/` directory under the name `users.tsv.gz` (`Gzip::compress()` automatically add the suffix `.gz`) and return a `201` HTTP response. If the upload failed it will return a `400` response.
This code will take any file uploaded in the key `tsv[users]`, gzip it and write it in the `path/to/stored/data/` directory under the name `users.tsv.gz` and return a `201` HTTP response. If the upload failed it will return a `400` response.

And for the code streaming this file:

Expand Down
5 changes: 3 additions & 2 deletions documentation/use_cases/http.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,17 @@ $os
->filesystem()
->mount(Path::of('path/to/stored/data/'))
->get(Name::of('somefile.txt'))
->map(static fn($file) => $file->content());
->map(Gzip::compress())
->match(
static fn($file) => $http(Request::of(
static fn($content) => $http(Request::of(
Url::of('https://some-app.tld/upload'),
Method::post,
ProtocolVersion::v11,
Headers::of(
ContentEncoding::of('gzip'),
),
$file->content(),
$content,
)),
static fn() => null,
);
Expand Down
66 changes: 7 additions & 59 deletions proofs/gzip.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@
declare(strict_types = 1);

use Innmind\Encoding\Gzip;
use Innmind\Filesystem\{
Adapter\Filesystem,
File\Content,
Name,
};
use Innmind\Url\Path;
use Innmind\Filesystem\File\Content;
use Innmind\Immutable\{
Monoid\Concat,
Str\Encoding,
Expand Down Expand Up @@ -42,20 +37,22 @@ static function($assert, $file) {
'Gzip compression reduce chunks size',
given($files->map(\file_get_contents(...))),
static function($assert, $file) {
$content = Content::ofString($file)->chunks();
$content = Content::ofString($file);
$compress = Gzip::compress();

$compressed = $compress($content);

$assert
->number(
$content
->chunks()
->fold(new Concat)
->toEncoding(Encoding::ascii)
->length(),
)
->greaterThan(
$compressed
->chunks()
->fold(new Concat)
->toEncoding(Encoding::ascii)
->length(),
Expand Down Expand Up @@ -94,15 +91,15 @@ static function($assert, $file) {
->between(0, 2048),
)),
static function($assert, $file) {
$original = Content::ofString($file)->chunks();
$original = Content::ofString($file);
$compress = Gzip::compress();
$decompress = Gzip::decompress();

$content = $decompress($compress($original));

$assert->same(
$original->fold(new Concat)->toString(),
$content->fold(new Concat)->toString(),
$original->chunks()->fold(new Concat)->toString(),
$content->chunks()->fold(new Concat)->toString(),
);
},
);
Expand All @@ -123,53 +120,4 @@ static function($assert, $file) {
);
},
);

yield proof(
'Gzip file compression',
given(
$files
->map(static fn($name) => \substr($name, 9)) // removes 'fixtures/'
->map(Name::of(...)),
),
static function($assert, $name) {
$adapter = Filesystem::mount(Path::of('fixtures/'));
$original = $adapter->get($name)->match(
static fn($file) => $file,
static fn() => null,
);

$assert->not()->null($original);

$compress = Gzip::compress();
$decompress = Gzip::decompress();

$compressed = $compress($original);

$assert
->string($compressed->name()->toString())
->startsWith($name->toString())
->endsWith('.gz');
$assert->same(
'application/gzip',
$compressed->mediaType()->toString(),
);
$assert
->number($compressed->content()->size()->match(
static fn($size) => $size->toInt(),
static fn() => null,
))
->lessThan($original->content()->size()->match(
static fn($size) => $size->toInt(),
static fn() => null,
));

$decompressed = $decompress($compressed);

$assert->same($name->toString(), $decompressed->name()->toString());
$assert->same(
$original->content()->toString(),
$decompressed->content()->toString(),
);
},
);
};
22 changes: 8 additions & 14 deletions proofs/tar.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,12 @@ static function($assert, $name) {
static fn($file) => $file,
static fn() => null,
);

$assert
->string($tar->name()->toString())
->startsWith('other-')
->contains($name)
->endsWith('.tar');
$assert->same('application/x-tar', $tar->mediaType()->toString());
$tar = File::named('test.tar', $tar);

$tmp->add($tar);

$exitCode = null;
\exec("tar -xf $path/other-$name.tar --directory=$path", result_code: $exitCode);
\exec("tar -xf $path/test.tar --directory=$path", result_code: $exitCode);
$assert->same(0, $exitCode);

$assert->same(
Expand Down Expand Up @@ -83,8 +77,7 @@ static function($assert) {
static fn() => null,
);

$assert->same('fixtures.tar', $tar->name()->toString());
$assert->same('application/x-tar', $tar->mediaType()->toString());
$tar = File::named('fixtures.tar', $tar);

$tmp->add($tar);

Expand Down Expand Up @@ -161,10 +154,12 @@ static function($assert, $name1, $name2) {
static fn() => null,
);

$tar = File::named('names.tar', $tar);

$tmp->add($tar);

$exitCode = null;
\exec("tar -xf $path/{$name1->toString()}.tar --directory=$path", result_code: $exitCode);
\exec("tar -xf $path/names.tar --directory=$path", result_code: $exitCode);
$assert->same(0, $exitCode);

$assert->true(
Expand Down Expand Up @@ -232,12 +227,11 @@ static function($assert, $file) {
$tmp->remove($file->name());

$tar = Tar::encode($clock)($file);
$tar = File::named('shape.tar', $tar);
$tmp->add($tar);

$exitCode = null;
$name = $path.$tar->name()->toString();
$name = \str_replace("'", "'\\''", $name);
\exec("tar -xf '$name' --directory=$path", result_code: $exitCode);
\exec("tar -xf '$path/shape.tar' --directory=$path", result_code: $exitCode);
$assert->same(0, $exitCode);

if ($file instanceof File) {
Expand Down
39 changes: 3 additions & 36 deletions src/Gzip/Compress.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@
Context,
Chunk,
};
use Innmind\Filesystem\{
File,
File\Content,
};
use Innmind\MediaType\MediaType;
use Innmind\Filesystem\File\Content;
use Innmind\Immutable\{
Sequence,
Str,
Expand All @@ -26,24 +22,9 @@ private function __construct()
{
}

/**
* @template T of File|Content|Sequence<Str>
*
* @param T $content
*
* @return T
*/
public function __invoke(File|Content|Sequence $content): File|Content|Sequence
public function __invoke(Content $content): Content
{
/**
* @psalm-suppress PossiblyInvalidArgument For some reason it doesn't understand the Sequence check
* @var T
*/
return match (true) {
$content instanceof File => $this->compressFile($content),
$content instanceof Content => $this->compressContent($content),
$content instanceof Sequence => $this->compressChunks($content),
};
return Content::ofChunks($this->compressChunks($content->chunks()));
}

/**
Expand All @@ -54,20 +35,6 @@ public static function max(): self
return new self;
}

private function compressFile(File $file): File
{
return File::named(
$file->name()->toString().'.gz',
$this->compressContent($file->content()),
MediaType::of('application/gzip'),
);
}

private function compressContent(Content $content): Content
{
return Content::ofChunks($this->compressChunks($content->chunks()));
}

/**
* @param Sequence<Str> $chunks
*
Expand Down
43 changes: 3 additions & 40 deletions src/Gzip/Decompress.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@
Context,
Chunk,
};
use Innmind\Filesystem\{
File,
File\Content,
};
use Innmind\Filesystem\File\Content;
use Innmind\Immutable\{
Sequence,
Str,
Expand All @@ -25,24 +22,9 @@ private function __construct()
{
}

/**
* @template T of File|Content|Sequence<Str>
*
* @param T $content
*
* @return T
*/
public function __invoke(File|Content|Sequence $content): File|Content|Sequence
public function __invoke(Content $content): Content
{
/**
* @psalm-suppress PossiblyInvalidArgument For some reason it doesn't understand the Sequence check
* @var T
*/
return match (true) {
$content instanceof File => $this->decompressFile($content),
$content instanceof Content => $this->decompressContent($content),
$content instanceof Sequence => $this->decompressChunks($content),
};
return Content::ofChunks($this->decompressChunks($content->chunks()));
}

/**
Expand All @@ -53,25 +35,6 @@ public static function max(): self
return new self;
}

private function decompressFile(File $file): File
{
$name = $file->name()->str();

/** @psalm-suppress ArgumentTypeCoercion */
return File::named(
match ($name->endsWith('.gz') && $name->length() !== 3) {
true => $name->dropEnd(3)->toString(),
false => $name->toString(),
},
$this->decompressContent($file->content()),
);
}

private function decompressContent(Content $content): Content
{
return Content::ofChunks($this->decompressChunks($content->chunks()));
}

/**
* @param Sequence<Str> $chunks
*
Expand Down
27 changes: 11 additions & 16 deletions src/Tar/Encode.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
File\Content,
Directory,
};
use Innmind\MediaType\MediaType;
use Innmind\TimeContinuum\{
Clock,
Format,
Expand All @@ -33,22 +32,18 @@ private function __construct(Clock $clock)
$this->clock = $clock;
}

public function __invoke(File|Directory $file): File
public function __invoke(File|Directory $file): Content
{
return File::named(
$file->name()->toString().'.tar',
Content::ofChunks(
$this
->encode(
$file->name()->str()->toEncoding(Str\Encoding::ascii),
$file,
)
->add(Str::of(
\pack('a1024', ''),
Str\Encoding::ascii,
)),
),
MediaType::of('application/x-tar'),
return Content::ofChunks(
$this
->encode(
$file->name()->str()->toEncoding(Str\Encoding::ascii),
$file,
)
->add(Str::of(
\pack('a1024', ''),
Str\Encoding::ascii,
)),
);
}

Expand Down