mimetypes

package module
v0.0.0-...-9a0ed80 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 17, 2026 License: BSD-3-Clause Imports: 6 Imported by: 0

README

go-ruby-mime-types/mime-types

mime-types — go-ruby-mime-types

Docs License Go Coverage

A pure-Go (no cgo) reimplementation of Ruby's MIME::Types registry — the data model and lookup behaviour of the mime-types gem, backed by the complete mime-types-data dataset. Look up MIME types by content type or by filename extension, with the gem's exact priority ordering — without any Ruby runtime.

It is the MIME-type backend for go-embedded-ruby, but is a standalone, reusable module with no dependency on the Ruby runtime — a sibling of go-ruby-regexp (the Onigmo engine), go-ruby-erb (the ERB compiler) and go-ruby-yaml (the Psych emitter/loader).

What it is — and isn't. This is the MIME type registry and lookup — a deterministic, interpreter-independent value model that needs no interpreter, so it lives here as pure Go. The full IANA/registry dataset is embedded (go:embed), so the registry is complete and needs no network. Binding the returned *Type values to live Ruby MIME::Type objects is the host's job; this library hands back a small, explicit model the host maps to and from its own objects.

Features

Faithful port of MIME::Types, validated field-for-field against the mime-types gem across the entire registry (every variant and every extension) on every supported platform:

  • Complete embedded registry — the mime-types-data dataset (version 3.2026.0414, 3094 type variants / 1612 extensions) is committed in-repo and embedded via go:embed. No network, no gem, no Ruby.
  • Get by content type (MIME::Types[str]) — case-insensitive, returns the priority-sorted variants for a simplified media/sub key.
  • GetRegexp by pattern (MIME::Types[/re/]) — every type whose simplified content type matches, priority-sorted and de-duplicated.
  • TypeFor / Of by filename (MIME::Types.type_for / .of) — extension lookup (case-insensitive), with the gem's preferred-extension boost and multi-filename union.
  • Type value modelContentType, MediaType, SubType, Simplified, Encoding, Extensions, PreferredExtension, Friendly, UseInstead, Docs, and the Registered / Provisional / Obsolete / Signature / Complete / Binary / ASCII predicates.
  • Exact priority orderingPriorityCompare reproduces the gem's precomputed sort priority bitmap (obsolete / provisional / registered / complete / extension count) and its simplified-name tiebreak.

CGO-free, dependency-free, 100% test coverage, gofmt + go vet clean, and green across the six 64-bit Go targets (amd64, arm64, riscv64, loong64, ppc64le, s390x) on Linux, macOS and Windows.

Install

go get github.com/go-ruby-mime-types/mime-types

Usage

package main

import (
	"fmt"
	"regexp"

	mimetypes "github.com/go-ruby-mime-types/mime-types"
)

func main() {
	r := mimetypes.Default() // the complete embedded registry

	// By filename extension — MIME::Types.type_for / .of
	for _, t := range r.TypeFor("report.html") {
		fmt.Println(t) // text/html
	}
	fmt.Println(r.TypeFor("archive.tar.gz")) // [application/gzip application/x-gzip]

	// By content type — MIME::Types[str] (case-insensitive)
	html := r.Get("text/html")[0]
	fmt.Println(html.MediaType(), html.SubType()) // text html
	fmt.Println(html.PreferredExtension())        // html
	fmt.Println(html.Friendly())                  // HyperText Markup Language (HTML)
	fmt.Println(html.Binary(), html.Registered()) // true true

	// By regexp — MIME::Types[/re/]
	for _, t := range r.GetRegexp(regexp.MustCompile(`^image/`)) {
		_ = t
	}
}

Value model

A *Type mirrors Ruby's MIME::Type; a *Registry mirrors the MIME::Types module. A host (such as go-embedded-ruby) maps these onto its own Ruby objects:

Ruby (MIME::Type) Go (*mimetypes.Type)
#content_type ContentType() string
#media_type MediaType() string
#sub_type SubType() string
#simplified Simplified() string
#encoding Encoding() string
#extensions Extensions() []string
#preferred_extension PreferredExtension() string
#friendly Friendly() string
#use_instead UseInstead() string
#docs Docs() string
#registered? Registered() bool
#provisional? Provisional() bool
#obsolete? Obsolete() bool
#signature? Signature() bool
#complete? Complete() bool
#binary? / #ascii? Binary() bool / ASCII() bool
#<=> / #priority_compare PriorityCompare(*Type) int
Ruby (MIME::Types) Go (*mimetypes.Registry)
MIME::Types[str] Get(typeID string) []*Type
MIME::Types[/re/] GetRegexp(*regexp.Regexp) []*Type
MIME::Types.type_for(fn) TypeFor(filenames ...string) []*Type
MIME::Types.of(fn) Of(filenames ...string) []*Type
MIME::Types.count Len() int

