Skip to content

Commit

Permalink
feat(rx): rename generic parameter (#129)
Browse files Browse the repository at this point in the history
  • Loading branch information
plastikfan committed Mar 26, 2024
1 parent 997330b commit f008dc2
Show file tree
Hide file tree
Showing 13 changed files with 305 additions and 305 deletions.
92 changes: 46 additions & 46 deletions rx/assert.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,100 +9,100 @@ import (
)

// AssertPredicate is a custom predicate based on the items.
type AssertPredicate[I any] func(items []I) error
type AssertPredicate[T any] func(items []T) error

// RxAssert lists the Observable assertions.
type RxAssert[I any] interface { //nolint:revive // foo
apply(*rxAssert[I])
itemsToBeChecked() (bool, []I)
itemsNoOrderedToBeChecked() (bool, []I)
type RxAssert[T any] interface { //nolint:revive // foo
apply(*rxAssert[T])
itemsToBeChecked() (bool, []T)
itemsNoOrderedToBeChecked() (bool, []T)
noItemsToBeChecked() bool
someItemsToBeChecked() bool
raisedErrorToBeChecked() (bool, error)
raisedErrorsToBeChecked() (bool, []error)
raisedAnErrorToBeChecked() (bool, error)
notRaisedErrorToBeChecked() bool
itemToBeChecked() (bool, I)
noItemToBeChecked() (bool, I)
customPredicatesToBeChecked() (bool, []AssertPredicate[I])
itemToBeChecked() (bool, T)
noItemToBeChecked() (bool, T)
customPredicatesToBeChecked() (bool, []AssertPredicate[T])
}

type rxAssert[I any] struct {
f func(*rxAssert[I])
type rxAssert[T any] struct {
f func(*rxAssert[T])
checkHasItems bool
checkHasNoItems bool
checkHasSomeItems bool
items []I
items []T
checkHasItemsNoOrder bool
itemsNoOrder []I
itemsNoOrder []T
checkHasRaisedError bool
err error
checkHasRaisedErrors bool
errs []error
checkHasRaisedAnError bool
checkHasNotRaisedError bool
checkHasItem bool
item I
item T
checkHasNoItem bool
checkHasCustomPredicate bool
customPredicates []AssertPredicate[I]
customPredicates []AssertPredicate[T]
}

func (ass *rxAssert[I]) apply(do *rxAssert[I]) {
func (ass *rxAssert[T]) apply(do *rxAssert[T]) {
ass.f(do)
}

func (ass *rxAssert[I]) itemsToBeChecked() (b bool, i []I) {
func (ass *rxAssert[T]) itemsToBeChecked() (b bool, i []T) {
return ass.checkHasItems, ass.items
}

func (ass *rxAssert[I]) itemsNoOrderedToBeChecked() (b bool, i []I) {
func (ass *rxAssert[T]) itemsNoOrderedToBeChecked() (b bool, i []T) {
return ass.checkHasItemsNoOrder, ass.itemsNoOrder
}

func (ass *rxAssert[I]) noItemsToBeChecked() bool {
func (ass *rxAssert[T]) noItemsToBeChecked() bool {
return ass.checkHasNoItems
}

func (ass *rxAssert[I]) someItemsToBeChecked() bool {
func (ass *rxAssert[T]) someItemsToBeChecked() bool {
return ass.checkHasSomeItems
}
func (ass *rxAssert[I]) raisedErrorToBeChecked() (bool, error) {
func (ass *rxAssert[T]) raisedErrorToBeChecked() (bool, error) {
return ass.checkHasRaisedError, ass.err
}

func (ass *rxAssert[I]) raisedErrorsToBeChecked() (bool, []error) {
func (ass *rxAssert[T]) raisedErrorsToBeChecked() (bool, []error) {
return ass.checkHasRaisedErrors, ass.errs
}

func (ass *rxAssert[I]) raisedAnErrorToBeChecked() (bool, error) {
func (ass *rxAssert[T]) raisedAnErrorToBeChecked() (bool, error) {
return ass.checkHasRaisedAnError, ass.err
}

func (ass *rxAssert[I]) notRaisedErrorToBeChecked() bool {
func (ass *rxAssert[T]) notRaisedErrorToBeChecked() bool {
return ass.checkHasNotRaisedError
}

func (ass *rxAssert[I]) itemToBeChecked() (b bool, i I) {
func (ass *rxAssert[T]) itemToBeChecked() (b bool, i T) {
return ass.checkHasItem, ass.item
}

func (ass *rxAssert[I]) noItemToBeChecked() (b bool, i I) {
func (ass *rxAssert[T]) noItemToBeChecked() (b bool, i T) {
return ass.checkHasNoItem, ass.item
}

func (ass *rxAssert[I]) customPredicatesToBeChecked() (bool, []AssertPredicate[I]) {
func (ass *rxAssert[T]) customPredicatesToBeChecked() (bool, []AssertPredicate[T]) {
return ass.checkHasCustomPredicate, ass.customPredicates
}

func newAssertion[I any](f func(*rxAssert[I])) *rxAssert[I] {
return &rxAssert[I]{
func newAssertion[T any](f func(*rxAssert[T])) *rxAssert[T] {
return &rxAssert[T]{
f: f,
}
}

func parseAssertions[I any](assertions ...RxAssert[I]) RxAssert[I] {
ass := new(rxAssert[I])
func parseAssertions[T any](assertions ...RxAssert[T]) RxAssert[T] {
ass := new(rxAssert[T])

for _, assertion := range assertions {
assertion.apply(ass)
Expand All @@ -111,9 +111,9 @@ func parseAssertions[I any](assertions ...RxAssert[I]) RxAssert[I] {
return ass
}

func Assert[I any](ctx context.Context, iterable Iterable[I], assertions ...RxAssert[I]) {
func Assert[T any](ctx context.Context, iterable Iterable[T], assertions ...RxAssert[T]) {
ass := parseAssertions(assertions...)
got := make([]I, 0)
got := make([]T, 0)
errs := make([]error, 0)
observe := iterable.Observe()

Expand Down Expand Up @@ -211,51 +211,51 @@ loop:
}
}

func HasItems[I any](expectedItems []I) RxAssert[I] {
return newAssertion(func(ra *rxAssert[I]) {
func HasItems[T any](expectedItems []T) RxAssert[T] {
return newAssertion(func(ra *rxAssert[T]) {
ra.checkHasItems = true
ra.items = expectedItems
})
}

// HasItem checks if a single or optional single has a specific item.
func HasItem[I any](i I) RxAssert[I] {
return newAssertion(func(a *rxAssert[I]) {
func HasItem[T any](i T) RxAssert[T] {
return newAssertion(func(a *rxAssert[T]) {
a.checkHasItem = true
a.item = i
})
}

// IsNotEmpty checks that the observable produces some items.
func IsNotEmpty[I any]() RxAssert[I] {
return newAssertion(func(a *rxAssert[I]) {
func IsNotEmpty[T any]() RxAssert[T] {
return newAssertion(func(a *rxAssert[T]) {
a.checkHasSomeItems = true
})
}

// IsEmpty checks that the observable has not produce any item.
func IsEmpty[I any]() RxAssert[I] {
return newAssertion(func(a *rxAssert[I]) {
func IsEmpty[T any]() RxAssert[T] {
return newAssertion(func(a *rxAssert[T]) {
a.checkHasNoItems = true
})
}

func HasError[I any](err error) RxAssert[I] {
return newAssertion(func(a *rxAssert[I]) {
func HasError[T any](err error) RxAssert[T] {
return newAssertion(func(a *rxAssert[T]) {
a.checkHasRaisedError = true
a.err = err
})
}

// HasAnError checks that the observable has produce an error.
func HasAnError[I any]() RxAssert[I] {
return newAssertion(func(a *rxAssert[I]) {
func HasAnError[T any]() RxAssert[T] {
return newAssertion(func(a *rxAssert[T]) {
a.checkHasRaisedAnError = true
})
}

func HasNoError[I any]() RxAssert[I] {
return newAssertion(func(ra *rxAssert[I]) {
func HasNoError[T any]() RxAssert[T] {
return newAssertion(func(ra *rxAssert[T]) {
ra.checkHasNotRaisedError = true
})
}
34 changes: 17 additions & 17 deletions rx/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,37 @@ package rx

// Amb takes several Observables, emit all of the items from only the first of these Observables
// to emit an item or notification.
func Amb[I any](observables []Observable[I], opts ...Option[I]) Observable[I] {
func Amb[T any](observables []Observable[T], opts ...Option[T]) Observable[T] {
_, _ = observables, opts

panic("Amb: NOT-IMPL")
}

// Empty creates an Observable with no item and terminate immediately.
func Empty[I any]() Observable[I] {
next := make(chan Item[I])
func Empty[T any]() Observable[T] {
next := make(chan Item[T])
close(next)

return &ObservableImpl[I]{
return &ObservableImpl[T]{
iterable: newChannelIterable(next),
}
}

// FromChannel creates a cold observable from a channel.
func FromChannel[I any](next <-chan Item[I], opts ...Option[I]) Observable[I] {
func FromChannel[T any](next <-chan Item[T], opts ...Option[T]) Observable[T] {
option := parseOptions(opts...)
ctx := option.buildContext(emptyContext)

return &ObservableImpl[I]{
return &ObservableImpl[T]{
parent: ctx,
iterable: newChannelIterable(next, opts...),
}
}

// Just creates an Observable with the provided items.
func Just[I any](values ...I) func(opts ...Option[I]) Observable[I] {
return func(opts ...Option[I]) Observable[I] {
return &ObservableImpl[I]{
func Just[T any](values ...T) func(opts ...Option[T]) Observable[T] {
return func(opts ...Option[T]) Observable[T] {
return &ObservableImpl[T]{
iterable: newJustIterable(values...)(opts...),
}
}
Expand All @@ -41,28 +41,28 @@ func Just[I any](values ...I) func(opts ...Option[I]) Observable[I] {
// JustSingle is like JustItem in that it is defined for a single item iterable
// but behaves like Just in that it returns a func.
// This is probably not required, just defined for experimental purposes for now.
func JustSingle[I any](value I, opts ...Option[I]) func(opts ...Option[I]) Single[I] {
return func(_ ...Option[I]) Single[I] {
return &SingleImpl[I]{
func JustSingle[T any](value T, opts ...Option[T]) func(opts ...Option[T]) Single[T] {
return func(_ ...Option[T]) Single[T] {
return &SingleImpl[T]{
iterable: newJustIterable(value)(opts...),
}
}
}

// JustItem creates a single from one item.
func JustItem[I any](value I, opts ...Option[I]) Single[I] {
func JustItem[T any](value T, opts ...Option[T]) Single[T] {
// Why does this not return a func, but Just does?
//
return &SingleImpl[I]{
return &SingleImpl[T]{
iterable: newJustIterable(value)(opts...),
}
}

// Never creates an Observable that emits no items and does not terminate.
func Never[I any]() Observable[I] {
next := make(chan Item[I])
func Never[T any]() Observable[T] {
next := make(chan Item[T])

return &ObservableImpl[I]{
return &ObservableImpl[T]{
iterable: newChannelIterable(next),
}
}
32 changes: 16 additions & 16 deletions rx/item.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ import (
type (
// Item is a wrapper having either a value or an error.
//
Item[I any] struct {
V I
Item[T any] struct {
V T
E error
}

// TimestampItem attach a timestamp to an item.
//
TimestampItem[I any] struct {
TimestampItem[T any] struct {
Timestamp time.Time
V I
V T
}

// CloseChannelStrategy indicates a strategy on whether to close a channel.
Expand All @@ -32,21 +32,21 @@ const (
)

// Of creates an item from a value.
func Of[I any](v I) Item[I] {
return Item[I]{V: v}
func Of[T any](v T) Item[T] {
return Item[T]{V: v}
}

// Error creates an item from an error.
func Error[I any](err error) Item[I] {
return Item[I]{E: err}
func Error[T any](err error) Item[T] {
return Item[T]{E: err}
}

// SendItems is an utility function that send a list of items and indicate a
// strategy on whether to close the channel once the function completes.
// This method has been derived from the original SendItems.
// (does not support channels or slice)
func SendItems[I any](ctx context.Context,
ch chan<- Item[I], strategy CloseChannelStrategy, items ...Item[I],
func SendItems[T any](ctx context.Context,
ch chan<- Item[T], strategy CloseChannelStrategy, items ...Item[T],
) {
if strategy == CloseChannel {
defer close(ch)
Expand All @@ -55,25 +55,25 @@ func SendItems[I any](ctx context.Context,
sendItems(ctx, ch, items...)
}

func sendItems[I any](ctx context.Context, ch chan<- Item[I], items ...Item[I]) {
func sendItems[T any](ctx context.Context, ch chan<- Item[T], items ...Item[T]) {
for _, item := range items {
item.SendContext(ctx, ch)
}
}

// IsError checks if an item is an error.
func (i Item[I]) IsError() bool {
func (i Item[T]) IsError() bool {
return i.E != nil
}

// SendBlocking sends an item and blocks until it is sent.
func (i Item[I]) SendBlocking(ch chan<- Item[I]) {
func (i Item[T]) SendBlocking(ch chan<- Item[T]) {
ch <- i
}

// SendContext sends an item and blocks until it is sent or a context canceled.
// It returns a boolean to indicate whether the item was sent.
func (i Item[I]) SendContext(ctx context.Context, ch chan<- Item[I]) bool {
func (i Item[T]) SendContext(ctx context.Context, ch chan<- Item[T]) bool {
select {
case <-ctx.Done(): // Context's done channel has the highest priority
return false
Expand All @@ -87,7 +87,7 @@ func (i Item[I]) SendContext(ctx context.Context, ch chan<- Item[I]) bool {
}
}

func (i Item[I]) SendOpContext(ctx context.Context, ch any) bool { // Item[operator[I]]
func (i Item[T]) SendOpContext(ctx context.Context, ch any) bool { // Item[operator[T]]
_ = ctx
_ = ch

Expand All @@ -96,7 +96,7 @@ func (i Item[I]) SendOpContext(ctx context.Context, ch any) bool { // Item[opera

// SendNonBlocking sends an item without blocking.
// It returns a boolean to indicate whether the item was sent.
func (i Item[I]) SendNonBlocking(ch chan<- Item[I]) bool {
func (i Item[T]) SendNonBlocking(ch chan<- Item[T]) bool {
select {
default:
return false
Expand Down
Loading

0 comments on commit f008dc2

Please sign in to comment.