Skip to content
/ fungi Public

Functional stream processing primitives for Go

License

Notifications You must be signed in to change notification settings

sharpvik/fungi

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

47 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Fungi

Go Reference

Fungi provides a great suite of functional stream processing primitives that can be used for a wide range of purposes. Use this library to describe your intent declaratively and produce elegant code that is easy to read and refactor.

Import

go get github.com/sharpvik/fungi@latest

Spread The Spores

Very soon fungi will start popping up all over your codebase! And that is a good thing. Here are some things it can help you with:

  1. Filter out irrelevant items using a custom validation function.
  2. Apply custom transformations to stream items (Map, TryMap).
  3. Select a Range of items you're interested in.
  4. Sort items with a generic comparator.
  5. Page items efficiently based on page number and size.
  6. Loop through every item (see also ForEach).
  7. Collect items into a Go builtin slice or map (CollectSlice, CollectMap).
  8. Find an item that fits a description.

Don't Sweat

Fungi is very well-tested with a consistent test coverage of over 95%. See for yourself:

git clone git@github.com:sharpvik/fungi.git
cd fungi
go test -cover
[6th of December 2022 checked out at v1.1.0]
PASS
coverage: 98.1% of statements
ok      github.com/sharpvik/fungi       0.193s

Moreover, our tests can and should be used as examples: they are written with clarity and readability in mind.

Test files have the _test.go suffix. Browse through, don't be shy!

Make It Stream

Written with generics, fungi gives you the flexibility to apply it to any iterator that implements the very simple fungi.Stream interface.

Suppose you already have multiple iterable types that fetch elements using a method called Recv. Here's how you can write a converter function to make them all comply with the fungi.Stream interface:

// Every one of your iterable receivers follows this generic interface.
type Receiver[T any] interface {
	Recv() (T, error)
}

// receiverStream implements fungi.Stream interface.
type receiverStream[T any] struct {
	Receiver[T]
}

// Next wraps Recv method of the origincal Receiver.
func (rs receiverStream[T]) Next() (T, error) {
	return rs.Recv()
}

// ReceiverStream converts any Receiver into a fungi.Stream.
func ReceiverStream[T any](r Receiver[T]) fungi.Stream[T] {
	return receiverStream[T]{r}
}

Declare Elegance

Here's how your code is going to look soon:

func GetNamesOfMyDrinkingBuddies() ([]string, error) {
    users := ReceiverStream[*User](GetMyFriends())
    over18 := fungi.FilterMap(func(u *User) (name string, isLegal bool) {
        return u.Name, u.Age >= 18
    })
    sortAlphabetically := fungi.Sort(func(a, b string) bool { return a < b })
    return fungi.CollectSlice(sortAlphabetically(over18(users)))
}