API

// Default returns the complete registry built from the embedded
// mime-types-data dataset (parsed once on first use).
func Default() *Registry

// New builds a Registry from explicit types (insertion order preserved).
func New(types []*Type) *Registry

func (r *Registry) Get(typeID string) []*Type           // MIME::Types[str]
func (r *Registry) GetRegexp(p *regexp.Regexp) []*Type   // MIME::Types[/re/]
func (r *Registry) TypeFor(filenames ...string) []*Type  // MIME::Types.type_for
func (r *Registry) Of(filenames ...string) []*Type       // MIME::Types.of
func (r *Registry) Len() int                             // MIME::Types.count
func (r *Registry) Types() []*Type                       // every variant

func (t *Type) ContentType() string
func (t *Type) MediaType() string
func (t *Type) SubType() string
func (t *Type) Simplified() string
func (t *Type) Encoding() string
func (t *Type) Extensions() []string
func (t *Type) PreferredExtension() string
func (t *Type) Friendly() string
func (t *Type) UseInstead() string
func (t *Type) Docs() string
func (t *Type) Registered() bool
func (t *Type) Provisional() bool
func (t *Type) Obsolete() bool
func (t *Type) Signature() bool
func (t *Type) Complete() bool
func (t *Type) Binary() bool
func (t *Type) ASCII() bool
func (t *Type) String() string
func (t *Type) PriorityCompare(other *Type) int

const DataVersion = "3.2026.0414" // embedded mime-types-data version

Tests & coverage

go test -race -cover ./...

The suite holds 100% statement coverage. A differential MRI oracle (oracle_test.go) shells out to the mime-types gem and asserts byte-for-byte parity across the whole registry — every field of all 3094 variants and the type_for result for all 1612 extensions, including priority ordering. The oracle skips itself when ruby (or the gem) is absent — the Windows and qemu cross-arch lanes — where the deterministic, Ruby-free tests alone keep coverage at 100%.

License

BSD-3-Clause © the go-ruby-mime-types/mime-types authors.

The embedded registry data derives from mime-types-data (MIT).

WebAssembly

Being pure Go (CGO=0), this library also compiles to WebAssembly — both GOOS=js GOARCH=wasm (browser / Node.js) and GOOS=wasip1 GOARCH=wasm (WASI). CI builds both targets on every push, alongside the six 64-bit native/qemu arches.

GOOS=js     GOARCH=wasm go build ./...   # browser / Node
GOOS=wasip1 GOARCH=wasm go build ./...   # WASI (wasmtime, wasmer, wasmedge, …)

Documentation

Overview

Package mimetypes is a pure-Go (CGO-free) reimplementation of Ruby's MIME::Types registry — the data model and lookup behaviour of the mime-types gem (backed by the mime-types-data registry), faithful to MRI.

The complete IANA/registry dataset shipped by the mime-types-data gem is embedded (via go:embed of mimetypes.json), so the registry is complete and no network or Ruby runtime is required. A Registry answers the same queries the gem exposes on the MIME::Types module:

r := mimetypes.Default()
r.Get("text/html")          // []*Type, priority sorted
r.GetRegexp(re)             // []*Type matching a content-type pattern
r.TypeFor("index.html")     // []*Type by filename extension
r.Of("a.tar.gz")            // alias of TypeFor

Each Type mirrors MIME::Type: ContentType, MediaType, SubType, Extensions, PreferredExtension, Friendly, Binary/ASCII, Obsolete, Registered, plus the gem's priority ordering (<=>). The value model is what go-embedded-ruby maps to Ruby MIME::Type objects.

Index

Constants

View Source
const DataVersion = "3.2026.0414"

DataVersion is the version of the embedded mime-types-data registry.

Variables

This section is empty.

Functions

This section is empty.

Types

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry is a queryable set of MIME types, mirroring Ruby's MIME::Types.

A Registry is read-only and safe for concurrent use. Use Default for the complete embedded registry, or New to build one from explicit entries.

func Default

func Default() *Registry

Default returns the complete registry built from the embedded mime-types-data dataset. It is parsed once on first use.

func New

func New(types []*Type) *Registry

New builds a Registry from the given types. The supplied types are indexed by their simplified key and by extension. Insertion order is preserved.

func (*Registry) Get

func (r *Registry) Get(typeID string) []*Type

