Help us shape the future of Go! Take the 2026 Go Developer Survey

shoot

package module
v0.8.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 1, 2026 License: MIT Imports: 7 Imported by: 0

README

GAP Logo

shoot

Language

A pack of tools for "go generate".

How to use?

Usage: shoot <subcommand> [options]
These are all the sub commands supported as of now:
new [-opt] [-getset] [-json] [-exp] [-tagcase=<case>] [-type=<Type> | -file=<GoFile>] [dir] [-s] [-v]
enum [-bit] [-json] [-text] -[sql] [-type=<Type> | -file=<GoFile>] [dir] [-v]
rest [-type=<Type> | -file=<GoFile>] [dir] [-v]
map [-path=<path>] [-alias=<alias>] [-to=<DestType>] [-type=<SrcType> | -file=<GoFile>] [dir] [-s] [-v]

using go1.24+ (SUGGESTED)

why 1.24

Tool dependencies

install
go get -tool github.com/loopopen/shoot/cmd/shoot@latest
generate instruction examples
//go:generate go tool shoot new -getset -json -type=YourType

//go:generate go tool shoot new -getset -json -file=$GOFILE

//go:generate go tool shoot enum -json -type=YourEnum

//go:generate go tool shoot rest -type=YourClient

//go:generate go tool shoot map -path=../destpath -type=YourSrcType
go generate			# run in the current directory
go generate ./...	# recursively run in the current directory and its subdirectories

generated file example 1:

// Code generated by "shoot new -getset -type=User"; DO NOT EDIT.

package example

// NewUser constructs a new instance of type User
func NewUser(id int, name string, age int) *User {
	return &User{
		id:   id,
		name: name,
		age:  age,
	}
}

// Id gets the value of field id
func (u *User) Id() int {
	return u.id
}

// Name gets the value of field name
func (u *User) Name() string {
	return u.name
}

// Age gets the value of field age
func (u *User) Age() int {
	return u.age
}

// SetId sets the value of field id
func (u *User) SetId(id_ int) {
	u.id = id_
}

// SetName sets the value of field name
func (u *User) SetName(name_ string) {
	u.name = name_
}

// SetAge sets the value of field age
func (u *User) SetAge(age_ int) {
	u.age = age_
}

generated file example 2:

// Code generated by "shoot rest -type=Client"; DO NOT EDIT.

package example

import (
	"context"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strings"
	"time"

	"github.com/loopopen/shoot"
)

type client struct {
	client *http.Client
	conf   *shoot.RestConf
}

func (c *client) GetUser(ctx context.Context, userID string, pageSize int, pageIdx *int) (*User, *http.Response, error) {
	path_ := "/users/{id}"
	path_ = strings.Replace(path_, "{id}", fmt.Sprintf("%v", userID), 1)

	url_, err := url.JoinPath(c.conf.BaseURL(), path_)
	if err != nil {
		return nil, nil, err
	}

	req_, err := http.NewRequestWithContext(ctx, "GET", url_, nil)
	if err != nil {
		return nil, nil, err
	}

	query_ := req_.URL.Query()
	query_.Set("size", fmt.Sprintf("%v", pageSize))
	if pageIdx != nil {
		query_.Set("page_idx", fmt.Sprintf("%v", *pageIdx))
	}
	req_.URL.RawQuery = query_.Encode()

	req_.Header.Add("Accept", "application/json")
	req_.Header.Add("Tenant-Id", "123")

	resp_, err := c.client.Do(req_)
	if err != nil {
		return nil, nil, err
	}
	defer resp_.Body.Close()

	switch {
	case resp_.StatusCode >= 500:
		body_, _ := io.ReadAll(resp_.Body)
		err = fmt.Errorf("server error %d: %s", resp_.StatusCode, string(body_))
	case resp_.StatusCode >= 400:
		body_, _ := io.ReadAll(resp_.Body)
		err = fmt.Errorf("client error %d: %s", resp_.StatusCode, string(body_))
	case resp_.StatusCode >= 300 || resp_.StatusCode < 200:
		err = fmt.Errorf("not supported error %d", resp_.StatusCode)
	}
	if err != nil {
		return nil, resp_, err
	}

	var r_ User
	err = json.NewDecoder(resp_.Body).Decode(&r_)
	if err == io.EOF {
		err = nil //ignore EOF errors caused by empty response body
	}
	if err != nil {
		return nil, resp_, err
	}
	return &r_, resp_, nil
}

generated file example 3:

// Code generated by "shoot map -path=../../domain/model -alias=domain -type=*"; DO NOT EDIT.

package dto

import domain "mapperexample/domain/model"

