commit
65dca5de6e
17
unpack.go
17
unpack.go
|
@ -7,8 +7,10 @@ import (
|
|||
"unicode"
|
||||
)
|
||||
|
||||
// ErrInvalidString - Определение пользовательской ошибки для недопустимой строки.
|
||||
var ErrInvalidString = errors.New("invalid string")
|
||||
|
||||
// state - Тип-перечисление для представления состояния автомата.
|
||||
type state int
|
||||
|
||||
const (
|
||||
|
@ -17,6 +19,7 @@ const (
|
|||
number
|
||||
)
|
||||
|
||||
// Unpack - Функция для распаковки строки в заданном формате.
|
||||
func Unpack(str string) (string, error) {
|
||||
var currentState state = start
|
||||
var result strings.Builder
|
||||
|
@ -25,6 +28,7 @@ func Unpack(str string) (string, error) {
|
|||
var runeArray = []rune(str)
|
||||
|
||||
if len(runeArray) > 0 && unicode.IsDigit(runeArray[0]) {
|
||||
// Если первый символ является цифрой, возвращаем ошибку "недопустимой строки".
|
||||
return "first rune is digit", ErrInvalidString
|
||||
}
|
||||
|
||||
|
@ -37,6 +41,7 @@ func Unpack(str string) (string, error) {
|
|||
numOfRepeat, _ = strconv.Atoi(string(char))
|
||||
repStr, err := repeatRune(runeArray[i-1], numOfRepeat)
|
||||
if err != nil {
|
||||
// Если функция repeatRune возвращает ошибку, удаляем последний символ из результата.
|
||||
res := result.String()
|
||||
result.Reset()
|
||||
result.WriteString(res[0 : len(res)-1])
|
||||
|
@ -45,16 +50,18 @@ func Unpack(str string) (string, error) {
|
|||
} else if char == '\\' {
|
||||
currentState = escape
|
||||
} else {
|
||||
currentState = start
|
||||
result.WriteRune(char)
|
||||
currentState = start
|
||||
}
|
||||
case number:
|
||||
if unicode.IsDigit(char) {
|
||||
// Если после цифры идет ещё одна цифра, возвращаем ошибку "недопустимой строки".
|
||||
return "", ErrInvalidString
|
||||
}
|
||||
currentState = start
|
||||
result.WriteRune(char)
|
||||
currentState = start
|
||||
case escape:
|
||||
// Если текущий символ - обратный слэш, добавляем его в результат.
|
||||
result.WriteRune(char)
|
||||
currentState = start
|
||||
}
|
||||
|
@ -65,12 +72,16 @@ func Unpack(str string) (string, error) {
|
|||
|
||||
}
|
||||
|
||||
// repeatRune - Функция для повторения символа заданное количество раз.
|
||||
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
|
||||
// Возвращаем пустую строку для отрицательных значений numOfRepeat.
|
||||
return "", errors.New("negative repeat")
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ func TestUnpack(t *testing.T) {
|
|||
{input: "a2", expected: "aa"},
|
||||
{input: "aa", expected: "aa"},
|
||||
{input: "a", expected: "a"},
|
||||
{input: "日本語", expected: "日本語"},
|
||||
{input: "日本語2", expected: "日本語語"},
|
||||
{input: "d\n5abc", expected: "d\n\n\n\n\nabc"},
|
||||
{input: `qwe\4\5`, expected: `qwe45`},
|
||||
{input: `qwe\45`, expected: `qwe44444`},
|
||||
|
|
Loading…
Reference in New Issue