package core

// Option represents a value that may or may not be present.
// A sum type: Some(T) | None.
type Option[T any] struct {
	value *T
}

// Some creates an Option containing a value.
func Some[T any](v T) Option[T] {
	return Option[T]{value: &v}
}

// None creates an empty Option.
func None[T any]() Option[T] {
	return Option[T]{}
}

// IsSome returns true if the Option contains a value.
func (o Option[T]) IsSome() bool {
	return o.value != nil
}

// IsNone returns true if the Option is empty.
func (o Option[T]) IsNone() bool {
	return o.value == nil
}

// Unwrap returns the value or panics if None.
func (o Option[T]) Unwrap() T {
	if o.value == nil {
		panic("called Unwrap on None")
	}
	return *o.value
}

// UnwrapOr returns the value or a default if None.
func (o Option[T]) UnwrapOr(def T) T {
	if o.value != nil {
		return *o.value
	}
	return def
}
