diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d24097..63625f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/documentation/use_cases/compressed_at_rest.md b/documentation/use_cases/compressed_at_rest.md index 39a49c0..7437d7f 100644 --- a/documentation/use_cases/compressed_at_rest.md +++ b/documentation/use_cases/compressed_at_rest.md @@ -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() @@ -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: diff --git a/documentation/use_cases/http.md b/documentation/use_cases/http.md index 64086e7..20822a5 100644 --- a/documentation/use_cases/http.md +++ b/documentation/use_cases/http.md @@ -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, ); diff --git a/proofs/gzip.php b/proofs/gzip.php index f4d6076..c4b9531 100644 --- a/proofs/gzip.php +++ b/proofs/gzip.php @@ -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, @@ -42,7 +37,7 @@ 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); @@ -50,12 +45,14 @@ static function($assert, $file) { $assert ->number( $content + ->chunks() ->fold(new Concat) ->toEncoding(Encoding::ascii) ->length(), ) ->greaterThan( $compressed + ->chunks() ->fold(new Concat) ->toEncoding(Encoding::ascii) ->length(), @@ -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(), ); }, ); @@ -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(), - ); - }, - ); }; diff --git a/proofs/tar.php b/proofs/tar.php index b9be047..00ecf9c 100644 --- a/proofs/tar.php +++ b/proofs/tar.php @@ -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( @@ -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); @@ -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( @@ -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) { diff --git a/src/Gzip/Compress.php b/src/Gzip/Compress.php index 279585d..1b902b6 100644 --- a/src/Gzip/Compress.php +++ b/src/Gzip/Compress.php @@ -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, @@ -26,24 +22,9 @@ private function __construct() { } - /** - * @template T of File|Content|Sequence - * - * @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())); } /** @@ -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 $chunks * diff --git a/src/Gzip/Decompress.php b/src/Gzip/Decompress.php index 0eeebd5..c299bcd 100644 --- a/src/Gzip/Decompress.php +++ b/src/Gzip/Decompress.php @@ -7,10 +7,7 @@ Context, Chunk, }; -use Innmind\Filesystem\{ - File, - File\Content, -}; +use Innmind\Filesystem\File\Content; use Innmind\Immutable\{ Sequence, Str, @@ -25,24 +22,9 @@ private function __construct() { } - /** - * @template T of File|Content|Sequence - * - * @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())); } /** @@ -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 $chunks * diff --git a/src/Tar/Encode.php b/src/Tar/Encode.php index d19c118..81fc496 100644 --- a/src/Tar/Encode.php +++ b/src/Tar/Encode.php @@ -8,7 +8,6 @@ File\Content, Directory, }; -use Innmind\MediaType\MediaType; use Innmind\TimeContinuum\{ Clock, Format, @@ -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, + )), ); }