<commit_before>package codegen

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/grokify/gotilla/io/ioutilmore"
	"github.com/pkg/errors"
)

func ConvertFilesInPlaceNestedstructsToPointers(dir string, rx *regexp.Regexp) ([]string, error) {
	filepaths := []string{}
	if rx == nil {
		rx = regexp.MustCompile(`.*\.go$`)
	}
	files, err := ioutilmore.DirEntriesRxSizeGt0(dir, ioutilmore.File, rx)
	if err != nil {
		return filepaths, errors.Wrap(err, "codegen.ConvertFilesInPlace.DirEntriesReNotEmpty")
	}
	for _, file := range files {
		filepath := filepath.Join(dir, file.Name())
		err := ConvertFileNestedstructsToPointers(filepath, filepath, file.Mode().Perm())
		if err != nil {
			return filepaths, errors.Wrap(err, "codegen.ConvertFilesInPlace.ConvertFile")
		}
		filepaths = append(filepaths, filepath)
	}
	return filepaths, nil
}

func ConvertFileNestedstructsToPointers(inFile, outFile string, perm os.FileMode) error {
	data, err := ioutil.ReadFile(inFile)
	if err != nil {
		return err
	}
	newLines := GoCodeNestedstructsToPointers(string(data))
	return ioutil.WriteFile(outFile, []byte(newLines), perm)
}

var (
	rxParenOpen  = regexp.MustCompile(`^type\s+\S+\s+struct\s+{\s*$`)
	rxParenClose = regexp.MustCompile(`^\s*}\s*$`)
	rxCustomType = regexp.MustCompile(`^(\s*[0-9A-Za-z]+\s+(?:[0-9a-z\]\[]+\])?)([A-Z].*)$`)
)

// GoCodeNestedstructsToPointers is designed to convert
// nested structs to pointers.
func GoCodeNestedstructsToPointers(code string) string {
	oldLines := strings.Split(code, "\n")
	newLines := []string{}
	inParen := false
	for _, line := range oldLines {
		if rxParenOpen.MatchString(line) {
			inParen = true
			newLines = append(newLines, line)
			continue
		} else if rxParenClose.MatchString(line) {<commit_msg>streamline code<commit_after>package codegen

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/grokify/gotilla/io/ioutilmore"
	"github.com/pkg/errors"
)

func ConvertFilesInPlaceNestedstructsToPointers(dir string, rx *regexp.Regexp) ([]string, error) {
	filepaths := []string{}
	if rx == nil {
		rx = regexp.MustCompile(`.*\.go$`)
	}
	files, err := ioutilmore.DirEntriesRxSizeGt0(dir, ioutilmore.File, rx)
	if err != nil {
		return filepaths, errors.Wrap(err, "codegen.ConvertFilesInPlace.DirEntriesReNotEmpty")
	}
	for _, file := range files {
		filepath := filepath.Join(dir, file.Name())
		err := ConvertFileNestedstructsToPointers(filepath, filepath, file.Mode().Perm())
		if err != nil {
			return filepaths, errors.Wrap(err, "codegen.ConvertFilesInPlace.ConvertFile")
		}
		filepaths = append(filepaths, filepath)
	}
	return filepaths, nil
}

func ConvertFileNestedstructsToPointers(inFile, outFile string, perm os.FileMode) error {
	data, err := ioutil.ReadFile(inFile)
	if err != nil {
		return err
	}
	return ioutil.WriteFile(
		outFile,
		[]byte(GoCodeNestedstructsToPointers(string(data))),
		perm)
}

var (
	rxParenOpen  = regexp.MustCompile(`^type\s+\S+\s+struct\s+{\s*$`)
	rxParenClose = regexp.MustCompile(`^\s*}\s*$`)
	rxCustomType = regexp.MustCompile(`^(\s*[0-9A-Za-z]+\s+(?:[0-9a-z\]\[]+\])?)([A-Z].*)$`)
)

// GoCodeNestedstructsToPointers is designed to convert
// nested structs to pointers.
func GoCodeNestedstructsToPointers(code string) string {
	oldLines := strings.Split(code, "\n")
	newLines := []string{}
	inParen := false
	for _, line := range oldLines {
		if rxParenOpen.MatchString(line) {
			inParen = true
			newLines = append(newLines, line)
			continue
		} else if rxParenClose.MatchString(line) {
{'fraction_non_alphanumeric': 0.15758260378424174, 'fraction_numerical': 0.002824060999717594, 'mean_word_length': 4.873963515754561, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3081269', 'n_tokens_mistral': 1401, 'n_tokens_neox': 1331, 'n_words': 246}