87 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			87 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
[](https://goreportcard.com/report/github.com/go-toolsmith/astcast)
 | 
						|
[](https://godoc.org/github.com/go-toolsmith/astcast)
 | 
						|
 | 
						|
# astcast
 | 
						|
 | 
						|
Package astcast wraps type assertion operations in such way that you don't have
 | 
						|
to worry about nil pointer results anymore.
 | 
						|
 | 
						|
## Installation
 | 
						|
 | 
						|
```bash
 | 
						|
go get -v github.com/go-toolsmith/astcast
 | 
						|
```
 | 
						|
 | 
						|
## Example
 | 
						|
 | 
						|
```go
 | 
						|
package main
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
 | 
						|
	"github.com/go-toolsmith/astcast"
 | 
						|
	"github.com/go-toolsmith/strparse"
 | 
						|
)
 | 
						|
 | 
						|
func main() {
 | 
						|
	x := strparse.Expr(`(foo * bar) + 1`)
 | 
						|
 | 
						|
	// x type is ast.Expr, we want to access bar operand
 | 
						|
	// that is a RHS of the LHS of the addition.
 | 
						|
	// Note that addition LHS (X field) is has parenthesis,
 | 
						|
	// so we have to remove them too.
 | 
						|
 | 
						|
	add := astcast.ToBinaryExpr(x)
 | 
						|
	mul := astcast.ToBinaryExpr(astcast.ToParenExpr(add.X).X)
 | 
						|
	bar := astcast.ToIdent(mul.Y)
 | 
						|
	fmt.Printf("%T %s\n", bar, bar.Name) // => *ast.Ident bar
 | 
						|
 | 
						|
	// If argument has different dynamic type,
 | 
						|
	// non-nil sentinel object of requested type is returned.
 | 
						|
	// Those sentinel objects are exported so if you need
 | 
						|
	// to know whether it was a nil interface value of
 | 
						|
	// failed type assertion, you can compare returned
 | 
						|
	// object with such a sentinel.
 | 
						|
 | 
						|
	y := astcast.ToCallExpr(strparse.Expr(`x`))
 | 
						|
	if y == astcast.NilCallExpr {
 | 
						|
		fmt.Println("it is a sentinel, type assertion failed")
 | 
						|
	}
 | 
						|
}
 | 
						|
```
 | 
						|
 | 
						|
Without `astcast`, you would have to do a lots of type assertions:
 | 
						|
 | 
						|
```go
 | 
						|
package main
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
 | 
						|
	"github.com/go-toolsmith/strparse"
 | 
						|
)
 | 
						|
 | 
						|
func main() {
 | 
						|
	x := strparse.Expr(`(foo * bar) + 1`)
 | 
						|
 | 
						|
	add, ok := x.(*ast.BinaryExpr)
 | 
						|
	if !ok || add == nil {
 | 
						|
		return
 | 
						|
	}
 | 
						|
	additionLHS, ok := add.X.(*ast.ParenExpr)
 | 
						|
	if !ok || additionLHS == nil {
 | 
						|
		return
 | 
						|
	}
 | 
						|
	mul, ok := additionLHS.X.(*ast.BinaryExpr)
 | 
						|
	if !ok || mul == nil {
 | 
						|
		return
 | 
						|
	}
 | 
						|
	bar, ok := mul.Y.(*ast.Ident)
 | 
						|
	if !ok || bar == nil {
 | 
						|
		return
 | 
						|
	}
 | 
						|
	fmt.Printf("%T %s\n", bar, bar.Name)
 | 
						|
}
 | 
						|
```
 |