https://github.com/pmorelli92/maybe
Maybe is a Go package to bring functional in Option type structures.
https://github.com/pmorelli92/maybe
functional golang option
Last synced: 5 months ago
JSON representation
Maybe is a Go package to bring functional in Option type structures.
- Host: GitHub
- URL: https://github.com/pmorelli92/maybe
- Owner: pmorelli92
- License: mit
- Created: 2021-04-27T19:55:42.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2022-03-23T13:55:41.000Z (over 3 years ago)
- Last Synced: 2025-02-26T03:41:25.567Z (7 months ago)
- Topics: functional, golang, option
- Language: Go
- Homepage:
- Size: 34.2 KB
- Stars: 9
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
## Maybe
[](https://goreportcard.com/report/github.com/pmorelli92/maybe)
[](https://github.com/pmorelli92/maybe/actions/workflows/ci.yml)
[](https://coveralls.io/github/pmorelli92/maybe?branch=main)Maybe is a library that adds an [Option data type](https://en.wikipedia.org/wiki/Option_type) for Golang. [Related blogpost here.](https://devandchill.com/posts/2021/04/introducing-maybe-package-bring-functional-to-go/)
### What does it offer:
The `Maybe[any]` type exported by this library is immutable and thread safe. The json serialization and de-serialization works in the same way as with the underlying (any) type. Using this library will free you up from using pointers and possible panics.
It also gets rid of the situations where an absence of value means something different from a default (zero) value. For example: a person with salary 100 means he/she has a paid job, 0 means an unpaid internship and null means unemployed. Supporting yourself with `Maybe[int]` eliminates the usage of null replacing it with `HasValue`:
- `salary.Value != 0` has a paid job.
- `salary.Value == 0 && salary.HasValue` has an unpaid internship.
- `salary.HasValue` does not have a job, this is serialized as `null` but you don't have to care about pointers.### When should I use it:
It can be used for transport layer (as it has json capabilities) but it could also be used on the domain layer.
### Examples:
**Marshal of Maybe[string] without value**
```go
package mainimport (
"encoding/json"
"fmt""github.com/pmorelli92/maybe"
)type Person struct {
Name maybe.Maybe[string] `json:"name"`
Age int `json:"age"`
}func main() {
p := Person{Age: 28}
bytes, _ := json.Marshal(p)
fmt.Println(string(bytes)) // {"name":null,"age":28}
}
```**Marshal of Maybe[string] with value**
```go
package mainimport (
"encoding/json"
"fmt""github.com/pmorelli92/maybe"
)type Person struct {
Name maybe.Maybe[string] `json:"name"`
Age int `json:"age"`
}func main() {
p := Person{Age: 28, Name: maybe.Set("Pablo")}
bytes, _ := json.Marshal(p)
fmt.Println(string(bytes)) // {"name":"Pablo","age":28}
}
```**Unmarshal of Maybe[string] without value**
```go
package mainimport (
"encoding/json"
"fmt""github.com/pmorelli92/maybe"
)type Person struct {
Name maybe.Maybe[string] `json:"name"`
Age int `json:"age"`
}func main() {
var p Person
_ = json.Unmarshal([]byte(`{"age":28}`), &p)
fmt.Println(p.Name.HasValue()) // false
}
```**Unmarshal of Maybe[string] with value**
```go
package mainimport (
"encoding/json"
"fmt""github.com/pmorelli92/maybe"
)type Person struct {
Name maybe.Maybe[string] `json:"name"`
Age int `json:"age"`
}func main() {
var p Person
_ = json.Unmarshal([]byte(`{"age":28, "name": "Pablo"}`), &p)
fmt.Println(p.Name.HasValue()) // true
fmt.Println(p.Name.Value()) // Pablo
}
```### Types supported:
`Maybe` is defined to support `[T any]` so it can support all underlying types. Personally I would not suggest using pointers as the underlying type as it will defeat the whole purpose.