#types - Common Types and Utilities

    Level: 2 Package: bobzhang/zip/types Dependencies: types/fpath

    #Overview

    The types package provides common type definitions and utilities used throughout the ZIP library, including compression types, file paths, and POSIX time handling.

    #Sub-Packages

    • types/fpath: File path manipulation and validation

    #Features

    • Compression Enum: Type-safe compression method representation
    • POSIX Time: Unix timestamp handling with DOS time conversion
    • File Paths: Unix-style path utilities (via fpath sub-package)

    #API

    #Compression

    #pub enum Compression

    pub enum Compression { Stored // No compression (method 0) Deflate // DEFLATE compression (method 8) // Future: Bzip2, LZMA, etc. } derive(Eq, Show)

    Represents ZIP compression methods.

    #Functions

    pub fn Compression::from_int(method : Int) -> Compression pub fn Compression::to_int(self : Compression) -> Int

    Convert between compression enum and ZIP method codes.

    Method Codes:
    • 0 = Stored (no compression)
    • 8 = DEFLATE

    #POSIX Time (Ptime)

    #pub typealias Int64 as Ptime

    POSIX timestamp (seconds since 1970-01-01 00:00:00 UTC).

    #Constants

    pub let dos_epoch : Ptime // 1980-01-01 00:00:00 UTC

    DOS epoch (ZIP file format epoch).

    #Functions

    #ptime_to_date_time(ptime : Ptime) -> ((Int, Int, Int), (Int, Int, Int))

    Convert POSIX time to date and time components.

    Returns: ((year, month, day), (hour, minute, second))

    #ptime_of_dos_date_time(dos_date : Int, dos_time : Int) -> Ptime

    Convert DOS date/time to POSIX timestamp.

    DOS Format:
    • Date: (year-1980) << 9 | month << 5 | day
    • Time: hour << 11 | minute << 5 | (second / 2)

    #ptime_to_dos_date_time(ptime : Ptime) -> (Int, Int)

    Convert POSIX timestamp to DOS date/time format.

    Returns: (dos_date, dos_time)

    #ptime_format(ptime : Ptime) -> String

    Format POSIX time as ISO 8601-like string.

    Format: "YYYY-MM-DD HH:MM:SS"

    #File Paths (Fpath)

    #pub typealias String as Fpath

    File path type (re-exported from types/fpath).

    #Functions

    pub fn fpath_ensure_unix(path : Fpath) -> Fpath

    Convert Windows-style paths (\) to Unix-style (/).

    pub fn fpath_ensure_directoryness(path : Fpath) -> Fpath

    Ensure directory paths end with /.

    pub fn fpath_sanitize(path : Fpath) -> Fpath

    Remove redundant separators and normalize path.

    #Usage Examples

    #Compression Types

    ///|
    test {
    // Create from ZIP method code
    let compression = @types.Compression::from_int(8) // DEFLATE

    // Convert to method code
    let method_code = compression.to_int()
    @json.inspect(method_code, content=8)

    // Test stored compression
    let stored = @types.Compression::from_int(0)
    @json.inspect(stored.to_int(), content=0)
    }

    #Time Conversion

    // Get current time as POSIX timestamp let now : Ptime = current_time() // Convert to DOS format for ZIP let (dos_date, dos_time) = ptime_to_dos_date_time(now) // Store in ZIP file... // Later, read from ZIP let mtime = ptime_of_dos_date_time(dos_date, dos_time) println("Modified: \{ptime_format(mtime)}") // Output: "Modified: 2025-10-02 14:30:45"

    #Date/Time Components

    let ((year, month, day), (hour, minute, second)) = ptime_to_date_time(now) println("\{year}-\{month}-\{day} \{hour}:\{minute}:\{second}")

    #File Paths

    // Normalize Windows path let path = fpath_ensure_unix("dir\\subdir\\file.txt") // Result: "dir/subdir/file.txt" // Ensure directory let dir = fpath_ensure_directoryness("mydir") // Result: "mydir/" // Sanitize path let clean = fpath_sanitize("dir//subdir/./file.txt") // Result: "dir/subdir/file.txt"

    #DOS Date/Time Format

    #Date Format (16 bits)

    Bits 15-9: Year (0 = 1980, 127 = 2107) Bits 8-5: Month (1-12) Bits 4-0: Day (1-31)

    #Time Format (16 bits)

    Bits 15-11: Hour (0-23) Bits 10-5: Minute (0-59) Bits 4-0: Second / 2 (0-29, representing 0-58 seconds)

    Note: DOS time has 2-second resolution.

    #Example

    // October 2, 2025, 14:30:45 // DOS Date: (2025-1980) << 9 | 10 << 5 | 2 = 0x5A82 // DOS Time: 14 << 11 | 30 << 5 | (45/2) = 0x73D6 let dos_date = 0x5A82 let dos_time = 0x73D6 let ptime = ptime_of_dos_date_time(dos_date, dos_time) println(ptime_format(ptime)) // Output: "2025-10-02 14:30:44" (45 seconds rounded down to 44)

    #Time Range Limitations

    #DOS Epoch

    • Minimum: 1980-01-01 00:00:00
    • Maximum: 2107-12-31 23:59:58

    #ZIP File Behavior

    • Times before 1980 are clamped to DOS epoch
    • Times after 2107 are clamped to max DOS time
    • 2-second resolution (odd seconds rounded down)

    #Implementation Notes

    #Compression

    • Extensible enum for future compression methods
    • Type-safe method codes
    • Easy to add new methods (Bzip2, LZMA, etc.)

    #Time Handling

    • All internal times are POSIX timestamps (Int64)
    • DOS conversion only at ZIP I/O boundaries
    • Timezone-agnostic (UTC assumed)
    • Leap second handling: not supported (matches DOS/ZIP spec)

    #File Paths

    • All paths normalized to Unix-style (/ separator)
    • Directory paths always end with /
    • Relative paths supported
    • No validation of path legality (allows any string)

    #Testing

    Run tests with:
    moon test types

    Tests cover:
    • Compression type conversion
    • DOS time conversion (boundary cases)
    • Date/time formatting
    • Path normalization
    • Epoch handling

    #Dependencies

    • types/fpath (Level 1) - File path utilities

    #Used By

    • Main zip package - For file metadata
    • All packages needing compression types or time handling

    #Future Enhancements

    Potential additions:
    • More compression methods (Bzip2, LZMA, etc.)
    • Extended timestamps (ZIP64)
    • Timezone support
    • Path validation and security checks
    • Unicode normalization for paths

    #References

    Fpath

    Filepath type and utilities Re-exports from types/fpath package

    Compression

    pub(all) enum Compression {
    Stored
    Deflate
    Bzip2
    Lzma
    Xz
    Zstd
    Other(Int)
    } derive(Eq,
    Debug
    )

    Compression formats supported in ZIP archives

    Compression::equal

    fn Compression::equal(Compression, Compression) -> Bool

    Compression::from_int

    #as_free_fn(compression)
    fn Compression::from_int(compression_method : Int) -> Compression

    Convert ZIP method number to compression format

    Compression::not_equal

    fn Compression::not_equal(x : Compression, y : Compression) -> Bool

    Compression::to_int

    fn Compression::to_int(self : Compression) -> Int

    Convert compression format to ZIP method number Map to ZIP numeric method id.

    Compression::to_string

    fn Compression::to_string(self : Compression) -> String

    Convert compression format to human-readable string Human-friendly lowercase string.

    FileMode

    pub(all) struct FileMode(Int) derive(Compare, Eq, Hash, ToJson,
    FromJson
    )

    Unix file mode (permission bits)
    impl Show for FileMode

    FileMode::compare

    fn FileMode::compare(FileMode, FileMode) -> Int

    FileMode::equal

    fn FileMode::equal(FileMode, FileMode) -> Bool

    FileMode::from_int

    fn FileMode::from_int(value : Int) -> FileMode

    Create FileMode from integer Wrap raw bits in FileMode.

    FileMode::hash

    fn FileMode::hash(self : FileMode) -> Int

    FileMode::hash_combine

    fn FileMode::hash_combine(FileMode, Hasher) -> Unit

    FileMode::not_equal

    fn FileMode::not_equal(x : FileMode, y : FileMode) -> Bool

    FileMode::op_ge

    fn FileMode::op_ge(x : FileMode, y : FileMode) -> Bool

    FileMode::op_gt

    fn FileMode::op_gt(x : FileMode, y : FileMode) -> Bool

    FileMode::op_le

    fn FileMode::op_le(x : FileMode, y : FileMode) -> Bool

    FileMode::op_lt

    fn FileMode::op_lt(x : FileMode, y : FileMode) -> Bool

    FileMode::output

    fn FileMode::output(x : FileMode, logger : &Logger) -> Unit

    FileMode::to_int

    fn FileMode::to_int(self : FileMode) -> Int

    Get the integer value of the file mode Raw integer permission bits (includes type bits if supplied externally).

    FileMode::to_json

    fn FileMode::to_json(FileMode) -> Json

    FileMode::to_string

    fn FileMode::to_string(x : FileMode) -> String

    Ptime

    pub(all) struct Ptime(Int) derive(Compare, Eq, Hash, ToJson,
    FromJson
    )

    POSIX time (seconds since Unix epoch: 1970-01-01 00:00:00 UTC).

    Standard Unix timestamp representation. ZIP files require conversion to DOS format which truncates to 2-second precision and has epoch 1980-01-01.

    Ptime::compare

    fn Ptime::compare(Ptime, Ptime) -> Int

    Ptime::equal

    fn Ptime::equal(Ptime, Ptime) -> Bool

    Ptime::hash

    fn Ptime::hash(self : Ptime) -> Int

    Ptime::hash_combine

    fn Ptime::hash_combine(Ptime, Hasher) -> Unit

    Ptime::not_equal

    fn Ptime::not_equal(x : Ptime, y : Ptime) -> Bool

    Ptime::op_ge

    fn Ptime::op_ge(x : Ptime, y : Ptime) -> Bool

    Ptime::op_gt

    fn Ptime::op_gt(x : Ptime, y : Ptime) -> Bool

    Ptime::op_le

    fn Ptime::op_le(x : Ptime, y : Ptime) -> Bool

    Ptime::op_lt

    fn Ptime::op_lt(x : Ptime, y : Ptime) -> Bool

    Ptime::to_json

    fn Ptime::to_json(Ptime) -> Json

    dos_epoch

    let dos_epoch : Ptime

    DOS epoch: 1980-01-01 00:00:00 UTC (in POSIX time).

    This is the earliest representable time in ZIP archives. Any POSIX time before this epoch will be clamped to this value when converting to DOS format.

    Value: 315532800 seconds = 10 years after Unix epoch.

    format_file_mode

    fn format_file_mode(mode : FileMode) -> String

    Format Unix file mode like ls -l (e.g., "rwxr-xr-x") Render rwx triads (owner/group/other).

    fpath_ensure_directoryness

    Re-export: ensure trailing slash.

    fpath_ensure_unix

    Re-export: normalize separators to '/'.

    fpath_sanitize

    Re-export: sanitize path components.

    ptime_format

    fn ptime_format(ptime : Ptime) -> String

    Format POSIX time as RFC 3339 (without T separator)

    ptime_of_dos_date_time

    fn ptime_of_dos_date_time(dos_date : UInt16, dos_time : UInt16) -> Ptime

    Convert MS-DOS date/time to POSIX time

    Parameters

    • dos_date: 16-bit DOS date value (UInt16)
      • Bits 0-4: Day of month (1-31)
      • Bits 5-8: Month (1-12)
      • Bits 9-15: Year offset from 1980 (0-127, represents 1980-2107)
    • dos_time: 16-bit DOS time value (UInt16)
      • Bits 0-4: Seconds/2 (0-29, represents 0-58 seconds in 2-second intervals)
      • Bits 5-10: Minutes (0-59)
      • Bits 11-15: Hours (0-23)

    Returns

    POSIX timestamp (seconds since Unix epoch: 1970-01-01 00:00:00 UTC)

    Notes

    • Both parameters are native UInt16 types as stored in ZIP file format
    • Valid range: 1980-01-01 00:00:00 to 2107-12-31 23:59:58
    • If dos_date < 0x21 (before 1980-01-01), returns dos_epoch (1980-01-01)
    • The ZIP format uses this encoding as defined in PKWARE's APPNOTE.TXT

    ptime_to_date_time

    fn ptime_to_date_time(ptime_s : Ptime) -> ((Int, Int, Int), (Int, Int, Int))

    Convert POSIX time to ((year, month, day), (hour, minute, second))

    ptime_to_dos_date_time

    fn ptime_to_dos_date_time(ptime_s : Ptime) -> (UInt16, UInt16)

    Convert POSIX time to MS-DOS date/time format

    Parameters

    • ptime_s: POSIX timestamp (seconds since Unix epoch: 1970-01-01 00:00:00 UTC)

    Returns

    A tuple (dos_date, dos_time) of UInt16 values:
    • dos_date: 16-bit DOS date with bits:
      • Bits 0-4: Day of month (1-31)
      • Bits 5-8: Month (1-12)
      • Bits 9-15: Year offset from 1980 (0-127, represents 1980-2107)
    • dos_time: 16-bit DOS time with bits:
      • Bits 0-4: Seconds/2 (0-29, represents 0-58 seconds in 2-second intervals)
      • Bits 5-10: Minutes (0-59)
      • Bits 11-15: Hours (0-23)

    Notes

    • Times before 1980-01-01 are clamped to 1980-01-01 00:00:00
    • Times after 2107-12-31 are clamped to 2107-12-31 23:59:59
    • Returns native UInt16 types as required by ZIP file format
    • Seconds are stored in 2-second intervals (precision loss)
    • The ZIP format uses this encoding as defined in PKWARE's APPNOTE.TXT

    Powered by MoonBit

    Site sourceReport issuePackagesBuild queueSkillsStatistics

    © 2026 mooncakes.io