<commit_before>package context

import (
	stdcontext "context"
	"time"

	"nimona.io/internal/rand"
)

type (
	// Context that matches std context
	Context stdcontext.Context
	// context wraps stdcontext.Context allowing adding tracing information
	// instead of using the Values.
	context struct {
		stdcontext.Context
		method        string
		arguments     map[string]interface{}
		correlationID string
	}
)

// Background context wrapper
func Background() *context {
	return New()
}

// A CancelFunc tells an operation to abandon its work
type CancelFunc func()

// WithCancel returns a copy of parent with a new Done channel
func WithCancel(parent stdcontext.Context) (*context, CancelFunc) {
	cctx, cf := stdcontext.WithCancel(parent)
	return New(WithParent(cctx)), CancelFunc(cf)
}

// Method returns the context's method
func (ctx *context) Method() string {
	return ctx.method
}

// WithTimeout wraps stdcontext.WithTimeout
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
	cctx, cf := stdcontext.WithTimeout(parent, timeout)
	return New(WithParent(cctx)), CancelFunc(cf)
}

// Arguments returns the context's arguments
func (ctx *context) Arguments() map[string]interface{} {
	return ctx.arguments
}

// CorrelationID returns the context's correlationID
func (ctx *context) CorrelationID() string {
	return ctx.correlationID
}

// New constructs a new *context from a parent Context and Options
func New(opts ...Option) *context {
	ctx := &context{
		Context:   stdcontext.Background(),
		arguments: map[string]interface{}{},
	}
	for _, opt := range opts {
		opt(ctx)
	}
	if ctx.correlationID == "" {
		ctx.correlationID = rand.String(12)
	}
	return ctx
}<commit_msg>feat(context): add FromContext, GetCorrelationID<commit_after>package context

import (
	stdcontext "context"
	"time"

	"nimona.io/internal/rand"
)

type (
	// Context that matches std context
	Context stdcontext.Context
	// context wraps stdcontext.Context allowing adding tracing information
	// instead of using the Values.
	context struct {
		stdcontext.Context
		method        string
		arguments     map[string]interface{}
		correlationID string
	}
)

// Background context wrapper
func Background() *context {
	return New()
}

// A CancelFunc tells an operation to abandon its work
type CancelFunc func()

// WithCancel returns a copy of parent with a new Done channel
func WithCancel(parent stdcontext.Context) (*context, CancelFunc) {
	cctx, cf := stdcontext.WithCancel(parent)
	return New(WithParent(cctx)), CancelFunc(cf)
}

// Method returns the context's method
func (ctx *context) Method() string {
	return ctx.method
}

// WithTimeout wraps stdcontext.WithTimeout
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
	cctx, cf := stdcontext.WithTimeout(parent, timeout)
	return New(
		WithParent(cctx),
		WithCorrelationID(
			GetCorrelationID(parent),
		),
	), CancelFunc(cf)
}

// Arguments returns the context's arguments
func (ctx *context) Arguments() map[string]interface{} {
	return ctx.arguments
}

// CorrelationID returns the context's correlationID
func (ctx *context) CorrelationID() string {
	if ctx.correlationID != "" {
		return ctx.correlationID
	}

	if ctx.Context != nil {
		return GetCorrelationID(ctx.Context)
	}

	return ""
}

// FromContext returns a new context from a parent
func FromContext(ctx stdcontext.Context) *context {
	return New(WithParent(ctx))
}

// GetCorrelationID returns the correlation if there is one
func GetCorrelationID(ctx stdcontext.Context) string {
	switch cctx := ctx.(type) {
	case *context:
		return cctx.CorrelationID()
	default:
		return ""
	}
}

// New constructs a new *context from a parent Context and Options
func New(opts ...Option) *context {
	ctx := &context{
		Context:   stdcontext.Background(),
		arguments: map[string]interface{}{},
	}
	for _, opt := range opts {
		opt(ctx)
	}
	if ctx.correlationID == "" {
		ctx.correlationID = rand.String(12)
	}
	return ctx
}
{'fraction_non_alphanumeric': 0.10616352201257861, 'fraction_numerical': 0.0010062893081761006, 'mean_word_length': 4.372972972972973, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4114467', 'n_tokens_mistral': 1236, 'n_tokens_neox': 1176, 'n_words': 375}