diff --git a/go.mod b/go.mod index 903e38a..556108e 100644 --- a/go.mod +++ b/go.mod @@ -2,9 +2,14 @@ module unpackstring go 1.19 -require github.com/stretchr/testify v1.7.0 +require ( + github.com/gijsbers/go-pcre v0.0.0-20161214203829-a84f3096ab3c + github.com/stretchr/testify v1.7.0 +) require ( + github.com/GRbit/go-pcre v1.0.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) diff --git a/go.sum b/go.sum index c221f64..4e8258b 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,10 @@ +github.com/GRbit/go-pcre v1.0.1 h1:8F7Wj1rxIq8ejKSXVVW2wE+4I4VnZbuOemrMk8kn3hc= +github.com/GRbit/go-pcre v1.0.1/go.mod h1:0g7qVGbMpd2Odevd92x1RpaLpR3c3F/Gv2HEnI7CwEA= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gijsbers/go-pcre v0.0.0-20161214203829-a84f3096ab3c h1:o5z/Stj4aWUiDiCVFdEOgXcwNF+Z7mQSlvDTaWBK98Q= +github.com/gijsbers/go-pcre v0.0.0-20161214203829-a84f3096ab3c/go.mod h1:Bd83Kcti1U5OMXYYTjilhd6os+l6AmlTMVbDtaBvycQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/unpack.go b/unpack.go index 75d811a..ea9a1bd 100644 --- a/unpack.go +++ b/unpack.go @@ -2,12 +2,78 @@ package unpackstring import ( "errors" + "strconv" + "strings" + "unicode" ) var ErrInvalidString = errors.New("invalid string") -func Unpack(_ string) (string, error) { - // Place your code here. - // test +type state int + +const ( + start state = iota + escape + number +) + +func Unpack(str string) (string, error) { + var currentState state = start + var result strings.Builder + numOfRepeat := 1 + //if firstCheckString(&str) == true { + // return "", ErrInvalidString + //} + + var runeArray = []rune(str) + + if len(runeArray) > 0 && unicode.IsDigit(runeArray[0]) { + return "first rune is digit", ErrInvalidString + } + + for i, char := range runeArray { + + switch currentState { + case start: + if unicode.IsDigit(char) { + currentState = number + numOfRepeat, _ = strconv.Atoi(string(char)) + } else if char == '\\' { + currentState = escape + } else { + currentState = start + result.WriteRune(char) + } + case number: + if unicode.IsDigit(char) { + return "", ErrInvalidString + } + repStr, err := repeatRune(runeArray[i-2], numOfRepeat) + if err != nil { + res := result.String() + result.Reset() + result.WriteString(res[0 : len(res)-1]) + } + result.WriteString(repStr) + currentState = start + result.WriteRune(char) + case escape: + result.WriteRune(char) + + } + + } + + return result.String(), nil + +} + +func repeatRune(char rune, numOfRepeat int) (string, error) { + if numOfRepeat > 0 { + return strings.Repeat(string(char), numOfRepeat-1), nil + } + if numOfRepeat == 0 { + return "", errors.New("zero repeat") + } return "", nil }