Get returns the types whose simplified content type matches typeID, priority-sorted. typeID is matched case-insensitively (e.g. "text/html" or "TEXT/HTML"). Mirrors MIME::Types#[] with a string argument.

func (*Registry) GetRegexp

func (r *Registry) GetRegexp(pattern *regexp.Regexp) []*Type

GetRegexp returns every type whose simplified content type matches the pattern, priority-sorted and de-duplicated. Mirrors MIME::Types#[] with a Regexp argument.

func (*Registry) Len

func (r *Registry) Len() int

Len reports the number of type variants in the registry. Mirrors MIME::Types#count.

func (*Registry) Of

func (r *Registry) Of(filenames ...string) []*Type

Of is an alias for Registry.TypeFor, mirroring MIME::Types#of.

func (*Registry) TypeFor

func (r *Registry) TypeFor(filenames ...string) []*Type

TypeFor returns the types associated with a filename's extension, priority-sorted (preferred-extension types favoured) and de-duplicated. The lookup is case-insensitive. Mirrors MIME::Types#type_for.

func (*Registry) Types

func (r *Registry) Types() []*Type

Types returns all type variants in registry order.

type Type

type Type struct {
	// contains filtered or unexported fields
}

Type is a single MIME type entry, mirroring Ruby's MIME::Type.

A Type is immutable once built by the registry; the accessor methods return copies of slices where mutation would otherwise leak into the registry.

func (*Type) ASCII

func (t *Type) ASCII() bool

ASCII reports whether the type is transferred as ASCII (7bit or quoted-printable). Mirrors MIME::Type#ascii?.

func (*Type) Binary

func (t *Type) Binary() bool

Binary reports whether the type is transferred as binary (base64 or 8bit). Mirrors MIME::Type#binary?.

func (*Type) Complete

func (t *Type) Complete() bool

Complete reports whether the type carries an extension list. Mirrors MIME::Type#complete?.

func (*Type) ContentType

func (t *Type) ContentType() string

ContentType returns the raw content type, preserving the registry's casing (e.g. "text/html"). Mirrors MIME::Type#content_type.

func (*Type) Docs

func (t *Type) Docs() string

Docs returns the documentation note for this type, or "". Mirrors MIME::Type#docs.

func (*Type) Encoding

func (t *Type) Encoding() string

Encoding returns the transfer encoding ("base64", "8bit", "7bit" or "quoted-printable"). Mirrors MIME::Type#encoding.

func (*Type) Extensions

func (t *Type) Extensions() []string

Extensions returns the file extensions associated with this type (without a leading dot). Mirrors MIME::Type#extensions.

func (*Type) Friendly

func (t *Type) Friendly() string

Friendly returns the human-readable English description, or "" if none. Mirrors MIME::Type#friendly (the "en" entry).

func (*Type) MediaType

func (t *Type) MediaType() string

MediaType returns the simplified, lowercased media type (e.g. "text"). Mirrors MIME::Type#media_type.

func (*Type) Obsolete

func (t *Type) Obsolete() bool

Obsolete reports whether the type is obsolete. Mirrors MIME::Type#obsolete?.

func (*Type) PreferredExtension

func (t *Type) PreferredExtension() string

PreferredExtension returns the preferred file extension. If none was set explicitly, the first extension is used; if there are no extensions, "" is returned. Mirrors MIME::Type#preferred_extension.

func (*Type) PriorityCompare

func (t *Type) PriorityCompare(other *Type) int

PriorityCompare orders two types the way MIME::Type#priority_compare (and the gem's #<=>) does: by the precomputed sort priority, then by the simplified representation alphabetically. It returns -1, 0 or 1.

func (*Type) Provisional

func (t *Type) Provisional() bool

Provisional reports whether the type is provisionally registered. Mirrors MIME::Type#provisional?.

func (*Type) Registered

func (t *Type) Registered() bool

Registered reports whether the type is IANA-registered. Mirrors MIME::Type#registered?.

func (*Type) Signature

func (t *Type) Signature() bool

Signature reports whether the type is a signature ("magic") type. Mirrors MIME::Type#signature?.

func (*Type) Simplified

func (t *Type) Simplified() string

Simplified returns the lowercased "media/sub" key. Mirrors MIME::Type#simplified.

func (*Type) String

func (t *Type) String() string

String returns the content type, matching MIME::Type#to_s.

func (*Type) SubType

func (t *Type) SubType() string

SubType returns the simplified, lowercased sub type (e.g. "html"). Mirrors MIME::Type#sub_type.

func (*Type) UseInstead

func (t *Type) UseInstead() string

UseInstead returns the replacement content type for an obsolete entry, or "" if there is none. Mirrors MIME::Type#use_instead.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL