Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,11 @@ coveralls-deps:
@echo "Installing coveralls"
@go get github.com/mattn/goveralls
@go install github.com/mattn/goveralls

.PHONY: godoc_run
godoc_run:
godoc -http=:6060

.PHONY: godoc_open
godoc_open:
xdg-open http://localhost:6060/pkg/$(shell go list -f "{{.ImportPath}}")
169 changes: 153 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,121 @@

# go-option: library to work with optional types

## Pre-generated basic optional types
Package `option` implements effective and useful instruments to work
with optional types in Go. It eliminates code doubling and provides
high performance due to:
- no memory allocations
- serialization without reflection (at least for pre-generated types)
- support for basic and custom types

## Table of contents

* [Installation](#installation)
* [Documentation](#documentation)
* [Quick start](#quick-start)
* [Using pre-generated optional types](#using-pre-generated-optional-types)
* [Usage with go-tarantool](#usage-with-go-tarantool)
* [Gentype Utility](#gentype-utility)
* [Overview](#overview)
* [Features](#features)
* [Gentype installation](#gentype-installation)
* [Generating Optional Types](#generating-optional-types)
* [Using Generated Types](#using-generated-types)
* [Development](#development)
* [Run tests](#run-tests)
* [License](#license)

## Installation

```shell
go install github.com/tarantool/go-option@latest
```

## Documentation

You could run the `godoc` server on `localhost:6060` with the command:

```shell
make godoc_run
```

And open the generated documentation in another terminal or use the
[link][godoc-url]:

```shell
make godoc_open
```

## Quick start

### Using pre-generated optional types

Generated types follow the pattern Optional<TypeName> and provide methods for working
with optional values:

```go
// Create an optional with a value.
opt := SomeOptionalString("hello")

// Check if a value is present.
if opt.IsSome() {
value := opt.Unwrap()
fmt.Println(value)
}

// Use a default value if none.
value := opt.UnwrapOr("default")

// Encode to MessagePack.
err := opt.EncodeMsgpack(encoder)
```

### Usage with go-tarantool

It may be necessary to use an optional type in a structure. For example,
to distinguish between a nil value and a missing one.

```Go
package main

import (
"github.com/tarantool/go-option"
tarantool "github.com/tarantool/go-tarantool/v2"
)

type User struct {
// may be used in conjunciton with 'msgpack:",omitempty"' directive to skip fields
_msgpack struct{} `msgpack:",asArray"` //nolint: structcheck,unused
Name string
Phone option.String
}

func main() {
var conn *tarantool.Doer
// Initialize tarantool connection

// Imagine you get a slice of users from Tarantool.
users := []User{
{
Name: "Nosipho Nnenne",
Phone: option.SomeString("+15056463408"),
},
{
Name: "Maryamu Efe",
Phone: option.NoneString(),
},
{
Name: "Venera Okafor",
},
}

for id, user := range users {
conn.Do(
tarantool.NewInsertRequest("users").Tuple(user),
)
}
}
```

## Gentype Utility

Expand All @@ -21,7 +135,7 @@ serialization support.

Gentype generates wrapper types for various Go primitives and
custom types that implement optional (some/none) semantics with
full MessagePack serialization capabilities. These generated types
full MessagePack serialization capabilities. These generated types
are useful for representing values that may or may not be present,
while ensuring proper encoding and decoding when using MessagePack.

Expand All @@ -30,24 +144,22 @@ while ensuring proper encoding and decoding when using MessagePack.
- Generates optional types for built-in types (bool, int, float, string, etc.)
- Supports custom types with MessagePack extension serialization
- Provides common optional type operations:
- `SomeXxx(value)` - Create an optional with a value
- `NoneXxx()` - Create an empty optional
- `Unwrap()`, `UnwrapOr()`, `UnwrapOrElse()` - Value extraction
- `IsSome()`, `IsNone()` - Presence checking
- `SomeXxx(value)` - Create an optional with a value
- `NoneXxx()` - Create an empty optional
- `Unwrap()`, `UnwrapOr()`, `UnwrapOrElse()` - Value extraction
- `IsSome()`, `IsNone()` - Presence checking
- Full MessagePack `CustomEncoder` and `CustomDecoder` implementation
- Type-safe operations

### Installation
### Gentype installation

```bash
go install github.com/tarantool/go-option/cmd/gentypes@latest
# OR (for go version 1.24+)
go get -tool github.com/tarantool/go-option/cmd/gentypes@latest
```

### Usage

#### Generating Optional Types
### Generating Optional Types

To generate optional types for existing types in a package:

Expand All @@ -66,12 +178,12 @@ Or you can use it to generate file from go:

Flags:

• `-package`: Path to the Go package containing types to wrap (default: `"."`)
• `-ext-code`: MessagePack extension code to use for custom types (must be between
-128 and 127, no default value)
• `-verbose`: Enable verbose output (default: `false`)
• `-package`: Path to the Go package containing types to wrap (default: `"."`)
• `-ext-code`: MessagePack extension code to use for custom types (must be between
-128 and 127, no default value)
• `-verbose`: Enable verbose output (default: `false`)

#### Using Generated Types
### Using Generated Types

Generated types follow the pattern Optional<TypeName> and provide methods for working
with optional values:
Expand All @@ -93,6 +205,31 @@ value := opt.UnwrapOr("default")
err := opt.EncodeMsgpack(encoder)
```

## Development

You could use our Makefile targets:

```shell
make codespell
make test
make testrace
make coveralls-deps
make coveralls
make coverage
```

### Run tests

To run default set of tests directly:

```shell
go test ./... -count=1
```

## License

BSD 2-Clause License

[godoc-badge]: https://pkg.go.dev/badge/github.com/tarantool/go-option.svg
[godoc-url]: https://pkg.go.dev/github.com/tarantool/go-option
[actions-badge]: https://github.com/tarantool/go-option/actions/workflows/testing.yaml/badge.svg
Expand All @@ -101,4 +238,4 @@ err := opt.EncodeMsgpack(encoder)
[coverage-url]: https://coveralls.io/github/tarantool/go-option?branch=master
[telegram-badge]: https://img.shields.io/badge/Telegram-join%20chat-blue.svg
[telegram-en-url]: http://telegram.me/tarantool
[telegram-ru-url]: http://telegram.me/tarantoolru
[telegram-ru-url]: http://telegram.me/tarantoolru
6 changes: 3 additions & 3 deletions doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// A Generic[T] can either contain a value of type T (Some) or be empty (None).
//
// This is useful for:
// - Clearly representing nullable fields in structs.
// - Avoiding nil pointer dereferences.
// - Providing explicit intent about optional values.
// - Clearly representing nullable fields in structs.
// - Avoiding nil pointer dereferences.
// - Providing explicit intent about optional values.
package option