func (s *SearchService) search(ctx context.Context, searchType string, parameters *searchParameters, opt *SearchOptions, result interface{}) (*Response, error) {
	params, err := qs.Values(opt)
	if err != nil {
		return nil, err
	}
	params.Set("q", parameters.Query)
	if parameters.RepositoryID != nil {
		params.Set("repository_id", strconv.FormatInt(*parameters.RepositoryID, 10))
	}
	u := fmt.Sprintf("search/%s?%s", searchType, params.Encode())
	req, err := s.client.NewRequest("GET", u, nil)
	if err != nil {
		return nil, err
	}
	switch {
	case searchType == "commits":
		req.Header.Set("Accept", mediaTypeCommitSearchPreview)
	case searchType == "repositories":
		req.Header.Set("Accept", mediaTypeTopicsPreview)
	case searchType == "labels":
		req.Header.Set("Accept", mediaTypeLabelDescriptionSearchPreview)
	case opt != nil && opt.TextMatch:
		req.Header.Set("Accept", "application/vnd.github.v3.text-match+json")
	}
	return s.client.Do(ctx, req, result)
}
Helper function that executes search queries against different
GitHub search types (repositories, commits, code, issues, users, labels)
package github
import (
	"context"
	"fmt"
	"strconv"
	qs "github.com/google/go-querystring/query"
)
type SearchService service
type SearchOptions struct {
	Sort string `url:"sort,omitempty"`
	Order string `url:"order,omitempty"`
	TextMatch bool `url:"-"`
	ListOptions
}
type searchParameters struct {
	Query        string
	RepositoryID *int64  
}
type RepositoriesSearchResult struct {
	Total             *int         `json:"total_count,omitempty"`
	IncompleteResults *bool        `json:"incomplete_results,omitempty"`
	Repositories      []Repository `json:"items,omitempty"`
}
func (s *SearchService) Repositories(ctx context.Context, query string, opt *SearchOptions) (*RepositoriesSearchResult, *Response, error) {
	result := new(RepositoriesSearchResult)
	resp, err := s.search(ctx, "repositories", &searchParameters{Query: query}, opt, result)
	return result, resp, err
}
type CommitsSearchResult struct {
	Total             *int            `json:"total_count,omitempty"`
	IncompleteResults *bool           `json:"incomplete_results,omitempty"`
	Commits           []*CommitResult `json:"items,omitempty"`
}
type CommitResult struct {
	SHA         *string   `json:"sha,omitempty"`
	Commit      *Commit   `json:"commit,omitempty"`
	Author      *User     `json:"author,omitempty"`
	Committer   *User     `json:"committer,omitempty"`
	Parents     []*Commit `json:"parents,omitempty"`
	HTMLURL     *string   `json:"html_url,omitempty"`
	URL         *string   `json:"url,omitempty"`
	CommentsURL *string   `json:"comments_url,omitempty"`
	Repository *Repository `json:"repository,omitempty"`
	Score      *float64    `json:"score,omitempty"`
}
func (s *SearchService) Commits(ctx context.Context, query string, opt *SearchOptions) (*CommitsSearchResult, *Response, error) {
	result := new(CommitsSearchResult)
	resp, err := s.search(ctx, "commits", &searchParameters{Query: query}, opt, result)
	return result, resp, err
}
type IssuesSearchResult struct {
	Total             *int    `json:"total_count,omitempty"`
	IncompleteResults *bool   `json:"incomplete_results,omitempty"`
	Issues            []Issue `json:"items,omitempty"`
}
func (s *SearchService) Issues(ctx context.Context, query string, opt *SearchOptions) (*IssuesSearchResult, *Response, error) {
	result := new(IssuesSearchResult)
	resp, err := s.search(ctx, "issues", &searchParameters{Query: query}, opt, result)
	return result, resp, err
}
type UsersSearchResult struct {
	Total             *int   `json:"total_count,omitempty"`
	IncompleteResults *bool  `json:"incomplete_results,omitempty"`
	Users             []User `json:"items,omitempty"`
}
func (s *SearchService) Users(ctx context.Context, query string, opt *SearchOptions) (*UsersSearchResult, *Response, error) {
	result := new(UsersSearchResult)
	resp, err := s.search(ctx, "users", &searchParameters{Query: query}, opt, result)
	return result, resp, err
}
type Match struct {
	Text    *string `json:"text,omitempty"`
	Indices []int   `json:"indices,omitempty"`
}
type TextMatch struct {
	ObjectURL  *string `json:"object_url,omitempty"`
	ObjectType *string `json:"object_type,omitempty"`
	Property   *string `json:"property,omitempty"`
	Fragment   *string `json:"fragment,omitempty"`
	Matches    []Match `json:"matches,omitempty"`
}
func (tm TextMatch) String() string {
	return Stringify(tm)
}
type CodeSearchResult struct {
	Total             *int         `json:"total_count,omitempty"`
	IncompleteResults *bool        `json:"incomplete_results,omitempty"`
	CodeResults       []CodeResult `json:"items,omitempty"`
}
type CodeResult struct {
	Name        *string     `json:"name,omitempty"`
	Path        *string     `json:"path,omitempty"`
	SHA         *string     `json:"sha,omitempty"`
	HTMLURL     *string     `json:"html_url,omitempty"`
	Repository  *Repository `json:"repository,omitempty"`
	TextMatches []TextMatch `json:"text_matches,omitempty"`
}
func (c CodeResult) String() string {
	return Stringify(c)
}
func (s *SearchService) Code(ctx context.Context, query string, opt *SearchOptions) (*CodeSearchResult, *Response, error) {
	result := new(CodeSearchResult)
	resp, err := s.search(ctx, "code", &searchParameters{Query: query}, opt, result)
	return result, resp, err
}
type LabelsSearchResult struct {
	Total             *int           `json:"total_count,omitempty"`
	IncompleteResults *bool          `json:"incomplete_results,omitempty"`
	Labels            []*LabelResult `json:"items,omitempty"`
}
type LabelResult struct {
	ID          *int64   `json:"id,omitempty"`
	URL         *string  `json:"url,omitempty"`
	Name        *string  `json:"name,omitempty"`
	Color       *string  `json:"color,omitempty"`
	Default     *bool    `json:"default,omitempty"`
	Description *string  `json:"description,omitempty"`
	Score       *float64 `json:"score,omitempty"`
}
func (l LabelResult) String() string {
	return Stringify(l)
}
func (s *SearchService) Labels(ctx context.Context, repoID int64, query string, opt *SearchOptions) (*LabelsSearchResult, *Response, error) {
	result := new(LabelsSearchResult)
	resp, err := s.search(ctx, "labels", &searchParameters{RepositoryID: &repoID, Query: query}, opt, result)
	return result, resp, err
}