grokify/mogo

View on GitHub
codegen/nestedstructtopointer.go

Summary

Maintainability
A
0 mins
Test Coverage
package codegen

import (
    "fmt"
    "os"
    "path/filepath"
    "regexp"
    "strings"

    "github.com/grokify/mogo/errors/errorsutil"
    "github.com/grokify/mogo/os/osutil"
)

func ConvertFilesInPlaceNestedstructsToPointers(dir string, rx *regexp.Regexp) ([]string, error) {
    filenames := []string{}
    if rx == nil {
        rx = regexp.MustCompile(`.*\.go$`)
    }
    entries, err := osutil.ReadDirMore(dir, rx, false, true, false)
    // files, err := os.DirEntriesRxSizeGt0(dir, ioutilmore.File, rx)
    if err != nil {
        return filenames, errorsutil.Wrap(err, "codegen.ConvertFilesInPlace.ReadDirMore")
    }
    //filenames := os.DirEntries(entries).Names(dir, true)
    //for _, filename := range filenames {
    for _, entry := range entries {
        filename := filepath.Join(dir, entry.Name())
        fileinfo, err := entry.Info()
        if err != nil {
            return filenames, errorsutil.Wrap(err, fmt.Sprintf("codegen.ConvertFilesInPlaceNestedstructsToPointers...entry.Info() [%s]", entry.Name()))
        }
        err = ConvertFileNestedstructsToPointers(filename, filename, fileinfo.Mode().Perm())
        if err != nil {
            return filenames, errorsutil.Wrap(err, "codegen.ConvertFilesInPlace.ConvertFile")
        }
        filenames = append(filenames, filename)
    }
    return filenames, nil
}

func ConvertFileNestedstructsToPointers(inFile, outFile string, perm os.FileMode) error {
    data, err := os.ReadFile(inFile)
    if err != nil {
        return err
    }
    return os.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) {
            inParen = false
            newLines = append(newLines, line)
            continue
        } else if inParen {
            m := rxCustomType.FindStringSubmatch(line)
            if len(m) > 0 {
                newLines = append(newLines, m[1]+"*"+m[2])
                continue
            }
        }
        newLines = append(newLines, line)
    }
    return strings.Join(newLines, "\n")
}