gnlib

package module
v0.58.0 Latest Latest
Warning

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

Go to latest
Published: Oct 17, 2025 License: MIT Imports: 11 Imported by: 7

README

gnlib

Go Reference

A collection of shared utilities and entities for Global Names Architecture Go projects.

Features

  • User-Friendly Error Handling: Terminal-colorized error messages with clean output
  • Generic Utilities: Type-safe Map, Filter, and other collection operations
  • Channel Operations: Chunk channel data into manageable batches
  • Version Comparison: Semantic version comparison utilities
  • UTF-8 Handling: Fix and normalize UTF-8 strings
  • Language Utilities: Convert between language codes and names
  • Domain Entities: Shared types for taxonomic name verification, reconciliation, and matching

Installation

go get github.com/gnames/gnlib

Usage

User-Friendly Error Messages

The error handling system allows you to create errors that produce clean, colorized output for the terminal, while preserving the underlying error details for logging.

Static FormatMessage Function

Use FormatMessage as a standalone function for any message formatting needs:

package main

import (
	"fmt"
	"github.com/gnames/gnlib"
)

func main() {
	// Format a message with tags and variables
	msg := gnlib.FormatMessage(
		"Processing <title>%s</title>: <em>%d</em> items found",
		[]any{"data.csv", 42},
	)
	fmt.Println(msg)
	// Output (with colors): Processing data.csv: 42 items found
}
MessageBase for Structured Errors

Create custom error types that embed MessageBase for more structured error handling:

package main

import (
	"errors"
	"fmt"
	"os"

	"github.com/gnames/gnlib"
)

func main() {
	// Create a custom error type
	type FileError struct {
		error
		gnlib.MessageBase
	}

	// Create a new error with a format string and variables
	base := gnlib.NewMessage(
		"<warning>Could not process file '%s'</warning>",
		[]any{"important.txt"},
	)
	err := FileError{
		error:       errors.New("file processing failed"),
		MessageBase: base,
	}

	// The UserMessage() method returns the formatted, colorized string
	fmt.Fprintln(os.Stdout, err.UserMessage())

	// Example of wrapping the error
	wrappedErr := fmt.Errorf("operation failed: %w", err)

	// You can inspect the error chain to get the user-friendly message
	var gnErr gnlib.Error
	if errors.As(wrappedErr, &gnErr) {
		fmt.Fprintln(os.Stdout, "---")
		fmt.Fprintln(os.Stdout, "Message from wrapped error:")
		fmt.Fprintln(os.Stdout, gnErr.UserMessage())
	}
}

This will produce the following output (with colors in the terminal):

Could not process file 'important.txt'
---
Message from wrapped error:
Could not process file 'important.txt'
Colorization Tags

Both FormatMessage and UserMessage() recognize the following tags for styling terminal output:

  • <title>...</title>: Renders text in green.
  • <warning>...</warning>: Renders text in red.
  • <em>...</em>: Renders text in yellow.
Generic Utilities

The library provides type-safe generic functions for common operations:

package main

import (
    "fmt"
    "github.com/gnames/gnlib"
)

func main() {
    // Map transforms a slice
    numbers := []int{1, 2, 3, 4, 5}
    doubled := gnlib.Map(numbers, func(n int) int { return n * 2 })
    fmt.Println(doubled) // [2 4 6 8 10]

    // Filter returns elements matching a condition
    evens := gnlib.FilterFunc(numbers, func(n int) bool { return n%2 == 0 })
    fmt.Println(evens) // [2 4]

    // SliceMap creates a lookup map from a slice
    fruits := []string{"apple", "banana", "cherry"}
    fruitMap := gnlib.SliceMap(fruits)
    fmt.Println(fruitMap["banana"]) // 1
}
Channel Operations

Process channel data in chunks:

package main

import (
    "context"
    "fmt"
    "github.com/gnames/gnlib"
)

func main() {
    input := make(chan int)
    go func() {
        for i := 1; i <= 10; i++ {
            input <- i
        }
        close(input)
    }()

    chunked := gnlib.ChunkChannel(context.Background(), input, 3)
    for chunk := range chunked {
        fmt.Println(chunk)
    }
    // Output:
    // [1 2 3]
    // [4 5 6]
    // [7 8 9]
    // [10]
}
Version Comparison

Compare semantic versions:

package main

import (
    "fmt"
    "github.com/gnames/gnlib"
)

func main() {
    result := gnlib.CmpVersion("v1.2.3", "v1.2.4")
    fmt.Println(result) // -1 (first is less than second)

    result = gnlib.CmpVersion("v2.0.0", "v1.9.9")
    fmt.Println(result) // 1 (first is greater than second)

    result = gnlib.CmpVersion("v1.0.0", "v1.0.0")
    fmt.Println(result) // 0 (versions are equal)
}
UTF-8 String Handling

Fix invalid UTF-8 sequences and normalize strings:

package main

import (
    "fmt"
    "github.com/gnames/gnlib"
)

func main() {
    // Replaces invalid UTF-8 with U+FFFD and normalizes to NFC
    fixed := gnlib.FixUtf8("invalid\xc3\x28utf8")
    fmt.Println(fixed)
}
Language Utilities

Convert between language codes and names:

package main

import (
    "fmt"
    "github.com/gnames/gnlib"
)

func main() {
    // Get ISO 639-3 code from language name
    code := gnlib.LangCode("English")
    fmt.Println(code) // "eng"

    code = gnlib.LangCode("en")
    fmt.Println(code) // "eng"

    // Get language name from code
    name := gnlib.LangName("fra")
    fmt.Println(name) // "French"
}

