import 'package:openapi/api.dart' show Optional; sealed class Option { const Option(); const factory Option.some(T value) = Some; const factory Option.none() = None; factory Option.fromNullable(T? value) => value != null ? Some(value) : None(); @pragma('vm:prefer-inline') bool get isSome => this is Some; @pragma('vm:prefer-inline') bool get isNone => this is None; @pragma('vm:prefer-inline') T? get unwrapOrNull => switch (this) { Some(:final value) => value, None() => null, }; U fold(U Function(T value) onSome, U Function() onNone) => switch (this) { Some(:final value) => onSome(value), None() => onNone(), }; @override String toString() => switch (this) { Some(:final value) => 'Some($value)', None() => 'None', }; } final class Some extends Option { final T value; const Some(this.value); @override bool operator ==(Object other) => other is Some && other.value == value; @override int get hashCode => value.hashCode; } final class None extends Option { const None(); @override bool operator ==(Object other) => other is None; @override int get hashCode => 0; } extension NullableOptionExtension on Option? { T? patch(T? current) => this == null ? current : this!.unwrapOrNull; } extension OptionToOptional on Option { Optional toOptional() => switch (this) { None() => const Optional.absent(), Some(:final value) => Optional.present(value), }; }