Skip to content

Commit

Permalink
feat: support Buffer source for Archive
Browse files Browse the repository at this point in the history
  • Loading branch information
Brooooooklyn committed Dec 3, 2023
1 parent ca33d24 commit f40839e
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 20 deletions.
9 changes: 9 additions & 0 deletions __test__/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { readFile } from 'node:fs/promises'
import { join } from 'node:path'

import test from 'ava'
Expand All @@ -16,3 +17,11 @@ test('should be able to unpack archive', (t) => {
archive.unpack(__dirname)
t.pass()
})

test('should be able to create archive from Buffer', async (t) => {
const archiveBuffer = await readFile(join(__dirname, 'src.tar'))
const archive = new Archive(archiveBuffer)
for (const entry of archive.entries()) {
t.is(typeof entry.path(), 'string')
}
})
2 changes: 1 addition & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ export class ReadonlyHeader {
}
export class Archive {
/** Create a new archive with the underlying path. */
constructor(path: string)
constructor(input: string | Buffer)
entries(): Entries
/**
* Unpacks the contents tarball into the specified `dst`.
Expand Down
10 changes: 4 additions & 6 deletions src/entry.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
use std::fs::File;

use napi::bindgen_prelude::Reference;
use napi::Env;
use napi::{bindgen_prelude::SharedReference, iterator::Generator};
use napi_derive::napi;

use crate::header::ReadonlyHeader;
use crate::Archive;
use crate::{Archive, ArchiveSource};

#[napi(iterator)]
pub struct Entries {
pub(crate) inner: SharedReference<Archive, tar::Entries<'static, File>>,
pub(crate) inner: SharedReference<Archive, tar::Entries<'static, ArchiveSource>>,
}

#[napi]
Expand All @@ -27,12 +25,12 @@ impl Generator for Entries {

#[napi]
pub struct Entry {
inner: tar::Entry<'static, File>,
inner: tar::Entry<'static, ArchiveSource>,
}

#[napi]
impl Entry {
pub fn new(inner: tar::Entry<'static, File>) -> Self {
pub fn new(inner: tar::Entry<'static, ArchiveSource>) -> Self {
Self { inner }
}

Expand Down
59 changes: 46 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,70 @@
#![deny(clippy::all)]

use std::fs::File;
use std::{
fs::File,
io::{Cursor, Read},
};

use napi::bindgen_prelude::{Env, Reference};
use napi::{
bindgen_prelude::{Env, Reference},
Either, JsBuffer,
};
use napi_derive::napi;

use crate::entry::Entries;

mod entry;
mod header;

pub struct ArchiveSource {
inner: Either<File, Cursor<Vec<u8>>>,
}

impl ArchiveSource {
fn from_node_input(input: Either<String, JsBuffer>) -> Result<Self, napi::Error> {
match input {
Either::A(path) => {
let file = File::open(path)?;
Ok(Self {
inner: Either::A(file),
})
}
Either::B(buffer) => Ok(Self {
inner: Either::B(Cursor::new(buffer.into_value()?.to_vec())),
}),
}
}
}

impl Read for ArchiveSource {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
match &mut self.inner {
Either::A(file) => file.read(buf),
Either::B(buffer) => buffer.read(buf),
}
}
}

#[napi]
pub struct Archive {
inner: tar::Archive<File>,
inner: tar::Archive<ArchiveSource>,
}

#[napi]
impl Archive {
#[napi(constructor)]
/// Create a new archive with the underlying path.
pub fn new(path: String) -> napi::Result<Self> {
let file = File::open(path)?;
let inner = tar::Archive::new(file);
Ok(Self { inner })
pub fn new(input: Either<String, JsBuffer>) -> napi::Result<Self> {
Ok(Self {
inner: tar::Archive::new(ArchiveSource::from_node_input(input)?),
})
}

#[napi]
pub fn entries(
&mut self,
this: Reference<Archive>,
env: Env,
) -> napi::Result<crate::entry::Entries> {
pub fn entries(&mut self, this: Reference<Archive>, env: Env) -> napi::Result<Entries> {
let entries = this.share_with(env, |archive| Ok(archive.inner.entries()?))?;

Ok(crate::entry::Entries { inner: entries })
Ok(Entries { inner: entries })
}

#[napi]
Expand Down

0 comments on commit f40839e

Please sign in to comment.