// ToDomain converts receiver to type domain.Order
func (o *Order) ToDomain() *domain.Order {
	if o == nil {
		return nil
	}
	order_ := new(domain.Order)
	order_.ID = o.ID
	order_.Amount = o.StringToDecimal(o.Amount)
	order_.Status = o.Status
	order_.OrderTime = o.StringToTime(o.OrderingTime)
	if o.Address != nil {
		order_.Address = *o.Address.ToDomain()
	}
	o.writeDomain(order_)
	return order_
}

// FromDomain reads from type domain.Order, then writes back to receiver and returns it
func (o *Order) FromDomain(order_ *domain.Order) *Order {
	if order_ == nil {
		return nil
	}
	if o == nil {
		o = new(Order)
	}
	o.ID = order_.ID
	o.Amount = o.DecimalToString(order_.Amount)
	o.Status = order_.Status
	o.OrderingTime = o.TimeToString(order_.OrderTime)
	o.Address = new(OrderAddress).FromDomain(&order_.Address)
	o.readDomain(order_)
	return o
}

more examples:

Inspiring projects

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsEnum

func IsEnum[T constraints.EnumShooter[T], TV constraints.Integer](value TV) bool

IsEnum checks whether a given integer value is a valid enum value of type T. Useful for validating raw input before casting or using it as an enum.

func NewRest

func NewRest[T RestClient[T]](opts ...Option[RestConf, *RestConf]) T

NewRest creates a new instance of type T that implements the RestClient interface.

func NewWith

func NewWith[T any, PT constraints.NewShooter[T]](opts ...Option[T, PT]) *T

NewWith creates a new instance of type T using the functional options pattern. It first initializes the instance with default values via SetDefault, then applies each provided Option in order. This pattern promotes clean, declarative construction of configurable types.

func ParseEnum

func ParseEnum[T constraints.EnumShooter[T]](str string) (T, error)

ParseEnum attempts to convert a string into its corresponding enum value. It uses the ValueMap() provided by the enum type to look up the value. Returns an error if the string does not match any known enum value.

func Register

func Register[T RestClient[T]](ctor func(RestConf) T)

Register associates a constructor function with a specific RestClient implementation. The constructor must accept a RestConf and return a concrete type that satisfies RestClient.

func TryParseEnum

func TryParseEnum[T constraints.EnumShooter[T]](str string, v *T) bool

TryParseEnum is a safe variant of ParseEnum. It attempts to parse the string into an enum value and stores the result in v. Returns true if successful, false otherwise. Does not return an error.

Types

type Option

type Option[T any, PT constraints.NewShooter[T]] func(*T)

Option defines a functional option for configuring an instance of type T. PT is a pointer type that satisfies DefaultSetter[T], allowing default setup.

func BaseURL

func BaseURL(baseURL_ string) Option[RestConf, *RestConf]

BaseURL is a configuration for the filed baseURL

func DefaultHeaders

func DefaultHeaders(defaultHeaders_ map[string]string) Option[RestConf, *RestConf]

DefaultHeaders is a configuration for the filed defaultHeaders

func EnableLogging

func EnableLogging(enableLogging_ bool) Option[RestConf, *RestConf]

EnableLogging is a configuration for the filed enableLogging

func Timeout

func Timeout(timeout_ string) Option[RestConf, *RestConf]

Timeout is a configuration for the filed timeout

func Use

func Use(middleware middleware.Middleware) Option[RestConf, *RestConf]

Use returns an Option function that applies the given middleware to a RestConf instance.

type Response added in v0.8.1

type Response struct {
	RawResponse *http.Response
	// contains filtered or unexported fields
}

Response wraps the response returned by net/http.

Body contains a cached copy of the response payload. RawResponse.Body has already been consumed and closed by the generated client.

func NewResponse added in v0.8.1

func NewResponse(rawResponse *http.Response, body []byte) *Response

NewResponse constructs a Response for generated clients.

func (*Response) Body added in v0.8.1

func (r *Response) Body() []byte

Body returns the response payload cached by the generated client.

func (*Response) Close added in v0.8.1

func (r *Response) Close() error

Close closes the underlying response body. Generated clients have normally closed it already.

func (*Response) Cookies added in v0.8.1

func (r *Response) Cookies() []*http.Cookie

Cookies returns the cookies included in the response.

func (*Response) Header added in v0.8.1

func (r *Response) Header() http.Header

Header returns the response headers.

func (*Response) IsError added in v0.8.1

func (r *Response) IsError() bool

IsError reports whether the status code is 4xx or 5xx.

func (*Response) IsSuccess added in v0.8.1

func (r *Response) IsSuccess() bool

IsSuccess reports whether the status code is in the 2xx range.

func (*Response) Proto added in v0.8.1

func (r *Response) Proto() string

Proto returns the HTTP protocol used for the response.

func (*Response) RawBody added in v0.8.1

func (r *Response) RawBody() io.ReadCloser

RawBody returns the consumed and closed underlying response body. Use StreamResponse for responses that must be read incrementally.

func (*Response) Size added in v0.8.1