Domain Entities

The library includes shared entity types for taxonomic name processing:

  • ent/verifier: Types for taxonomic name verification results
  • ent/reconciler: Types for name reconciliation and manifests
  • ent/matcher: Types for name matching operations
  • ent/nomcode: Nomenclatural code enumerations
  • ent/gnml: Global Names Markup Language types
  • ent/gnvers: Version information types

See the API documentation for details on these packages.

License

Released under the MIT License. See LICENSE file for details.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ChunkChannel added in v0.46.0

func ChunkChannel[T any](ctx context.Context, input <-chan T, chunkSize int) <-chan []T

ChunkChannel reads from an input channel and sends slices (chunks) of up to `chunkSize` items to an output channel. If the input channel is closed, any remaining items are sent as a final slice. The output channel is closed after all data is processed.

Parameters:

  • `ctx`: Context for cancellation.
  • `input`: Input channel.
  • `chunkSize`: Max items per chunk.

Returns:

  • Output channel with slices of items.

Example:

input := make(chan int)
go func() { for i := 1; i <= 10; i++ { input <- i }; close(input) }()
chunked := ChunkChannel(context.Background(), input, 3)
for chunk := range chunked { fmt.Println(chunk) }
// Output: [1 2 3] [4 5 6] [7 8 9] [10]

func CmpVersion added in v0.44.0

func CmpVersion(a, b string) int

CmpVersion compares two semantic versions (eg v0.1.3 vs v0.2.0) as a and b. It returns 0 if the versions are equal, 1 if a is greater than b, and -1 if a is less than b. The version strings are expected to be in a format that can be split into integer components for comparison, such as "1.2.3" or "1.0.0".

func FilterFunc added in v0.32.0

func FilterFunc[T any](s []T, f func(T) bool) []T

Filter returns a new slice containing only the elements of s for which filter function returns true.

func FixUtf8 added in v0.49.0

func FixUtf8(s string) string

FixUtf8 cleans a string by replacing invalid UTF-8 sequences with U+FFFD and normalizing to NFC.

func FormatMessage added in v0.58.0

func FormatMessage(msg string, vars []any) string

FormatMessage is a static function that takes a message string with optional format variables and returns a colorized string based on tags.

It replaces format verbs in the message with values from the vars slice. It also parses the following tags and replaces them with colored output:

  • <title>...</title> for green text.
  • <warning>...</warning> for red text.
  • <em>...</em> for yellow text.

Example:

msg := FormatMessage("Processing <title>%s</title>", []any{"file.txt"})

func LangCode added in v0.33.0

func LangCode(lang string) string

func LangName added in v0.33.0

func LangName(code string) string

func Map

func Map[T any, U any](s []T, f func(T) U) []U

Map applies a function to each element of a slice and returns a new slice in the same order.

func PrintUserMessage added in v0.57.0

func PrintUserMessage(err error)

func SliceMap added in v0.45.0

func SliceMap[T comparable](s []T) map[T]int

SliceMap takes a slice and returns back a lookup map which allows to find index for each element of the slice. If the value happens several times in the slice, the index corresponds to the first matching element.

Types

type Error added in v0.57.0

type Error interface {
	error
	// UserMessage returns a formatted and colorized string that is safe to
	// display to an end-user.
	UserMessage() string
}

Error is an interface for errors that can produce a formatted, user-friendly message. It is intended for errors that need to be displayed to the end-user on STDOUT.

type ErrorBase added in v0.57.0

type ErrorBase = MessageBase

ErrorBase is an alias for MessageBase for backward compatibility. Deprecated: Use MessageBase instead.

func NewError added in v0.57.0

func NewError(msg string, vars []any) ErrorBase

NewError is a constructor for ErrorBase. It takes a message string (which can be a format string) and a slice of arguments for the format string. Deprecated: Use NewMessage instead.

type MessageBase added in v0.58.0

type MessageBase struct {
	// Msg is the message string. It can be a format string for fmt.Sprintf.
	Msg string
	// Vars is a slice of arguments for the Msg format string.
	Vars []any
}

MessageBase is a base type that implements the Error interface. It can be embedded in other error types to provide the basic functionality for formatted, colorized messages. It can also be used independently for non-error messages that need colorization.

func NewMessage added in v0.58.0

func NewMessage(msg string, vars []any) MessageBase

NewMessage is a constructor for MessageBase. It takes a message string (which can be a format string) and a slice of arguments for the format string.

func (MessageBase) UserMessage added in v0.58.0

func (mb MessageBase) UserMessage() string

UserMessage formats the error message with its variables and applies terminal colors based on tags.

It replaces format verbs in the Msg string with values from the Vars slice. It also parses the following tags and replaces them with colored output:

  • <title>...</title> for green text.
  • <warning>...</warning> for red text.
  • <em>...</em> for yellow text.

Directories

Path Synopsis
ent
nomcode
Package nomcode provides types and functions for nomenclatural codes.
Package nomcode provides types and functions for nomenclatural codes.
reconciler
package reconciler describes entities for implementation of a Reconciliation Service API v0.2 https://www.w3.org/community/reports/reconciliation/CG-FINAL-specs-0.2-20230410/
package reconciler describes entities for implementation of a Reconciliation Service API v0.2 https://www.w3.org/community/reports/reconciliation/CG-FINAL-specs-0.2-20230410/

Jump to

Keyboard shortcuts

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