Repository: goccy/go-yaml
Pull request #339 (2023-01-16 12:42:55)

Support strings starting with @
## 📟 Context

It seems that I ran into an unsupported situation when generating yaml with strings starting with `@`.

Golang playground example that shows the output: https://play.golang.com/p/ANKYK0xUXF8.

From the example above, we get the following yaml:

```yaml
k: @foobar
```

which is not valid. See [yaml linter](https://www.yamllint.com/):

![Screenshot 2023-01-16 at 13 23 53](https://user-images.githubusercontent.com/337347/212677582-6c898c3f-bbd8-4315-ade0-6a293e3460de.png)

## 🤔 What does this PR do?

* Update `token.go` so that strings starting with `@` are quoted.
* Update the related test.

## ⚙️ How to test this locally?

1. Use the code from the playground example: https://play.golang.com/p/ANKYK0xUXF8
1. Using this PR, we get the following:
    ```yaml
    k: "@foobar"
    ```
    
That's a valid YAML 🎉 


goccy: @10io Thank you for your contribution !! The changes LGTM 👍 
Please resolve conflict for token_test.go


Patch:
diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
index a2221ed..a935b3f 100644
--- a/.github/workflows/go.yml
+++ b/.github/workflows/go.yml
@@ -5,8 +5,8 @@ on:
       - master
   pull_request:
 jobs:
-  test:
-    name: Test
+  race-test:
+    name: Test with -race
     strategy:
       matrix:
         os: [ "ubuntu-latest", "macos-latest", "windows-latest" ]
@@ -22,6 +22,27 @@ jobs:
     - name: test
       run: |
         make test
+  
+  i386-test:
+    name: Test in i386
+    strategy:
+      matrix:
+        os: [ "ubuntu-latest", "windows-latest" ]
+        go-version: [ "1.18", "1.19", "1.20" ]
+    runs-on: ${{ matrix.os }}
+    env:
+      GOARCH: "386"
+    steps:
+    - name: setup Go ${{ matrix.go-version }}
+      uses: actions/setup-go@v3
+      with:
+        go-version: ${{ matrix.go-version }}
+    - name: checkout
+      uses: actions/checkout@v3
+    - name: test
+      run: |
+        make simple-test
+  
   ycat:
     name: ycat
     runs-on: ubuntu-latest
diff --git a/Makefile b/Makefile
index 45281a6..1b1d923 100644
--- a/Makefile
+++ b/Makefile
@@ -2,6 +2,10 @@
 test:
 	go test -v -race ./...
 
+.PHONY: simple-test
+simple-test:
+	go test -v ./...
+
 .PHONY: cover
 cover:
 	go test -coverprofile=cover.out ./...
diff --git a/decode.go b/decode.go
index 369ee26..6b15618 100644
--- a/decode.go
+++ b/decode.go
@@ -172,7 +172,7 @@ func (d *Decoder) addHeadOrLineCommentToMap(node ast.Node) {
 	}
 	texts := []string{}
 	targetLine := node.GetToken().Position.Line
-	minCommentLine := math.MaxInt64
+	minCommentLine := math.MaxInt
 	for _, comment := range commentGroup.Comments {
 		if minCommentLine > comment.Token.Position.Line {
 			minCommentLine = comment.Token.Position.Line
diff --git a/token/token.go b/token/token.go
index 4943023..182f4be 100644
--- a/token/token.go
+++ b/token/token.go
@@ -623,7 +623,7 @@ func IsNeedQuoted(value string) bool {
 	}
 	first := value[0]
 	switch first {
-	case '*', '&', '[', '{', '}', ']', ',', '!', '|', '>', '%', '\'', '"':
+	case '*', '&', '[', '{', '}', ']', ',', '!', '|', '>', '%', '\'', '"', '@':
 		return true
 	}
 	last := value[len(value)-1]


Test patch:
diff --git a/token/token_test.go b/token/token_test.go
index 3e14870..4f5764f 100644
--- a/token/token_test.go
+++ b/token/token_test.go
@@ -117,6 +117,7 @@ func TestIsNeedQuoted(t *testing.T) {
 		"off",
 		"Off",
 		"OFF",
+		"@test",
 	}
 	for i, test := range needQuotedTests {
 		if !token.IsNeedQuoted(test) {