A pure MoonBit implementation of ZIP archive extraction
moon add wangmingfa/zipximport { unzip_file_path } from "wangmingfa/zipx"
async fn {
// Extract all files to memory (no output directory)
let extracted = unzip_file_path("/path/to/archive.zip")
for entry in extracted.iter() {
let (filename, data) = entry
// Process extracted file...
}
// Extract files to a directory
let extracted = unzip_file_path("/path/to/archive.zip", output_dir="./output")
// Files are written to ./output directory
}import { unzip_file, zip_file_open, zip_file_list } from "wangmingfa/zipx"
// Extract all files from a ZIP archive (requires pre-loaded data)
let extracted : Array[(String, Bytes)] = unzip_file(zip_data)
for entry in extracted.iter() {
let (filename, data) = entry
// Process extracted file...
}
// Or use lower-level API
let zip = zip_file_open(zip_data)
let files = zip_file_list(zip) // Get list of filenames
let (filename, data) = zip_file_extract(zip, 0) // Extract by index# Build the CLI tool
moon build cmd/main/
# List files in a ZIP archive
moon run cmd/main/ list /path/to/archive.zip
# Extract files from a ZIP archive
moon run cmd/main/ unzip /path/to/archive.zip ./output_dir
# Enable debug logging (timing & internal diagnostics)
moon run cmd/main/ --debug unzip /path/to/archive.zip ./output_dir
moon run cmd/main/ list /path/to/archive.zip --debugpub async fn unzip_file_path(path : String, output_dir? : String) -> Array[(String, Bytes)] raiseasync fn {
// Extract to memory only
let extracted = unzip_file_path("/path/to/archive.zip")
// Extract to directory
let extracted = unzip_file_path("/path/to/archive.zip", output_dir="./output")
}pub fn unzip_file(data : Bytes) -> Array[(String, Bytes)] raisepub fn zip_file_open(data : Bytes) -> ZipFile raisepub fn zip_file_list(zip : ZipFile) -> Array[String]pub fn zip_file_extract(zip : ZipFile, index : Int) -> (String, Bytes) raisepub fn inflate(data : Bytes) -> Bytes///|
pub enum CompressionMethod {
Stored // No compression
Deflated // DEFLATE compression
Unsupported(UInt16) // Unsupported method
}| Method | Description |
|---|---|
| Store (0) | No compression |
| Deflate (8) | DEFLATE compression |
pub struct CentralDirectoryFileHeader {
signature : UInt
version_made_by : UInt16
version_needed : UInt16
flags : UInt16
compression_method : CompressionMethod
last_mod_time : UInt16
last_mod_date : UInt16
crc32 : UInt
compressed_size : UInt
uncompressed_size : UInt
filename_length : UInt16
extra_field_length : UInt16
comment_length : UInt16
disk_number_start : UInt16
internal_file_attrs : UInt16
external_file_attrs : UInt
local_header_offset : UInt
filename : String
extra_field : Bytes
comment : String
}pub enum CompressionMethod {
Stored
Deflated
Unsupported(UInt16)
}pub struct EndOfCentralDirectoryRecord {
signature : UInt
disk_number : UInt16
cd_start_disk : UInt16
cd_entries_on_disk : UInt16
cd_entries_total : UInt16
cd_size : UInt
cd_offset : UInt
comment_length : UInt16
comment : String
}pub struct LocalFileHeader {
signature : UInt
version_needed : UInt16
flags : UInt16
compression_method : CompressionMethod
last_mod_time : UInt16
last_mod_date : UInt16
crc32 : UInt
compressed_size : UInt
uncompressed_size : UInt
filename_length : UInt16
extra_field_length : UInt16
filename : String
extra_field : Bytes
}pub struct ZipFile {
data : Bytes
eocd : EndOfCentralDirectoryRecord
cd_entries : Array[CentralDirectoryFileHeader]
}fn inflate(data : Bytes, uncompressed_size : Int) -> Bytes raiselet decompressed = inflate(compressed_data)let extracted = unzip_file(zip_data)
for entry in extracted.iter() {
let (filename, data) = entry
println("Extracted: " + filename)
}async fn {
// Just get the files in memory
let extracted = unzip_file_path("/path/to/archive.zip")
// Extract to a directory
let extracted = unzip_file_path("/path/to/archive.zip", output_dir="./output")
}let (filename, data) = zip_file_extract(zip, 0)let files = zip_file_list(zip)
for filename in files.iter() {
println(filename)
}let zip = zip_file_open(zip_data)
let files = zip_file_list(zip)