Skip to content

chris-tomich/adtenum

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ADT Enumerations for Go

License

This project provides Rust-style enumerations, also known as algebraic data types (ADTs), for Go. It aims to provide the power and flexibility of pattern matching with enum types to Go. At the moment, to use the types and functions in this library to create enums, some boiler plate code is required but there is a plan to create a go generate utility to help reduce manual creation of that boiler plate code.

Example

Using adtenum package, you're able to create enumerations that contain tuples which can then be used in a type switch as in the following example.

func inspect(event WebEvent) string {
	// We can now perform a type switch on the WebEvent type to determine which enum value we have.
	// We can then extract the value from the enum value similar to what could be done in Rust.
	switch vals := event.(type) {
	case PageLoad:
		return fmt.Sprint(vals())
	case PageUnload:
		return fmt.Sprint(vals())
	case KeyPress:
		return fmt.Sprintf("%c", vals())
	case Paste:
		return fmt.Sprint(vals())
	case Click:
		return fmt.Sprint(vals())
	default:
		return "Unknown"
	}
}

For a more thorough example look at enum_test.go which contains a Go port of the WebEvent example written to explain Rust enumerations in Rust By Example.

Quick Start

First import the package using go get.

go get github.com/chris-tomich/adtenum

Declare the new enumeration type using the adtenum.Enum as the underlying type. In the following example we create a new WebEvent enumeration type which we also pass as the first type parameter to adtenum.Enum

type WebEvent adtenum.Enum[WebEvent]

Once you have your enumeration type, you can begin creating the values for the enumeration. All enumeration values use one of the adtenum Value types as their underlying type. In the following example we create a constant value which will always have the value PageLoad.

type PageLoad adtenum.ConstValue[string]

In this next example, we create an enumeration value called Click that contains two integers.

type Click adtenum.TwoVariantValue[int, int]

Once we've added our values, we now need to create constructors for creating new instances of our enumeration values. In the future, a go generate utility is planned to help with creation of this boiler plate. For our constant value, we need to provide the constant value that will be used for every value of the enumeration value to the CreateConstValueConstructor.

var NewPageLoad func() PageLoad = adtenum.CreateConstValueConstructor[PageLoad]("PageLoad")

For our enumeration value Click we create our constructor using CreateTwoVariantValueConstructor as in the example below.

var NewClick func(int, int) Click = adtenum.CreateTwoVariantValueConstructor[Click]()

Once we've created constructors to create new enumeration values for us, we need to complete the last piece which makes our enumeration value types legitimate values of our enumeration type WebEvent. The following code is effectively implementing the interface of our WebEvent enumeration type.

func (val PageLoad) EnumType() WebEvent {
	return val
}

func (val Click) EnumType() WebEvent {
	return val
}

Once this is completed, we can now use the enumeration type and it's values. We also now have similar pattern matching capabilities as found with Rust enumerations. In the following example, we can use a Go type switch to elicit the enumeration value type into a variable vals and then get the values for that tuple.

func inspect(event WebEvent) string {
	switch vals := event.(type) {
	case PageLoad:
		return fmt.Sprint(vals())
	case Click:
        x, y := vals()
		return fmt.Sprint(x, y)
	default:
		return "Unknown"
	}
}

func main() {
    load := NewPageLoad()
    click := NewClick(20, 80)

    // writes 'PageLoad' to output
    fmt.Println(inspect(load))

    // writes '20 80' to output
    fmt.Println(inspect(click))
}

About

A Rust style enums implementation for Go.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages