|
1 | 1 | # Fungi
|
2 | 2 |
|
| 3 | +[](https://pkg.go.dev/github.com/getkalido/[email protected]) |
| 4 | + |
3 | 5 | **Fungi** provides a great suite of functional stream processing primitives that
|
4 |
| -can be used for a wide range of purposes. |
| 6 | +can be used for a wide range of purposes. Use this library to describe your |
| 7 | +intent declaratively and produce elegant code that is easy to read and refactor. |
| 8 | + |
| 9 | +## Beta Testing |
| 10 | + |
| 11 | +Please import our latest stable beta version: |
| 12 | + |
| 13 | +```bash |
| 14 | +go get github.com/getkalido/ [email protected] |
| 15 | +``` |
| 16 | + |
| 17 | +## Spread The Spores |
| 18 | + |
| 19 | +Very soon `fungi` will start popping up all over your codebase! And that is a |
| 20 | +good thing. Here are some things it can help you with: |
| 21 | + |
| 22 | +1. [`Filter`][filter] out irrelevant items using a custom validation function. |
| 23 | +2. Apply custom transformations to stream items ([`Map`][map]). |
| 24 | +3. Select a [`Range`][range] of items you're interested in. |
| 25 | +4. [`Sort`][sort] items with a generic comparator. |
| 26 | +5. [`Page`][page] items efficiently based on page number and size. |
| 27 | +6. [`Loop`][loop] through every item (see also [`ForEach`][for_each]). |
| 28 | +7. Collect items into a Go builtin `slice` or `map` |
| 29 | + ([`CollectSlice`][slice] & [`CollectMap`][hmap]). |
| 30 | + |
| 31 | +[filter]: ./filter.go |
| 32 | +[map]: ./map.go |
| 33 | +[range]: ./range.go |
| 34 | +[sort]: ./sort.go |
| 35 | +[page]: ./page.go |
| 36 | +[loop]: ./loop.go |
| 37 | +[for_each]: ./for_each.go |
| 38 | +[slice]: ./slice.go |
| 39 | +[hmap]: ./hmap.go |
| 40 | + |
| 41 | +## Don't Sweat |
| 42 | + |
| 43 | +Fungi is very well-tested with a consistent test coverage of **over 95%**. |
| 44 | +See for yourself: |
| 45 | + |
| 46 | +```bash |
| 47 | +git clone [email protected]:getkalido/fungi.git |
| 48 | +cd fungi |
| 49 | +go test -cover |
| 50 | +``` |
| 51 | + |
| 52 | +``` |
| 53 | +[8th of August 2022 checked out at v1.0.0-beta] |
| 54 | +PASS |
| 55 | +coverage: 97.4% of statements |
| 56 | +ok github.com/getkalido/fungi 0.286s |
| 57 | +``` |
| 58 | + |
| 59 | +Moreover, our tests can and _should_ be used as examples: they are written with |
| 60 | +clarity and readability in mind. |
| 61 | + |
| 62 | +> Test files have the `_test.go` suffix. Browse through, don't be shy! |
| 63 | +
|
| 64 | +## Make It Stream |
| 65 | + |
| 66 | +Written with generics, `fungi` gives you the flexibility to apply it to any |
| 67 | +iterator that implements the very simple [`fungi.Stream`](stream.go) interface. |
| 68 | + |
| 69 | +Suppose you already have multiple iterable `type`s that fetch elements using a |
| 70 | +method called `Recv`. Here's how you can write a converter function to make them |
| 71 | +all comply with the [`fungi.Stream`](stream.go) interface: |
| 72 | + |
| 73 | +```go |
| 74 | +// Every one of your iterable receivers follows this generic interface. |
| 75 | +type Receiver[T any] interface { |
| 76 | + Recv() (T, error) |
| 77 | +} |
| 78 | + |
| 79 | +// receiverStream implements fungi.Stream interface. |
| 80 | +type receiverStream[T any] struct { |
| 81 | + Receiver[T] |
| 82 | +} |
| 83 | + |
| 84 | +// Next wraps Recv method of the origincal Receiver. |
| 85 | +func (rs receiverStream[T]) Next() (T, error) { |
| 86 | + return rs.Recv() |
| 87 | +} |
| 88 | + |
| 89 | +// ReceiverStream converts any Receiver into a fungi.Stream. |
| 90 | +func ReceiverStream[T any](r Receiver[T]) fungi.Stream[T] { |
| 91 | + return receiverStream[T]{r} |
| 92 | +} |
| 93 | +``` |
| 94 | + |
| 95 | +## Declare Elegance |
| 96 | + |
| 97 | +Here's how your code is going to look soon: |
5 | 98 |
|
6 |
| -Written with generics, it gives you the flexibility to apply it to any iterator |
7 |
| -that implements the very simple [`fungi.Stream`](stream.go) interface. |
| 99 | +```go |
| 100 | +func GetNamesOfMyDrinkingBuddies() ([]string, error) { |
| 101 | + users := ReceiverStream[*User](GetMyFriends()) |
| 102 | + over18 := fungi.FilterMap(func(u *User) (name string, isLegal bool) { |
| 103 | + return u.Name, u.Age >= 18 |
| 104 | + }) |
| 105 | + sortAlphabetically := fungi.Sort(func(a, b string) bool { return a < b }) |
| 106 | + return fungi.CollectSlice(sortAlphabetically(over18(users))) |
| 107 | +} |
| 108 | +``` |
0 commit comments