func (r *Response) Size() int64

Size returns the size of the cached response payload.

func (*Response) Status added in v0.8.1

func (r *Response) Status() string

Status returns the HTTP status text, for example "200 OK".

func (*Response) StatusCode added in v0.8.1

func (r *Response) StatusCode() int

StatusCode returns the HTTP status code.

func (*Response) String added in v0.8.1

func (r *Response) String() string

String returns the cached response payload as a trimmed string.

type RestClient

type RestClient[T any] interface {
	ConfigHTTPClient(config func(client *http.Client)) T
	ShootRest()
}

RestClient defines the interface for REST-capable clients.

type RestConf

type RestConf struct {
	// contains filtered or unexported fields
}

RestConf holds configuration parameters for initializing a RestClient.

func NewRestConf

func NewRestConf(baseUrl string, timeout string, enableLogging bool, defaultHeaders map[string]string) *RestConf

NewRestConf constructs a new instance of type RestConf

func (*RestConf) BaseURL

func (r *RestConf) BaseURL() string

BaseURL gets the value of field baseURL

func (*RestConf) BuildMiddleware

func (r *RestConf) BuildMiddleware() http.RoundTripper

BuildMiddleware constructs the middleware chain by wrapping the default HTTP transport.

func (*RestConf) DefaultHeaders

func (r *RestConf) DefaultHeaders() map[string]string

DefaultHeaders gets the value of field defaultHeaders

func (*RestConf) EnableLogging

func (r *RestConf) EnableLogging() bool

EnableLogging gets the value of field enableLogging

func (*RestConf) SetBaseURL

func (r *RestConf) SetBaseURL(baseURL_ string)

SetBaseURL sets the value of field baseURL

func (*RestConf) SetDefaultHeaders

func (r *RestConf) SetDefaultHeaders(defaultHeaders_ map[string]string)

SetDefaultHeaders sets the value of field defaultHeaders

func (*RestConf) SetEnableLogging

func (r *RestConf) SetEnableLogging(enableLogging_ bool)

SetEnableLogging sets the value of field enableLogging

func (*RestConf) SetTimeout

func (r *RestConf) SetTimeout(timeout_ string)

SetTimeout sets the value of field timeout

func (RestConf) ShootNew

func (r RestConf) ShootNew()

ShootNew exists solely to fulfill the NewShooter interface contract

func (*RestConf) Timeout

func (r *RestConf) Timeout() string

Timeout gets the value of field timeout

func (*RestConf) With

func (r *RestConf) With(opts ...Option[RestConf, *RestConf]) *RestConf

With initializes this instance using the functional options pattern

type RestConfGetter

type RestConfGetter interface {
	BaseURL() string
	Timeout() string
	EnableLogging() bool
	DefaultHeaders() map[string]string
}

RestConfGetter is read-only interface for RestConf type

type RestConfSetter

type RestConfSetter interface {
	SetBaseURL(string)
	SetTimeout(string)
	SetEnableLogging(bool)
	SetDefaultHeaders(map[string]string)
}

RestConfSetter is write-only interface for RestConf type

type StreamResponse added in v0.8.1

type StreamResponse struct {
	RawResponse *http.Response
}

StreamResponse wraps an HTTP response whose body has not been consumed. The caller must close it after reading, including when the request returns a non-nil error together with a StreamResponse.

func NewStreamResponse added in v0.8.1

func NewStreamResponse(rawResponse *http.Response) *StreamResponse

NewStreamResponse constructs a StreamResponse for generated clients.

func (*StreamResponse) Body added in v0.8.1

func (r *StreamResponse) Body() io.ReadCloser

Body returns the underlying response stream. The caller must close it.

func (*StreamResponse) Close added in v0.8.1

func (r *StreamResponse) Close() error

Close closes the underlying response stream.

func (*StreamResponse) Cookies added in v0.8.1

func (r *StreamResponse) Cookies() []*http.Cookie

Cookies returns the cookies included in the response.

func (*StreamResponse) Header added in v0.8.1

func (r *StreamResponse) Header() http.Header

Header returns the response headers.

func (*StreamResponse) IsError added in v0.8.1

func (r *StreamResponse) IsError() bool

IsError reports whether the status code is 4xx or 5xx.

func (*StreamResponse) IsSuccess added in v0.8.1

func (r *StreamResponse) IsSuccess() bool

IsSuccess reports whether the status code is in the 2xx range.

func (*StreamResponse) Proto added in v0.8.1

func (r *StreamResponse) Proto() string

Proto returns the HTTP protocol used for the response.

func (*StreamResponse) Status added in v0.8.1

func (r *StreamResponse) Status() string

Status returns the HTTP status text, for example "200 OK".

func (*StreamResponse) StatusCode added in v0.8.1

func (r *StreamResponse) StatusCode() int

StatusCode returns the HTTP status code.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL