Skip to content

Quick Start

This guide walks through the most common usage patterns for wuming.

The fastest way to get started — a single function call that uses all available detectors:

ctx := context.Background()

// One-liner: detect and redact all PII.
redacted, err := wuming.Redact(ctx, "SSN 123-45-6789, email john@acme.com")
// redacted: "SSN [NATIONAL_ID], email [EMAIL]"

You can also get match details:

matches, err := wuming.Detect(ctx, "BSN 123456782, call 06-12345678")
// matches contains all detected PII with type, confidence, position

Or the full result:

result, err := wuming.Process(ctx, text)
// result.Original, result.Redacted, result.Matches, result.MatchCount

Compliance Preset

Use a preset to configure detection for a specific regulation. The preset automatically selects the right locales and PII types:

// GDPR — EU/EEA personal data
w := wuming.New(wuming.WithPreset("gdpr"))
result, err := w.Process(ctx, "Steuer-ID 12345678911, email jan@example.de")

// HIPAA — US protected health information
w = wuming.New(wuming.WithPreset("hipaa"))
result, err = w.Process(ctx, "SSN 123-45-6789, Medicare 1EG4-TE5-MK72")

// PCI-DSS — credit card data only
w = wuming.New(wuming.WithPreset("pci-dss"))
result, err = w.Process(ctx, "Card: 4111-1111-1111-1111")

See Compliance Presets for all 10 available presets.

Custom Instance

Create a configured instance for more control:

w := wuming.New()
result, err := w.Process(ctx, "My SSN is 123-45-6789")
// result.Redacted: "My SSN is [NATIONAL_ID]"

Configuring Locales

To restrict detection to a specific locale (global detectors always run regardless):

w := wuming.New(
    wuming.WithLocale("nl"),
)
result, err := w.Process(ctx, "BSN: 123456782, SSN: 123-45-6789")
// Only the BSN is detected (SSN is US-specific and filtered out)

You can combine multiple locales:

w := wuming.New(
    wuming.WithLocale("nl"),
    wuming.WithLocale("de"),
)

Choosing a Replacer Strategy

wuming ships with four replacer strategies:

Replaces PII with a type label (default):

import "github.com/taoq-ai/wuming/adapter/replacer"

w := wuming.New(
    wuming.WithReplacer(replacer.NewRedact()),
)
// "john@example.com" -> "[EMAIL]"

Replaces characters with asterisks, preserving the last 4:

w := wuming.New(
    wuming.WithReplacer(replacer.NewMask()),
)
// "john@example.com" -> "************.com"

Replaces PII with a deterministic SHA-256 hash (truncated to 16 hex chars):

w := wuming.New(
    wuming.WithReplacer(replacer.NewHash()),
)
// "john@example.com" -> "a8cfcd74832004e0"

Provide your own replacement function:

w := wuming.New(
    wuming.WithReplacer(replacer.NewCustom("my-replacer", func(m model.Match) string {
        return fmt.Sprintf("<%s:REDACTED>", m.Type)
    })),
)

Filtering by PII Type

Restrict detection to specific PII types:

w := wuming.New(
    wuming.WithPIITypes(model.Email, model.Phone),
)

Confidence Threshold

Filter out low-confidence matches:

w := wuming.New(
    wuming.WithConfidenceThreshold(0.8),
)

Concurrency Control

Limit the number of detectors running in parallel:

w := wuming.New(
    wuming.WithConcurrency(4),
)

Full Working Example

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/taoq-ai/wuming"
    "github.com/taoq-ai/wuming/adapter/replacer"
    "github.com/taoq-ai/wuming/domain/model"
)

func main() {
    w := wuming.New(
        wuming.WithLocale("nl"),
        wuming.WithReplacer(replacer.NewMask()),
        wuming.WithConfidenceThreshold(0.7),
        wuming.WithPIITypes(model.Email, model.Phone, model.NationalID),
        wuming.WithConcurrency(4),
    )

    text := "Contact Jan at jan@bedrijf.nl or 06-12345678. BSN: 123456782."

    result, err := w.Process(context.Background(), text)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println("Original:", result.Original)
    fmt.Println("Redacted:", result.Redacted)
    fmt.Printf("Matches:  %d\n", result.MatchCount)

    for _, m := range result.Matches {
        fmt.Printf("  - %s: %q (confidence: %.2f, detector: %s)\n",
            m.Type, m.Value, m.Confidence, m.Detector)
    }
}