Initial release: Go Jdenticon library v0.1.0
- Core library with SVG and PNG generation - CLI tool with generate and batch commands - Cross-platform path handling for Windows compatibility - Comprehensive test suite with integration tests
This commit is contained in:
124
jdenticon/generator.go
Normal file
124
jdenticon/generator.go
Normal file
@@ -0,0 +1,124 @@
|
||||
package jdenticon
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/ungluedlabs/go-jdenticon/internal/engine"
|
||||
"github.com/ungluedlabs/go-jdenticon/internal/util"
|
||||
)
|
||||
|
||||
// Generator provides thread-safe identicon generation with caching.
|
||||
// It wraps the internal engine.Generator to provide a clean public API.
|
||||
type Generator struct {
|
||||
engine *engine.Generator
|
||||
config Config // Store the configuration for validation during Generate calls
|
||||
}
|
||||
|
||||
// NewGenerator creates a new Generator with default configuration and default caching.
|
||||
func NewGenerator() (*Generator, error) {
|
||||
engineGen, err := engine.NewDefaultGenerator()
|
||||
if err != nil {
|
||||
return nil, NewErrGenerationFailed("", 0, err)
|
||||
}
|
||||
|
||||
return &Generator{
|
||||
engine: engineGen,
|
||||
config: DefaultConfig(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewGeneratorWithCacheSize creates a new Generator with the specified cache size.
|
||||
func NewGeneratorWithCacheSize(cacheSize int) (*Generator, error) {
|
||||
if cacheSize <= 0 {
|
||||
return nil, NewErrInvalidInput("cacheSize", fmt.Sprintf("%d", cacheSize), "must be positive")
|
||||
}
|
||||
|
||||
config := engine.DefaultGeneratorConfig()
|
||||
config.CacheSize = cacheSize
|
||||
|
||||
engineGen, err := engine.NewGeneratorWithConfig(config)
|
||||
if err != nil {
|
||||
return nil, NewErrCacheCreationFailed(cacheSize, err)
|
||||
}
|
||||
|
||||
return &Generator{
|
||||
engine: engineGen,
|
||||
config: DefaultConfig(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewGeneratorWithConfig creates a new Generator with custom configuration and caching.
|
||||
func NewGeneratorWithConfig(config Config, cacheSize int) (*Generator, error) {
|
||||
if cacheSize <= 0 {
|
||||
return nil, NewErrInvalidInput("cacheSize", fmt.Sprintf("%d", cacheSize), "must be positive")
|
||||
}
|
||||
|
||||
// Convert public config to internal config
|
||||
colorConfig, err := config.toEngineColorConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
generatorConfig := engine.GeneratorConfig{
|
||||
ColorConfig: colorConfig,
|
||||
CacheSize: cacheSize,
|
||||
MaxComplexity: config.MaxComplexity,
|
||||
MaxIconSize: config.MaxIconSize,
|
||||
}
|
||||
|
||||
engineGen, err := engine.NewGeneratorWithConfig(generatorConfig)
|
||||
if err != nil {
|
||||
return nil, NewErrCacheCreationFailed(cacheSize, err)
|
||||
}
|
||||
|
||||
return &Generator{
|
||||
engine: engineGen,
|
||||
config: config,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Generate creates an identicon for the given input string and size with context support.
|
||||
// The context can be used to set timeouts or cancel generation.
|
||||
//
|
||||
// The input string is hashed to generate a deterministic identicon.
|
||||
// Size must be positive and represents the width/height in pixels.
|
||||
//
|
||||
// This method applies the security limits that were configured when the Generator was created.
|
||||
// For different limits, create a new Generator with NewGeneratorWithConfig.
|
||||
//
|
||||
// This method is thread-safe and uses caching if configured.
|
||||
func (g *Generator) Generate(ctx context.Context, input string, size int) (*Icon, error) {
|
||||
// Apply validation using the generator's stored configuration
|
||||
if err := validateInputs(input, size, g.config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Check for early cancellation
|
||||
if err := ctx.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Convert input to hash
|
||||
hash := util.ComputeHash(input)
|
||||
|
||||
// Validate complexity before generation
|
||||
if err := validateComplexity(hash, g.config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Generate using the internal engine with context
|
||||
engineIcon, err := g.engine.Generate(ctx, hash, float64(size))
|
||||
if err != nil {
|
||||
return nil, NewErrGenerationFailed(input, size, err)
|
||||
}
|
||||
|
||||
// Wrap in public Icon directly
|
||||
return newIcon(engineIcon), nil
|
||||
}
|
||||
|
||||
// GetCacheMetrics returns the cache hit and miss counts.
|
||||
// These metrics are thread-safe to read.
|
||||
func (g *Generator) GetCacheMetrics() (hits, misses int64) {
|
||||
return g.engine.GetCacheMetrics()
|
||||
}
|
||||
Reference in New Issue
Block a user